5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2008 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
23 #include "groups_internal.h"
25 /************************** Types and definitions ***************************/
27 /* Structure to hold all SKE callbacks. */
28 struct SilcSKECallbacksStruct {
29 SilcSKEVerifyCb verify_key;
30 SilcSKECompletionCb completed;
34 /************************ Static utility functions **************************/
37 SILC_FSM_STATE(silc_ske_st_initiator_start);
38 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
39 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
40 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
41 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
42 SILC_FSM_STATE(silc_ske_st_initiator_end);
43 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
44 SILC_FSM_STATE(silc_ske_st_initiator_error);
45 SILC_FSM_STATE(silc_ske_st_initiator_failure);
46 SILC_FSM_STATE(silc_ske_st_responder_start);
47 SILC_FSM_STATE(silc_ske_st_responder_phase1);
48 SILC_FSM_STATE(silc_ske_st_responder_phase2);
49 SILC_FSM_STATE(silc_ske_st_responder_phase4);
50 SILC_FSM_STATE(silc_ske_st_responder_phase5);
51 SILC_FSM_STATE(silc_ske_st_responder_end);
52 SILC_FSM_STATE(silc_ske_st_responder_aborted);
53 SILC_FSM_STATE(silc_ske_st_responder_failure);
54 SILC_FSM_STATE(silc_ske_st_responder_error);
55 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
56 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done);
57 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end);
58 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait);
59 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
60 SILC_FSM_STATE(silc_ske_st_rekey_responder_done);
61 SILC_FSM_STATE(silc_ske_st_rekey_responder_end);
62 SILC_TASK_CALLBACK(silc_ske_packet_send_retry);
65 silc_ske_process_key_material(SilcSKE ske,
66 SilcUInt32 req_iv_len,
67 SilcUInt32 req_enc_key_len,
68 SilcUInt32 req_hmac_key_len,
69 SilcSKERekeyMaterial *rekey);
70 static SilcBool silc_ske_packet_send(SilcSKE ske,
72 SilcPacketFlags flags,
73 const unsigned char *data,
78 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
79 SilcPacketStream stream,
81 void *callback_context,
84 SilcSKE ske = callback_context;
86 /* Clear retransmission */
87 ske->retry_timer = SILC_SKE_RETRY_MIN;
89 silc_schedule_task_del_by_callback(ske->schedule,
90 silc_ske_packet_send_retry);
92 /* Signal for new packet */
95 /* Check if we were aborted */
97 silc_packet_free(packet);
101 silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
103 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
105 silc_fsm_continue_sync(&ske->fsm);
109 /* See if received failure from remote */
110 if (packet->type == SILC_PACKET_FAILURE) {
112 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
114 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
117 /* Handle rekey and SUCCESS packets synchronously. After SUCCESS packets
118 they keys are taken into use immediately, hence the synchronous
119 processing to get the keys in use as soon as possible. */
120 if (ske->rekeying || packet->type == SILC_PACKET_SUCCESS)
121 silc_fsm_continue_sync(&ske->fsm);
123 silc_fsm_continue(&ske->fsm);
128 /* Packet stream callbacks */
129 static SilcPacketCallbacks silc_ske_stream_cbs =
131 silc_ske_packet_receive, NULL, NULL
134 /* Aborts SKE protocol */
136 static void silc_ske_abort(SilcAsyncOperation op, void *context)
138 SilcSKE ske = context;
142 /* Public key verification completion callback */
144 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
145 void *completion_context)
147 ske->status = status;
148 SILC_FSM_CALL_CONTINUE(&ske->fsm);
151 /* SKR find callback */
153 static void silc_ske_skr_callback(SilcSKR repository,
155 SilcSKRStatus status,
156 SilcDList keys, void *context)
158 SilcSKE ske = context;
160 silc_skr_find_free(find);
162 if (status != SILC_SKR_OK) {
163 if (ske->callbacks->verify_key) {
164 /* Verify from application */
165 ske->callbacks->verify_key(ske, ske->prop->public_key,
166 ske->callbacks->context,
167 silc_ske_pk_verified, NULL);
173 silc_dlist_uninit(keys);
176 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
177 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
178 SILC_FSM_CALL_CONTINUE(&ske->fsm);
181 /* Checks remote and local versions */
183 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
185 SilcUInt32 r_software_version = 0;
186 char *r_software_string = NULL;
188 if (!ske->remote_version || !ske->version)
189 return SILC_SKE_STATUS_BAD_VERSION;
191 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
193 &r_software_string, NULL))
194 return SILC_SKE_STATUS_BAD_VERSION;
196 return SILC_SKE_STATUS_OK;
199 /* Selects the supported security properties from the initiator's Key
200 Exchange Start Payload. A responder function. Saves our reply
201 start payload to ske->start_payload. */
204 silc_ske_select_security_properties(SilcSKE ske,
205 SilcSKEStartPayload remote_payload,
206 SilcSKESecurityProperties *prop)
208 SilcSKEStatus status;
209 SilcSKEStartPayload rp, payload;
213 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
217 /* Check for mandatory fields */
218 if (!rp->ke_grp_len) {
219 SILC_LOG_DEBUG(("KE group not defined in payload"));
220 return SILC_SKE_STATUS_BAD_PAYLOAD;
222 if (!rp->pkcs_alg_len) {
223 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
224 return SILC_SKE_STATUS_BAD_PAYLOAD;
226 if (!rp->enc_alg_len) {
227 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
228 return SILC_SKE_STATUS_BAD_PAYLOAD;
230 if (!rp->hash_alg_len) {
231 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
232 return SILC_SKE_STATUS_BAD_PAYLOAD;
234 if (!rp->hmac_alg_len) {
235 SILC_LOG_DEBUG(("HMAC not defined in payload"));
236 return SILC_SKE_STATUS_BAD_PAYLOAD;
239 /* Allocate security properties */
240 *prop = silc_calloc(1, sizeof(**prop));
242 return SILC_SKE_STATUS_OUT_OF_MEMORY;
244 /* Allocate our reply start payload */
245 payload = silc_calloc(1, sizeof(*payload));
248 return SILC_SKE_STATUS_OUT_OF_MEMORY;
251 /* Check version string */
252 ske->remote_version = silc_memdup(rp->version, rp->version_len);
253 status = silc_ske_check_version(ske);
254 if (status != SILC_SKE_STATUS_OK) {
255 ske->status = status;
259 /* Flags are returned unchanged. */
260 (*prop)->flags = payload->flags = rp->flags;
262 /* Take cookie, we must return it to sender unmodified. */
263 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
264 if (!payload->cookie) {
265 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
268 payload->cookie_len = SILC_SKE_COOKIE_LEN;
269 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
271 /* In case IV included flag and session port is set the first 16-bits of
272 cookie will include our session port. */
273 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
274 /* Take remote port */
275 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
278 SILC_PUT16_MSB(ske->session_port, payload->cookie);
281 /* Put our version to our reply */
282 payload->version = strdup(ske->version);
283 if (!payload->version) {
284 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
287 payload->version_len = strlen(ske->version);
289 /* Get supported Key Exchange groups */
290 cp = rp->ke_grp_list;
291 if (cp && strchr(cp, ',')) {
295 len = strcspn(cp, ",");
296 item = silc_calloc(len + 1, sizeof(char));
298 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
301 memcpy(item, cp, len);
303 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
305 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
306 SILC_LOG_DEBUG(("Found KE group `%s'", item));
308 payload->ke_grp_len = len;
309 payload->ke_grp_list = item;
323 if (!payload->ke_grp_len && !payload->ke_grp_list) {
324 SILC_LOG_DEBUG(("Could not find supported KE group"));
326 return SILC_SKE_STATUS_UNKNOWN_GROUP;
329 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
330 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
332 payload->ke_grp_len = rp->ke_grp_len;
333 payload->ke_grp_list = strdup(rp->ke_grp_list);
336 /* Save group to security properties */
337 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
338 if (status != SILC_SKE_STATUS_OK) {
340 return SILC_SKE_STATUS_UNKNOWN_GROUP;
343 /* Get supported PKCS algorithms */
344 cp = rp->pkcs_alg_list;
345 if (cp && strchr(cp, ',')) {
349 len = strcspn(cp, ",");
350 item = silc_calloc(len + 1, sizeof(char));
352 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
355 memcpy(item, cp, len);
357 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
359 if (silc_pkcs_find_algorithm(item, NULL)) {
360 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
362 payload->pkcs_alg_len = len;
363 payload->pkcs_alg_list = item;
377 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
378 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
379 silc_free(payload->ke_grp_list);
381 return SILC_SKE_STATUS_UNKNOWN_PKCS;
384 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
385 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
387 payload->pkcs_alg_len = rp->pkcs_alg_len;
388 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
391 /* Get supported encryption algorithms */
392 cp = rp->enc_alg_list;
393 if (cp && strchr(cp, ',')) {
397 len = strcspn(cp, ",");
398 item = silc_calloc(len + 1, sizeof(char));
400 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
403 memcpy(item, cp, len);
405 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
407 if (silc_cipher_is_supported(item) == TRUE) {
408 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
410 payload->enc_alg_len = len;
411 payload->enc_alg_list = item;
425 if (!payload->enc_alg_len && !payload->enc_alg_list) {
426 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
427 silc_free(payload->ke_grp_list);
428 silc_free(payload->pkcs_alg_list);
430 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
433 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
436 payload->enc_alg_len = rp->enc_alg_len;
437 payload->enc_alg_list = strdup(rp->enc_alg_list);
440 /* Save selected cipher to security properties */
441 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
442 silc_free(payload->ke_grp_list);
443 silc_free(payload->pkcs_alg_list);
445 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
448 /* Get supported hash algorithms */
449 cp = rp->hash_alg_list;
450 if (cp && strchr(cp, ',')) {
454 len = strcspn(cp, ",");
455 item = silc_calloc(len + 1, sizeof(char));
457 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
460 memcpy(item, cp, len);
462 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
464 if (silc_hash_is_supported(item) == TRUE) {
465 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
467 payload->hash_alg_len = len;
468 payload->hash_alg_list = item;
482 if (!payload->hash_alg_len && !payload->hash_alg_list) {
483 SILC_LOG_DEBUG(("Could not find supported hash alg"));
484 silc_free(payload->ke_grp_list);
485 silc_free(payload->pkcs_alg_list);
486 silc_free(payload->enc_alg_list);
488 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
491 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
494 payload->hash_alg_len = rp->hash_alg_len;
495 payload->hash_alg_list = strdup(rp->hash_alg_list);
498 /* Save selected hash algorithm to security properties */
499 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
500 silc_free(payload->ke_grp_list);
501 silc_free(payload->pkcs_alg_list);
502 silc_free(payload->enc_alg_list);
504 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
507 /* Get supported HMACs */
508 cp = rp->hmac_alg_list;
509 if (cp && strchr(cp, ',')) {
513 len = strcspn(cp, ",");
514 item = silc_calloc(len + 1, sizeof(char));
516 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
519 memcpy(item, cp, len);
521 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
523 if (silc_hmac_is_supported(item) == TRUE) {
524 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
526 payload->hmac_alg_len = len;
527 payload->hmac_alg_list = item;
541 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
542 SILC_LOG_DEBUG(("Could not find supported HMAC"));
543 silc_free(payload->ke_grp_list);
544 silc_free(payload->pkcs_alg_list);
545 silc_free(payload->enc_alg_list);
546 silc_free(payload->hash_alg_list);
548 return SILC_SKE_STATUS_UNKNOWN_HMAC;
551 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
554 payload->hmac_alg_len = rp->hmac_alg_len;
555 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
558 /* Save selected HMACc to security properties */
559 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
560 silc_free(payload->ke_grp_list);
561 silc_free(payload->pkcs_alg_list);
562 silc_free(payload->enc_alg_list);
563 silc_free(payload->hash_alg_list);
565 return SILC_SKE_STATUS_UNKNOWN_HMAC;
568 /* Get supported compression algorithms */
569 cp = rp->comp_alg_list;
570 if (cp && strchr(cp, ',')) {
574 len = strcspn(cp, ",");
575 item = silc_calloc(len + 1, sizeof(char));
577 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
580 memcpy(item, cp, len);
582 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
585 if (!strcmp(item, "none")) {
586 SILC_LOG_DEBUG(("Found Compression `%s'", item));
587 payload->comp_alg_len = len;
588 payload->comp_alg_list = item;
592 if (silc_hmac_is_supported(item) == TRUE) {
593 SILC_LOG_DEBUG(("Found Compression `%s'", item));
594 payload->comp_alg_len = len;
595 payload->comp_alg_list = item;
611 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
612 2 + payload->version_len +
613 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
614 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
615 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
617 /* Save our reply payload */
618 ske->start_payload = payload;
620 return SILC_SKE_STATUS_OK;
623 /* Creates random number such that 1 < rnd < n and at most length
624 of len bits. The rnd sent as argument must be initialized. */
626 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
630 SilcSKEStatus status = SILC_SKE_STATUS_OK;
631 unsigned char *string;
635 return SILC_SKE_STATUS_ERROR;
637 SILC_LOG_DEBUG(("Creating random number"));
641 /* Get the random number as string */
642 string = silc_rng_get_rn_data(ske->rng, l);
644 return SILC_SKE_STATUS_OUT_OF_MEMORY;
646 /* Decode the string into a MP integer */
647 silc_mp_bin2mp(string, l, rnd);
648 silc_mp_mod_2exp(rnd, rnd, len);
651 if (silc_mp_cmp_ui(rnd, 1) < 0)
652 status = SILC_SKE_STATUS_ERROR;
653 if (silc_mp_cmp(rnd, n) >= 0)
654 status = SILC_SKE_STATUS_ERROR;
656 memset(string, 'F', l);
662 /* Creates a hash value HASH as defined in the SKE protocol. If the
663 `initiator' is TRUE then this function is used to create the HASH_i
664 hash value defined in the protocol. If it is FALSE then this is used
665 to create the HASH value defined by the protocol. */
667 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
668 unsigned char *return_hash,
669 SilcUInt32 *return_hash_len,
672 SilcSKEStatus status = SILC_SKE_STATUS_OK;
674 unsigned char *e, *f, *KEY, *s_data;
675 SilcUInt32 e_len, f_len, KEY_len, s_len;
678 SILC_LOG_DEBUG(("Start"));
680 if (initiator == FALSE) {
681 s_data = (ske->start_payload_copy ?
682 silc_buffer_data(ske->start_payload_copy) : NULL);
683 s_len = (ske->start_payload_copy ?
684 silc_buffer_len(ske->start_payload_copy) : 0);
685 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
686 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
687 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
689 /* Format the buffer used to compute the hash value */
690 buf = silc_buffer_alloc_size(s_len +
691 ske->ke2_payload->pk_len +
692 ske->ke1_payload->pk_len +
693 e_len + f_len + KEY_len);
695 return SILC_SKE_STATUS_OUT_OF_MEMORY;
697 /* Initiator is not required to send its public key */
698 if (!ske->ke1_payload->pk_data) {
700 silc_buffer_format(buf,
701 SILC_STR_DATA(s_data, s_len),
702 SILC_STR_DATA(ske->ke2_payload->pk_data,
703 ske->ke2_payload->pk_len),
704 SILC_STR_DATA(e, e_len),
705 SILC_STR_DATA(f, f_len),
706 SILC_STR_DATA(KEY, KEY_len),
710 silc_buffer_format(buf,
711 SILC_STR_DATA(s_data, s_len),
712 SILC_STR_DATA(ske->ke2_payload->pk_data,
713 ske->ke2_payload->pk_len),
714 SILC_STR_DATA(ske->ke1_payload->pk_data,
715 ske->ke1_payload->pk_len),
716 SILC_STR_DATA(e, e_len),
717 SILC_STR_DATA(f, f_len),
718 SILC_STR_DATA(KEY, KEY_len),
722 silc_buffer_free(buf);
725 memset(KEY, 0, KEY_len);
729 return SILC_SKE_STATUS_ERROR;
734 memset(KEY, 0, KEY_len);
739 s_data = (ske->start_payload_copy ?
740 silc_buffer_data(ske->start_payload_copy) : NULL);
741 s_len = (ske->start_payload_copy ?
742 silc_buffer_len(ske->start_payload_copy) : 0);
743 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
745 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
747 return SILC_SKE_STATUS_OUT_OF_MEMORY;
749 /* Format the buffer used to compute the hash value */
751 silc_buffer_format(buf,
752 SILC_STR_DATA(s_data, s_len),
753 SILC_STR_DATA(ske->ke1_payload->pk_data,
754 ske->ke1_payload->pk_len),
755 SILC_STR_DATA(e, e_len),
758 silc_buffer_free(buf);
761 return SILC_SKE_STATUS_ERROR;
764 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
771 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
773 *return_hash_len = silc_hash_len(ske->prop->hash);
775 if (initiator == FALSE) {
776 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
778 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
781 silc_buffer_free(buf);
786 /* Generate rekey material */
788 static SilcSKERekeyMaterial
789 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
791 SilcSKERekeyMaterial rekey;
794 /* Create rekey material */
795 rekey = silc_calloc(1, sizeof(*rekey));
800 if (ske->prop->group)
801 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
802 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
803 hash = silc_hash_get_name(ske->prop->hash);
804 rekey->hash = silc_memdup(hash, strlen(hash));
809 if (rekey->pfs == FALSE) {
810 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
811 keymat->enc_key_len / 8);
812 if (!rekey->send_enc_key) {
816 rekey->enc_key_len = keymat->enc_key_len;
822 /* Assembles security properties */
824 static SilcSKEStartPayload
825 silc_ske_assemble_security_properties(SilcSKE ske,
826 SilcSKESecurityPropertyFlag flags,
829 SilcSKEStartPayload rp;
832 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
834 rp = silc_calloc(1, sizeof(*rp));
837 rp->flags = (unsigned char)flags;
839 /* Set random cookie */
840 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
841 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
842 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
843 rp->cookie_len = SILC_SKE_COOKIE_LEN;
845 /* In case IV included flag and session port is set the first 16-bits of
846 cookie will include our session port. */
847 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
848 SILC_PUT16_MSB(ske->session_port, rp->cookie);
851 rp->version = strdup(version);
852 rp->version_len = strlen(version);
854 /* Get supported Key Exhange groups */
855 rp->ke_grp_list = silc_ske_get_supported_groups();
856 rp->ke_grp_len = strlen(rp->ke_grp_list);
858 /* Get supported PKCS algorithms */
859 rp->pkcs_alg_list = silc_pkcs_get_supported();
860 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
862 /* Get supported encryption algorithms */
863 rp->enc_alg_list = silc_cipher_get_supported();
864 rp->enc_alg_len = strlen(rp->enc_alg_list);
866 /* Get supported hash algorithms */
867 rp->hash_alg_list = silc_hash_get_supported();
868 rp->hash_alg_len = strlen(rp->hash_alg_list);
870 /* Get supported HMACs */
871 rp->hmac_alg_list = silc_hmac_get_supported();
872 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
875 /* Get supported compression algorithms */
876 rp->comp_alg_list = strdup("none");
877 rp->comp_alg_len = strlen("none");
879 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
880 2 + rp->version_len +
881 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
882 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
883 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
888 /* Packet retransmission callback. */
890 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
892 SilcSKE ske = context;
894 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
896 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
897 ske->retry_count = 0;
898 ske->retry_timer = SILC_SKE_RETRY_MIN;
899 silc_free(ske->retrans.data);
900 ske->retrans.data = NULL;
901 ske->status = SILC_SKE_STATUS_TIMEOUT;
903 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
905 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
906 silc_fsm_continue_sync(&ske->fsm);
910 SILC_LOG_DEBUG(("Retransmitting packet"));
911 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
912 ske->retrans.data, ske->retrans.data_len);
915 /* Install retransmission timer */
917 static void silc_ske_install_retransmission(SilcSKE ske)
919 if (!silc_packet_stream_is_udp(ske->stream))
922 if (ske->retrans.data) {
923 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
925 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
926 ske, ske->retry_timer, 0);
928 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
929 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
932 /* Sends SILC packet. Handles retransmissions with UDP streams. */
934 static SilcBool silc_ske_packet_send(SilcSKE ske,
936 SilcPacketFlags flags,
937 const unsigned char *data,
942 /* Send the packet */
943 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
945 if (silc_packet_stream_is_udp(ske->stream) &&
946 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
947 silc_free(ske->retrans.data);
948 ske->retrans.type = type;
949 ske->retrans.flags = flags;
950 ske->retrans.data = silc_memdup(data, data_len);
951 ske->retrans.data_len = data_len;
952 silc_ske_install_retransmission(ske);
958 /* Calls completion callback. Completion is called always in this function
959 and must not be called anywhere else. */
961 static void silc_ske_completion(SilcSKE ske)
963 /* Call the completion callback */
964 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
965 if (ske->status != SILC_SKE_STATUS_OK)
966 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
967 ske->callbacks->context);
969 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
970 ske->rekey, ske->callbacks->context);
974 /* SKE FSM destructor. */
976 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
977 void *destructor_context)
979 SilcSKE ske = fsm_context;
980 ske->running = FALSE;
985 /* Key exchange timeout task callback */
987 SILC_TASK_CALLBACK(silc_ske_timeout)
989 SilcSKE ske = context;
991 SILC_LOG_DEBUG(("Timeout"));
994 ske->status = SILC_SKE_STATUS_TIMEOUT;
996 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
998 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1000 silc_fsm_continue_sync(&ske->fsm);
1003 /******************************* Protocol API *******************************/
1005 /* Allocates new SKE object. */
1007 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1008 SilcSKR repository, SilcPublicKey public_key,
1009 SilcPrivateKey private_key, void *context)
1013 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1015 if (!rng || !schedule)
1019 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1023 ske = silc_calloc(1, sizeof(*ske));
1026 ske->status = SILC_SKE_STATUS_OK;
1028 ske->repository = repository;
1029 ske->user_data = context;
1030 ske->schedule = schedule;
1031 ske->public_key = public_key;
1032 ske->private_key = private_key;
1033 ske->retry_timer = SILC_SKE_RETRY_MIN;
1039 /* Free's SKE object. */
1041 void silc_ske_free(SilcSKE ske)
1043 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1052 /* If already aborted, destroy the session immediately */
1054 ske->status = SILC_SKE_STATUS_ERROR;
1056 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1058 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1059 silc_fsm_continue_sync(&ske->fsm);
1065 if (ske->refcnt > 0)
1068 /* Free start payload */
1069 if (ske->start_payload)
1070 silc_ske_payload_start_free(ske->start_payload);
1072 /* Free KE payload */
1073 if (ske->ke1_payload)
1074 silc_ske_payload_ke_free(ske->ke1_payload);
1075 if (ske->ke2_payload)
1076 silc_ske_payload_ke_free(ske->ke2_payload);
1077 silc_free(ske->remote_version);
1081 if (ske->prop->group)
1082 silc_ske_group_free(ske->prop->group);
1083 if (ske->prop->cipher)
1084 silc_cipher_free(ske->prop->cipher);
1085 if (ske->prop->hash)
1086 silc_hash_free(ske->prop->hash);
1087 if (ske->prop->hmac)
1088 silc_hmac_free(ske->prop->hmac);
1089 if (ske->prop->public_key)
1090 silc_pkcs_public_key_free(ske->prop->public_key);
1091 silc_free(ske->prop);
1094 silc_ske_free_key_material(ske->keymat);
1095 if (ske->start_payload_copy)
1096 silc_buffer_free(ske->start_payload_copy);
1098 silc_mp_uninit(ske->x);
1102 silc_mp_uninit(ske->KEY);
1103 silc_free(ske->KEY);
1105 silc_free(ske->retrans.data);
1106 silc_free(ske->hash);
1107 silc_free(ske->callbacks);
1109 memset(ske, 'F', sizeof(*ske));
1113 /* Return user context */
1115 void *silc_ske_get_context(SilcSKE ske)
1117 return ske->user_data;
1120 /* Sets protocol callbacks */
1122 void silc_ske_set_callbacks(SilcSKE ske,
1123 SilcSKEVerifyCb verify_key,
1124 SilcSKECompletionCb completed,
1128 silc_free(ske->callbacks);
1129 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1130 if (!ske->callbacks)
1132 ske->callbacks->verify_key = verify_key;
1133 ske->callbacks->completed = completed;
1134 ske->callbacks->context = context;
1138 /******************************** Initiator *********************************/
1140 /* Start protocol. Send our proposal */
1142 SILC_FSM_STATE(silc_ske_st_initiator_start)
1144 SilcSKE ske = fsm_context;
1145 SilcBuffer payload_buf;
1148 SILC_LOG_DEBUG(("Start"));
1152 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1153 return SILC_FSM_CONTINUE;
1156 /* Encode the payload */
1157 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1159 if (status != SILC_SKE_STATUS_OK) {
1160 /** Error encoding Start Payload */
1161 ske->status = status;
1162 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1163 return SILC_FSM_CONTINUE;
1166 /* Save the the payload buffer for future use. It is later used to
1167 compute the HASH value. */
1168 ske->start_payload_copy = payload_buf;
1170 /* Send the packet. */
1171 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1172 silc_buffer_data(payload_buf),
1173 silc_buffer_len(payload_buf))) {
1174 /** Error sending packet */
1175 SILC_LOG_DEBUG(("Error sending packet"));
1176 ske->status = SILC_SKE_STATUS_ERROR;
1177 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1178 return SILC_FSM_CONTINUE;
1181 /* Add key exchange timeout */
1182 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1183 ske, ske->timeout, 0);
1185 /** Wait for responder proposal */
1186 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1187 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1188 return SILC_FSM_WAIT;
1191 /* Phase-1. Receives responder's proposal */
1193 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1195 SilcSKE ske = fsm_context;
1196 SilcSKEStatus status;
1197 SilcSKEStartPayload payload;
1198 SilcSKESecurityProperties prop;
1199 SilcSKEDiffieHellmanGroup group = NULL;
1200 SilcBuffer packet_buf = &ske->packet->buffer;
1201 SilcUInt16 remote_port = 0;
1205 SILC_LOG_DEBUG(("Start"));
1207 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1208 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1209 silc_ske_install_retransmission(ske);
1210 silc_packet_free(ske->packet);
1212 return SILC_FSM_WAIT;
1215 /* Decode the payload */
1216 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1217 if (status != SILC_SKE_STATUS_OK) {
1218 /** Error decoding Start Payload */
1219 silc_packet_free(ske->packet);
1221 ske->status = status;
1222 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1223 return SILC_FSM_CONTINUE;
1226 /* Get remote ID and set it to stream */
1227 if (ske->packet->src_id_len) {
1228 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1229 ske->packet->src_id_type,
1230 (ske->packet->src_id_type == SILC_ID_SERVER ?
1231 (void *)&id.u.server_id : (void *)&id.u.client_id),
1232 (ske->packet->src_id_type == SILC_ID_SERVER ?
1233 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1234 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1235 (ske->packet->src_id_type == SILC_ID_SERVER ?
1236 (void *)&id.u.server_id : (void *)&id.u.client_id));
1239 silc_packet_free(ske->packet);
1242 /* Check that the cookie is returned unmodified. In case IV included
1243 flag and session port has been set, the first two bytes of cookie
1244 are the session port and we ignore them in this check. */
1245 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1246 /* Take remote port */
1247 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1250 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1251 SILC_SKE_COOKIE_LEN - coff)) {
1252 /** Invalid cookie */
1253 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1254 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1255 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1256 return SILC_FSM_CONTINUE;
1259 /* Check version string */
1260 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1261 status = silc_ske_check_version(ske);
1262 if (status != SILC_SKE_STATUS_OK) {
1263 /** Version mismatch */
1264 ske->status = status;
1265 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1266 return SILC_FSM_CONTINUE;
1269 /* Free our KE Start Payload context, we don't need it anymore. */
1270 silc_ske_payload_start_free(ske->start_payload);
1271 ske->start_payload = NULL;
1273 /* Take the selected security properties into use while doing
1274 the key exchange. This is used only while doing the key
1276 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1279 prop->flags = payload->flags;
1280 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1281 if (status != SILC_SKE_STATUS_OK)
1284 prop->group = group;
1285 prop->remote_port = remote_port;
1287 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1288 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1291 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1292 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1295 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1296 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1299 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1300 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1304 /* Save remote's KE Start Payload */
1305 ske->start_payload = payload;
1307 /** Send KE Payload */
1308 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1309 return SILC_FSM_CONTINUE;
1313 silc_ske_payload_start_free(payload);
1315 silc_ske_group_free(group);
1317 silc_cipher_free(prop->cipher);
1319 silc_hash_free(prop->hash);
1321 silc_hmac_free(prop->hmac);
1325 if (status == SILC_SKE_STATUS_OK)
1326 status = SILC_SKE_STATUS_ERROR;
1329 ske->status = status;
1330 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1331 return SILC_FSM_CONTINUE;
1334 /* Phase-2. Send KE payload */
1336 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1338 SilcSKE ske = fsm_context;
1339 SilcSKEStatus status;
1340 SilcBuffer payload_buf;
1342 SilcSKEKEPayload payload;
1345 SILC_LOG_DEBUG(("Start"));
1347 /* Create the random number x, 1 < x < q. */
1348 x = silc_calloc(1, sizeof(*x));
1350 /** Out of memory */
1351 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1352 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1353 return SILC_FSM_CONTINUE;
1357 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1358 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1360 if (status != SILC_SKE_STATUS_OK) {
1361 /** Error generating random number */
1364 ske->status = status;
1365 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1366 return SILC_FSM_CONTINUE;
1369 /* Encode the result to Key Exchange Payload. */
1371 payload = silc_calloc(1, sizeof(*payload));
1373 /** Out of memory */
1376 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1377 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1378 return SILC_FSM_CONTINUE;
1380 ske->ke1_payload = payload;
1382 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1384 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1385 silc_mp_init(&payload->x);
1386 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1387 &ske->prop->group->group);
1389 /* Get public key */
1390 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1391 if (!payload->pk_data) {
1392 /** Error encoding public key */
1395 silc_mp_uninit(&payload->x);
1397 ske->ke1_payload = NULL;
1398 ske->status = SILC_SKE_STATUS_ERROR;
1399 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1400 return SILC_FSM_CONTINUE;
1402 payload->pk_len = pk_len;
1403 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1405 /* Compute signature data if we are doing mutual authentication */
1406 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1407 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1408 SilcUInt32 hash_len, sign_len;
1410 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1411 SILC_LOG_DEBUG(("Computing HASH_i value"));
1413 /* Compute the hash value */
1414 memset(hash, 0, sizeof(hash));
1415 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1417 SILC_LOG_DEBUG(("Signing HASH_i value"));
1419 /* Sign the hash value */
1420 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1421 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1422 /** Error computing signature */
1425 silc_mp_uninit(&payload->x);
1426 silc_free(payload->pk_data);
1428 ske->ke1_payload = NULL;
1429 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1430 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1431 return SILC_FSM_CONTINUE;
1433 payload->sign_data = silc_memdup(sign, sign_len);
1434 if (payload->sign_data)
1435 payload->sign_len = sign_len;
1436 memset(sign, 0, sizeof(sign));
1439 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1440 if (status != SILC_SKE_STATUS_OK) {
1441 /** Error encoding KE payload */
1444 silc_mp_uninit(&payload->x);
1445 silc_free(payload->pk_data);
1446 silc_free(payload->sign_data);
1448 ske->ke1_payload = NULL;
1449 ske->status = status;
1450 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1451 return SILC_FSM_CONTINUE;
1456 /* Check for backwards compatibility */
1458 /* Send the packet. */
1459 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1460 silc_buffer_data(payload_buf),
1461 silc_buffer_len(payload_buf))) {
1462 /** Error sending packet */
1463 SILC_LOG_DEBUG(("Error sending packet"));
1464 ske->status = SILC_SKE_STATUS_ERROR;
1465 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1466 return SILC_FSM_CONTINUE;
1469 silc_buffer_free(payload_buf);
1471 /** Waiting responder's KE payload */
1472 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1473 return SILC_FSM_WAIT;
1476 /* Phase-3. Process responder's KE payload */
1478 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1480 SilcSKE ske = fsm_context;
1481 SilcSKEStatus status;
1482 SilcSKEKEPayload payload;
1484 SilcBuffer packet_buf = &ske->packet->buffer;
1486 SILC_LOG_DEBUG(("Start"));
1488 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1489 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1490 silc_ske_install_retransmission(ske);
1491 silc_packet_free(ske->packet);
1493 return SILC_FSM_WAIT;
1496 /* Decode the payload */
1497 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1498 if (status != SILC_SKE_STATUS_OK) {
1499 /** Error decoding KE payload */
1500 silc_packet_free(ske->packet);
1502 ske->status = status;
1503 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1504 return SILC_FSM_CONTINUE;
1506 silc_packet_free(ske->packet);
1508 ske->ke2_payload = payload;
1510 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1511 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1512 "even though we require it"));
1513 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1517 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1519 /* Compute the shared secret key */
1520 KEY = silc_calloc(1, sizeof(*KEY));
1522 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1525 /* Decode the remote's public key */
1526 if (payload->pk_data &&
1527 !silc_pkcs_public_key_alloc(payload->pk_type,
1528 payload->pk_data, payload->pk_len,
1529 &ske->prop->public_key)) {
1530 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1531 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1535 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1537 SILC_LOG_DEBUG(("Verifying public key"));
1539 /** Waiting public key verification */
1540 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1542 /* If repository is provided, verify the key from there. */
1543 if (ske->repository) {
1546 find = silc_skr_find_alloc();
1548 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1551 silc_skr_find_set_pkcs_type(find,
1552 silc_pkcs_get_type(ske->prop->public_key));
1553 silc_skr_find_set_public_key(find, ske->prop->public_key);
1554 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1556 /* Find key from repository */
1557 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1558 find, silc_ske_skr_callback, ske));
1560 /* Verify from application */
1561 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1562 ske->callbacks->context,
1563 silc_ske_pk_verified, NULL));
1568 /** Process key material */
1569 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1570 return SILC_FSM_CONTINUE;
1573 silc_ske_payload_ke_free(payload);
1574 ske->ke2_payload = NULL;
1576 silc_mp_uninit(ske->KEY);
1577 silc_free(ske->KEY);
1580 if (status == SILC_SKE_STATUS_OK)
1581 return SILC_SKE_STATUS_ERROR;
1584 ske->status = status;
1585 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1586 return SILC_FSM_CONTINUE;
1589 /* Process key material */
1591 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1593 SilcSKE ske = fsm_context;
1594 SilcSKEStatus status;
1595 SilcSKEKEPayload payload;
1596 unsigned char hash[SILC_HASH_MAXLEN];
1597 SilcUInt32 hash_len;
1598 int key_len, block_len;
1602 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1603 return SILC_FSM_CONTINUE;
1606 /* Check result of public key verification */
1607 if (ske->status != SILC_SKE_STATUS_OK) {
1608 /** Public key not verified */
1609 SILC_LOG_DEBUG(("Public key verification failed"));
1610 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1611 return SILC_FSM_CONTINUE;
1614 payload = ske->ke2_payload;
1616 /* Compute the HASH value */
1617 SILC_LOG_DEBUG(("Computing HASH value"));
1618 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1619 if (status != SILC_SKE_STATUS_OK)
1621 ske->hash = silc_memdup(hash, hash_len);
1622 ske->hash_len = hash_len;
1624 if (ske->prop->public_key) {
1625 SILC_LOG_DEBUG(("Public key is authentic"));
1626 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1628 /* Verify signature */
1629 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1630 payload->sign_len, hash, hash_len, NULL)) {
1631 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1632 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1636 SILC_LOG_DEBUG(("Signature is Ok"));
1637 memset(hash, 'F', hash_len);
1640 ske->status = SILC_SKE_STATUS_OK;
1642 /* In case we are doing rekey move to finish it. */
1645 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1646 return SILC_FSM_CONTINUE;
1649 /* Process key material */
1650 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1651 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1652 hash_len = silc_hash_len(ske->prop->hash);
1653 ske->keymat = silc_ske_process_key_material(ske, block_len,
1657 SILC_LOG_ERROR(("Error processing key material"));
1658 status = SILC_SKE_STATUS_ERROR;
1662 /* Send SUCCESS packet */
1663 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1664 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1665 /** Error sending packet */
1666 SILC_LOG_DEBUG(("Error sending packet"));
1667 ske->status = SILC_SKE_STATUS_ERROR;
1668 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1669 return SILC_FSM_CONTINUE;
1672 /** Waiting completion */
1673 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1674 return SILC_FSM_WAIT;
1677 memset(hash, 'F', sizeof(hash));
1678 silc_ske_payload_ke_free(payload);
1679 ske->ke2_payload = NULL;
1681 silc_mp_uninit(ske->KEY);
1682 silc_free(ske->KEY);
1686 memset(ske->hash, 'F', hash_len);
1687 silc_free(ske->hash);
1691 if (status == SILC_SKE_STATUS_OK)
1692 status = SILC_SKE_STATUS_ERROR;
1695 ske->status = status;
1696 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1697 return SILC_FSM_CONTINUE;
1700 /* Protocol completed */
1702 SILC_FSM_STATE(silc_ske_st_initiator_end)
1704 SilcSKE ske = fsm_context;
1706 SILC_LOG_DEBUG(("Start"));
1708 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1709 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1710 silc_ske_install_retransmission(ske);
1711 silc_packet_free(ske->packet);
1713 return SILC_FSM_WAIT;
1716 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1718 silc_packet_free(ske->packet);
1720 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1721 silc_schedule_task_del_by_context(ske->schedule, ske);
1723 /* Call completion */
1724 silc_ske_completion(ske);
1726 return SILC_FSM_FINISH;
1729 /* Aborted by application */
1731 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1733 SilcSKE ske = fsm_context;
1734 unsigned char data[4];
1736 SILC_LOG_DEBUG(("Aborted by caller"));
1738 /* Send FAILURE packet */
1739 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1740 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1742 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1743 silc_schedule_task_del_by_context(ske->schedule, ske);
1745 /* Call completion */
1746 silc_ske_completion(ske);
1748 return SILC_FSM_FINISH;
1751 /* Error occurred. Send error to remote host */
1753 SILC_FSM_STATE(silc_ske_st_initiator_error)
1755 SilcSKE ske = fsm_context;
1756 SilcSKEStatus status;
1757 unsigned char data[4];
1759 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1760 silc_ske_map_status(ske->status), ske->status));
1762 status = ske->status;
1763 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1764 status = SILC_SKE_STATUS_ERROR;
1766 /* Send FAILURE packet */
1767 SILC_PUT32_MSB((SilcUInt32)status, data);
1768 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1770 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1771 silc_schedule_task_del_by_context(ske->schedule, ske);
1773 /* Call completion */
1774 silc_ske_completion(ske);
1776 return SILC_FSM_FINISH;
1779 /* Failure received from remote */
1781 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1783 SilcSKE ske = fsm_context;
1784 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1786 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1787 SILC_GET32_MSB(error, ske->packet->buffer.data);
1788 ske->status = error;
1789 silc_packet_free(ske->packet);
1793 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1794 silc_ske_map_status(ske->status), ske->status));
1796 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1797 silc_schedule_task_del_by_context(ske->schedule, ske);
1799 /* Call completion */
1800 silc_ske_completion(ske);
1802 return SILC_FSM_FINISH;
1805 /* Starts the protocol as initiator */
1807 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1808 SilcPacketStream stream,
1809 SilcSKEParams params,
1810 SilcSKEStartPayload start_payload)
1812 SILC_LOG_DEBUG(("Start SKE as initiator"));
1814 if (!ske || !stream || !params || !params->version)
1817 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1820 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1823 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1824 ske->session_port = params->session_port;
1826 /* Generate security properties if not provided */
1827 if (!start_payload) {
1828 start_payload = silc_ske_assemble_security_properties(ske,
1835 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1836 ske->start_payload = start_payload;
1837 ske->version = params->version;
1838 ske->running = TRUE;
1840 /* Link to packet stream to get key exchange packets */
1841 ske->stream = stream;
1842 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1843 SILC_PACKET_KEY_EXCHANGE,
1844 SILC_PACKET_KEY_EXCHANGE_2,
1845 SILC_PACKET_SUCCESS,
1846 SILC_PACKET_FAILURE, -1);
1848 /* Start SKE as initiator */
1849 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1854 /******************************** Responder *********************************/
1856 /* Start protocol as responder. Wait initiator's start payload */
1858 SILC_FSM_STATE(silc_ske_st_responder_start)
1860 SilcSKE ske = fsm_context;
1862 SILC_LOG_DEBUG(("Start"));
1866 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1867 return SILC_FSM_CONTINUE;
1870 /* Add key exchange timeout */
1871 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1872 ske, ske->timeout, 0);
1874 /** Wait for initiator */
1875 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1876 return SILC_FSM_WAIT;
1879 /* Decode initiator's start payload. Select the security properties from
1880 the initiator's start payload and send our reply start payload back. */
1882 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1884 SilcSKE ske = fsm_context;
1885 SilcSKEStatus status;
1886 SilcSKEStartPayload remote_payload = NULL;
1887 SilcBuffer packet_buf = &ske->packet->buffer;
1890 SILC_LOG_DEBUG(("Start"));
1892 /* Decode the payload */
1893 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1894 if (status != SILC_SKE_STATUS_OK) {
1895 /** Error decoding Start Payload */
1896 silc_packet_free(ske->packet);
1898 ske->status = status;
1899 silc_fsm_next(fsm, silc_ske_st_responder_error);
1900 return SILC_FSM_CONTINUE;
1903 /* Get remote ID and set it to stream */
1904 if (ske->packet->src_id_len) {
1905 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1906 ske->packet->src_id_type,
1907 (ske->packet->src_id_type == SILC_ID_SERVER ?
1908 (void *)&id.u.server_id : (void *)&id.u.client_id),
1909 (ske->packet->src_id_type == SILC_ID_SERVER ?
1910 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1911 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1912 (ske->packet->src_id_type == SILC_ID_SERVER ?
1913 (void *)&id.u.server_id : (void *)&id.u.client_id));
1916 /* Take a copy of the payload buffer for future use. It is used to
1917 compute the HASH value. */
1918 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1920 silc_packet_free(ske->packet);
1923 /* Force the mutual authentication flag if we want to do it. */
1924 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1925 SILC_LOG_DEBUG(("Force mutual authentication"));
1926 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1929 /* Force PFS flag if we require it */
1930 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1931 SILC_LOG_DEBUG(("Force PFS"));
1932 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1935 /* Disable IV Included flag if requested */
1936 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1937 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1938 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1939 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1942 /* Check and select security properties */
1943 status = silc_ske_select_security_properties(ske, remote_payload,
1945 if (status != SILC_SKE_STATUS_OK) {
1946 /** Error selecting proposal */
1947 silc_ske_payload_start_free(remote_payload);
1948 ske->status = status;
1949 silc_fsm_next(fsm, silc_ske_st_responder_error);
1950 return SILC_FSM_CONTINUE;
1953 silc_ske_payload_start_free(remote_payload);
1955 /* Encode our reply payload to send the selected security properties */
1956 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1958 if (status != SILC_SKE_STATUS_OK)
1961 /* Send the packet. */
1962 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1963 silc_buffer_data(packet_buf),
1964 silc_buffer_len(packet_buf)))
1967 silc_buffer_free(packet_buf);
1969 /** Waiting initiator's KE payload */
1970 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1971 return SILC_FSM_WAIT;
1974 if (ske->prop->group)
1975 silc_ske_group_free(ske->prop->group);
1976 if (ske->prop->cipher)
1977 silc_cipher_free(ske->prop->cipher);
1978 if (ske->prop->hash)
1979 silc_hash_free(ske->prop->hash);
1980 if (ske->prop->hmac)
1981 silc_hmac_free(ske->prop->hmac);
1982 silc_free(ske->prop);
1985 if (status == SILC_SKE_STATUS_OK)
1986 status = SILC_SKE_STATUS_ERROR;
1989 ske->status = status;
1990 silc_fsm_next(fsm, silc_ske_st_responder_error);
1991 return SILC_FSM_CONTINUE;
1994 /* Phase-2. Decode initiator's KE payload */
1996 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1998 SilcSKE ske = fsm_context;
1999 SilcSKEStatus status;
2000 SilcSKEKEPayload recv_payload;
2001 SilcBuffer packet_buf = &ske->packet->buffer;
2003 SILC_LOG_DEBUG(("Start"));
2005 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2006 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2007 silc_ske_install_retransmission(ske);
2008 silc_packet_free(ske->packet);
2010 return SILC_FSM_WAIT;
2013 /* Decode Key Exchange Payload */
2014 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2015 if (status != SILC_SKE_STATUS_OK) {
2016 /** Error decoding KE payload */
2017 silc_packet_free(ske->packet);
2019 ske->status = status;
2020 silc_fsm_next(fsm, silc_ske_st_responder_error);
2021 return SILC_FSM_CONTINUE;
2024 ske->ke1_payload = recv_payload;
2026 silc_packet_free(ske->packet);
2029 /* Verify public key, except in rekey, when it is not sent */
2031 if (!recv_payload->pk_data) {
2032 /** Public key not provided */
2033 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2034 "certificate), even though we require it"));
2035 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2036 silc_fsm_next(fsm, silc_ske_st_responder_error);
2037 return SILC_FSM_CONTINUE;
2040 /* Decode the remote's public key */
2041 if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2042 recv_payload->pk_data,
2043 recv_payload->pk_len,
2044 &ske->prop->public_key)) {
2045 /** Error decoding public key */
2046 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2047 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2048 silc_fsm_next(fsm, silc_ske_st_responder_error);
2049 return SILC_FSM_CONTINUE;
2052 SILC_LOG_DEBUG(("Verifying public key"));
2054 /** Waiting public key verification */
2055 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2057 /* If repository is provided, verify the key from there. */
2058 if (ske->repository) {
2061 find = silc_skr_find_alloc();
2063 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2064 silc_fsm_next(fsm, silc_ske_st_responder_error);
2065 return SILC_FSM_CONTINUE;
2067 silc_skr_find_set_pkcs_type(find,
2068 silc_pkcs_get_type(ske->prop->public_key));
2069 silc_skr_find_set_public_key(find, ske->prop->public_key);
2070 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2072 /* Find key from repository */
2073 SILC_FSM_CALL(silc_skr_find(ske->repository,
2074 silc_fsm_get_schedule(fsm), find,
2075 silc_ske_skr_callback, ske));
2077 /* Verify from application */
2078 if (ske->callbacks->verify_key)
2079 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2080 ske->callbacks->context,
2081 silc_ske_pk_verified, NULL));
2085 /** Generate KE2 payload */
2086 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2087 return SILC_FSM_CONTINUE;
2090 /* Phase-4. Generate KE2 payload */
2092 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2094 SilcSKE ske = fsm_context;
2095 SilcSKEStatus status;
2096 SilcSKEKEPayload recv_payload, send_payload;
2101 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2102 return SILC_FSM_CONTINUE;
2105 /* Check result of public key verification */
2106 if (ske->status != SILC_SKE_STATUS_OK) {
2107 /** Public key not verified */
2108 SILC_LOG_DEBUG(("Public key verification failed"));
2109 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2110 return SILC_FSM_CONTINUE;
2113 recv_payload = ske->ke1_payload;
2115 /* The public key verification was performed only if the Mutual
2116 Authentication flag is set. */
2117 if (ske->start_payload &&
2118 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2119 unsigned char hash[SILC_HASH_MAXLEN];
2120 SilcUInt32 hash_len;
2122 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2124 /* Compute the hash value */
2125 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2126 if (status != SILC_SKE_STATUS_OK) {
2127 /** Error computing hash */
2128 ske->status = status;
2129 silc_fsm_next(fsm, silc_ske_st_responder_error);
2130 return SILC_FSM_CONTINUE;
2133 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2135 /* Verify signature */
2136 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2137 recv_payload->sign_len, hash, hash_len, NULL)) {
2138 /** Incorrect signature */
2139 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2140 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2141 silc_fsm_next(fsm, silc_ske_st_responder_error);
2142 return SILC_FSM_CONTINUE;
2145 SILC_LOG_DEBUG(("Signature is Ok"));
2147 memset(hash, 'F', hash_len);
2150 /* Create the random number x, 1 < x < q. */
2151 x = silc_calloc(1, sizeof(*x));
2154 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2155 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2157 if (status != SILC_SKE_STATUS_OK) {
2158 /** Error generating random number */
2161 ske->status = status;
2162 silc_fsm_next(fsm, silc_ske_st_responder_error);
2163 return SILC_FSM_CONTINUE;
2166 /* Save the results for later processing */
2167 send_payload = silc_calloc(1, sizeof(*send_payload));
2169 ske->ke2_payload = send_payload;
2171 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2173 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2174 silc_mp_init(&send_payload->x);
2175 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2176 &ske->prop->group->group);
2178 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2180 /* Compute the shared secret key */
2181 KEY = silc_calloc(1, sizeof(*KEY));
2183 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2184 &ske->prop->group->group);
2187 /** Send KE2 payload */
2188 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2189 return SILC_FSM_CONTINUE;
2192 /* Phase-5. Send KE2 payload */
2194 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2196 SilcSKE ske = fsm_context;
2197 SilcSKEStatus status;
2198 SilcBuffer payload_buf;
2199 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2200 SilcUInt32 hash_len, sign_len, pk_len;
2202 SILC_LOG_DEBUG(("Start"));
2204 if (ske->public_key && ske->private_key) {
2205 SILC_LOG_DEBUG(("Getting public key"));
2207 /* Get the public key */
2208 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2210 /** Error encoding public key */
2211 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2212 silc_fsm_next(fsm, silc_ske_st_responder_error);
2213 return SILC_FSM_CONTINUE;
2215 ske->ke2_payload->pk_data = pk;
2216 ske->ke2_payload->pk_len = pk_len;
2219 SILC_LOG_DEBUG(("Computing HASH value"));
2221 /* Compute the hash value */
2222 memset(hash, 0, sizeof(hash));
2223 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2224 if (status != SILC_SKE_STATUS_OK) {
2225 /** Error computing hash */
2226 ske->status = status;
2227 silc_fsm_next(fsm, silc_ske_st_responder_error);
2228 return SILC_FSM_CONTINUE;
2230 ske->hash = silc_memdup(hash, hash_len);
2231 ske->hash_len = hash_len;
2233 if (ske->public_key && ske->private_key) {
2234 SILC_LOG_DEBUG(("Signing HASH value"));
2236 /* Sign the hash value */
2237 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2238 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2239 /** Error computing signature */
2240 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2241 silc_fsm_next(fsm, silc_ske_st_responder_error);
2242 return SILC_FSM_CONTINUE;
2244 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2245 ske->ke2_payload->sign_len = sign_len;
2246 memset(sign, 0, sizeof(sign));
2248 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2250 /* Encode the Key Exchange Payload */
2251 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2253 if (status != SILC_SKE_STATUS_OK) {
2254 /** Error encoding KE payload */
2255 ske->status = status;
2256 silc_fsm_next(fsm, silc_ske_st_responder_error);
2257 return SILC_FSM_CONTINUE;
2260 /* Send the packet. */
2261 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2262 payload_buf->data, silc_buffer_len(payload_buf))) {
2263 SILC_LOG_DEBUG(("Error sending packet"));
2264 ske->status = SILC_SKE_STATUS_ERROR;
2265 silc_fsm_next(fsm, silc_ske_st_responder_error);
2266 return SILC_FSM_CONTINUE;
2269 silc_buffer_free(payload_buf);
2271 /* In case we are doing rekey move to finish it. */
2274 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2275 return SILC_FSM_CONTINUE;
2278 /** Waiting completion */
2279 silc_fsm_next(fsm, silc_ske_st_responder_end);
2280 return SILC_FSM_WAIT;
2283 /* Protocol completed */
2285 SILC_FSM_STATE(silc_ske_st_responder_end)
2287 SilcSKE ske = fsm_context;
2288 unsigned char tmp[4];
2289 SilcUInt32 hash_len, key_len, block_len;
2291 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2292 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2293 silc_ske_install_retransmission(ske);
2294 silc_packet_free(ske->packet);
2296 return SILC_FSM_WAIT;
2298 silc_packet_free(ske->packet);
2301 /* Process key material */
2302 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2303 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2304 hash_len = silc_hash_len(ske->prop->hash);
2305 ske->keymat = silc_ske_process_key_material(ske, block_len,
2309 /** Error processing key material */
2310 ske->status = SILC_SKE_STATUS_ERROR;
2311 silc_fsm_next(fsm, silc_ske_st_responder_error);
2312 return SILC_FSM_CONTINUE;
2315 /* Send SUCCESS packet */
2316 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2317 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2319 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2320 silc_schedule_task_del_by_context(ske->schedule, ske);
2322 /* Call completion */
2323 silc_ske_completion(ske);
2325 return SILC_FSM_FINISH;
2328 /* Aborted by application */
2330 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2332 SilcSKE ske = fsm_context;
2333 unsigned char tmp[4];
2335 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2337 /* Send FAILURE packet */
2338 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2339 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2341 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2342 silc_schedule_task_del_by_context(ske->schedule, ske);
2344 /* Call completion */
2345 silc_ske_completion(ske);
2347 return SILC_FSM_FINISH;
2350 /* Failure received from remote */
2352 SILC_FSM_STATE(silc_ske_st_responder_failure)
2354 SilcSKE ske = fsm_context;
2355 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2357 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2359 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2360 SILC_GET32_MSB(error, ske->packet->buffer.data);
2361 ske->status = error;
2362 silc_packet_free(ske->packet);
2366 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2367 silc_schedule_task_del_by_context(ske->schedule, ske);
2369 /* Call completion */
2370 silc_ske_completion(ske);
2372 return SILC_FSM_FINISH;
2375 /* Error occurred */
2377 SILC_FSM_STATE(silc_ske_st_responder_error)
2379 SilcSKE ske = fsm_context;
2380 unsigned char tmp[4];
2382 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2383 ske->status, silc_ske_map_status(ske->status)));
2385 /* Send FAILURE packet */
2386 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2387 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2388 SILC_PUT32_MSB(ske->status, tmp);
2389 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2391 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2392 silc_schedule_task_del_by_context(ske->schedule, ske);
2394 /* Call completion */
2395 silc_ske_completion(ske);
2397 return SILC_FSM_FINISH;
2400 /* Starts the protocol as responder. */
2402 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2403 SilcPacketStream stream,
2404 SilcSKEParams params)
2406 SILC_LOG_DEBUG(("Start SKE as responder"));
2408 if (!ske || !stream || !params || !params->version)
2411 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2414 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2417 ske->responder = TRUE;
2418 ske->flags = params->flags;
2419 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2420 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2421 ske->session_port = params->session_port;
2422 ske->version = strdup(params->version);
2425 ske->running = TRUE;
2427 /* Link to packet stream to get key exchange packets */
2428 ske->stream = stream;
2429 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2430 SILC_PACKET_KEY_EXCHANGE,
2431 SILC_PACKET_KEY_EXCHANGE_1,
2432 SILC_PACKET_SUCCESS,
2433 SILC_PACKET_FAILURE, -1);
2435 /* Start SKE as responder */
2436 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2441 /***************************** Initiator Rekey ******************************/
2445 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2447 SilcSKE ske = fsm_context;
2450 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2454 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2455 return SILC_FSM_CONTINUE;
2458 /* Add rekey exchange timeout */
2459 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2462 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2465 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2466 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2467 return SILC_FSM_CONTINUE;
2470 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2471 /** Cannot allocate hash */
2472 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2473 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2474 return SILC_FSM_CONTINUE;
2477 /* Send REKEY packet to start rekey protocol */
2478 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2479 /** Error sending packet */
2480 SILC_LOG_DEBUG(("Error sending packet"));
2481 ske->status = SILC_SKE_STATUS_ERROR;
2482 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2483 return SILC_FSM_CONTINUE;
2486 /* If doing rekey without PFS, move directly to the end of the protocol. */
2487 if (!ske->rekey->pfs) {
2488 /** Rekey without PFS */
2489 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2490 return SILC_FSM_CONTINUE;
2493 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2495 if (status != SILC_SKE_STATUS_OK) {
2496 /** Unknown group */
2497 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2498 return SILC_FSM_CONTINUE;
2501 /** Rekey with PFS */
2502 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2503 return SILC_FSM_CONTINUE;
2506 /* Sends REKEY_DONE packet to finish the protocol. */
2508 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2510 SilcSKE ske = fsm_context;
2511 SilcCipher send_key;
2514 SilcUInt32 key_len, block_len, hash_len, x_len;
2515 unsigned char *pfsbuf;
2517 SILC_LOG_DEBUG(("Start"));
2519 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2520 key_len = silc_cipher_get_key_len(send_key);
2521 block_len = silc_cipher_get_block_len(send_key);
2522 hash = ske->prop->hash;
2523 hash_len = silc_hash_len(hash);
2525 /* Process key material */
2526 if (ske->rekey->pfs) {
2528 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2530 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2533 memset(pfsbuf, 0, x_len);
2539 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2540 ske->rekey->enc_key_len / 8,
2546 SILC_LOG_ERROR(("Error processing key material"));
2547 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2548 return SILC_FSM_CONTINUE;
2551 ske->prop->cipher = send_key;
2552 ske->prop->hmac = hmac_send;
2554 /* Get sending keys */
2555 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2556 &hmac_send, NULL, NULL)) {
2557 /** Cannot get keys */
2558 ske->status = SILC_SKE_STATUS_ERROR;
2559 ske->prop->cipher = NULL;
2560 ske->prop->hmac = NULL;
2561 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2562 return SILC_FSM_CONTINUE;
2565 ske->prop->cipher = NULL;
2566 ske->prop->hmac = NULL;
2568 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2569 packet sent after this call will be protected with the new keys. */
2570 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2572 /** Cannot set keys */
2573 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2574 ske->status = SILC_SKE_STATUS_ERROR;
2575 silc_cipher_free(send_key);
2576 silc_hmac_free(hmac_send);
2577 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2578 return SILC_FSM_CONTINUE;
2581 /** Wait for REKEY_DONE */
2582 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2583 return SILC_FSM_WAIT;
2586 /* Rekey protocol end */
2588 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2590 SilcSKE ske = fsm_context;
2591 SilcCipher receive_key;
2592 SilcHmac hmac_receive;
2593 SilcSKERekeyMaterial rekey;
2595 SILC_LOG_DEBUG(("Start"));
2597 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2598 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2599 silc_packet_free(ske->packet);
2601 return SILC_FSM_WAIT;
2604 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2605 ske->prop->cipher = receive_key;
2606 ske->prop->hmac = hmac_receive;
2608 /* Get receiving keys */
2609 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2610 NULL, &hmac_receive, NULL)) {
2611 /** Cannot get keys */
2612 ske->status = SILC_SKE_STATUS_ERROR;
2613 ske->prop->cipher = NULL;
2614 ske->prop->hmac = NULL;
2615 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2616 return SILC_FSM_CONTINUE;
2619 /* Set new receiving keys into use. All packets received after this will
2620 be decrypted with the new keys. */
2621 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2622 hmac_receive, FALSE)) {
2623 /** Cannot set keys */
2624 SILC_LOG_DEBUG(("Cannot set new keys"));
2625 ske->status = SILC_SKE_STATUS_ERROR;
2626 silc_cipher_free(receive_key);
2627 silc_hmac_free(hmac_receive);
2628 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2629 return SILC_FSM_CONTINUE;
2632 SILC_LOG_DEBUG(("Rekey completed successfully"));
2634 /* Generate new rekey material */
2635 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2638 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2639 ske->prop->cipher = NULL;
2640 ske->prop->hmac = NULL;
2641 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2642 return SILC_FSM_CONTINUE;
2644 rekey->pfs = ske->rekey->pfs;
2647 ske->prop->cipher = NULL;
2648 ske->prop->hmac = NULL;
2649 silc_packet_free(ske->packet);
2651 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2652 silc_schedule_task_del_by_context(ske->schedule, ske);
2654 /* Call completion */
2655 silc_ske_completion(ske);
2657 return SILC_FSM_FINISH;
2660 /* Starts rekey protocol as initiator */
2663 silc_ske_rekey_initiator(SilcSKE ske,
2664 SilcPacketStream stream,
2665 SilcSKERekeyMaterial rekey)
2667 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2669 if (!ske || !stream || !rekey) {
2670 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2675 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2678 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2682 ske->responder = FALSE;
2683 ske->running = TRUE;
2684 ske->rekeying = TRUE;
2686 /* Link to packet stream to get key exchange packets */
2687 ske->stream = stream;
2688 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2690 SILC_PACKET_REKEY_DONE,
2691 SILC_PACKET_KEY_EXCHANGE_2,
2692 SILC_PACKET_SUCCESS,
2693 SILC_PACKET_FAILURE, -1);
2695 /* Start SKE rekey as initiator */
2696 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2701 /***************************** Responder Rekey ******************************/
2703 /* Wait for initiator's packet */
2705 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2707 SilcSKE ske = fsm_context;
2709 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2713 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2714 return SILC_FSM_CONTINUE;
2717 /* Add rekey exchange timeout */
2718 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2721 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2723 /* If REKEY packet already received process it directly */
2724 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2725 return SILC_FSM_CONTINUE;
2727 /* Wait for REKEY */
2728 return SILC_FSM_WAIT;
2731 /* Process initiator's REKEY packet */
2733 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2735 SilcSKE ske = fsm_context;
2736 SilcSKEStatus status;
2738 SILC_LOG_DEBUG(("Start"));
2740 if (ske->packet->type != SILC_PACKET_REKEY) {
2741 ske->status = SILC_SKE_STATUS_ERROR;
2742 silc_packet_free(ske->packet);
2744 silc_fsm_next(fsm, silc_ske_st_responder_error);
2745 return SILC_FSM_CONTINUE;
2748 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2751 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2752 silc_fsm_next(fsm, silc_ske_st_responder_error);
2753 return SILC_FSM_CONTINUE;
2756 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2757 /** Cannot allocate hash */
2758 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2759 silc_fsm_next(fsm, silc_ske_st_responder_error);
2760 return SILC_FSM_CONTINUE;
2763 /* If doing rekey without PFS, move directly to the end of the protocol. */
2764 if (!ske->rekey->pfs) {
2765 /** Rekey without PFS */
2766 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2767 return SILC_FSM_CONTINUE;
2770 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2772 if (status != SILC_SKE_STATUS_OK) {
2773 /** Unknown group */
2774 silc_fsm_next(fsm, silc_ske_st_responder_error);
2775 return SILC_FSM_CONTINUE;
2778 /** Rekey with PFS */
2779 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2780 return SILC_FSM_WAIT;
2783 /* Sends REKEY_DONE packet to finish the protocol. */
2785 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2787 SilcSKE ske = fsm_context;
2788 SilcCipher send_key;
2791 SilcUInt32 key_len, block_len, hash_len, x_len;
2792 unsigned char *pfsbuf;
2794 SILC_LOG_DEBUG(("Start"));
2796 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2797 key_len = silc_cipher_get_key_len(send_key);
2798 block_len = silc_cipher_get_block_len(send_key);
2799 hash = ske->prop->hash;
2800 hash_len = silc_hash_len(hash);
2802 /* Process key material */
2803 if (ske->rekey->pfs) {
2805 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2807 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2810 memset(pfsbuf, 0, x_len);
2816 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2817 ske->rekey->enc_key_len / 8,
2823 SILC_LOG_ERROR(("Error processing key material"));
2824 silc_fsm_next(fsm, silc_ske_st_responder_error);
2825 return SILC_FSM_CONTINUE;
2828 ske->prop->cipher = send_key;
2829 ske->prop->hmac = hmac_send;
2831 /* Get sending keys */
2832 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2833 &hmac_send, NULL, NULL)) {
2834 /** Cannot get keys */
2835 ske->status = SILC_SKE_STATUS_ERROR;
2836 ske->prop->cipher = NULL;
2837 ske->prop->hmac = NULL;
2838 silc_fsm_next(fsm, silc_ske_st_responder_error);
2839 return SILC_FSM_CONTINUE;
2842 ske->prop->cipher = NULL;
2843 ske->prop->hmac = NULL;
2845 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2846 packet sent after this call will be protected with the new keys. */
2847 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2849 /** Cannot set keys */
2850 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2851 ske->status = SILC_SKE_STATUS_ERROR;
2852 silc_cipher_free(send_key);
2853 silc_hmac_free(hmac_send);
2854 silc_fsm_next(fsm, silc_ske_st_responder_error);
2855 return SILC_FSM_CONTINUE;
2858 /** Wait for REKEY_DONE */
2859 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2860 return SILC_FSM_WAIT;
2863 /* Rekey protocol end */
2865 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2867 SilcSKE ske = fsm_context;
2868 SilcCipher receive_key;
2869 SilcHmac hmac_receive;
2870 SilcSKERekeyMaterial rekey;
2872 SILC_LOG_DEBUG(("Start"));
2874 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2875 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2876 silc_packet_free(ske->packet);
2878 return SILC_FSM_WAIT;
2881 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2882 ske->prop->cipher = receive_key;
2883 ske->prop->hmac = hmac_receive;
2885 /* Get receiving keys */
2886 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2887 NULL, &hmac_receive, NULL)) {
2888 /** Cannot get keys */
2889 ske->status = SILC_SKE_STATUS_ERROR;
2890 ske->prop->cipher = NULL;
2891 ske->prop->hmac = NULL;
2892 silc_fsm_next(fsm, silc_ske_st_responder_error);
2893 return SILC_FSM_CONTINUE;
2896 /* Set new receiving keys into use. All packets received after this will
2897 be decrypted with the new keys. */
2898 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2899 hmac_receive, FALSE)) {
2900 /** Cannot set keys */
2901 SILC_LOG_DEBUG(("Cannot set new keys"));
2902 ske->status = SILC_SKE_STATUS_ERROR;
2903 ske->prop->cipher = NULL;
2904 ske->prop->hmac = NULL;
2905 silc_cipher_free(receive_key);
2906 silc_hmac_free(hmac_receive);
2907 silc_fsm_next(fsm, silc_ske_st_responder_error);
2908 return SILC_FSM_CONTINUE;
2911 SILC_LOG_DEBUG(("Rekey completed successfully"));
2913 /* Generate new rekey material */
2914 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2917 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2918 ske->prop->cipher = NULL;
2919 ske->prop->hmac = NULL;
2920 silc_fsm_next(fsm, silc_ske_st_responder_error);
2921 return SILC_FSM_CONTINUE;
2923 rekey->pfs = ske->rekey->pfs;
2926 ske->prop->cipher = NULL;
2927 ske->prop->hmac = NULL;
2928 silc_packet_free(ske->packet);
2930 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2931 silc_schedule_task_del_by_context(ske->schedule, ske);
2933 /* Call completion */
2934 silc_ske_completion(ske);
2936 return SILC_FSM_FINISH;
2939 /* Starts rekey protocol as responder */
2942 silc_ske_rekey_responder(SilcSKE ske,
2943 SilcPacketStream stream,
2944 SilcSKERekeyMaterial rekey,
2947 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2949 if (!ske || !stream || !rekey)
2952 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2955 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2959 ske->responder = TRUE;
2960 ske->running = TRUE;
2961 ske->rekeying = TRUE;
2962 ske->packet = packet;
2964 /* Link to packet stream to get key exchange packets */
2965 ske->stream = stream;
2966 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2968 SILC_PACKET_REKEY_DONE,
2969 SILC_PACKET_KEY_EXCHANGE_1,
2970 SILC_PACKET_SUCCESS,
2971 SILC_PACKET_FAILURE, -1);
2973 /* Start SKE rekey as responder */
2974 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2979 /* Processes the provided key material `data' as the SILC protocol
2980 specification defines. */
2983 silc_ske_process_key_material_data(unsigned char *data,
2984 SilcUInt32 data_len,
2985 SilcUInt32 req_iv_len,
2986 SilcUInt32 req_enc_key_len,
2987 SilcUInt32 req_hmac_key_len,
2991 unsigned char hashd[SILC_HASH_MAXLEN];
2992 SilcUInt32 hash_len = req_hmac_key_len;
2993 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2994 SilcSKEKeyMaterial key;
2996 SILC_LOG_DEBUG(("Start"));
2998 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3001 key = silc_calloc(1, sizeof(*key));
3005 buf = silc_buffer_alloc_size(1 + data_len);
3008 silc_buffer_format(buf,
3009 SILC_STR_UI_CHAR(0),
3010 SILC_STR_DATA(data, data_len),
3014 memset(hashd, 0, sizeof(hashd));
3016 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3017 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3018 memcpy(key->send_iv, hashd, req_iv_len);
3019 memset(hashd, 0, sizeof(hashd));
3021 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3022 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3023 memcpy(key->receive_iv, hashd, req_iv_len);
3024 key->iv_len = req_iv_len;
3026 /* Take the encryption keys. If requested key size is more than
3027 the size of hash length we will distribute more key material
3028 as protocol defines. */
3030 if (enc_key_len > hash_len) {
3032 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3033 k3[SILC_HASH_MAXLEN];
3034 unsigned char *dtmp;
3037 if (enc_key_len > (3 * hash_len))
3040 /* Take first round */
3041 memset(k1, 0, sizeof(k1));
3042 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3044 /* Take second round */
3045 dist = silc_buffer_alloc_size(data_len + hash_len);
3048 silc_buffer_format(dist,
3049 SILC_STR_DATA(data, data_len),
3050 SILC_STR_DATA(k1, hash_len),
3052 memset(k2, 0, sizeof(k2));
3053 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3055 /* Take third round */
3056 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3057 silc_buffer_pull_tail(dist, hash_len);
3058 silc_buffer_pull(dist, data_len + hash_len);
3059 silc_buffer_format(dist,
3060 SILC_STR_DATA(k2, hash_len),
3062 silc_buffer_push(dist, data_len + hash_len);
3063 memset(k3, 0, sizeof(k3));
3064 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3066 /* Then, save the keys */
3067 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3068 memcpy(dtmp, k1, hash_len);
3069 memcpy(dtmp + hash_len, k2, hash_len);
3070 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3072 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3073 memcpy(key->send_enc_key, dtmp, enc_key_len);
3074 key->enc_key_len = req_enc_key_len;
3076 memset(dtmp, 0, (3 * hash_len));
3077 memset(k1, 0, sizeof(k1));
3078 memset(k2, 0, sizeof(k2));
3079 memset(k3, 0, sizeof(k3));
3081 silc_buffer_clear(dist);
3082 silc_buffer_free(dist);
3084 /* Take normal hash as key */
3085 memset(hashd, 0, sizeof(hashd));
3086 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3087 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3088 memcpy(key->send_enc_key, hashd, enc_key_len);
3089 key->enc_key_len = req_enc_key_len;
3093 if (enc_key_len > hash_len) {
3095 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3096 k3[SILC_HASH_MAXLEN];
3097 unsigned char *dtmp;
3100 if (enc_key_len > (3 * hash_len))
3103 /* Take first round */
3104 memset(k1, 0, sizeof(k1));
3105 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3107 /* Take second round */
3108 dist = silc_buffer_alloc_size(data_len + hash_len);
3111 silc_buffer_format(dist,
3112 SILC_STR_DATA(data, data_len),
3113 SILC_STR_DATA(k1, hash_len),
3115 memset(k2, 0, sizeof(k2));
3116 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3118 /* Take third round */
3119 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3120 silc_buffer_pull_tail(dist, hash_len);
3121 silc_buffer_pull(dist, data_len + hash_len);
3122 silc_buffer_format(dist,
3123 SILC_STR_DATA(k2, hash_len),
3125 silc_buffer_push(dist, data_len + hash_len);
3126 memset(k3, 0, sizeof(k3));
3127 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3129 /* Then, save the keys */
3130 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3131 memcpy(dtmp, k1, hash_len);
3132 memcpy(dtmp + hash_len, k2, hash_len);
3133 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3135 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3136 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3137 key->enc_key_len = req_enc_key_len;
3139 memset(dtmp, 0, (3 * hash_len));
3140 memset(k1, 0, sizeof(k1));
3141 memset(k2, 0, sizeof(k2));
3142 memset(k3, 0, sizeof(k3));
3144 silc_buffer_clear(dist);
3145 silc_buffer_free(dist);
3147 /* Take normal hash as key */
3148 memset(hashd, 0, sizeof(hashd));
3149 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3150 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3151 memcpy(key->receive_enc_key, hashd, enc_key_len);
3152 key->enc_key_len = req_enc_key_len;
3155 /* Take HMAC keys */
3156 memset(hashd, 0, sizeof(hashd));
3158 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3159 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3160 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3161 memset(hashd, 0, sizeof(hashd));
3163 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3164 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3165 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3166 key->hmac_key_len = req_hmac_key_len;
3167 memset(hashd, 0, sizeof(hashd));
3169 silc_buffer_clear(buf);
3170 silc_buffer_free(buf);
3172 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3177 /* Processes negotiated key material as protocol specifies. This returns
3178 the actual keys to be used in the SILC. */
3181 silc_ske_process_key_material(SilcSKE ske,
3182 SilcUInt32 req_iv_len,
3183 SilcUInt32 req_enc_key_len,
3184 SilcUInt32 req_hmac_key_len,
3185 SilcSKERekeyMaterial *rekey)
3188 unsigned char *tmpbuf;
3190 SilcSKEKeyMaterial key;
3192 /* Encode KEY to binary data */
3193 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3195 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3198 silc_buffer_format(buf,
3199 SILC_STR_DATA(tmpbuf, klen),
3200 SILC_STR_DATA(ske->hash, ske->hash_len),
3203 /* Process the key material */
3204 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3205 req_iv_len, req_enc_key_len,
3209 memset(tmpbuf, 0, klen);
3211 silc_buffer_clear(buf);
3212 silc_buffer_free(buf);
3215 *rekey = silc_ske_make_rekey_material(ske, key);
3223 /* Free key material structure */
3225 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3231 silc_free(key->send_iv);
3232 if (key->receive_iv)
3233 silc_free(key->receive_iv);
3234 if (key->send_enc_key) {
3235 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3236 silc_free(key->send_enc_key);
3238 if (key->receive_enc_key) {
3239 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3240 silc_free(key->receive_enc_key);
3242 if (key->send_hmac_key) {
3243 memset(key->send_hmac_key, 0, key->hmac_key_len);
3244 silc_free(key->send_hmac_key);
3246 if (key->receive_hmac_key) {
3247 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3248 silc_free(key->receive_hmac_key);
3253 /* Free rekey material */
3255 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3259 if (rekey->send_enc_key) {
3260 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3261 silc_free(rekey->send_enc_key);
3263 silc_free(rekey->hash);
3267 /* Set keys into use */
3269 SilcBool silc_ske_set_keys(SilcSKE ske,
3270 SilcSKEKeyMaterial keymat,
3271 SilcSKESecurityProperties prop,
3272 SilcCipher *ret_send_key,
3273 SilcCipher *ret_receive_key,
3274 SilcHmac *ret_hmac_send,
3275 SilcHmac *ret_hmac_receive,
3278 unsigned char iv[SILC_HASH_MAXLEN];
3279 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3281 /* Allocate ciphers to be used in the communication */
3283 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3287 if (ret_receive_key) {
3288 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3293 /* Allocate HMACs */
3294 if (ret_hmac_send) {
3295 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3299 if (ret_hmac_receive) {
3300 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3307 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3311 /* Set key material */
3312 memset(iv, 0, sizeof(iv));
3313 if (ske->responder) {
3315 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3316 keymat->enc_key_len, TRUE);
3318 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3320 if (!ske->rekeying) {
3322 memcpy(iv, ske->hash, 4);
3324 memcpy(iv + 4, keymat->receive_iv, 8);
3326 /* Rekey, recompute the truncated hash value. */
3327 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3329 memcpy(iv + 4, keymat->receive_iv, 8);
3331 memset(iv + 4, 0, 12);
3334 silc_cipher_set_iv(*ret_send_key, iv);
3337 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3340 if (ret_receive_key) {
3341 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3342 keymat->enc_key_len, FALSE);
3344 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3346 if (!ske->rekeying) {
3348 memcpy(iv, ske->hash, 4);
3350 memcpy(iv + 4, keymat->send_iv, 8);
3352 /* Rekey, recompute the truncated hash value. */
3353 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3355 memcpy(iv + 4, keymat->send_iv, 8);
3357 memset(iv + 4, 0, 12);
3360 silc_cipher_set_iv(*ret_receive_key, iv);
3363 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3367 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3368 keymat->hmac_key_len);
3369 if (ret_hmac_receive)
3370 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3371 keymat->hmac_key_len);
3374 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3375 keymat->enc_key_len, TRUE);
3377 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3379 if (!ske->rekeying) {
3381 memcpy(iv, ske->hash, 4);
3383 memcpy(iv + 4, keymat->send_iv, 8);
3385 /* Rekey, recompute the truncated hash value. */
3386 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3388 memcpy(iv + 4, keymat->send_iv, 8);
3390 memset(iv + 4, 0, 12);
3393 silc_cipher_set_iv(*ret_send_key, iv);
3396 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3399 if (ret_receive_key) {
3400 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3401 keymat->enc_key_len, FALSE);
3403 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3405 if (!ske->rekeying) {
3406 /* Set IV. If IV Included flag was negotiated we only set the
3407 truncated hash value. */
3408 memcpy(iv, ske->hash, 4);
3410 memcpy(iv + 4, keymat->receive_iv, 8);
3412 /* Rekey, recompute the truncated hash value. */
3413 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3415 memcpy(iv + 4, keymat->receive_iv, 8);
3417 memset(iv + 4, 0, 12);
3420 silc_cipher_set_iv(*ret_receive_key, iv);
3423 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3427 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3428 keymat->hmac_key_len);
3429 if (ret_hmac_receive)
3430 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3431 keymat->hmac_key_len);
3437 const char *silc_ske_status_string[] =
3441 "Unexpected error occurred",
3442 "Bad payload in packet",
3443 "Unsupported group",
3444 "Unsupported cipher",
3446 "Unsupported hash function",
3448 "Unsupported public key (or certificate)",
3449 "Incorrect signature",
3450 "Bad or unsupported version",
3454 "Remote did not provide public key",
3455 "Bad reserved field in packet",
3456 "Bad payload length in packet",
3457 "Error computing signature",
3458 "System out of memory",
3459 "Key exchange timeout",
3464 /* Maps status to readable string and returns the string. If string is not
3465 found and empty character string ("") is returned. */
3467 const char *silc_ske_map_status(SilcSKEStatus status)
3471 for (i = 0; silc_ske_status_string[i]; i++)
3473 return silc_ske_status_string[i];
3478 /* Parses remote host's version string. */
3480 SilcBool silc_ske_parse_version(SilcSKE ske,
3481 SilcUInt32 *protocol_version,
3482 char **protocol_version_string,
3483 SilcUInt32 *software_version,
3484 char **software_version_string,
3485 char **vendor_version)
3487 return silc_parse_version_string(ske->remote_version,
3489 protocol_version_string,
3491 software_version_string,
3495 /* Get security properties */
3497 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3502 /* Get key material */
3504 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)