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,
76 static void silc_ske_notify_failure(SilcSKE ske);
79 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
80 SilcPacketStream stream,
82 void *callback_context,
85 SilcSKE ske = callback_context;
87 /* Clear retransmission */
88 ske->retry_timer = SILC_SKE_RETRY_MIN;
90 silc_schedule_task_del_by_callback(ske->schedule,
91 silc_ske_packet_send_retry);
93 /* Signal for new packet */
96 /* Check if we were aborted */
98 silc_packet_free(packet);
102 silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
104 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
106 silc_fsm_continue_sync(&ske->fsm);
110 /* See if received failure from remote */
111 if (packet->type == SILC_PACKET_FAILURE) {
112 silc_ske_notify_failure(ske);
115 /* Handle rekey and SUCCESS packets synchronously. After SUCCESS packets
116 they keys are taken into use immediately, hence the synchronous
117 processing to get the keys in use as soon as possible. */
118 if (ske->rekeying || packet->type == SILC_PACKET_SUCCESS)
119 silc_fsm_continue_sync(&ske->fsm);
121 silc_fsm_continue(&ske->fsm);
126 /* Packet stream callbacks */
127 static SilcPacketCallbacks silc_ske_stream_cbs =
129 silc_ske_packet_receive, NULL, NULL
132 /* Aborts SKE protocol */
134 static void silc_ske_abort(SilcAsyncOperation op, void *context)
136 SilcSKE ske = context;
140 /* Public key verification completion callback */
142 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
143 void *completion_context)
145 ske->status = status;
146 SILC_FSM_CALL_CONTINUE(&ske->fsm);
149 /* SKR find callback */
151 static void silc_ske_skr_callback(SilcSKR repository,
153 SilcSKRStatus status,
154 SilcDList keys, void *context)
156 SilcSKE ske = context;
158 silc_skr_find_free(find);
160 if (status != SILC_SKR_OK) {
161 if (ske->callbacks->verify_key) {
162 /* Verify from application */
163 ske->callbacks->verify_key(ske, ske->prop->public_key,
164 ske->callbacks->context,
165 silc_ske_pk_verified, NULL);
171 silc_dlist_uninit(keys);
174 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
175 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
176 SILC_FSM_CALL_CONTINUE(&ske->fsm);
179 /* Checks remote and local versions */
181 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
183 if (!ske->remote_version || !ske->version)
184 return SILC_SKE_STATUS_BAD_VERSION;
186 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
188 return SILC_SKE_STATUS_BAD_VERSION;
190 return SILC_SKE_STATUS_OK;
193 /* Selects the supported security properties from the initiator's Key
194 Exchange Start Payload. A responder function. Saves our reply
195 start payload to ske->start_payload. */
198 silc_ske_select_security_properties(SilcSKE ske,
199 SilcSKEStartPayload remote_payload,
200 SilcSKESecurityProperties *prop)
202 SilcSKEStatus status;
203 SilcSKEStartPayload rp, payload;
207 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
211 /* Check for mandatory fields */
212 if (!rp->ke_grp_len) {
213 SILC_LOG_DEBUG(("KE group not defined in payload"));
214 return SILC_SKE_STATUS_BAD_PAYLOAD;
216 if (!rp->pkcs_alg_len) {
217 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
218 return SILC_SKE_STATUS_BAD_PAYLOAD;
220 if (!rp->enc_alg_len) {
221 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
222 return SILC_SKE_STATUS_BAD_PAYLOAD;
224 if (!rp->hash_alg_len) {
225 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
226 return SILC_SKE_STATUS_BAD_PAYLOAD;
228 if (!rp->hmac_alg_len) {
229 SILC_LOG_DEBUG(("HMAC not defined in payload"));
230 return SILC_SKE_STATUS_BAD_PAYLOAD;
233 /* Allocate security properties */
234 *prop = silc_calloc(1, sizeof(**prop));
236 return SILC_SKE_STATUS_OUT_OF_MEMORY;
238 /* Allocate our reply start payload */
239 payload = silc_calloc(1, sizeof(*payload));
242 return SILC_SKE_STATUS_OUT_OF_MEMORY;
245 /* Check version string */
246 ske->remote_version = silc_memdup(rp->version, rp->version_len);
247 status = silc_ske_check_version(ske);
248 if (status != SILC_SKE_STATUS_OK) {
249 ske->status = status;
253 /* Flags are returned unchanged. */
254 (*prop)->flags = payload->flags = rp->flags;
256 /* Take cookie, we must return it to sender unmodified. */
257 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
258 if (!payload->cookie) {
259 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
262 payload->cookie_len = SILC_SKE_COOKIE_LEN;
263 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
265 /* In case IV included flag and session port is set the first 16-bits of
266 cookie will include our session port. */
267 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
268 /* Take remote port */
269 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
272 SILC_PUT16_MSB(ske->session_port, payload->cookie);
275 /* Put our version to our reply */
276 payload->version = strdup(ske->version);
277 if (!payload->version) {
278 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
281 payload->version_len = strlen(ske->version);
283 /* Get supported Key Exchange groups */
284 cp = rp->ke_grp_list;
285 if (cp && strchr(cp, ',')) {
289 len = strcspn(cp, ",");
290 item = silc_calloc(len + 1, sizeof(char));
292 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
295 memcpy(item, cp, len);
297 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
299 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
300 SILC_LOG_DEBUG(("Found KE group `%s'", item));
302 payload->ke_grp_len = len;
303 payload->ke_grp_list = item;
317 if (!payload->ke_grp_len && !payload->ke_grp_list) {
318 SILC_LOG_DEBUG(("Could not find supported KE group"));
320 return SILC_SKE_STATUS_UNKNOWN_GROUP;
323 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
324 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
326 payload->ke_grp_len = rp->ke_grp_len;
327 payload->ke_grp_list = strdup(rp->ke_grp_list);
330 /* Save group to security properties */
331 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
332 if (status != SILC_SKE_STATUS_OK) {
334 return SILC_SKE_STATUS_UNKNOWN_GROUP;
337 /* Get supported PKCS algorithms */
338 cp = rp->pkcs_alg_list;
339 if (cp && strchr(cp, ',')) {
343 len = strcspn(cp, ",");
344 item = silc_calloc(len + 1, sizeof(char));
346 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
349 memcpy(item, cp, len);
351 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
353 if (silc_pkcs_find_algorithm(item, NULL)) {
354 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
356 payload->pkcs_alg_len = len;
357 payload->pkcs_alg_list = item;
371 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
372 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
373 silc_free(payload->ke_grp_list);
375 return SILC_SKE_STATUS_UNKNOWN_PKCS;
378 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
379 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
381 payload->pkcs_alg_len = rp->pkcs_alg_len;
382 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
385 /* Get supported encryption algorithms */
386 cp = rp->enc_alg_list;
387 if (cp && strchr(cp, ',')) {
391 len = strcspn(cp, ",");
392 item = silc_calloc(len + 1, sizeof(char));
394 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
397 memcpy(item, cp, len);
399 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
401 if (silc_cipher_is_supported(item) == TRUE) {
402 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
404 payload->enc_alg_len = len;
405 payload->enc_alg_list = item;
419 if (!payload->enc_alg_len && !payload->enc_alg_list) {
420 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
421 silc_free(payload->ke_grp_list);
422 silc_free(payload->pkcs_alg_list);
424 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
427 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
430 payload->enc_alg_len = rp->enc_alg_len;
431 payload->enc_alg_list = strdup(rp->enc_alg_list);
434 /* Save selected cipher to security properties */
435 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
436 silc_free(payload->ke_grp_list);
437 silc_free(payload->pkcs_alg_list);
439 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
442 /* Get supported hash algorithms */
443 cp = rp->hash_alg_list;
444 if (cp && strchr(cp, ',')) {
448 len = strcspn(cp, ",");
449 item = silc_calloc(len + 1, sizeof(char));
451 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
454 memcpy(item, cp, len);
456 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
458 if (silc_hash_is_supported(item) == TRUE) {
459 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
461 payload->hash_alg_len = len;
462 payload->hash_alg_list = item;
476 if (!payload->hash_alg_len && !payload->hash_alg_list) {
477 SILC_LOG_DEBUG(("Could not find supported hash alg"));
478 silc_free(payload->ke_grp_list);
479 silc_free(payload->pkcs_alg_list);
480 silc_free(payload->enc_alg_list);
482 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
485 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
488 payload->hash_alg_len = rp->hash_alg_len;
489 payload->hash_alg_list = strdup(rp->hash_alg_list);
492 /* Save selected hash algorithm to security properties */
493 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
494 silc_free(payload->ke_grp_list);
495 silc_free(payload->pkcs_alg_list);
496 silc_free(payload->enc_alg_list);
498 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
501 /* Get supported HMACs */
502 cp = rp->hmac_alg_list;
503 if (cp && strchr(cp, ',')) {
507 len = strcspn(cp, ",");
508 item = silc_calloc(len + 1, sizeof(char));
510 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
513 memcpy(item, cp, len);
515 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
517 if (silc_hmac_is_supported(item) == TRUE) {
518 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
520 payload->hmac_alg_len = len;
521 payload->hmac_alg_list = item;
535 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
536 SILC_LOG_DEBUG(("Could not find supported HMAC"));
537 silc_free(payload->ke_grp_list);
538 silc_free(payload->pkcs_alg_list);
539 silc_free(payload->enc_alg_list);
540 silc_free(payload->hash_alg_list);
542 return SILC_SKE_STATUS_UNKNOWN_HMAC;
545 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
548 payload->hmac_alg_len = rp->hmac_alg_len;
549 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
552 /* Save selected HMACc to security properties */
553 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
554 silc_free(payload->ke_grp_list);
555 silc_free(payload->pkcs_alg_list);
556 silc_free(payload->enc_alg_list);
557 silc_free(payload->hash_alg_list);
559 return SILC_SKE_STATUS_UNKNOWN_HMAC;
562 /* Get supported compression algorithms */
563 cp = rp->comp_alg_list;
564 if (cp && strchr(cp, ',')) {
568 len = strcspn(cp, ",");
569 item = silc_calloc(len + 1, sizeof(char));
571 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
574 memcpy(item, cp, len);
576 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
579 if (!strcmp(item, "none")) {
580 SILC_LOG_DEBUG(("Found Compression `%s'", item));
581 payload->comp_alg_len = len;
582 payload->comp_alg_list = item;
586 if (silc_hmac_is_supported(item) == TRUE) {
587 SILC_LOG_DEBUG(("Found Compression `%s'", item));
588 payload->comp_alg_len = len;
589 payload->comp_alg_list = item;
605 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
606 2 + payload->version_len +
607 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
608 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
609 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
611 /* Save our reply payload */
612 ske->start_payload = payload;
614 return SILC_SKE_STATUS_OK;
617 /* Creates random number such that 1 < rnd < n and at most length
618 of len bits. The rnd sent as argument must be initialized. */
620 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
624 SilcSKEStatus status = SILC_SKE_STATUS_OK;
625 unsigned char *string;
629 return SILC_SKE_STATUS_ERROR;
631 SILC_LOG_DEBUG(("Creating random number"));
635 /* Get the random number as string */
636 string = silc_rng_get_rn_data(ske->rng, l);
638 return SILC_SKE_STATUS_OUT_OF_MEMORY;
640 /* Decode the string into a MP integer */
641 silc_mp_bin2mp(string, l, rnd);
642 silc_mp_mod_2exp(rnd, rnd, len);
645 if (silc_mp_cmp_ui(rnd, 1) < 0)
646 status = SILC_SKE_STATUS_ERROR;
647 if (silc_mp_cmp(rnd, n) >= 0)
648 status = SILC_SKE_STATUS_ERROR;
650 memset(string, 'F', l);
656 /* Creates a hash value HASH as defined in the SKE protocol. If the
657 `initiator' is TRUE then this function is used to create the HASH_i
658 hash value defined in the protocol. If it is FALSE then this is used
659 to create the HASH value defined by the protocol. */
661 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
662 unsigned char *return_hash,
663 SilcUInt32 *return_hash_len,
666 SilcSKEStatus status = SILC_SKE_STATUS_OK;
668 unsigned char *e, *f, *KEY, *s_data;
669 SilcUInt32 e_len, f_len, KEY_len, s_len;
672 SILC_LOG_DEBUG(("Start"));
674 if (initiator == FALSE) {
675 s_data = (ske->start_payload_copy ?
676 silc_buffer_data(ske->start_payload_copy) : NULL);
677 s_len = (ske->start_payload_copy ?
678 silc_buffer_len(ske->start_payload_copy) : 0);
679 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
680 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
681 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
683 /* Format the buffer used to compute the hash value */
684 buf = silc_buffer_alloc_size(s_len +
685 ske->ke2_payload->pk_len +
686 ske->ke1_payload->pk_len +
687 e_len + f_len + KEY_len);
689 return SILC_SKE_STATUS_OUT_OF_MEMORY;
691 /* Initiator is not required to send its public key */
692 if (!ske->ke1_payload->pk_data) {
694 silc_buffer_format(buf,
695 SILC_STR_DATA(s_data, s_len),
696 SILC_STR_DATA(ske->ke2_payload->pk_data,
697 ske->ke2_payload->pk_len),
698 SILC_STR_DATA(e, e_len),
699 SILC_STR_DATA(f, f_len),
700 SILC_STR_DATA(KEY, KEY_len),
704 silc_buffer_format(buf,
705 SILC_STR_DATA(s_data, s_len),
706 SILC_STR_DATA(ske->ke2_payload->pk_data,
707 ske->ke2_payload->pk_len),
708 SILC_STR_DATA(ske->ke1_payload->pk_data,
709 ske->ke1_payload->pk_len),
710 SILC_STR_DATA(e, e_len),
711 SILC_STR_DATA(f, f_len),
712 SILC_STR_DATA(KEY, KEY_len),
716 silc_buffer_free(buf);
719 memset(KEY, 0, KEY_len);
723 return SILC_SKE_STATUS_ERROR;
728 memset(KEY, 0, KEY_len);
733 s_data = (ske->start_payload_copy ?
734 silc_buffer_data(ske->start_payload_copy) : NULL);
735 s_len = (ske->start_payload_copy ?
736 silc_buffer_len(ske->start_payload_copy) : 0);
737 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
739 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
741 return SILC_SKE_STATUS_OUT_OF_MEMORY;
743 /* Format the buffer used to compute the hash value */
745 silc_buffer_format(buf,
746 SILC_STR_DATA(s_data, s_len),
747 SILC_STR_DATA(ske->ke1_payload->pk_data,
748 ske->ke1_payload->pk_len),
749 SILC_STR_DATA(e, e_len),
752 silc_buffer_free(buf);
755 return SILC_SKE_STATUS_ERROR;
758 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
765 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
767 *return_hash_len = silc_hash_len(ske->prop->hash);
769 if (initiator == FALSE) {
770 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
772 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
775 silc_buffer_free(buf);
780 /* Generate rekey material */
782 static SilcSKERekeyMaterial
783 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
785 SilcSKERekeyMaterial rekey;
788 /* Create rekey material */
789 rekey = silc_calloc(1, sizeof(*rekey));
794 if (ske->prop->group)
795 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
796 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
797 hash = silc_hash_get_name(ske->prop->hash);
798 rekey->hash = silc_memdup(hash, strlen(hash));
803 if (rekey->pfs == FALSE) {
804 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
805 keymat->enc_key_len / 8);
806 if (!rekey->send_enc_key) {
810 rekey->enc_key_len = keymat->enc_key_len;
816 /* Assembles security properties */
818 static SilcSKEStartPayload
819 silc_ske_assemble_security_properties(SilcSKE ske,
820 SilcSKESecurityPropertyFlag flags,
823 SilcSKEStartPayload rp;
826 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
828 rp = silc_calloc(1, sizeof(*rp));
831 rp->flags = (unsigned char)flags;
833 /* Set random cookie */
834 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
835 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
836 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
837 rp->cookie_len = SILC_SKE_COOKIE_LEN;
839 /* In case IV included flag and session port is set the first 16-bits of
840 cookie will include our session port. */
841 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
842 SILC_PUT16_MSB(ske->session_port, rp->cookie);
845 rp->version = strdup(version);
846 rp->version_len = strlen(version);
848 /* Get supported Key Exhange groups */
849 rp->ke_grp_list = silc_ske_get_supported_groups();
850 rp->ke_grp_len = strlen(rp->ke_grp_list);
852 /* Get supported PKCS algorithms */
853 rp->pkcs_alg_list = silc_pkcs_get_supported();
854 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
856 /* Get supported encryption algorithms */
857 rp->enc_alg_list = silc_cipher_get_supported();
858 rp->enc_alg_len = strlen(rp->enc_alg_list);
860 /* Get supported hash algorithms */
861 rp->hash_alg_list = silc_hash_get_supported();
862 rp->hash_alg_len = strlen(rp->hash_alg_list);
864 /* Get supported HMACs */
865 rp->hmac_alg_list = silc_hmac_get_supported();
866 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
869 /* Get supported compression algorithms */
870 rp->comp_alg_list = strdup("none");
871 rp->comp_alg_len = strlen("none");
873 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
874 2 + rp->version_len +
875 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
876 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
877 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
882 /* Packet retransmission callback. */
884 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
886 SilcSKE ske = context;
888 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
890 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
891 ske->retry_count = 0;
892 ske->retry_timer = SILC_SKE_RETRY_MIN;
893 silc_free(ske->retrans.data);
894 ske->retrans.data = NULL;
895 ske->status = SILC_SKE_STATUS_TIMEOUT;
896 silc_ske_notify_failure(ske);
897 silc_fsm_continue_sync(&ske->fsm);
901 SILC_LOG_DEBUG(("Retransmitting packet"));
902 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
903 ske->retrans.data, ske->retrans.data_len);
906 /* Install retransmission timer */
908 static void silc_ske_install_retransmission(SilcSKE ske)
910 if (!silc_packet_stream_is_udp(ske->stream))
913 if (ske->retrans.data) {
914 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
916 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
917 ske, ske->retry_timer, 0);
919 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
920 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
923 /* Sends SILC packet. Handles retransmissions with UDP streams. */
925 static SilcBool silc_ske_packet_send(SilcSKE ske,
927 SilcPacketFlags flags,
928 const unsigned char *data,
933 /* Send the packet */
934 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
936 if (silc_packet_stream_is_udp(ske->stream) &&
937 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
938 silc_free(ske->retrans.data);
939 ske->retrans.type = type;
940 ske->retrans.flags = flags;
941 ske->retrans.data = silc_memdup(data, data_len);
942 ske->retrans.data_len = data_len;
943 silc_ske_install_retransmission(ske);
949 /* Calls completion callback. Completion is called always in this function
950 and must not be called anywhere else. */
952 static void silc_ske_completion(SilcSKE ske)
954 /* Call the completion callback */
955 if (!ske->aborted && ske->callbacks->completed) {
956 if (ske->status != SILC_SKE_STATUS_OK)
957 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
958 ske->callbacks->context);
960 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
961 ske->rekey, ske->callbacks->context);
965 /* SKE FSM destructor. */
967 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
968 void *destructor_context)
970 SilcSKE ske = fsm_context;
974 /* Key exchange timeout task callback */
976 SILC_TASK_CALLBACK(silc_ske_timeout)
978 SilcSKE ske = context;
980 SILC_LOG_DEBUG(("Timeout"));
983 ske->status = SILC_SKE_STATUS_TIMEOUT;
984 silc_ske_notify_failure(ske);
986 silc_fsm_continue_sync(&ske->fsm);
989 /******************************* Protocol API *******************************/
991 /* Allocates new SKE object. */
993 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
994 SilcSKR repository, SilcPublicKey public_key,
995 SilcPrivateKey private_key, void *context)
999 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1001 if (!rng || !schedule)
1005 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1009 ske = silc_calloc(1, sizeof(*ske));
1012 ske->status = SILC_SKE_STATUS_OK;
1014 ske->repository = repository;
1015 ske->user_data = context;
1016 ske->schedule = schedule;
1017 ske->public_key = public_key;
1018 ske->private_key = private_key;
1019 ske->retry_timer = SILC_SKE_RETRY_MIN;
1025 /* Free's SKE object. */
1027 void silc_ske_free(SilcSKE ske)
1032 SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu", ske, ske->aborted, ske->refcnt));
1036 * If already aborted, destroy the session immediately. Only do the
1037 * notification work if we have not already though, as doing so twice
1038 * results in memory corruption. We may have silc_ske_free called
1039 * twice, once when the abort is requested, and then again when the
1040 * FSM finish routine is called. We have to be prepared to handle
1045 ske->status = SILC_SKE_STATUS_ERROR;
1047 silc_ske_notify_failure(ske);
1049 silc_fsm_continue_sync(&ske->fsm);
1053 if (ske->refcnt > 0)
1056 /* Free start payload */
1057 if (ske->start_payload)
1058 silc_ske_payload_start_free(ske->start_payload);
1060 /* Free KE payload */
1061 if (ske->ke1_payload)
1062 silc_ske_payload_ke_free(ske->ke1_payload);
1063 if (ske->ke2_payload)
1064 silc_ske_payload_ke_free(ske->ke2_payload);
1065 silc_free(ske->remote_version);
1069 if (ske->prop->group)
1070 silc_ske_group_free(ske->prop->group);
1071 if (ske->prop->cipher)
1072 silc_cipher_free(ske->prop->cipher);
1073 if (ske->prop->hash)
1074 silc_hash_free(ske->prop->hash);
1075 if (ske->prop->hmac)
1076 silc_hmac_free(ske->prop->hmac);
1077 if (ske->prop->public_key)
1078 silc_pkcs_public_key_free(ske->prop->public_key);
1079 silc_free(ske->prop);
1082 silc_ske_free_key_material(ske->keymat);
1083 if (ske->start_payload_copy)
1084 silc_buffer_free(ske->start_payload_copy);
1086 silc_mp_uninit(ske->x);
1090 silc_mp_uninit(ske->KEY);
1091 silc_free(ske->KEY);
1093 silc_free(ske->retrans.data);
1094 silc_free(ske->hash);
1095 silc_free(ske->callbacks);
1097 memset(ske, 0xdd, sizeof(*ske));
1101 /* Return user context */
1103 void *silc_ske_get_context(SilcSKE ske)
1105 return ske->user_data;
1108 /* Sets protocol callbacks */
1110 void silc_ske_set_callbacks(SilcSKE ske,
1111 SilcSKEVerifyCb verify_key,
1112 SilcSKECompletionCb completed,
1116 silc_free(ske->callbacks);
1117 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1118 if (!ske->callbacks)
1120 ske->callbacks->verify_key = verify_key;
1121 ske->callbacks->completed = completed;
1122 ske->callbacks->context = context;
1126 /******************************** Initiator *********************************/
1128 /* Start protocol. Send our proposal */
1130 SILC_FSM_STATE(silc_ske_st_initiator_start)
1132 SilcSKE ske = fsm_context;
1133 SilcBuffer payload_buf;
1136 SILC_LOG_DEBUG(("Start"));
1140 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1141 return SILC_FSM_CONTINUE;
1144 /* Encode the payload */
1145 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1147 if (status != SILC_SKE_STATUS_OK) {
1148 /** Error encoding Start Payload */
1149 ske->status = status;
1150 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1151 return SILC_FSM_CONTINUE;
1154 /* Save the the payload buffer for future use. It is later used to
1155 compute the HASH value. */
1156 ske->start_payload_copy = payload_buf;
1158 /* Send the packet. */
1159 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1160 silc_buffer_data(payload_buf),
1161 silc_buffer_len(payload_buf))) {
1162 /** Error sending packet */
1163 SILC_LOG_DEBUG(("Error sending packet"));
1164 ske->status = SILC_SKE_STATUS_ERROR;
1165 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1166 return SILC_FSM_CONTINUE;
1169 /* Add key exchange timeout */
1170 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1171 ske, ske->timeout, 0);
1173 /** Wait for responder proposal */
1174 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1175 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1176 return SILC_FSM_WAIT;
1179 /* Phase-1. Receives responder's proposal */
1181 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1183 SilcSKE ske = fsm_context;
1184 SilcSKEStatus status;
1185 SilcSKEStartPayload payload;
1186 SilcSKESecurityProperties prop;
1187 SilcSKEDiffieHellmanGroup group = NULL;
1188 SilcBuffer packet_buf = &ske->packet->buffer;
1189 SilcUInt16 remote_port = 0;
1193 SILC_LOG_DEBUG(("Start"));
1195 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1196 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1197 silc_ske_install_retransmission(ske);
1198 silc_packet_free(ske->packet);
1200 return SILC_FSM_WAIT;
1203 /* Decode the payload */
1204 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1205 if (status != SILC_SKE_STATUS_OK) {
1206 /** Error decoding Start Payload */
1207 silc_packet_free(ske->packet);
1209 ske->status = status;
1210 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1211 return SILC_FSM_CONTINUE;
1214 /* Get remote ID and set it to stream */
1215 if (ske->packet->src_id_len) {
1216 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1217 ske->packet->src_id_type,
1218 (ske->packet->src_id_type == SILC_ID_SERVER ?
1219 (void *)&id.u.server_id : (void *)&id.u.client_id),
1220 (ske->packet->src_id_type == SILC_ID_SERVER ?
1221 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1222 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1223 (ske->packet->src_id_type == SILC_ID_SERVER ?
1224 (void *)&id.u.server_id : (void *)&id.u.client_id));
1227 silc_packet_free(ske->packet);
1230 /* Check that the cookie is returned unmodified. In case IV included
1231 flag and session port has been set, the first two bytes of cookie
1232 are the session port and we ignore them in this check. */
1233 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1234 /* Take remote port */
1235 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1238 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1239 SILC_SKE_COOKIE_LEN - coff)) {
1240 /** Invalid cookie */
1241 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1242 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1243 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1244 return SILC_FSM_CONTINUE;
1247 /* Check version string */
1248 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1249 status = silc_ske_check_version(ske);
1250 if (status != SILC_SKE_STATUS_OK) {
1251 /** Version mismatch */
1252 ske->status = status;
1253 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1254 return SILC_FSM_CONTINUE;
1257 /* Free our KE Start Payload context, we don't need it anymore. */
1258 silc_ske_payload_start_free(ske->start_payload);
1259 ske->start_payload = NULL;
1261 /* Take the selected security properties into use while doing
1262 the key exchange. This is used only while doing the key
1264 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1267 prop->flags = payload->flags;
1268 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1269 if (status != SILC_SKE_STATUS_OK)
1272 prop->group = group;
1273 prop->remote_port = remote_port;
1275 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1276 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1279 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1280 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1283 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1284 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1287 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1288 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1292 /* Save remote's KE Start Payload */
1293 ske->start_payload = payload;
1295 /** Send KE Payload */
1296 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1297 return SILC_FSM_CONTINUE;
1301 silc_ske_payload_start_free(payload);
1303 silc_ske_group_free(group);
1305 silc_cipher_free(prop->cipher);
1307 silc_hash_free(prop->hash);
1309 silc_hmac_free(prop->hmac);
1313 if (status == SILC_SKE_STATUS_OK)
1314 status = SILC_SKE_STATUS_ERROR;
1317 ske->status = status;
1318 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1319 return SILC_FSM_CONTINUE;
1322 /* Phase-2. Send KE payload */
1324 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1326 SilcSKE ske = fsm_context;
1327 SilcSKEStatus status;
1328 SilcBuffer payload_buf;
1330 SilcSKEKEPayload payload;
1333 SILC_LOG_DEBUG(("Start"));
1335 /* Create the random number x, 1 < x < q. */
1336 x = silc_calloc(1, sizeof(*x));
1338 /** Out of memory */
1339 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1340 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1341 return SILC_FSM_CONTINUE;
1345 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1346 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1348 if (status != SILC_SKE_STATUS_OK) {
1349 /** Error generating random number */
1352 ske->status = status;
1353 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1354 return SILC_FSM_CONTINUE;
1357 /* Encode the result to Key Exchange Payload. */
1359 payload = silc_calloc(1, sizeof(*payload));
1361 /** Out of memory */
1364 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1365 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1366 return SILC_FSM_CONTINUE;
1368 ske->ke1_payload = payload;
1370 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1372 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1373 silc_mp_init(&payload->x);
1374 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1375 &ske->prop->group->group);
1377 /* Get public key */
1378 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1379 if (!payload->pk_data) {
1380 /** Error encoding public key */
1383 silc_mp_uninit(&payload->x);
1385 ske->ke1_payload = NULL;
1386 ske->status = SILC_SKE_STATUS_ERROR;
1387 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1388 return SILC_FSM_CONTINUE;
1390 payload->pk_len = pk_len;
1391 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1393 /* Compute signature data if we are doing mutual authentication */
1394 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1395 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1396 SilcUInt32 hash_len, sign_len;
1398 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1399 SILC_LOG_DEBUG(("Computing HASH_i value"));
1401 /* Compute the hash value */
1402 memset(hash, 0, sizeof(hash));
1403 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1405 SILC_LOG_DEBUG(("Signing HASH_i value"));
1407 /* Sign the hash value */
1408 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1409 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1410 /** Error computing signature */
1413 silc_mp_uninit(&payload->x);
1414 silc_free(payload->pk_data);
1416 ske->ke1_payload = NULL;
1417 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1418 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1419 return SILC_FSM_CONTINUE;
1421 payload->sign_data = silc_memdup(sign, sign_len);
1422 if (payload->sign_data)
1423 payload->sign_len = sign_len;
1424 memset(sign, 0, sizeof(sign));
1427 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1428 if (status != SILC_SKE_STATUS_OK) {
1429 /** Error encoding KE payload */
1432 silc_mp_uninit(&payload->x);
1433 silc_free(payload->pk_data);
1434 silc_free(payload->sign_data);
1436 ske->ke1_payload = NULL;
1437 ske->status = status;
1438 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1439 return SILC_FSM_CONTINUE;
1444 /* Check for backwards compatibility */
1446 /* Send the packet. */
1447 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1448 silc_buffer_data(payload_buf),
1449 silc_buffer_len(payload_buf))) {
1450 /** Error sending packet */
1451 SILC_LOG_DEBUG(("Error sending packet"));
1452 ske->status = SILC_SKE_STATUS_ERROR;
1453 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1454 return SILC_FSM_CONTINUE;
1457 silc_buffer_free(payload_buf);
1459 /** Waiting responder's KE payload */
1460 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1461 return SILC_FSM_WAIT;
1464 /* Phase-3. Process responder's KE payload */
1466 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1468 SilcSKE ske = fsm_context;
1469 SilcSKEStatus status;
1470 SilcSKEKEPayload payload;
1472 SilcBuffer packet_buf = &ske->packet->buffer;
1474 SILC_LOG_DEBUG(("Start"));
1476 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1477 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1478 silc_ske_install_retransmission(ske);
1479 silc_packet_free(ske->packet);
1481 return SILC_FSM_WAIT;
1484 /* Decode the payload */
1485 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1486 if (status != SILC_SKE_STATUS_OK) {
1487 /** Error decoding KE payload */
1488 silc_packet_free(ske->packet);
1490 ske->status = status;
1491 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1492 return SILC_FSM_CONTINUE;
1494 silc_packet_free(ske->packet);
1496 ske->ke2_payload = payload;
1498 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1499 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1500 "even though we require it"));
1501 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1505 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1507 /* Compute the shared secret key */
1508 KEY = silc_calloc(1, sizeof(*KEY));
1510 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1513 /* Decode the remote's public key */
1514 if (payload->pk_data &&
1515 !silc_pkcs_public_key_alloc(payload->pk_type,
1516 payload->pk_data, payload->pk_len,
1517 &ske->prop->public_key)) {
1518 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1519 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1523 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1525 SILC_LOG_DEBUG(("Verifying public key"));
1527 /** Waiting public key verification */
1528 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1530 /* If repository is provided, verify the key from there. */
1531 if (ske->repository) {
1534 find = silc_skr_find_alloc();
1536 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1539 silc_skr_find_set_pkcs_type(find,
1540 silc_pkcs_get_type(ske->prop->public_key));
1541 silc_skr_find_set_public_key(find, ske->prop->public_key);
1542 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1544 /* Find key from repository */
1545 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1546 find, silc_ske_skr_callback, ske));
1548 /* Verify from application */
1549 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1550 ske->callbacks->context,
1551 silc_ske_pk_verified, NULL));
1556 /** Process key material */
1557 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1558 return SILC_FSM_CONTINUE;
1561 silc_ske_payload_ke_free(payload);
1562 ske->ke2_payload = NULL;
1564 silc_mp_uninit(ske->KEY);
1565 silc_free(ske->KEY);
1568 if (status == SILC_SKE_STATUS_OK)
1569 return SILC_SKE_STATUS_ERROR;
1572 ske->status = status;
1573 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1574 return SILC_FSM_CONTINUE;
1577 /* Process key material */
1579 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1581 SilcSKE ske = fsm_context;
1582 SilcSKEStatus status;
1583 SilcSKEKEPayload payload;
1584 unsigned char hash[SILC_HASH_MAXLEN];
1585 SilcUInt32 hash_len;
1586 int key_len, block_len;
1590 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1591 return SILC_FSM_CONTINUE;
1594 /* Check result of public key verification */
1595 if (ske->status != SILC_SKE_STATUS_OK) {
1596 /** Public key not verified */
1597 SILC_LOG_DEBUG(("Public key verification failed"));
1598 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1599 return SILC_FSM_CONTINUE;
1602 payload = ske->ke2_payload;
1604 /* Compute the HASH value */
1605 SILC_LOG_DEBUG(("Computing HASH value"));
1606 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1607 if (status != SILC_SKE_STATUS_OK)
1609 ske->hash = silc_memdup(hash, hash_len);
1610 ske->hash_len = hash_len;
1612 if (ske->prop->public_key) {
1613 SILC_LOG_DEBUG(("Public key is authentic"));
1614 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1616 /* Verify signature */
1617 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1618 payload->sign_len, hash, hash_len, NULL)) {
1619 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1620 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1624 SILC_LOG_DEBUG(("Signature is Ok"));
1625 memset(hash, 'F', hash_len);
1628 ske->status = SILC_SKE_STATUS_OK;
1630 /* In case we are doing rekey move to finish it. */
1633 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1634 return SILC_FSM_CONTINUE;
1637 /* Process key material */
1638 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1639 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1640 hash_len = silc_hash_len(ske->prop->hash);
1641 ske->keymat = silc_ske_process_key_material(ske, block_len,
1645 SILC_LOG_ERROR(("Error processing key material"));
1646 status = SILC_SKE_STATUS_ERROR;
1650 /* Send SUCCESS packet */
1651 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1652 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1653 /** Error sending packet */
1654 SILC_LOG_DEBUG(("Error sending packet"));
1655 ske->status = SILC_SKE_STATUS_ERROR;
1656 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1657 return SILC_FSM_CONTINUE;
1660 /** Waiting completion */
1661 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1662 return SILC_FSM_WAIT;
1665 memset(hash, 'F', sizeof(hash));
1666 silc_ske_payload_ke_free(payload);
1667 ske->ke2_payload = NULL;
1669 silc_mp_uninit(ske->KEY);
1670 silc_free(ske->KEY);
1674 memset(ske->hash, 'F', hash_len);
1675 silc_free(ske->hash);
1679 if (status == SILC_SKE_STATUS_OK)
1680 status = SILC_SKE_STATUS_ERROR;
1683 ske->status = status;
1684 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1685 return SILC_FSM_CONTINUE;
1688 /* Protocol completed */
1690 SILC_FSM_STATE(silc_ske_st_initiator_end)
1692 SilcSKE ske = fsm_context;
1694 SILC_LOG_DEBUG(("Start"));
1696 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1697 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1698 silc_ske_install_retransmission(ske);
1699 silc_packet_free(ske->packet);
1701 return SILC_FSM_WAIT;
1704 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1706 silc_packet_free(ske->packet);
1708 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1709 silc_schedule_task_del_by_context(ske->schedule, ske);
1711 /* Call completion */
1712 silc_ske_completion(ske);
1714 return SILC_FSM_FINISH;
1717 /* Aborted by application */
1719 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1721 SilcSKE ske = fsm_context;
1722 unsigned char data[4];
1724 SILC_LOG_DEBUG(("Aborted by caller"));
1726 /* Send FAILURE packet */
1727 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1728 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1730 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1731 silc_schedule_task_del_by_context(ske->schedule, ske);
1733 /* Call completion */
1734 silc_ske_completion(ske);
1736 return SILC_FSM_FINISH;
1739 /* Error occurred. Send error to remote host */
1741 SILC_FSM_STATE(silc_ske_st_initiator_error)
1743 SilcSKE ske = fsm_context;
1744 SilcSKEStatus status;
1745 unsigned char data[4];
1747 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1748 silc_ske_map_status(ske->status), ske->status));
1750 status = ske->status;
1751 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1752 status = SILC_SKE_STATUS_ERROR;
1754 /* Send FAILURE packet */
1755 SILC_PUT32_MSB((SilcUInt32)status, data);
1756 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1758 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1759 silc_schedule_task_del_by_context(ske->schedule, ske);
1761 /* Call completion */
1762 silc_ske_completion(ske);
1764 return SILC_FSM_FINISH;
1767 /* Failure received from remote */
1769 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1771 SilcSKE ske = fsm_context;
1772 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1774 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1775 SILC_GET32_MSB(error, ske->packet->buffer.data);
1776 ske->status = error;
1777 silc_packet_free(ske->packet);
1781 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1782 silc_ske_map_status(ske->status), ske->status));
1784 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1785 silc_schedule_task_del_by_context(ske->schedule, ske);
1787 /* Call completion */
1788 silc_ske_completion(ske);
1790 return SILC_FSM_FINISH;
1793 /* Starts the protocol as initiator */
1795 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1796 SilcPacketStream stream,
1797 SilcSKEParams params,
1798 SilcSKEStartPayload start_payload)
1800 SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; start_payload=%p", ske, stream, params, start_payload));
1802 if (!ske || !stream || !params || !params->version)
1805 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1808 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1811 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1812 ske->session_port = params->session_port;
1814 /* Generate security properties if not provided */
1815 if (!start_payload) {
1816 start_payload = silc_ske_assemble_security_properties(ske,
1823 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1824 ske->start_payload = start_payload;
1825 ske->version = params->version;
1828 /* Link to packet stream to get key exchange packets */
1829 ske->stream = stream;
1830 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1831 SILC_PACKET_KEY_EXCHANGE,
1832 SILC_PACKET_KEY_EXCHANGE_2,
1833 SILC_PACKET_SUCCESS,
1834 SILC_PACKET_FAILURE, -1);
1836 /* Start SKE as initiator */
1837 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1842 /******************************** Responder *********************************/
1844 /* Start protocol as responder. Wait initiator's start payload */
1846 SILC_FSM_STATE(silc_ske_st_responder_start)
1848 SilcSKE ske = fsm_context;
1850 SILC_LOG_DEBUG(("Start"));
1854 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1855 return SILC_FSM_CONTINUE;
1858 /* Add key exchange timeout */
1859 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1860 ske, ske->timeout, 0);
1862 /** Wait for initiator */
1863 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1864 return SILC_FSM_WAIT;
1867 /* Decode initiator's start payload. Select the security properties from
1868 the initiator's start payload and send our reply start payload back. */
1870 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1872 SilcSKE ske = fsm_context;
1873 SilcSKEStatus status;
1874 SilcSKEStartPayload remote_payload = NULL;
1875 SilcBuffer packet_buf = &ske->packet->buffer;
1878 SILC_LOG_DEBUG(("Start"));
1880 /* Decode the payload */
1881 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1882 if (status != SILC_SKE_STATUS_OK) {
1883 /** Error decoding Start Payload */
1884 silc_packet_free(ske->packet);
1886 ske->status = status;
1887 silc_fsm_next(fsm, silc_ske_st_responder_error);
1888 return SILC_FSM_CONTINUE;
1891 /* Get remote ID and set it to stream */
1892 if (ske->packet->src_id_len) {
1893 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1894 ske->packet->src_id_type,
1895 (ske->packet->src_id_type == SILC_ID_SERVER ?
1896 (void *)&id.u.server_id : (void *)&id.u.client_id),
1897 (ske->packet->src_id_type == SILC_ID_SERVER ?
1898 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1899 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1900 (ske->packet->src_id_type == SILC_ID_SERVER ?
1901 (void *)&id.u.server_id : (void *)&id.u.client_id));
1904 /* Take a copy of the payload buffer for future use. It is used to
1905 compute the HASH value. */
1906 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1908 silc_packet_free(ske->packet);
1911 /* Force the mutual authentication flag if we want to do it. */
1912 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1913 SILC_LOG_DEBUG(("Force mutual authentication"));
1914 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1917 /* Force PFS flag if we require it */
1918 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1919 SILC_LOG_DEBUG(("Force PFS"));
1920 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1923 /* Disable IV Included flag if requested */
1924 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1925 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1926 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1927 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1930 /* Check and select security properties */
1931 status = silc_ske_select_security_properties(ske, remote_payload,
1933 if (status != SILC_SKE_STATUS_OK) {
1934 /** Error selecting proposal */
1935 silc_ske_payload_start_free(remote_payload);
1936 ske->status = status;
1937 silc_fsm_next(fsm, silc_ske_st_responder_error);
1938 return SILC_FSM_CONTINUE;
1941 silc_ske_payload_start_free(remote_payload);
1943 /* Encode our reply payload to send the selected security properties */
1944 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1946 if (status != SILC_SKE_STATUS_OK)
1949 /* Send the packet. */
1950 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1951 silc_buffer_data(packet_buf),
1952 silc_buffer_len(packet_buf)))
1955 silc_buffer_free(packet_buf);
1957 /** Waiting initiator's KE payload */
1958 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1959 return SILC_FSM_WAIT;
1962 if (ske->prop->group)
1963 silc_ske_group_free(ske->prop->group);
1964 if (ske->prop->cipher)
1965 silc_cipher_free(ske->prop->cipher);
1966 if (ske->prop->hash)
1967 silc_hash_free(ske->prop->hash);
1968 if (ske->prop->hmac)
1969 silc_hmac_free(ske->prop->hmac);
1970 silc_free(ske->prop);
1973 if (status == SILC_SKE_STATUS_OK)
1974 status = SILC_SKE_STATUS_ERROR;
1977 ske->status = status;
1978 silc_fsm_next(fsm, silc_ske_st_responder_error);
1979 return SILC_FSM_CONTINUE;
1982 /* Phase-2. Decode initiator's KE payload */
1984 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1986 SilcSKE ske = fsm_context;
1987 SilcSKEStatus status;
1988 SilcSKEKEPayload recv_payload;
1989 SilcBuffer packet_buf = &ske->packet->buffer;
1991 SILC_LOG_DEBUG(("Start"));
1993 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1994 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1995 silc_ske_install_retransmission(ske);
1996 silc_packet_free(ske->packet);
1998 return SILC_FSM_WAIT;
2001 /* Decode Key Exchange Payload */
2002 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2003 if (status != SILC_SKE_STATUS_OK) {
2004 /** Error decoding KE payload */
2005 silc_packet_free(ske->packet);
2007 ske->status = status;
2008 silc_fsm_next(fsm, silc_ske_st_responder_error);
2009 return SILC_FSM_CONTINUE;
2012 ske->ke1_payload = recv_payload;
2014 silc_packet_free(ske->packet);
2017 /* Verify public key, except in rekey, when it is not sent */
2019 if (!recv_payload->pk_data) {
2020 /** Public key not provided */
2021 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2022 "certificate), even though we require it"));
2023 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2024 silc_fsm_next(fsm, silc_ske_st_responder_error);
2025 return SILC_FSM_CONTINUE;
2028 /* Decode the remote's public key */
2029 if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2030 recv_payload->pk_data,
2031 recv_payload->pk_len,
2032 &ske->prop->public_key)) {
2033 /** Error decoding public key */
2034 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2035 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2036 silc_fsm_next(fsm, silc_ske_st_responder_error);
2037 return SILC_FSM_CONTINUE;
2040 SILC_LOG_DEBUG(("Verifying public key"));
2042 /** Waiting public key verification */
2043 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2045 /* If repository is provided, verify the key from there. */
2046 if (ske->repository) {
2049 find = silc_skr_find_alloc();
2051 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2052 silc_fsm_next(fsm, silc_ske_st_responder_error);
2053 return SILC_FSM_CONTINUE;
2055 silc_skr_find_set_pkcs_type(find,
2056 silc_pkcs_get_type(ske->prop->public_key));
2057 silc_skr_find_set_public_key(find, ske->prop->public_key);
2058 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2060 /* Find key from repository */
2061 SILC_FSM_CALL(silc_skr_find(ske->repository,
2062 silc_fsm_get_schedule(fsm), find,
2063 silc_ske_skr_callback, ske));
2065 /* Verify from application */
2066 if (ske->callbacks->verify_key)
2067 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2068 ske->callbacks->context,
2069 silc_ske_pk_verified, NULL));
2073 /** Generate KE2 payload */
2074 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2075 return SILC_FSM_CONTINUE;
2078 /* Phase-4. Generate KE2 payload */
2080 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2082 SilcSKE ske = fsm_context;
2083 SilcSKEStatus status;
2084 SilcSKEKEPayload recv_payload, send_payload;
2089 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2090 return SILC_FSM_CONTINUE;
2093 /* Check result of public key verification */
2094 if (ske->status != SILC_SKE_STATUS_OK) {
2095 /** Public key not verified */
2096 SILC_LOG_DEBUG(("Public key verification failed"));
2097 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2098 return SILC_FSM_CONTINUE;
2101 recv_payload = ske->ke1_payload;
2103 /* The public key verification was performed only if the Mutual
2104 Authentication flag is set. */
2105 if (ske->start_payload &&
2106 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2107 unsigned char hash[SILC_HASH_MAXLEN];
2108 SilcUInt32 hash_len;
2110 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2112 /* Compute the hash value */
2113 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2114 if (status != SILC_SKE_STATUS_OK) {
2115 /** Error computing hash */
2116 ske->status = status;
2117 silc_fsm_next(fsm, silc_ske_st_responder_error);
2118 return SILC_FSM_CONTINUE;
2121 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2123 /* Verify signature */
2124 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2125 recv_payload->sign_len, hash, hash_len, NULL)) {
2126 /** Incorrect signature */
2127 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2128 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2129 silc_fsm_next(fsm, silc_ske_st_responder_error);
2130 return SILC_FSM_CONTINUE;
2133 SILC_LOG_DEBUG(("Signature is Ok"));
2135 memset(hash, 'F', hash_len);
2138 /* Create the random number x, 1 < x < q. */
2139 x = silc_calloc(1, sizeof(*x));
2142 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2143 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2145 if (status != SILC_SKE_STATUS_OK) {
2146 /** Error generating random number */
2149 ske->status = status;
2150 silc_fsm_next(fsm, silc_ske_st_responder_error);
2151 return SILC_FSM_CONTINUE;
2154 /* Save the results for later processing */
2155 send_payload = silc_calloc(1, sizeof(*send_payload));
2157 ske->ke2_payload = send_payload;
2159 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2161 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2162 silc_mp_init(&send_payload->x);
2163 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2164 &ske->prop->group->group);
2166 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2168 /* Compute the shared secret key */
2169 KEY = silc_calloc(1, sizeof(*KEY));
2171 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2172 &ske->prop->group->group);
2175 /** Send KE2 payload */
2176 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2177 return SILC_FSM_CONTINUE;
2180 /* Phase-5. Send KE2 payload */
2182 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2184 SilcSKE ske = fsm_context;
2185 SilcSKEStatus status;
2186 SilcBuffer payload_buf;
2187 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2188 SilcUInt32 hash_len, sign_len, pk_len;
2190 SILC_LOG_DEBUG(("Start"));
2192 if (ske->public_key && ske->private_key) {
2193 SILC_LOG_DEBUG(("Getting public key"));
2195 /* Get the public key */
2196 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2198 /** Error encoding public key */
2199 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2200 silc_fsm_next(fsm, silc_ske_st_responder_error);
2201 return SILC_FSM_CONTINUE;
2203 ske->ke2_payload->pk_data = pk;
2204 ske->ke2_payload->pk_len = pk_len;
2207 SILC_LOG_DEBUG(("Computing HASH value"));
2209 /* Compute the hash value */
2210 memset(hash, 0, sizeof(hash));
2211 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2212 if (status != SILC_SKE_STATUS_OK) {
2213 /** Error computing hash */
2214 ske->status = status;
2215 silc_fsm_next(fsm, silc_ske_st_responder_error);
2216 return SILC_FSM_CONTINUE;
2218 ske->hash = silc_memdup(hash, hash_len);
2219 ske->hash_len = hash_len;
2221 if (ske->public_key && ske->private_key) {
2222 SILC_LOG_DEBUG(("Signing HASH value"));
2224 /* Sign the hash value */
2225 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2226 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2227 /** Error computing signature */
2228 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2229 silc_fsm_next(fsm, silc_ske_st_responder_error);
2230 return SILC_FSM_CONTINUE;
2232 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2233 ske->ke2_payload->sign_len = sign_len;
2234 memset(sign, 0, sizeof(sign));
2236 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2238 /* Encode the Key Exchange Payload */
2239 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2241 if (status != SILC_SKE_STATUS_OK) {
2242 /** Error encoding KE payload */
2243 ske->status = status;
2244 silc_fsm_next(fsm, silc_ske_st_responder_error);
2245 return SILC_FSM_CONTINUE;
2248 /* Send the packet. */
2249 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2250 payload_buf->data, silc_buffer_len(payload_buf))) {
2251 SILC_LOG_DEBUG(("Error sending packet"));
2252 ske->status = SILC_SKE_STATUS_ERROR;
2253 silc_fsm_next(fsm, silc_ske_st_responder_error);
2254 return SILC_FSM_CONTINUE;
2257 silc_buffer_free(payload_buf);
2259 /* In case we are doing rekey move to finish it. */
2262 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2263 return SILC_FSM_CONTINUE;
2266 /** Waiting completion */
2267 silc_fsm_next(fsm, silc_ske_st_responder_end);
2268 return SILC_FSM_WAIT;
2271 /* Protocol completed */
2273 SILC_FSM_STATE(silc_ske_st_responder_end)
2275 SilcSKE ske = fsm_context;
2276 unsigned char tmp[4];
2277 SilcUInt32 hash_len, key_len, block_len;
2279 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2280 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2281 silc_ske_install_retransmission(ske);
2282 silc_packet_free(ske->packet);
2284 return SILC_FSM_WAIT;
2286 silc_packet_free(ske->packet);
2289 /* Process key material */
2290 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2291 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2292 hash_len = silc_hash_len(ske->prop->hash);
2293 ske->keymat = silc_ske_process_key_material(ske, block_len,
2297 /** Error processing key material */
2298 ske->status = SILC_SKE_STATUS_ERROR;
2299 silc_fsm_next(fsm, silc_ske_st_responder_error);
2300 return SILC_FSM_CONTINUE;
2303 /* Send SUCCESS packet */
2304 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2305 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2307 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2308 silc_schedule_task_del_by_context(ske->schedule, ske);
2310 /* Call completion */
2311 silc_ske_completion(ske);
2313 return SILC_FSM_FINISH;
2316 /* Aborted by application */
2318 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2320 SilcSKE ske = fsm_context;
2321 unsigned char tmp[4];
2323 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2325 /* Send FAILURE packet */
2326 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2327 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2329 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2330 silc_schedule_task_del_by_context(ske->schedule, ske);
2332 /* Call completion */
2333 silc_ske_completion(ske);
2335 return SILC_FSM_FINISH;
2338 /* Failure received from remote */
2340 SILC_FSM_STATE(silc_ske_st_responder_failure)
2342 SilcSKE ske = fsm_context;
2343 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2345 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2347 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2348 SILC_GET32_MSB(error, ske->packet->buffer.data);
2349 ske->status = error;
2350 silc_packet_free(ske->packet);
2354 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2355 silc_schedule_task_del_by_context(ske->schedule, ske);
2357 /* Call completion */
2358 silc_ske_completion(ske);
2360 return SILC_FSM_FINISH;
2363 /* Error occurred */
2365 SILC_FSM_STATE(silc_ske_st_responder_error)
2367 SilcSKE ske = fsm_context;
2368 unsigned char tmp[4];
2370 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2371 ske->status, silc_ske_map_status(ske->status)));
2373 /* Send FAILURE packet */
2374 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2375 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2376 SILC_PUT32_MSB(ske->status, tmp);
2377 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2379 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2380 silc_schedule_task_del_by_context(ske->schedule, ske);
2382 /* Call completion */
2383 silc_ske_completion(ske);
2385 return SILC_FSM_FINISH;
2388 /* Starts the protocol as responder. */
2390 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2391 SilcPacketStream stream,
2392 SilcSKEParams params)
2394 SILC_LOG_DEBUG(("Start SKE as responder"));
2396 if (!ske || !stream || !params || !params->version)
2399 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2402 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2405 ske->responder = TRUE;
2406 ske->flags = params->flags;
2407 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2408 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2409 ske->session_port = params->session_port;
2410 ske->version = params->version;
2415 /* Link to packet stream to get key exchange packets */
2416 ske->stream = stream;
2417 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2418 SILC_PACKET_KEY_EXCHANGE,
2419 SILC_PACKET_KEY_EXCHANGE_1,
2420 SILC_PACKET_SUCCESS,
2421 SILC_PACKET_FAILURE, -1);
2423 /* Start SKE as responder */
2424 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2429 /***************************** Initiator Rekey ******************************/
2433 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2435 SilcSKE ske = fsm_context;
2438 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2442 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2443 return SILC_FSM_CONTINUE;
2446 /* Add rekey exchange timeout */
2447 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2450 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2453 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2454 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2455 return SILC_FSM_CONTINUE;
2458 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2459 /** Cannot allocate hash */
2460 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2461 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2462 return SILC_FSM_CONTINUE;
2465 /* Send REKEY packet to start rekey protocol */
2466 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2467 /** Error sending packet */
2468 SILC_LOG_DEBUG(("Error sending packet"));
2469 ske->status = SILC_SKE_STATUS_ERROR;
2470 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2471 return SILC_FSM_CONTINUE;
2474 /* If doing rekey without PFS, move directly to the end of the protocol. */
2475 if (!ske->rekey->pfs) {
2476 /** Rekey without PFS */
2477 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2478 return SILC_FSM_CONTINUE;
2481 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2483 if (status != SILC_SKE_STATUS_OK) {
2484 /** Unknown group */
2485 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2486 return SILC_FSM_CONTINUE;
2489 /** Rekey with PFS */
2490 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2491 return SILC_FSM_CONTINUE;
2494 /* Sends REKEY_DONE packet to finish the protocol. */
2496 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2498 SilcSKE ske = fsm_context;
2499 SilcCipher send_key;
2502 SilcUInt32 key_len, block_len, hash_len, x_len;
2503 unsigned char *pfsbuf;
2505 SILC_LOG_DEBUG(("Start"));
2507 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2508 key_len = silc_cipher_get_key_len(send_key);
2509 block_len = silc_cipher_get_block_len(send_key);
2510 hash = ske->prop->hash;
2511 hash_len = silc_hash_len(hash);
2513 /* Process key material */
2514 if (ske->rekey->pfs) {
2516 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2518 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2521 memset(pfsbuf, 0, x_len);
2527 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2528 ske->rekey->enc_key_len / 8,
2534 SILC_LOG_ERROR(("Error processing key material"));
2535 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2536 return SILC_FSM_CONTINUE;
2539 ske->prop->cipher = send_key;
2540 ske->prop->hmac = hmac_send;
2542 /* Get sending keys */
2543 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2544 &hmac_send, NULL, NULL)) {
2545 /** Cannot get keys */
2546 ske->status = SILC_SKE_STATUS_ERROR;
2547 ske->prop->cipher = NULL;
2548 ske->prop->hmac = NULL;
2549 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2550 return SILC_FSM_CONTINUE;
2553 ske->prop->cipher = NULL;
2554 ske->prop->hmac = NULL;
2556 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2557 packet sent after this call will be protected with the new keys. */
2558 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2560 /** Cannot set keys */
2561 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2562 ske->status = SILC_SKE_STATUS_ERROR;
2563 silc_cipher_free(send_key);
2564 silc_hmac_free(hmac_send);
2565 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2566 return SILC_FSM_CONTINUE;
2569 /** Wait for REKEY_DONE */
2570 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2571 return SILC_FSM_WAIT;
2574 /* Rekey protocol end */
2576 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2578 SilcSKE ske = fsm_context;
2579 SilcCipher receive_key;
2580 SilcHmac hmac_receive;
2581 SilcSKERekeyMaterial rekey;
2583 SILC_LOG_DEBUG(("Start"));
2585 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2586 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2587 silc_packet_free(ske->packet);
2589 return SILC_FSM_WAIT;
2592 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2593 ske->prop->cipher = receive_key;
2594 ske->prop->hmac = hmac_receive;
2596 /* Get receiving keys */
2597 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2598 NULL, &hmac_receive, NULL)) {
2599 /** Cannot get keys */
2600 ske->status = SILC_SKE_STATUS_ERROR;
2601 ske->prop->cipher = NULL;
2602 ske->prop->hmac = NULL;
2603 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2604 return SILC_FSM_CONTINUE;
2607 /* Set new receiving keys into use. All packets received after this will
2608 be decrypted with the new keys. */
2609 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2610 hmac_receive, FALSE)) {
2611 /** Cannot set keys */
2612 SILC_LOG_DEBUG(("Cannot set new keys"));
2613 ske->status = SILC_SKE_STATUS_ERROR;
2614 silc_cipher_free(receive_key);
2615 silc_hmac_free(hmac_receive);
2616 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2617 return SILC_FSM_CONTINUE;
2620 SILC_LOG_DEBUG(("Rekey completed successfully"));
2622 /* Generate new rekey material */
2623 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2626 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2627 ske->prop->cipher = NULL;
2628 ske->prop->hmac = NULL;
2629 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2630 return SILC_FSM_CONTINUE;
2632 rekey->pfs = ske->rekey->pfs;
2635 ske->prop->cipher = NULL;
2636 ske->prop->hmac = NULL;
2637 silc_packet_free(ske->packet);
2639 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2640 silc_schedule_task_del_by_context(ske->schedule, ske);
2642 /* Call completion */
2643 silc_ske_completion(ske);
2645 return SILC_FSM_FINISH;
2648 /* Starts rekey protocol as initiator */
2651 silc_ske_rekey_initiator(SilcSKE ske,
2652 SilcPacketStream stream,
2653 SilcSKERekeyMaterial rekey)
2655 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2657 if (!ske || !stream || !rekey) {
2658 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2663 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2666 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2670 ske->responder = FALSE;
2671 ske->rekeying = TRUE;
2674 /* Link to packet stream to get key exchange packets */
2675 ske->stream = stream;
2676 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2678 SILC_PACKET_REKEY_DONE,
2679 SILC_PACKET_KEY_EXCHANGE_2,
2680 SILC_PACKET_SUCCESS,
2681 SILC_PACKET_FAILURE, -1);
2683 /* Start SKE rekey as initiator */
2684 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2689 /***************************** Responder Rekey ******************************/
2691 /* Wait for initiator's packet */
2693 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2695 SilcSKE ske = fsm_context;
2697 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2701 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2702 return SILC_FSM_CONTINUE;
2705 /* Add rekey exchange timeout */
2706 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2709 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2711 /* If REKEY packet already received process it directly */
2712 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2713 return SILC_FSM_CONTINUE;
2715 /* Wait for REKEY */
2716 return SILC_FSM_WAIT;
2719 /* Process initiator's REKEY packet */
2721 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2723 SilcSKE ske = fsm_context;
2724 SilcSKEStatus status;
2726 SILC_LOG_DEBUG(("Start"));
2728 if (ske->packet->type != SILC_PACKET_REKEY) {
2729 ske->status = SILC_SKE_STATUS_ERROR;
2730 silc_packet_free(ske->packet);
2732 silc_fsm_next(fsm, silc_ske_st_responder_error);
2733 return SILC_FSM_CONTINUE;
2736 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2739 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2740 silc_fsm_next(fsm, silc_ske_st_responder_error);
2741 return SILC_FSM_CONTINUE;
2744 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2745 /** Cannot allocate hash */
2746 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2747 silc_fsm_next(fsm, silc_ske_st_responder_error);
2748 return SILC_FSM_CONTINUE;
2751 /* If doing rekey without PFS, move directly to the end of the protocol. */
2752 if (!ske->rekey->pfs) {
2753 /** Rekey without PFS */
2754 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2755 return SILC_FSM_CONTINUE;
2758 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2760 if (status != SILC_SKE_STATUS_OK) {
2761 /** Unknown group */
2762 silc_fsm_next(fsm, silc_ske_st_responder_error);
2763 return SILC_FSM_CONTINUE;
2766 /** Rekey with PFS */
2767 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2768 return SILC_FSM_WAIT;
2771 /* Sends REKEY_DONE packet to finish the protocol. */
2773 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2775 SilcSKE ske = fsm_context;
2776 SilcCipher send_key;
2779 SilcUInt32 key_len, block_len, hash_len, x_len;
2780 unsigned char *pfsbuf;
2782 SILC_LOG_DEBUG(("Start"));
2784 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2785 key_len = silc_cipher_get_key_len(send_key);
2786 block_len = silc_cipher_get_block_len(send_key);
2787 hash = ske->prop->hash;
2788 hash_len = silc_hash_len(hash);
2790 /* Process key material */
2791 if (ske->rekey->pfs) {
2793 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2795 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2798 memset(pfsbuf, 0, x_len);
2804 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2805 ske->rekey->enc_key_len / 8,
2811 SILC_LOG_ERROR(("Error processing key material"));
2812 silc_fsm_next(fsm, silc_ske_st_responder_error);
2813 return SILC_FSM_CONTINUE;
2816 ske->prop->cipher = send_key;
2817 ske->prop->hmac = hmac_send;
2819 /* Get sending keys */
2820 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2821 &hmac_send, NULL, NULL)) {
2822 /** Cannot get keys */
2823 ske->status = SILC_SKE_STATUS_ERROR;
2824 ske->prop->cipher = NULL;
2825 ske->prop->hmac = NULL;
2826 silc_fsm_next(fsm, silc_ske_st_responder_error);
2827 return SILC_FSM_CONTINUE;
2830 ske->prop->cipher = NULL;
2831 ske->prop->hmac = NULL;
2833 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2834 packet sent after this call will be protected with the new keys. */
2835 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2837 /** Cannot set keys */
2838 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2839 ske->status = SILC_SKE_STATUS_ERROR;
2840 silc_cipher_free(send_key);
2841 silc_hmac_free(hmac_send);
2842 silc_fsm_next(fsm, silc_ske_st_responder_error);
2843 return SILC_FSM_CONTINUE;
2846 /** Wait for REKEY_DONE */
2847 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2848 return SILC_FSM_WAIT;
2851 /* Rekey protocol end */
2853 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2855 SilcSKE ske = fsm_context;
2856 SilcCipher receive_key;
2857 SilcHmac hmac_receive;
2858 SilcSKERekeyMaterial rekey;
2860 SILC_LOG_DEBUG(("Start"));
2862 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2863 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2864 silc_packet_free(ske->packet);
2866 return SILC_FSM_WAIT;
2869 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2870 ske->prop->cipher = receive_key;
2871 ske->prop->hmac = hmac_receive;
2873 /* Get receiving keys */
2874 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2875 NULL, &hmac_receive, NULL)) {
2876 /** Cannot get keys */
2877 ske->status = SILC_SKE_STATUS_ERROR;
2878 ske->prop->cipher = NULL;
2879 ske->prop->hmac = NULL;
2880 silc_fsm_next(fsm, silc_ske_st_responder_error);
2881 return SILC_FSM_CONTINUE;
2884 /* Set new receiving keys into use. All packets received after this will
2885 be decrypted with the new keys. */
2886 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2887 hmac_receive, FALSE)) {
2888 /** Cannot set keys */
2889 SILC_LOG_DEBUG(("Cannot set new keys"));
2890 ske->status = SILC_SKE_STATUS_ERROR;
2891 ske->prop->cipher = NULL;
2892 ske->prop->hmac = NULL;
2893 silc_cipher_free(receive_key);
2894 silc_hmac_free(hmac_receive);
2895 silc_fsm_next(fsm, silc_ske_st_responder_error);
2896 return SILC_FSM_CONTINUE;
2899 SILC_LOG_DEBUG(("Rekey completed successfully"));
2901 /* Generate new rekey material */
2902 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2905 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2906 ske->prop->cipher = NULL;
2907 ske->prop->hmac = NULL;
2908 silc_fsm_next(fsm, silc_ske_st_responder_error);
2909 return SILC_FSM_CONTINUE;
2911 rekey->pfs = ske->rekey->pfs;
2914 ske->prop->cipher = NULL;
2915 ske->prop->hmac = NULL;
2916 silc_packet_free(ske->packet);
2918 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2919 silc_schedule_task_del_by_context(ske->schedule, ske);
2921 /* Call completion */
2922 silc_ske_completion(ske);
2924 return SILC_FSM_FINISH;
2927 /* Starts rekey protocol as responder */
2930 silc_ske_rekey_responder(SilcSKE ske,
2931 SilcPacketStream stream,
2932 SilcSKERekeyMaterial rekey,
2935 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2937 if (!ske || !stream || !rekey)
2940 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2943 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2947 ske->responder = TRUE;
2948 ske->rekeying = TRUE;
2949 ske->packet = packet;
2952 /* Link to packet stream to get key exchange packets */
2953 ske->stream = stream;
2954 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2956 SILC_PACKET_REKEY_DONE,
2957 SILC_PACKET_KEY_EXCHANGE_1,
2958 SILC_PACKET_SUCCESS,
2959 SILC_PACKET_FAILURE, -1);
2961 /* Start SKE rekey as responder */
2962 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2967 /* Processes the provided key material `data' as the SILC protocol
2968 specification defines. */
2971 silc_ske_process_key_material_data(unsigned char *data,
2972 SilcUInt32 data_len,
2973 SilcUInt32 req_iv_len,
2974 SilcUInt32 req_enc_key_len,
2975 SilcUInt32 req_hmac_key_len,
2979 unsigned char hashd[SILC_HASH_MAXLEN];
2980 SilcUInt32 hash_len = req_hmac_key_len;
2981 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2982 SilcSKEKeyMaterial key;
2984 SILC_LOG_DEBUG(("Start"));
2986 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2989 key = silc_calloc(1, sizeof(*key));
2993 buf = silc_buffer_alloc_size(1 + data_len);
2996 silc_buffer_format(buf,
2997 SILC_STR_UI_CHAR(0),
2998 SILC_STR_DATA(data, data_len),
3002 memset(hashd, 0, sizeof(hashd));
3004 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3005 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3006 memcpy(key->send_iv, hashd, req_iv_len);
3007 memset(hashd, 0, sizeof(hashd));
3009 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3010 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3011 memcpy(key->receive_iv, hashd, req_iv_len);
3012 key->iv_len = req_iv_len;
3014 /* Take the encryption keys. If requested key size is more than
3015 the size of hash length we will distribute more key material
3016 as protocol defines. */
3018 if (enc_key_len > hash_len) {
3020 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3021 k3[SILC_HASH_MAXLEN];
3022 unsigned char *dtmp;
3025 if (enc_key_len > (3 * hash_len))
3028 /* Take first round */
3029 memset(k1, 0, sizeof(k1));
3030 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3032 /* Take second round */
3033 dist = silc_buffer_alloc_size(data_len + hash_len);
3036 silc_buffer_format(dist,
3037 SILC_STR_DATA(data, data_len),
3038 SILC_STR_DATA(k1, hash_len),
3040 memset(k2, 0, sizeof(k2));
3041 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3043 /* Take third round */
3044 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3045 silc_buffer_pull_tail(dist, hash_len);
3046 silc_buffer_pull(dist, data_len + hash_len);
3047 silc_buffer_format(dist,
3048 SILC_STR_DATA(k2, hash_len),
3050 silc_buffer_push(dist, data_len + hash_len);
3051 memset(k3, 0, sizeof(k3));
3052 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3054 /* Then, save the keys */
3055 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3056 memcpy(dtmp, k1, hash_len);
3057 memcpy(dtmp + hash_len, k2, hash_len);
3058 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3060 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3061 memcpy(key->send_enc_key, dtmp, enc_key_len);
3062 key->enc_key_len = req_enc_key_len;
3064 memset(dtmp, 0, (3 * hash_len));
3065 memset(k1, 0, sizeof(k1));
3066 memset(k2, 0, sizeof(k2));
3067 memset(k3, 0, sizeof(k3));
3069 silc_buffer_clear(dist);
3070 silc_buffer_free(dist);
3072 /* Take normal hash as key */
3073 memset(hashd, 0, sizeof(hashd));
3074 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3075 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3076 memcpy(key->send_enc_key, hashd, enc_key_len);
3077 key->enc_key_len = req_enc_key_len;
3081 if (enc_key_len > hash_len) {
3083 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3084 k3[SILC_HASH_MAXLEN];
3085 unsigned char *dtmp;
3088 if (enc_key_len > (3 * hash_len))
3091 /* Take first round */
3092 memset(k1, 0, sizeof(k1));
3093 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3095 /* Take second round */
3096 dist = silc_buffer_alloc_size(data_len + hash_len);
3099 silc_buffer_format(dist,
3100 SILC_STR_DATA(data, data_len),
3101 SILC_STR_DATA(k1, hash_len),
3103 memset(k2, 0, sizeof(k2));
3104 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3106 /* Take third round */
3107 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3108 silc_buffer_pull_tail(dist, hash_len);
3109 silc_buffer_pull(dist, data_len + hash_len);
3110 silc_buffer_format(dist,
3111 SILC_STR_DATA(k2, hash_len),
3113 silc_buffer_push(dist, data_len + hash_len);
3114 memset(k3, 0, sizeof(k3));
3115 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3117 /* Then, save the keys */
3118 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3119 memcpy(dtmp, k1, hash_len);
3120 memcpy(dtmp + hash_len, k2, hash_len);
3121 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3123 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3124 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3125 key->enc_key_len = req_enc_key_len;
3127 memset(dtmp, 0, (3 * hash_len));
3128 memset(k1, 0, sizeof(k1));
3129 memset(k2, 0, sizeof(k2));
3130 memset(k3, 0, sizeof(k3));
3132 silc_buffer_clear(dist);
3133 silc_buffer_free(dist);
3135 /* Take normal hash as key */
3136 memset(hashd, 0, sizeof(hashd));
3137 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3138 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3139 memcpy(key->receive_enc_key, hashd, enc_key_len);
3140 key->enc_key_len = req_enc_key_len;
3143 /* Take HMAC keys */
3144 memset(hashd, 0, sizeof(hashd));
3146 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3147 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3148 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3149 memset(hashd, 0, sizeof(hashd));
3151 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3152 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3153 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3154 key->hmac_key_len = req_hmac_key_len;
3155 memset(hashd, 0, sizeof(hashd));
3157 silc_buffer_clear(buf);
3158 silc_buffer_free(buf);
3160 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3165 /* Processes negotiated key material as protocol specifies. This returns
3166 the actual keys to be used in the SILC. */
3169 silc_ske_process_key_material(SilcSKE ske,
3170 SilcUInt32 req_iv_len,
3171 SilcUInt32 req_enc_key_len,
3172 SilcUInt32 req_hmac_key_len,
3173 SilcSKERekeyMaterial *rekey)
3176 unsigned char *tmpbuf;
3178 SilcSKEKeyMaterial key;
3180 /* Encode KEY to binary data */
3181 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3183 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3186 silc_buffer_format(buf,
3187 SILC_STR_DATA(tmpbuf, klen),
3188 SILC_STR_DATA(ske->hash, ske->hash_len),
3191 /* Process the key material */
3192 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3193 req_iv_len, req_enc_key_len,
3197 memset(tmpbuf, 0, klen);
3199 silc_buffer_clear(buf);
3200 silc_buffer_free(buf);
3203 *rekey = silc_ske_make_rekey_material(ske, key);
3211 /* Free key material structure */
3213 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3219 silc_free(key->send_iv);
3220 if (key->receive_iv)
3221 silc_free(key->receive_iv);
3222 if (key->send_enc_key) {
3223 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3224 silc_free(key->send_enc_key);
3226 if (key->receive_enc_key) {
3227 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3228 silc_free(key->receive_enc_key);
3230 if (key->send_hmac_key) {
3231 memset(key->send_hmac_key, 0, key->hmac_key_len);
3232 silc_free(key->send_hmac_key);
3234 if (key->receive_hmac_key) {
3235 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3236 silc_free(key->receive_hmac_key);
3241 /* Free rekey material */
3243 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3247 if (rekey->send_enc_key) {
3248 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3249 silc_free(rekey->send_enc_key);
3251 silc_free(rekey->hash);
3255 /* Set keys into use */
3257 SilcBool silc_ske_set_keys(SilcSKE ske,
3258 SilcSKEKeyMaterial keymat,
3259 SilcSKESecurityProperties prop,
3260 SilcCipher *ret_send_key,
3261 SilcCipher *ret_receive_key,
3262 SilcHmac *ret_hmac_send,
3263 SilcHmac *ret_hmac_receive,
3266 unsigned char iv[SILC_HASH_MAXLEN];
3267 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3269 /* Allocate ciphers to be used in the communication */
3271 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3275 if (ret_receive_key) {
3276 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3281 /* Allocate HMACs */
3282 if (ret_hmac_send) {
3283 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3287 if (ret_hmac_receive) {
3288 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3295 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3299 /* Set key material */
3300 memset(iv, 0, sizeof(iv));
3301 if (ske->responder) {
3303 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3304 keymat->enc_key_len, TRUE);
3306 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3308 if (!ske->rekeying) {
3310 memcpy(iv, ske->hash, 4);
3312 memcpy(iv + 4, keymat->receive_iv, 8);
3314 /* Rekey, recompute the truncated hash value. */
3315 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3317 memcpy(iv + 4, keymat->receive_iv, 8);
3319 memset(iv + 4, 0, 12);
3322 silc_cipher_set_iv(*ret_send_key, iv);
3325 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3328 if (ret_receive_key) {
3329 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3330 keymat->enc_key_len, FALSE);
3332 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3334 if (!ske->rekeying) {
3336 memcpy(iv, ske->hash, 4);
3338 memcpy(iv + 4, keymat->send_iv, 8);
3340 /* Rekey, recompute the truncated hash value. */
3341 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3343 memcpy(iv + 4, keymat->send_iv, 8);
3345 memset(iv + 4, 0, 12);
3348 silc_cipher_set_iv(*ret_receive_key, iv);
3351 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3355 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3356 keymat->hmac_key_len);
3357 if (ret_hmac_receive)
3358 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3359 keymat->hmac_key_len);
3362 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3363 keymat->enc_key_len, TRUE);
3365 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3367 if (!ske->rekeying) {
3369 memcpy(iv, ske->hash, 4);
3371 memcpy(iv + 4, keymat->send_iv, 8);
3373 /* Rekey, recompute the truncated hash value. */
3374 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3376 memcpy(iv + 4, keymat->send_iv, 8);
3378 memset(iv + 4, 0, 12);
3381 silc_cipher_set_iv(*ret_send_key, iv);
3384 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3387 if (ret_receive_key) {
3388 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3389 keymat->enc_key_len, FALSE);
3391 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3393 if (!ske->rekeying) {
3394 /* Set IV. If IV Included flag was negotiated we only set the
3395 truncated hash value. */
3396 memcpy(iv, ske->hash, 4);
3398 memcpy(iv + 4, keymat->receive_iv, 8);
3400 /* Rekey, recompute the truncated hash value. */
3401 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3403 memcpy(iv + 4, keymat->receive_iv, 8);
3405 memset(iv + 4, 0, 12);
3408 silc_cipher_set_iv(*ret_receive_key, iv);
3411 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3415 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3416 keymat->hmac_key_len);
3417 if (ret_hmac_receive)
3418 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3419 keymat->hmac_key_len);
3425 const char *silc_ske_status_string[] =
3429 "Unexpected error occurred",
3430 "Bad payload in packet",
3431 "Unsupported group",
3432 "Unsupported cipher",
3434 "Unsupported hash function",
3436 "Unsupported public key (or certificate)",
3437 "Incorrect signature",
3438 "Bad or unsupported version",
3442 "Remote did not provide public key",
3443 "Bad reserved field in packet",
3444 "Bad payload length in packet",
3445 "Error computing signature",
3446 "System out of memory",
3447 "Key exchange timeout",
3452 /* Maps status to readable string and returns the string. If string is not
3453 found and empty character string ("") is returned. */
3455 const char *silc_ske_map_status(SilcSKEStatus status)
3459 for (i = 0; silc_ske_status_string[i]; i++)
3461 return silc_ske_status_string[i];
3466 /* Parses remote host's version string. */
3468 SilcBool silc_ske_parse_version(SilcSKE ske,
3469 SilcUInt32 *protocol_version,
3470 char **protocol_version_string,
3471 SilcUInt32 *software_version,
3472 char **software_version_string,
3473 char **vendor_version)
3475 return silc_parse_version_string(ske->remote_version,
3477 protocol_version_string,
3479 software_version_string,
3483 /* Get security properties */
3485 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3490 /* Get key material */
3492 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
3498 * Notify the owner of the ske that we failed. Ensures that we don't make the
3499 * same callout twice, as the notification callback routines are not designed
3500 * to handle that case.
3502 static void silc_ske_notify_failure(SilcSKE ske)
3504 SILC_LOG_DEBUG(("Notifying SKE %p owner of failure (failure_notified = %lu)", ske, ske->failure_notified));
3507 * First, check if we have already made a failure callout. If so, then we
3511 if (ske->failure_notified)
3515 * Mark ourselves as having already sent the failure notification here and
3519 ske->failure_notified = TRUE;
3521 SILC_LOG_DEBUG(("Actually calling real failure notify callback for SKE %p (responder = %s)", ske, ske->responder ? "TRUE" : "FALSE"));
3524 * Finally, make the call to the owner's registered failure callback.
3528 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
3530 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);