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;
971 ske->fsm_finished = TRUE;
975 /* Key exchange timeout task callback */
977 SILC_TASK_CALLBACK(silc_ske_timeout)
979 SilcSKE ske = context;
981 SILC_LOG_DEBUG(("Timeout"));
984 ske->status = SILC_SKE_STATUS_TIMEOUT;
985 silc_ske_notify_failure(ske);
987 silc_fsm_continue_sync(&ske->fsm);
990 /******************************* Protocol API *******************************/
992 /* Allocates new SKE object. */
994 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
995 SilcSKR repository, SilcPublicKey public_key,
996 SilcPrivateKey private_key, void *context)
1000 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1002 if (!rng || !schedule)
1006 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1010 ske = silc_calloc(1, sizeof(*ske));
1013 ske->status = SILC_SKE_STATUS_OK;
1015 ske->repository = repository;
1016 ske->user_data = context;
1017 ske->schedule = schedule;
1018 ske->public_key = public_key;
1019 ske->private_key = private_key;
1020 ske->retry_timer = SILC_SKE_RETRY_MIN;
1026 /* Free's SKE object. */
1028 void silc_ske_free(SilcSKE ske)
1033 SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu", ske, ske->aborted, ske->refcnt));
1037 * If already aborted, destroy the session immediately. Only do the
1038 * notification work if we have not already though, as doing so twice
1039 * results in memory corruption. We may have silc_ske_free called
1040 * twice, once when the abort is requested, and then again when the
1041 * FSM finish routine is called. We have to be prepared to handle
1046 ske->status = SILC_SKE_STATUS_ERROR;
1048 silc_ske_notify_failure(ske);
1050 if (!ske->fsm_finished)
1051 silc_fsm_continue_sync(&ske->fsm);
1053 SILC_LOG_DEBUG(("Not continuing FSM as it's finished for SKE %p", ske));
1057 if (ske->refcnt > 0)
1060 /* Free start payload */
1061 if (ske->start_payload)
1062 silc_ske_payload_start_free(ske->start_payload);
1064 /* Free KE payload */
1065 if (ske->ke1_payload)
1066 silc_ske_payload_ke_free(ske->ke1_payload);
1067 if (ske->ke2_payload)
1068 silc_ske_payload_ke_free(ske->ke2_payload);
1069 silc_free(ske->remote_version);
1073 if (ske->prop->group)
1074 silc_ske_group_free(ske->prop->group);
1075 if (ske->prop->cipher)
1076 silc_cipher_free(ske->prop->cipher);
1077 if (ske->prop->hash)
1078 silc_hash_free(ske->prop->hash);
1079 if (ske->prop->hmac)
1080 silc_hmac_free(ske->prop->hmac);
1081 if (ske->prop->public_key)
1082 silc_pkcs_public_key_free(ske->prop->public_key);
1083 silc_free(ske->prop);
1086 silc_ske_free_key_material(ske->keymat);
1087 if (ske->start_payload_copy)
1088 silc_buffer_free(ske->start_payload_copy);
1090 silc_mp_uninit(ske->x);
1094 silc_mp_uninit(ske->KEY);
1095 silc_free(ske->KEY);
1097 silc_free(ske->retrans.data);
1098 silc_free(ske->hash);
1099 silc_free(ske->callbacks);
1101 memset(ske, 0xdd, sizeof(*ske));
1105 /* Return user context */
1107 void *silc_ske_get_context(SilcSKE ske)
1109 return ske->user_data;
1112 /* Sets protocol callbacks */
1114 void silc_ske_set_callbacks(SilcSKE ske,
1115 SilcSKEVerifyCb verify_key,
1116 SilcSKECompletionCb completed,
1120 silc_free(ske->callbacks);
1121 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1122 if (!ske->callbacks)
1124 ske->callbacks->verify_key = verify_key;
1125 ske->callbacks->completed = completed;
1126 ske->callbacks->context = context;
1130 /******************************** Initiator *********************************/
1132 /* Start protocol. Send our proposal */
1134 SILC_FSM_STATE(silc_ske_st_initiator_start)
1136 SilcSKE ske = fsm_context;
1137 SilcBuffer payload_buf;
1140 SILC_LOG_DEBUG(("Start"));
1144 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1145 return SILC_FSM_CONTINUE;
1148 /* Encode the payload */
1149 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1151 if (status != SILC_SKE_STATUS_OK) {
1152 /** Error encoding Start Payload */
1153 ske->status = status;
1154 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1155 return SILC_FSM_CONTINUE;
1158 /* Save the the payload buffer for future use. It is later used to
1159 compute the HASH value. */
1160 ske->start_payload_copy = payload_buf;
1162 /* Send the packet. */
1163 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1164 silc_buffer_data(payload_buf),
1165 silc_buffer_len(payload_buf))) {
1166 /** Error sending packet */
1167 SILC_LOG_DEBUG(("Error sending packet"));
1168 ske->status = SILC_SKE_STATUS_ERROR;
1169 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1170 return SILC_FSM_CONTINUE;
1173 /* Add key exchange timeout */
1174 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1175 ske, ske->timeout, 0);
1177 /** Wait for responder proposal */
1178 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1179 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1180 return SILC_FSM_WAIT;
1183 /* Phase-1. Receives responder's proposal */
1185 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1187 SilcSKE ske = fsm_context;
1188 SilcSKEStatus status;
1189 SilcSKEStartPayload payload;
1190 SilcSKESecurityProperties prop;
1191 SilcSKEDiffieHellmanGroup group = NULL;
1192 SilcBuffer packet_buf = &ske->packet->buffer;
1193 SilcUInt16 remote_port = 0;
1197 SILC_LOG_DEBUG(("Start"));
1199 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1200 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1201 silc_ske_install_retransmission(ske);
1202 silc_packet_free(ske->packet);
1204 return SILC_FSM_WAIT;
1207 /* Decode the payload */
1208 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1209 if (status != SILC_SKE_STATUS_OK) {
1210 /** Error decoding Start Payload */
1211 silc_packet_free(ske->packet);
1213 ske->status = status;
1214 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1215 return SILC_FSM_CONTINUE;
1218 /* Get remote ID and set it to stream */
1219 if (ske->packet->src_id_len) {
1220 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1221 ske->packet->src_id_type,
1222 (ske->packet->src_id_type == SILC_ID_SERVER ?
1223 (void *)&id.u.server_id : (void *)&id.u.client_id),
1224 (ske->packet->src_id_type == SILC_ID_SERVER ?
1225 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1226 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1227 (ske->packet->src_id_type == SILC_ID_SERVER ?
1228 (void *)&id.u.server_id : (void *)&id.u.client_id));
1231 silc_packet_free(ske->packet);
1234 /* Check that the cookie is returned unmodified. In case IV included
1235 flag and session port has been set, the first two bytes of cookie
1236 are the session port and we ignore them in this check. */
1237 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1238 /* Take remote port */
1239 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1242 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1243 SILC_SKE_COOKIE_LEN - coff)) {
1244 /** Invalid cookie */
1245 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1246 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1247 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1248 return SILC_FSM_CONTINUE;
1251 /* Check version string */
1252 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1253 status = silc_ske_check_version(ske);
1254 if (status != SILC_SKE_STATUS_OK) {
1255 /** Version mismatch */
1256 ske->status = status;
1257 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1258 return SILC_FSM_CONTINUE;
1261 /* Free our KE Start Payload context, we don't need it anymore. */
1262 silc_ske_payload_start_free(ske->start_payload);
1263 ske->start_payload = NULL;
1265 /* Take the selected security properties into use while doing
1266 the key exchange. This is used only while doing the key
1268 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1271 prop->flags = payload->flags;
1272 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1273 if (status != SILC_SKE_STATUS_OK)
1276 prop->group = group;
1277 prop->remote_port = remote_port;
1279 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1280 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1283 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1284 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1287 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1288 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1291 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1292 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1296 /* Save remote's KE Start Payload */
1297 ske->start_payload = payload;
1299 /** Send KE Payload */
1300 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1301 return SILC_FSM_CONTINUE;
1305 silc_ske_payload_start_free(payload);
1307 silc_ske_group_free(group);
1309 silc_cipher_free(prop->cipher);
1311 silc_hash_free(prop->hash);
1313 silc_hmac_free(prop->hmac);
1317 if (status == SILC_SKE_STATUS_OK)
1318 status = SILC_SKE_STATUS_ERROR;
1321 ske->status = status;
1322 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1323 return SILC_FSM_CONTINUE;
1326 /* Phase-2. Send KE payload */
1328 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1330 SilcSKE ske = fsm_context;
1331 SilcSKEStatus status;
1332 SilcBuffer payload_buf;
1334 SilcSKEKEPayload payload;
1337 SILC_LOG_DEBUG(("Start"));
1339 /* Create the random number x, 1 < x < q. */
1340 x = silc_calloc(1, sizeof(*x));
1342 /** Out of memory */
1343 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1344 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1345 return SILC_FSM_CONTINUE;
1349 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1350 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1352 if (status != SILC_SKE_STATUS_OK) {
1353 /** Error generating random number */
1356 ske->status = status;
1357 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1358 return SILC_FSM_CONTINUE;
1361 /* Encode the result to Key Exchange Payload. */
1363 payload = silc_calloc(1, sizeof(*payload));
1365 /** Out of memory */
1368 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1369 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1370 return SILC_FSM_CONTINUE;
1372 ske->ke1_payload = payload;
1374 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1376 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1377 silc_mp_init(&payload->x);
1378 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1379 &ske->prop->group->group);
1381 /* Get public key */
1382 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1383 if (!payload->pk_data) {
1384 /** Error encoding public key */
1387 silc_mp_uninit(&payload->x);
1389 ske->ke1_payload = NULL;
1390 ske->status = SILC_SKE_STATUS_ERROR;
1391 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1392 return SILC_FSM_CONTINUE;
1394 payload->pk_len = pk_len;
1395 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1397 /* Compute signature data if we are doing mutual authentication */
1398 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1399 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1400 SilcUInt32 hash_len, sign_len;
1402 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1403 SILC_LOG_DEBUG(("Computing HASH_i value"));
1405 /* Compute the hash value */
1406 memset(hash, 0, sizeof(hash));
1407 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1409 SILC_LOG_DEBUG(("Signing HASH_i value"));
1411 /* Sign the hash value */
1412 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1413 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1414 /** Error computing signature */
1417 silc_mp_uninit(&payload->x);
1418 silc_free(payload->pk_data);
1420 ske->ke1_payload = NULL;
1421 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1422 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1423 return SILC_FSM_CONTINUE;
1425 payload->sign_data = silc_memdup(sign, sign_len);
1426 if (payload->sign_data)
1427 payload->sign_len = sign_len;
1428 memset(sign, 0, sizeof(sign));
1431 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1432 if (status != SILC_SKE_STATUS_OK) {
1433 /** Error encoding KE payload */
1436 silc_mp_uninit(&payload->x);
1437 silc_free(payload->pk_data);
1438 silc_free(payload->sign_data);
1440 ske->ke1_payload = NULL;
1441 ske->status = status;
1442 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1443 return SILC_FSM_CONTINUE;
1448 /* Check for backwards compatibility */
1450 /* Send the packet. */
1451 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1452 silc_buffer_data(payload_buf),
1453 silc_buffer_len(payload_buf))) {
1454 /** Error sending packet */
1455 SILC_LOG_DEBUG(("Error sending packet"));
1456 ske->status = SILC_SKE_STATUS_ERROR;
1457 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1458 return SILC_FSM_CONTINUE;
1461 silc_buffer_free(payload_buf);
1463 /** Waiting responder's KE payload */
1464 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1465 return SILC_FSM_WAIT;
1468 /* Phase-3. Process responder's KE payload */
1470 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1472 SilcSKE ske = fsm_context;
1473 SilcSKEStatus status;
1474 SilcSKEKEPayload payload;
1476 SilcBuffer packet_buf = &ske->packet->buffer;
1478 SILC_LOG_DEBUG(("Start"));
1480 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1481 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1482 silc_ske_install_retransmission(ske);
1483 silc_packet_free(ske->packet);
1485 return SILC_FSM_WAIT;
1488 /* Decode the payload */
1489 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1490 if (status != SILC_SKE_STATUS_OK) {
1491 /** Error decoding KE payload */
1492 silc_packet_free(ske->packet);
1494 ske->status = status;
1495 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1496 return SILC_FSM_CONTINUE;
1498 silc_packet_free(ske->packet);
1500 ske->ke2_payload = payload;
1502 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1503 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1504 "even though we require it"));
1505 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1509 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1511 /* Compute the shared secret key */
1512 KEY = silc_calloc(1, sizeof(*KEY));
1514 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1517 /* Decode the remote's public key */
1518 if (payload->pk_data &&
1519 !silc_pkcs_public_key_alloc(payload->pk_type,
1520 payload->pk_data, payload->pk_len,
1521 &ske->prop->public_key)) {
1522 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1523 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1527 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1529 SILC_LOG_DEBUG(("Verifying public key"));
1531 /** Waiting public key verification */
1532 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1534 /* If repository is provided, verify the key from there. */
1535 if (ske->repository) {
1538 find = silc_skr_find_alloc();
1540 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1543 silc_skr_find_set_pkcs_type(find,
1544 silc_pkcs_get_type(ske->prop->public_key));
1545 silc_skr_find_set_public_key(find, ske->prop->public_key);
1546 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1548 /* Find key from repository */
1549 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1550 find, silc_ske_skr_callback, ske));
1552 /* Verify from application */
1553 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1554 ske->callbacks->context,
1555 silc_ske_pk_verified, NULL));
1560 /** Process key material */
1561 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1562 return SILC_FSM_CONTINUE;
1565 silc_ske_payload_ke_free(payload);
1566 ske->ke2_payload = NULL;
1568 silc_mp_uninit(ske->KEY);
1569 silc_free(ske->KEY);
1572 if (status == SILC_SKE_STATUS_OK)
1573 return SILC_SKE_STATUS_ERROR;
1576 ske->status = status;
1577 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1578 return SILC_FSM_CONTINUE;
1581 /* Process key material */
1583 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1585 SilcSKE ske = fsm_context;
1586 SilcSKEStatus status;
1587 SilcSKEKEPayload payload;
1588 unsigned char hash[SILC_HASH_MAXLEN];
1589 SilcUInt32 hash_len;
1590 int key_len, block_len;
1594 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1595 return SILC_FSM_CONTINUE;
1598 /* Check result of public key verification */
1599 if (ske->status != SILC_SKE_STATUS_OK) {
1600 /** Public key not verified */
1601 SILC_LOG_DEBUG(("Public key verification failed"));
1602 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1603 return SILC_FSM_CONTINUE;
1606 payload = ske->ke2_payload;
1608 /* Compute the HASH value */
1609 SILC_LOG_DEBUG(("Computing HASH value"));
1610 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1611 if (status != SILC_SKE_STATUS_OK)
1613 ske->hash = silc_memdup(hash, hash_len);
1614 ske->hash_len = hash_len;
1616 if (ske->prop->public_key) {
1617 SILC_LOG_DEBUG(("Public key is authentic"));
1618 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1620 /* Verify signature */
1621 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1622 payload->sign_len, hash, hash_len, NULL)) {
1623 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1624 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1628 SILC_LOG_DEBUG(("Signature is Ok"));
1629 memset(hash, 'F', hash_len);
1632 ske->status = SILC_SKE_STATUS_OK;
1634 /* In case we are doing rekey move to finish it. */
1637 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1638 return SILC_FSM_CONTINUE;
1641 /* Process key material */
1642 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1643 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1644 hash_len = silc_hash_len(ske->prop->hash);
1645 ske->keymat = silc_ske_process_key_material(ske, block_len,
1649 SILC_LOG_ERROR(("Error processing key material"));
1650 status = SILC_SKE_STATUS_ERROR;
1654 /* Send SUCCESS packet */
1655 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1656 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1657 /** Error sending packet */
1658 SILC_LOG_DEBUG(("Error sending packet"));
1659 ske->status = SILC_SKE_STATUS_ERROR;
1660 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1661 return SILC_FSM_CONTINUE;
1664 /** Waiting completion */
1665 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1666 return SILC_FSM_WAIT;
1669 memset(hash, 'F', sizeof(hash));
1670 silc_ske_payload_ke_free(payload);
1671 ske->ke2_payload = NULL;
1673 silc_mp_uninit(ske->KEY);
1674 silc_free(ske->KEY);
1678 memset(ske->hash, 'F', hash_len);
1679 silc_free(ske->hash);
1683 if (status == SILC_SKE_STATUS_OK)
1684 status = SILC_SKE_STATUS_ERROR;
1687 ske->status = status;
1688 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1689 return SILC_FSM_CONTINUE;
1692 /* Protocol completed */
1694 SILC_FSM_STATE(silc_ske_st_initiator_end)
1696 SilcSKE ske = fsm_context;
1698 SILC_LOG_DEBUG(("Start"));
1700 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1701 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1702 silc_ske_install_retransmission(ske);
1703 silc_packet_free(ske->packet);
1705 return SILC_FSM_WAIT;
1708 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1710 silc_packet_free(ske->packet);
1712 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1713 silc_schedule_task_del_by_context(ske->schedule, ske);
1715 /* Call completion */
1716 silc_ske_completion(ske);
1718 return SILC_FSM_FINISH;
1721 /* Aborted by application */
1723 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1725 SilcSKE ske = fsm_context;
1726 unsigned char data[4];
1728 SILC_LOG_DEBUG(("Aborted by caller"));
1730 /* Send FAILURE packet */
1731 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1732 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1734 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1735 silc_schedule_task_del_by_context(ske->schedule, ske);
1737 /* Call completion */
1738 silc_ske_completion(ske);
1740 return SILC_FSM_FINISH;
1743 /* Error occurred. Send error to remote host */
1745 SILC_FSM_STATE(silc_ske_st_initiator_error)
1747 SilcSKE ske = fsm_context;
1748 SilcSKEStatus status;
1749 unsigned char data[4];
1751 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1752 silc_ske_map_status(ske->status), ske->status));
1754 status = ske->status;
1755 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1756 status = SILC_SKE_STATUS_ERROR;
1758 /* Send FAILURE packet */
1759 SILC_PUT32_MSB((SilcUInt32)status, data);
1760 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1762 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1763 silc_schedule_task_del_by_context(ske->schedule, ske);
1765 /* Call completion */
1766 silc_ske_completion(ske);
1768 return SILC_FSM_FINISH;
1771 /* Failure received from remote */
1773 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1775 SilcSKE ske = fsm_context;
1776 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1778 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1779 SILC_GET32_MSB(error, ske->packet->buffer.data);
1780 ske->status = error;
1781 silc_packet_free(ske->packet);
1785 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1786 silc_ske_map_status(ske->status), ske->status));
1788 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1789 silc_schedule_task_del_by_context(ske->schedule, ske);
1791 /* Call completion */
1792 silc_ske_completion(ske);
1794 return SILC_FSM_FINISH;
1797 /* Starts the protocol as initiator */
1799 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1800 SilcPacketStream stream,
1801 SilcSKEParams params,
1802 SilcSKEStartPayload start_payload)
1804 SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; start_payload=%p", ske, stream, params, start_payload));
1806 if (!ske || !stream || !params || !params->version)
1809 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1812 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1815 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1816 ske->session_port = params->session_port;
1818 /* Generate security properties if not provided */
1819 if (!start_payload) {
1820 start_payload = silc_ske_assemble_security_properties(ske,
1827 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1828 ske->start_payload = start_payload;
1829 ske->version = params->version;
1832 /* Link to packet stream to get key exchange packets */
1833 ske->stream = stream;
1834 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1835 SILC_PACKET_KEY_EXCHANGE,
1836 SILC_PACKET_KEY_EXCHANGE_2,
1837 SILC_PACKET_SUCCESS,
1838 SILC_PACKET_FAILURE, -1);
1840 /* Start SKE as initiator */
1841 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1846 /******************************** Responder *********************************/
1848 /* Start protocol as responder. Wait initiator's start payload */
1850 SILC_FSM_STATE(silc_ske_st_responder_start)
1852 SilcSKE ske = fsm_context;
1854 SILC_LOG_DEBUG(("Start"));
1858 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1859 return SILC_FSM_CONTINUE;
1862 /* Add key exchange timeout */
1863 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1864 ske, ske->timeout, 0);
1866 /** Wait for initiator */
1867 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1868 return SILC_FSM_WAIT;
1871 /* Decode initiator's start payload. Select the security properties from
1872 the initiator's start payload and send our reply start payload back. */
1874 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1876 SilcSKE ske = fsm_context;
1877 SilcSKEStatus status;
1878 SilcSKEStartPayload remote_payload = NULL;
1879 SilcBuffer packet_buf = &ske->packet->buffer;
1882 SILC_LOG_DEBUG(("Start"));
1884 /* Decode the payload */
1885 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1886 if (status != SILC_SKE_STATUS_OK) {
1887 /** Error decoding Start Payload */
1888 silc_packet_free(ske->packet);
1890 ske->status = status;
1891 silc_fsm_next(fsm, silc_ske_st_responder_error);
1892 return SILC_FSM_CONTINUE;
1895 /* Get remote ID and set it to stream */
1896 if (ske->packet->src_id_len) {
1897 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1898 ske->packet->src_id_type,
1899 (ske->packet->src_id_type == SILC_ID_SERVER ?
1900 (void *)&id.u.server_id : (void *)&id.u.client_id),
1901 (ske->packet->src_id_type == SILC_ID_SERVER ?
1902 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1903 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1904 (ske->packet->src_id_type == SILC_ID_SERVER ?
1905 (void *)&id.u.server_id : (void *)&id.u.client_id));
1908 /* Take a copy of the payload buffer for future use. It is used to
1909 compute the HASH value. */
1910 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1912 silc_packet_free(ske->packet);
1915 /* Force the mutual authentication flag if we want to do it. */
1916 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1917 SILC_LOG_DEBUG(("Force mutual authentication"));
1918 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1921 /* Force PFS flag if we require it */
1922 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1923 SILC_LOG_DEBUG(("Force PFS"));
1924 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1927 /* Disable IV Included flag if requested */
1928 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1929 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1930 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1931 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1934 /* Check and select security properties */
1935 status = silc_ske_select_security_properties(ske, remote_payload,
1937 if (status != SILC_SKE_STATUS_OK) {
1938 /** Error selecting proposal */
1939 silc_ske_payload_start_free(remote_payload);
1940 ske->status = status;
1941 silc_fsm_next(fsm, silc_ske_st_responder_error);
1942 return SILC_FSM_CONTINUE;
1945 silc_ske_payload_start_free(remote_payload);
1947 /* Encode our reply payload to send the selected security properties */
1948 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1950 if (status != SILC_SKE_STATUS_OK)
1953 /* Send the packet. */
1954 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1955 silc_buffer_data(packet_buf),
1956 silc_buffer_len(packet_buf)))
1959 silc_buffer_free(packet_buf);
1961 /** Waiting initiator's KE payload */
1962 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1963 return SILC_FSM_WAIT;
1966 if (ske->prop->group)
1967 silc_ske_group_free(ske->prop->group);
1968 if (ske->prop->cipher)
1969 silc_cipher_free(ske->prop->cipher);
1970 if (ske->prop->hash)
1971 silc_hash_free(ske->prop->hash);
1972 if (ske->prop->hmac)
1973 silc_hmac_free(ske->prop->hmac);
1974 silc_free(ske->prop);
1977 if (status == SILC_SKE_STATUS_OK)
1978 status = SILC_SKE_STATUS_ERROR;
1981 ske->status = status;
1982 silc_fsm_next(fsm, silc_ske_st_responder_error);
1983 return SILC_FSM_CONTINUE;
1986 /* Phase-2. Decode initiator's KE payload */
1988 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1990 SilcSKE ske = fsm_context;
1991 SilcSKEStatus status;
1992 SilcSKEKEPayload recv_payload;
1993 SilcBuffer packet_buf = &ske->packet->buffer;
1995 SILC_LOG_DEBUG(("Start"));
1997 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1998 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1999 silc_ske_install_retransmission(ske);
2000 silc_packet_free(ske->packet);
2002 return SILC_FSM_WAIT;
2005 /* Decode Key Exchange Payload */
2006 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2007 if (status != SILC_SKE_STATUS_OK) {
2008 /** Error decoding KE payload */
2009 silc_packet_free(ske->packet);
2011 ske->status = status;
2012 silc_fsm_next(fsm, silc_ske_st_responder_error);
2013 return SILC_FSM_CONTINUE;
2016 ske->ke1_payload = recv_payload;
2018 silc_packet_free(ske->packet);
2021 /* Verify public key, except in rekey, when it is not sent */
2023 if (!recv_payload->pk_data) {
2024 /** Public key not provided */
2025 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2026 "certificate), even though we require it"));
2027 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2028 silc_fsm_next(fsm, silc_ske_st_responder_error);
2029 return SILC_FSM_CONTINUE;
2032 /* Decode the remote's public key */
2033 if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2034 recv_payload->pk_data,
2035 recv_payload->pk_len,
2036 &ske->prop->public_key)) {
2037 /** Error decoding public key */
2038 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2039 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2040 silc_fsm_next(fsm, silc_ske_st_responder_error);
2041 return SILC_FSM_CONTINUE;
2044 SILC_LOG_DEBUG(("Verifying public key"));
2046 /** Waiting public key verification */
2047 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2049 /* If repository is provided, verify the key from there. */
2050 if (ske->repository) {
2053 find = silc_skr_find_alloc();
2055 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2056 silc_fsm_next(fsm, silc_ske_st_responder_error);
2057 return SILC_FSM_CONTINUE;
2059 silc_skr_find_set_pkcs_type(find,
2060 silc_pkcs_get_type(ske->prop->public_key));
2061 silc_skr_find_set_public_key(find, ske->prop->public_key);
2062 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2064 /* Find key from repository */
2065 SILC_FSM_CALL(silc_skr_find(ske->repository,
2066 silc_fsm_get_schedule(fsm), find,
2067 silc_ske_skr_callback, ske));
2069 /* Verify from application */
2070 if (ske->callbacks->verify_key)
2071 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2072 ske->callbacks->context,
2073 silc_ske_pk_verified, NULL));
2077 /** Generate KE2 payload */
2078 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2079 return SILC_FSM_CONTINUE;
2082 /* Phase-4. Generate KE2 payload */
2084 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2086 SilcSKE ske = fsm_context;
2087 SilcSKEStatus status;
2088 SilcSKEKEPayload recv_payload, send_payload;
2093 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2094 return SILC_FSM_CONTINUE;
2097 /* Check result of public key verification */
2098 if (ske->status != SILC_SKE_STATUS_OK) {
2099 /** Public key not verified */
2100 SILC_LOG_DEBUG(("Public key verification failed"));
2101 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2102 return SILC_FSM_CONTINUE;
2105 recv_payload = ske->ke1_payload;
2107 /* The public key verification was performed only if the Mutual
2108 Authentication flag is set. */
2109 if (ske->start_payload &&
2110 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2111 unsigned char hash[SILC_HASH_MAXLEN];
2112 SilcUInt32 hash_len;
2114 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2116 /* Compute the hash value */
2117 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2118 if (status != SILC_SKE_STATUS_OK) {
2119 /** Error computing hash */
2120 ske->status = status;
2121 silc_fsm_next(fsm, silc_ske_st_responder_error);
2122 return SILC_FSM_CONTINUE;
2125 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2127 /* Verify signature */
2128 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2129 recv_payload->sign_len, hash, hash_len, NULL)) {
2130 /** Incorrect signature */
2131 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2132 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2133 silc_fsm_next(fsm, silc_ske_st_responder_error);
2134 return SILC_FSM_CONTINUE;
2137 SILC_LOG_DEBUG(("Signature is Ok"));
2139 memset(hash, 'F', hash_len);
2142 /* Create the random number x, 1 < x < q. */
2143 x = silc_calloc(1, sizeof(*x));
2146 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2147 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2149 if (status != SILC_SKE_STATUS_OK) {
2150 /** Error generating random number */
2153 ske->status = status;
2154 silc_fsm_next(fsm, silc_ske_st_responder_error);
2155 return SILC_FSM_CONTINUE;
2158 /* Save the results for later processing */
2159 send_payload = silc_calloc(1, sizeof(*send_payload));
2161 ske->ke2_payload = send_payload;
2163 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2165 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2166 silc_mp_init(&send_payload->x);
2167 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2168 &ske->prop->group->group);
2170 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2172 /* Compute the shared secret key */
2173 KEY = silc_calloc(1, sizeof(*KEY));
2175 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2176 &ske->prop->group->group);
2179 /** Send KE2 payload */
2180 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2181 return SILC_FSM_CONTINUE;
2184 /* Phase-5. Send KE2 payload */
2186 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2188 SilcSKE ske = fsm_context;
2189 SilcSKEStatus status;
2190 SilcBuffer payload_buf;
2191 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2192 SilcUInt32 hash_len, sign_len, pk_len;
2194 SILC_LOG_DEBUG(("Start"));
2196 if (ske->public_key && ske->private_key) {
2197 SILC_LOG_DEBUG(("Getting public key"));
2199 /* Get the public key */
2200 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2202 /** Error encoding public key */
2203 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2204 silc_fsm_next(fsm, silc_ske_st_responder_error);
2205 return SILC_FSM_CONTINUE;
2207 ske->ke2_payload->pk_data = pk;
2208 ske->ke2_payload->pk_len = pk_len;
2211 SILC_LOG_DEBUG(("Computing HASH value"));
2213 /* Compute the hash value */
2214 memset(hash, 0, sizeof(hash));
2215 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2216 if (status != SILC_SKE_STATUS_OK) {
2217 /** Error computing hash */
2218 ske->status = status;
2219 silc_fsm_next(fsm, silc_ske_st_responder_error);
2220 return SILC_FSM_CONTINUE;
2222 ske->hash = silc_memdup(hash, hash_len);
2223 ske->hash_len = hash_len;
2225 if (ske->public_key && ske->private_key) {
2226 SILC_LOG_DEBUG(("Signing HASH value"));
2228 /* Sign the hash value */
2229 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2230 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2231 /** Error computing signature */
2232 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2233 silc_fsm_next(fsm, silc_ske_st_responder_error);
2234 return SILC_FSM_CONTINUE;
2236 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2237 ske->ke2_payload->sign_len = sign_len;
2238 memset(sign, 0, sizeof(sign));
2240 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2242 /* Encode the Key Exchange Payload */
2243 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2245 if (status != SILC_SKE_STATUS_OK) {
2246 /** Error encoding KE payload */
2247 ske->status = status;
2248 silc_fsm_next(fsm, silc_ske_st_responder_error);
2249 return SILC_FSM_CONTINUE;
2252 /* Send the packet. */
2253 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2254 payload_buf->data, silc_buffer_len(payload_buf))) {
2255 SILC_LOG_DEBUG(("Error sending packet"));
2256 ske->status = SILC_SKE_STATUS_ERROR;
2257 silc_fsm_next(fsm, silc_ske_st_responder_error);
2258 return SILC_FSM_CONTINUE;
2261 silc_buffer_free(payload_buf);
2263 /* In case we are doing rekey move to finish it. */
2266 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2267 return SILC_FSM_CONTINUE;
2270 /** Waiting completion */
2271 silc_fsm_next(fsm, silc_ske_st_responder_end);
2272 return SILC_FSM_WAIT;
2275 /* Protocol completed */
2277 SILC_FSM_STATE(silc_ske_st_responder_end)
2279 SilcSKE ske = fsm_context;
2280 unsigned char tmp[4];
2281 SilcUInt32 hash_len, key_len, block_len;
2283 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2284 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2285 silc_ske_install_retransmission(ske);
2286 silc_packet_free(ske->packet);
2288 return SILC_FSM_WAIT;
2290 silc_packet_free(ske->packet);
2293 /* Process key material */
2294 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2295 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2296 hash_len = silc_hash_len(ske->prop->hash);
2297 ske->keymat = silc_ske_process_key_material(ske, block_len,
2301 /** Error processing key material */
2302 ske->status = SILC_SKE_STATUS_ERROR;
2303 silc_fsm_next(fsm, silc_ske_st_responder_error);
2304 return SILC_FSM_CONTINUE;
2307 /* Send SUCCESS packet */
2308 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2309 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2311 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2312 silc_schedule_task_del_by_context(ske->schedule, ske);
2314 /* Call completion */
2315 silc_ske_completion(ske);
2317 return SILC_FSM_FINISH;
2320 /* Aborted by application */
2322 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2324 SilcSKE ske = fsm_context;
2325 unsigned char tmp[4];
2327 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2329 /* Send FAILURE packet */
2330 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2331 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2333 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2334 silc_schedule_task_del_by_context(ske->schedule, ske);
2336 /* Call completion */
2337 silc_ske_completion(ske);
2339 return SILC_FSM_FINISH;
2342 /* Failure received from remote */
2344 SILC_FSM_STATE(silc_ske_st_responder_failure)
2346 SilcSKE ske = fsm_context;
2347 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2349 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2351 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2352 SILC_GET32_MSB(error, ske->packet->buffer.data);
2353 ske->status = error;
2354 silc_packet_free(ske->packet);
2358 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2359 silc_schedule_task_del_by_context(ske->schedule, ske);
2361 /* Call completion */
2362 silc_ske_completion(ske);
2364 return SILC_FSM_FINISH;
2367 /* Error occurred */
2369 SILC_FSM_STATE(silc_ske_st_responder_error)
2371 SilcSKE ske = fsm_context;
2372 unsigned char tmp[4];
2374 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2375 ske->status, silc_ske_map_status(ske->status)));
2377 /* Send FAILURE packet */
2378 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2379 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2380 SILC_PUT32_MSB(ske->status, tmp);
2381 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2383 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2384 silc_schedule_task_del_by_context(ske->schedule, ske);
2386 /* Call completion */
2387 silc_ske_completion(ske);
2389 return SILC_FSM_FINISH;
2392 /* Starts the protocol as responder. */
2394 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2395 SilcPacketStream stream,
2396 SilcSKEParams params)
2398 SILC_LOG_DEBUG(("Start SKE as responder"));
2400 if (!ske || !stream || !params || !params->version)
2403 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2406 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2409 ske->responder = TRUE;
2410 ske->flags = params->flags;
2411 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2412 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2413 ske->session_port = params->session_port;
2414 ske->version = params->version;
2419 /* Link to packet stream to get key exchange packets */
2420 ske->stream = stream;
2421 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2422 SILC_PACKET_KEY_EXCHANGE,
2423 SILC_PACKET_KEY_EXCHANGE_1,
2424 SILC_PACKET_SUCCESS,
2425 SILC_PACKET_FAILURE, -1);
2427 /* Start SKE as responder */
2428 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2433 /***************************** Initiator Rekey ******************************/
2437 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2439 SilcSKE ske = fsm_context;
2442 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2446 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2447 return SILC_FSM_CONTINUE;
2450 /* Add rekey exchange timeout */
2451 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2454 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2457 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2458 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2459 return SILC_FSM_CONTINUE;
2462 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2463 /** Cannot allocate hash */
2464 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2465 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2466 return SILC_FSM_CONTINUE;
2469 /* Send REKEY packet to start rekey protocol */
2470 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2471 /** Error sending packet */
2472 SILC_LOG_DEBUG(("Error sending packet"));
2473 ske->status = SILC_SKE_STATUS_ERROR;
2474 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2475 return SILC_FSM_CONTINUE;
2478 /* If doing rekey without PFS, move directly to the end of the protocol. */
2479 if (!ske->rekey->pfs) {
2480 /** Rekey without PFS */
2481 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2482 return SILC_FSM_CONTINUE;
2485 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2487 if (status != SILC_SKE_STATUS_OK) {
2488 /** Unknown group */
2489 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2490 return SILC_FSM_CONTINUE;
2493 /** Rekey with PFS */
2494 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2495 return SILC_FSM_CONTINUE;
2498 /* Sends REKEY_DONE packet to finish the protocol. */
2500 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2502 SilcSKE ske = fsm_context;
2503 SilcCipher send_key;
2506 SilcUInt32 key_len, block_len, hash_len, x_len;
2507 unsigned char *pfsbuf;
2509 SILC_LOG_DEBUG(("Start"));
2511 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2512 key_len = silc_cipher_get_key_len(send_key);
2513 block_len = silc_cipher_get_block_len(send_key);
2514 hash = ske->prop->hash;
2515 hash_len = silc_hash_len(hash);
2517 /* Process key material */
2518 if (ske->rekey->pfs) {
2520 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2522 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2525 memset(pfsbuf, 0, x_len);
2531 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2532 ske->rekey->enc_key_len / 8,
2538 SILC_LOG_ERROR(("Error processing key material"));
2539 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2540 return SILC_FSM_CONTINUE;
2543 ske->prop->cipher = send_key;
2544 ske->prop->hmac = hmac_send;
2546 /* Get sending keys */
2547 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2548 &hmac_send, NULL, NULL)) {
2549 /** Cannot get keys */
2550 ske->status = SILC_SKE_STATUS_ERROR;
2551 ske->prop->cipher = NULL;
2552 ske->prop->hmac = NULL;
2553 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2554 return SILC_FSM_CONTINUE;
2557 ske->prop->cipher = NULL;
2558 ske->prop->hmac = NULL;
2560 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2561 packet sent after this call will be protected with the new keys. */
2562 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2564 /** Cannot set keys */
2565 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2566 ske->status = SILC_SKE_STATUS_ERROR;
2567 silc_cipher_free(send_key);
2568 silc_hmac_free(hmac_send);
2569 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2570 return SILC_FSM_CONTINUE;
2573 /** Wait for REKEY_DONE */
2574 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2575 return SILC_FSM_WAIT;
2578 /* Rekey protocol end */
2580 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2582 SilcSKE ske = fsm_context;
2583 SilcCipher receive_key;
2584 SilcHmac hmac_receive;
2585 SilcSKERekeyMaterial rekey;
2587 SILC_LOG_DEBUG(("Start"));
2589 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2590 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2591 silc_packet_free(ske->packet);
2593 return SILC_FSM_WAIT;
2596 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2597 ske->prop->cipher = receive_key;
2598 ske->prop->hmac = hmac_receive;
2600 /* Get receiving keys */
2601 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2602 NULL, &hmac_receive, NULL)) {
2603 /** Cannot get keys */
2604 ske->status = SILC_SKE_STATUS_ERROR;
2605 ske->prop->cipher = NULL;
2606 ske->prop->hmac = NULL;
2607 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2608 return SILC_FSM_CONTINUE;
2611 /* Set new receiving keys into use. All packets received after this will
2612 be decrypted with the new keys. */
2613 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2614 hmac_receive, FALSE)) {
2615 /** Cannot set keys */
2616 SILC_LOG_DEBUG(("Cannot set new keys"));
2617 ske->status = SILC_SKE_STATUS_ERROR;
2618 silc_cipher_free(receive_key);
2619 silc_hmac_free(hmac_receive);
2620 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2621 return SILC_FSM_CONTINUE;
2624 SILC_LOG_DEBUG(("Rekey completed successfully"));
2626 /* Generate new rekey material */
2627 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2630 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2631 ske->prop->cipher = NULL;
2632 ske->prop->hmac = NULL;
2633 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2634 return SILC_FSM_CONTINUE;
2636 rekey->pfs = ske->rekey->pfs;
2639 ske->prop->cipher = NULL;
2640 ske->prop->hmac = NULL;
2641 silc_packet_free(ske->packet);
2643 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2644 silc_schedule_task_del_by_context(ske->schedule, ske);
2646 /* Call completion */
2647 silc_ske_completion(ske);
2649 return SILC_FSM_FINISH;
2652 /* Starts rekey protocol as initiator */
2655 silc_ske_rekey_initiator(SilcSKE ske,
2656 SilcPacketStream stream,
2657 SilcSKERekeyMaterial rekey)
2659 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2661 if (!ske || !stream || !rekey) {
2662 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2667 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2670 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2674 ske->responder = FALSE;
2675 ske->rekeying = TRUE;
2678 /* Link to packet stream to get key exchange packets */
2679 ske->stream = stream;
2680 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2682 SILC_PACKET_REKEY_DONE,
2683 SILC_PACKET_KEY_EXCHANGE_2,
2684 SILC_PACKET_SUCCESS,
2685 SILC_PACKET_FAILURE, -1);
2687 /* Start SKE rekey as initiator */
2688 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2693 /***************************** Responder Rekey ******************************/
2695 /* Wait for initiator's packet */
2697 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2699 SilcSKE ske = fsm_context;
2701 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2705 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2706 return SILC_FSM_CONTINUE;
2709 /* Add rekey exchange timeout */
2710 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2713 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2715 /* If REKEY packet already received process it directly */
2716 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2717 return SILC_FSM_CONTINUE;
2719 /* Wait for REKEY */
2720 return SILC_FSM_WAIT;
2723 /* Process initiator's REKEY packet */
2725 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2727 SilcSKE ske = fsm_context;
2728 SilcSKEStatus status;
2730 SILC_LOG_DEBUG(("Start"));
2732 if (ske->packet->type != SILC_PACKET_REKEY) {
2733 ske->status = SILC_SKE_STATUS_ERROR;
2734 silc_packet_free(ske->packet);
2736 silc_fsm_next(fsm, silc_ske_st_responder_error);
2737 return SILC_FSM_CONTINUE;
2740 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2743 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2744 silc_fsm_next(fsm, silc_ske_st_responder_error);
2745 return SILC_FSM_CONTINUE;
2748 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2749 /** Cannot allocate hash */
2750 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2751 silc_fsm_next(fsm, silc_ske_st_responder_error);
2752 return SILC_FSM_CONTINUE;
2755 /* If doing rekey without PFS, move directly to the end of the protocol. */
2756 if (!ske->rekey->pfs) {
2757 /** Rekey without PFS */
2758 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2759 return SILC_FSM_CONTINUE;
2762 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2764 if (status != SILC_SKE_STATUS_OK) {
2765 /** Unknown group */
2766 silc_fsm_next(fsm, silc_ske_st_responder_error);
2767 return SILC_FSM_CONTINUE;
2770 /** Rekey with PFS */
2771 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2772 return SILC_FSM_WAIT;
2775 /* Sends REKEY_DONE packet to finish the protocol. */
2777 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2779 SilcSKE ske = fsm_context;
2780 SilcCipher send_key;
2783 SilcUInt32 key_len, block_len, hash_len, x_len;
2784 unsigned char *pfsbuf;
2786 SILC_LOG_DEBUG(("Start"));
2788 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2789 key_len = silc_cipher_get_key_len(send_key);
2790 block_len = silc_cipher_get_block_len(send_key);
2791 hash = ske->prop->hash;
2792 hash_len = silc_hash_len(hash);
2794 /* Process key material */
2795 if (ske->rekey->pfs) {
2797 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2799 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2802 memset(pfsbuf, 0, x_len);
2808 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2809 ske->rekey->enc_key_len / 8,
2815 SILC_LOG_ERROR(("Error processing key material"));
2816 silc_fsm_next(fsm, silc_ske_st_responder_error);
2817 return SILC_FSM_CONTINUE;
2820 ske->prop->cipher = send_key;
2821 ske->prop->hmac = hmac_send;
2823 /* Get sending keys */
2824 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2825 &hmac_send, NULL, NULL)) {
2826 /** Cannot get keys */
2827 ske->status = SILC_SKE_STATUS_ERROR;
2828 ske->prop->cipher = NULL;
2829 ske->prop->hmac = NULL;
2830 silc_fsm_next(fsm, silc_ske_st_responder_error);
2831 return SILC_FSM_CONTINUE;
2834 ske->prop->cipher = NULL;
2835 ske->prop->hmac = NULL;
2837 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2838 packet sent after this call will be protected with the new keys. */
2839 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2841 /** Cannot set keys */
2842 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2843 ske->status = SILC_SKE_STATUS_ERROR;
2844 silc_cipher_free(send_key);
2845 silc_hmac_free(hmac_send);
2846 silc_fsm_next(fsm, silc_ske_st_responder_error);
2847 return SILC_FSM_CONTINUE;
2850 /** Wait for REKEY_DONE */
2851 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2852 return SILC_FSM_WAIT;
2855 /* Rekey protocol end */
2857 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2859 SilcSKE ske = fsm_context;
2860 SilcCipher receive_key;
2861 SilcHmac hmac_receive;
2862 SilcSKERekeyMaterial rekey;
2864 SILC_LOG_DEBUG(("Start"));
2866 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2867 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2868 silc_packet_free(ske->packet);
2870 return SILC_FSM_WAIT;
2873 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2874 ske->prop->cipher = receive_key;
2875 ske->prop->hmac = hmac_receive;
2877 /* Get receiving keys */
2878 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2879 NULL, &hmac_receive, NULL)) {
2880 /** Cannot get keys */
2881 ske->status = SILC_SKE_STATUS_ERROR;
2882 ske->prop->cipher = NULL;
2883 ske->prop->hmac = NULL;
2884 silc_fsm_next(fsm, silc_ske_st_responder_error);
2885 return SILC_FSM_CONTINUE;
2888 /* Set new receiving keys into use. All packets received after this will
2889 be decrypted with the new keys. */
2890 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2891 hmac_receive, FALSE)) {
2892 /** Cannot set keys */
2893 SILC_LOG_DEBUG(("Cannot set new keys"));
2894 ske->status = SILC_SKE_STATUS_ERROR;
2895 ske->prop->cipher = NULL;
2896 ske->prop->hmac = NULL;
2897 silc_cipher_free(receive_key);
2898 silc_hmac_free(hmac_receive);
2899 silc_fsm_next(fsm, silc_ske_st_responder_error);
2900 return SILC_FSM_CONTINUE;
2903 SILC_LOG_DEBUG(("Rekey completed successfully"));
2905 /* Generate new rekey material */
2906 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2909 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2910 ske->prop->cipher = NULL;
2911 ske->prop->hmac = NULL;
2912 silc_fsm_next(fsm, silc_ske_st_responder_error);
2913 return SILC_FSM_CONTINUE;
2915 rekey->pfs = ske->rekey->pfs;
2918 ske->prop->cipher = NULL;
2919 ske->prop->hmac = NULL;
2920 silc_packet_free(ske->packet);
2922 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2923 silc_schedule_task_del_by_context(ske->schedule, ske);
2925 /* Call completion */
2926 silc_ske_completion(ske);
2928 return SILC_FSM_FINISH;
2931 /* Starts rekey protocol as responder */
2934 silc_ske_rekey_responder(SilcSKE ske,
2935 SilcPacketStream stream,
2936 SilcSKERekeyMaterial rekey,
2939 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2941 if (!ske || !stream || !rekey)
2944 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2947 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2951 ske->responder = TRUE;
2952 ske->rekeying = TRUE;
2953 ske->packet = packet;
2956 /* Link to packet stream to get key exchange packets */
2957 ske->stream = stream;
2958 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2960 SILC_PACKET_REKEY_DONE,
2961 SILC_PACKET_KEY_EXCHANGE_1,
2962 SILC_PACKET_SUCCESS,
2963 SILC_PACKET_FAILURE, -1);
2965 /* Start SKE rekey as responder */
2966 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2971 /* Processes the provided key material `data' as the SILC protocol
2972 specification defines. */
2975 silc_ske_process_key_material_data(unsigned char *data,
2976 SilcUInt32 data_len,
2977 SilcUInt32 req_iv_len,
2978 SilcUInt32 req_enc_key_len,
2979 SilcUInt32 req_hmac_key_len,
2983 unsigned char hashd[SILC_HASH_MAXLEN];
2984 SilcUInt32 hash_len = req_hmac_key_len;
2985 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2986 SilcSKEKeyMaterial key;
2988 SILC_LOG_DEBUG(("Start"));
2990 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2993 key = silc_calloc(1, sizeof(*key));
2997 buf = silc_buffer_alloc_size(1 + data_len);
3000 silc_buffer_format(buf,
3001 SILC_STR_UI_CHAR(0),
3002 SILC_STR_DATA(data, data_len),
3006 memset(hashd, 0, sizeof(hashd));
3008 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3009 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3010 memcpy(key->send_iv, hashd, req_iv_len);
3011 memset(hashd, 0, sizeof(hashd));
3013 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3014 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3015 memcpy(key->receive_iv, hashd, req_iv_len);
3016 key->iv_len = req_iv_len;
3018 /* Take the encryption keys. If requested key size is more than
3019 the size of hash length we will distribute more key material
3020 as protocol defines. */
3022 if (enc_key_len > hash_len) {
3024 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3025 k3[SILC_HASH_MAXLEN];
3026 unsigned char *dtmp;
3029 if (enc_key_len > (3 * hash_len))
3032 /* Take first round */
3033 memset(k1, 0, sizeof(k1));
3034 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3036 /* Take second round */
3037 dist = silc_buffer_alloc_size(data_len + hash_len);
3040 silc_buffer_format(dist,
3041 SILC_STR_DATA(data, data_len),
3042 SILC_STR_DATA(k1, hash_len),
3044 memset(k2, 0, sizeof(k2));
3045 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3047 /* Take third round */
3048 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3049 silc_buffer_pull_tail(dist, hash_len);
3050 silc_buffer_pull(dist, data_len + hash_len);
3051 silc_buffer_format(dist,
3052 SILC_STR_DATA(k2, hash_len),
3054 silc_buffer_push(dist, data_len + hash_len);
3055 memset(k3, 0, sizeof(k3));
3056 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3058 /* Then, save the keys */
3059 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3060 memcpy(dtmp, k1, hash_len);
3061 memcpy(dtmp + hash_len, k2, hash_len);
3062 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3064 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3065 memcpy(key->send_enc_key, dtmp, enc_key_len);
3066 key->enc_key_len = req_enc_key_len;
3068 memset(dtmp, 0, (3 * hash_len));
3069 memset(k1, 0, sizeof(k1));
3070 memset(k2, 0, sizeof(k2));
3071 memset(k3, 0, sizeof(k3));
3073 silc_buffer_clear(dist);
3074 silc_buffer_free(dist);
3076 /* Take normal hash as key */
3077 memset(hashd, 0, sizeof(hashd));
3078 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3079 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3080 memcpy(key->send_enc_key, hashd, enc_key_len);
3081 key->enc_key_len = req_enc_key_len;
3085 if (enc_key_len > hash_len) {
3087 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3088 k3[SILC_HASH_MAXLEN];
3089 unsigned char *dtmp;
3092 if (enc_key_len > (3 * hash_len))
3095 /* Take first round */
3096 memset(k1, 0, sizeof(k1));
3097 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3099 /* Take second round */
3100 dist = silc_buffer_alloc_size(data_len + hash_len);
3103 silc_buffer_format(dist,
3104 SILC_STR_DATA(data, data_len),
3105 SILC_STR_DATA(k1, hash_len),
3107 memset(k2, 0, sizeof(k2));
3108 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3110 /* Take third round */
3111 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3112 silc_buffer_pull_tail(dist, hash_len);
3113 silc_buffer_pull(dist, data_len + hash_len);
3114 silc_buffer_format(dist,
3115 SILC_STR_DATA(k2, hash_len),
3117 silc_buffer_push(dist, data_len + hash_len);
3118 memset(k3, 0, sizeof(k3));
3119 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3121 /* Then, save the keys */
3122 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3123 memcpy(dtmp, k1, hash_len);
3124 memcpy(dtmp + hash_len, k2, hash_len);
3125 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3127 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3128 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3129 key->enc_key_len = req_enc_key_len;
3131 memset(dtmp, 0, (3 * hash_len));
3132 memset(k1, 0, sizeof(k1));
3133 memset(k2, 0, sizeof(k2));
3134 memset(k3, 0, sizeof(k3));
3136 silc_buffer_clear(dist);
3137 silc_buffer_free(dist);
3139 /* Take normal hash as key */
3140 memset(hashd, 0, sizeof(hashd));
3141 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3142 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3143 memcpy(key->receive_enc_key, hashd, enc_key_len);
3144 key->enc_key_len = req_enc_key_len;
3147 /* Take HMAC keys */
3148 memset(hashd, 0, sizeof(hashd));
3150 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3151 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3152 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3153 memset(hashd, 0, sizeof(hashd));
3155 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3156 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3157 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3158 key->hmac_key_len = req_hmac_key_len;
3159 memset(hashd, 0, sizeof(hashd));
3161 silc_buffer_clear(buf);
3162 silc_buffer_free(buf);
3164 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3169 /* Processes negotiated key material as protocol specifies. This returns
3170 the actual keys to be used in the SILC. */
3173 silc_ske_process_key_material(SilcSKE ske,
3174 SilcUInt32 req_iv_len,
3175 SilcUInt32 req_enc_key_len,
3176 SilcUInt32 req_hmac_key_len,
3177 SilcSKERekeyMaterial *rekey)
3180 unsigned char *tmpbuf;
3182 SilcSKEKeyMaterial key;
3184 /* Encode KEY to binary data */
3185 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3187 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3190 silc_buffer_format(buf,
3191 SILC_STR_DATA(tmpbuf, klen),
3192 SILC_STR_DATA(ske->hash, ske->hash_len),
3195 /* Process the key material */
3196 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3197 req_iv_len, req_enc_key_len,
3201 memset(tmpbuf, 0, klen);
3203 silc_buffer_clear(buf);
3204 silc_buffer_free(buf);
3207 *rekey = silc_ske_make_rekey_material(ske, key);
3215 /* Free key material structure */
3217 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3223 silc_free(key->send_iv);
3224 if (key->receive_iv)
3225 silc_free(key->receive_iv);
3226 if (key->send_enc_key) {
3227 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3228 silc_free(key->send_enc_key);
3230 if (key->receive_enc_key) {
3231 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3232 silc_free(key->receive_enc_key);
3234 if (key->send_hmac_key) {
3235 memset(key->send_hmac_key, 0, key->hmac_key_len);
3236 silc_free(key->send_hmac_key);
3238 if (key->receive_hmac_key) {
3239 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3240 silc_free(key->receive_hmac_key);
3245 /* Free rekey material */
3247 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3251 if (rekey->send_enc_key) {
3252 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3253 silc_free(rekey->send_enc_key);
3255 silc_free(rekey->hash);
3259 /* Set keys into use */
3261 SilcBool silc_ske_set_keys(SilcSKE ske,
3262 SilcSKEKeyMaterial keymat,
3263 SilcSKESecurityProperties prop,
3264 SilcCipher *ret_send_key,
3265 SilcCipher *ret_receive_key,
3266 SilcHmac *ret_hmac_send,
3267 SilcHmac *ret_hmac_receive,
3270 unsigned char iv[SILC_HASH_MAXLEN];
3271 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3273 /* Allocate ciphers to be used in the communication */
3275 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3279 if (ret_receive_key) {
3280 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3285 /* Allocate HMACs */
3286 if (ret_hmac_send) {
3287 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3291 if (ret_hmac_receive) {
3292 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3299 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3303 /* Set key material */
3304 memset(iv, 0, sizeof(iv));
3305 if (ske->responder) {
3307 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3308 keymat->enc_key_len, TRUE);
3310 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3312 if (!ske->rekeying) {
3314 memcpy(iv, ske->hash, 4);
3316 memcpy(iv + 4, keymat->receive_iv, 8);
3318 /* Rekey, recompute the truncated hash value. */
3319 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3321 memcpy(iv + 4, keymat->receive_iv, 8);
3323 memset(iv + 4, 0, 12);
3326 silc_cipher_set_iv(*ret_send_key, iv);
3329 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3332 if (ret_receive_key) {
3333 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3334 keymat->enc_key_len, FALSE);
3336 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3338 if (!ske->rekeying) {
3340 memcpy(iv, ske->hash, 4);
3342 memcpy(iv + 4, keymat->send_iv, 8);
3344 /* Rekey, recompute the truncated hash value. */
3345 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3347 memcpy(iv + 4, keymat->send_iv, 8);
3349 memset(iv + 4, 0, 12);
3352 silc_cipher_set_iv(*ret_receive_key, iv);
3355 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3359 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3360 keymat->hmac_key_len);
3361 if (ret_hmac_receive)
3362 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3363 keymat->hmac_key_len);
3366 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3367 keymat->enc_key_len, TRUE);
3369 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3371 if (!ske->rekeying) {
3373 memcpy(iv, ske->hash, 4);
3375 memcpy(iv + 4, keymat->send_iv, 8);
3377 /* Rekey, recompute the truncated hash value. */
3378 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3380 memcpy(iv + 4, keymat->send_iv, 8);
3382 memset(iv + 4, 0, 12);
3385 silc_cipher_set_iv(*ret_send_key, iv);
3388 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3391 if (ret_receive_key) {
3392 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3393 keymat->enc_key_len, FALSE);
3395 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3397 if (!ske->rekeying) {
3398 /* Set IV. If IV Included flag was negotiated we only set the
3399 truncated hash value. */
3400 memcpy(iv, ske->hash, 4);
3402 memcpy(iv + 4, keymat->receive_iv, 8);
3404 /* Rekey, recompute the truncated hash value. */
3405 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3407 memcpy(iv + 4, keymat->receive_iv, 8);
3409 memset(iv + 4, 0, 12);
3412 silc_cipher_set_iv(*ret_receive_key, iv);
3415 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3419 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3420 keymat->hmac_key_len);
3421 if (ret_hmac_receive)
3422 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3423 keymat->hmac_key_len);
3429 const char *silc_ske_status_string[] =
3433 "Unexpected error occurred",
3434 "Bad payload in packet",
3435 "Unsupported group",
3436 "Unsupported cipher",
3438 "Unsupported hash function",
3440 "Unsupported public key (or certificate)",
3441 "Incorrect signature",
3442 "Bad or unsupported version",
3446 "Remote did not provide public key",
3447 "Bad reserved field in packet",
3448 "Bad payload length in packet",
3449 "Error computing signature",
3450 "System out of memory",
3451 "Key exchange timeout",
3456 /* Maps status to readable string and returns the string. If string is not
3457 found and empty character string ("") is returned. */
3459 const char *silc_ske_map_status(SilcSKEStatus status)
3463 for (i = 0; silc_ske_status_string[i]; i++)
3465 return silc_ske_status_string[i];
3470 /* Parses remote host's version string. */
3472 SilcBool silc_ske_parse_version(SilcSKE ske,
3473 SilcUInt32 *protocol_version,
3474 char **protocol_version_string,
3475 SilcUInt32 *software_version,
3476 char **software_version_string,
3477 char **vendor_version)
3479 return silc_parse_version_string(ske->remote_version,
3481 protocol_version_string,
3483 software_version_string,
3487 /* Get security properties */
3489 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3494 /* Get key material */
3496 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
3502 * Notify the owner of the ske that we failed. Ensures that we don't make the
3503 * same callout twice, as the notification callback routines are not designed
3504 * to handle that case.
3506 static void silc_ske_notify_failure(SilcSKE ske)
3508 SILC_LOG_DEBUG(("Notifying SKE %p owner of failure (failure_notified = %lu)", ske, ske->failure_notified));
3511 * First, check if we have already made a failure callout. If so, then we
3515 if (ske->failure_notified)
3519 * Mark ourselves as having already sent the failure notification here and
3523 ske->failure_notified = TRUE;
3525 SILC_LOG_DEBUG(("Actually calling real failure notify callback for SKE %p (responder = %s)", ske, ske->responder ? "TRUE" : "FALSE"));
3528 * Finally, make the call to the owner's registered failure callback.
3532 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
3534 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);