5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2007 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_phase2_send);
41 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
42 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
43 SILC_FSM_STATE(silc_ske_st_initiator_phase5);
44 SILC_FSM_STATE(silc_ske_st_initiator_end);
45 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
46 SILC_FSM_STATE(silc_ske_st_initiator_error);
47 SILC_FSM_STATE(silc_ske_st_initiator_failure);
48 SILC_FSM_STATE(silc_ske_st_responder_start);
49 SILC_FSM_STATE(silc_ske_st_responder_phase1);
50 SILC_FSM_STATE(silc_ske_st_responder_phase2);
51 SILC_FSM_STATE(silc_ske_st_responder_phase4);
52 SILC_FSM_STATE(silc_ske_st_responder_phase5);
53 SILC_FSM_STATE(silc_ske_st_responder_phase5_send);
54 SILC_FSM_STATE(silc_ske_st_responder_end);
55 SILC_FSM_STATE(silc_ske_st_responder_aborted);
56 SILC_FSM_STATE(silc_ske_st_responder_failure);
57 SILC_FSM_STATE(silc_ske_st_responder_error);
58 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
59 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done);
60 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end);
61 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait);
62 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
63 SILC_FSM_STATE(silc_ske_st_rekey_responder_done);
64 SILC_FSM_STATE(silc_ske_st_rekey_responder_end);
65 SILC_TASK_CALLBACK(silc_ske_packet_send_retry);
68 silc_ske_process_key_material(SilcSKE ske,
69 SilcUInt32 req_iv_len,
70 SilcUInt32 req_enc_key_len,
71 SilcUInt32 req_hmac_key_len,
72 SilcSKERekeyMaterial *rekey);
73 static SilcBool silc_ske_packet_send(SilcSKE ske,
75 SilcPacketFlags flags,
76 const unsigned char *data,
81 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
82 SilcPacketStream stream,
84 void *callback_context,
87 SilcSKE ske = callback_context;
89 /* Clear retransmission */
90 ske->retry_timer = SILC_SKE_RETRY_MIN;
92 silc_schedule_task_del_by_callback(ske->schedule,
93 silc_ske_packet_send_retry);
95 /* Signal for new packet */
98 /* Check if we were aborted */
100 silc_packet_free(packet);
104 silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
106 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
108 silc_fsm_continue_sync(&ske->fsm);
112 /* See if received failure from remote */
113 if (packet->type == SILC_PACKET_FAILURE) {
115 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
117 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
120 /* Handle rekey and SUCCESS packets synchronously. After SUCCESS packets
121 they keys are taken into use immediately, hence the synchronous
122 processing to get the keys in use as soon as possible. */
123 if (ske->rekeying || packet->type == SILC_PACKET_SUCCESS)
124 silc_fsm_continue_sync(&ske->fsm);
126 silc_fsm_continue(&ske->fsm);
131 /* Packet stream callbacks */
132 static SilcPacketCallbacks silc_ske_stream_cbs =
134 silc_ske_packet_receive, NULL, NULL
137 /* Aborts SKE protocol */
139 static void silc_ske_abort(SilcAsyncOperation op, void *context)
141 SilcSKE ske = context;
143 silc_async_abort(ske->key_op, NULL, NULL);
147 /* Public key verification completion callback */
149 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
150 void *completion_context)
152 ske->status = status;
153 SILC_FSM_CALL_CONTINUE(&ske->fsm);
156 /* SKR find callback */
158 static void silc_ske_skr_callback(SilcSKR repository,
160 SilcSKRStatus status,
161 SilcDList keys, void *context)
163 SilcSKE ske = context;
165 silc_skr_find_free(find);
167 if (status != SILC_SKR_OK) {
168 if (ske->callbacks->verify_key) {
169 /* Verify from application */
170 ske->callbacks->verify_key(ske, ske->prop->public_key,
171 ske->callbacks->context,
172 silc_ske_pk_verified, NULL);
178 silc_dlist_uninit(keys);
181 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
182 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
183 SILC_FSM_CALL_CONTINUE(&ske->fsm);
186 /* Checks remote and local versions */
188 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
190 SilcUInt32 r_software_version = 0;
191 char *r_software_string = NULL;
193 if (!ske->remote_version || !ske->version)
194 return SILC_SKE_STATUS_BAD_VERSION;
196 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
198 &r_software_string, NULL))
199 return SILC_SKE_STATUS_BAD_VERSION;
201 return SILC_SKE_STATUS_OK;
204 /* Selects the supported security properties from the initiator's Key
205 Exchange Start Payload. A responder function. Saves our reply
206 start payload to ske->start_payload. */
209 silc_ske_select_security_properties(SilcSKE ske,
210 SilcSKEStartPayload remote_payload,
211 SilcSKESecurityProperties *prop)
213 SilcSKEStatus status;
214 SilcSKEStartPayload rp, payload;
218 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
222 /* Check for mandatory fields */
223 if (!rp->ke_grp_len) {
224 SILC_LOG_DEBUG(("KE group not defined in payload"));
225 return SILC_SKE_STATUS_BAD_PAYLOAD;
227 if (!rp->pkcs_alg_len) {
228 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
229 return SILC_SKE_STATUS_BAD_PAYLOAD;
231 if (!rp->enc_alg_len) {
232 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
233 return SILC_SKE_STATUS_BAD_PAYLOAD;
235 if (!rp->hash_alg_len) {
236 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
237 return SILC_SKE_STATUS_BAD_PAYLOAD;
239 if (!rp->hmac_alg_len) {
240 SILC_LOG_DEBUG(("HMAC not defined in payload"));
241 return SILC_SKE_STATUS_BAD_PAYLOAD;
244 /* Allocate security properties */
245 *prop = silc_calloc(1, sizeof(**prop));
247 return SILC_SKE_STATUS_OUT_OF_MEMORY;
249 /* Allocate our reply start payload */
250 payload = silc_calloc(1, sizeof(*payload));
253 return SILC_SKE_STATUS_OUT_OF_MEMORY;
256 /* Check version string */
257 ske->remote_version = silc_memdup(rp->version, rp->version_len);
258 status = silc_ske_check_version(ske);
259 if (status != SILC_SKE_STATUS_OK) {
260 ske->status = status;
264 /* Flags are returned unchanged. */
265 (*prop)->flags = payload->flags = rp->flags;
267 /* Take cookie, we must return it to sender unmodified. */
268 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
269 if (!payload->cookie) {
270 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
273 payload->cookie_len = SILC_SKE_COOKIE_LEN;
274 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
276 /* In case IV included flag and session port is set the first 16-bits of
277 cookie will include our session port. */
278 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
279 /* Take remote port */
280 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
283 SILC_PUT16_MSB(ske->session_port, payload->cookie);
286 /* Put our version to our reply */
287 payload->version = strdup(ske->version);
288 if (!payload->version) {
289 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
292 payload->version_len = strlen(ske->version);
294 /* Get supported Key Exchange groups */
295 cp = rp->ke_grp_list;
296 if (cp && strchr(cp, ',')) {
300 len = strcspn(cp, ",");
301 item = silc_calloc(len + 1, sizeof(char));
303 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
306 memcpy(item, cp, len);
308 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
310 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
311 SILC_LOG_DEBUG(("Found KE group `%s'", item));
313 payload->ke_grp_len = len;
314 payload->ke_grp_list = item;
328 if (!payload->ke_grp_len && !payload->ke_grp_list) {
329 SILC_LOG_DEBUG(("Could not find supported KE group"));
331 return SILC_SKE_STATUS_UNKNOWN_GROUP;
334 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
335 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
337 payload->ke_grp_len = rp->ke_grp_len;
338 payload->ke_grp_list = strdup(rp->ke_grp_list);
341 /* Save group to security properties */
342 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
343 if (status != SILC_SKE_STATUS_OK) {
345 return SILC_SKE_STATUS_UNKNOWN_GROUP;
348 /* Get supported PKCS algorithms */
349 cp = rp->pkcs_alg_list;
350 if (cp && strchr(cp, ',')) {
354 len = strcspn(cp, ",");
355 item = silc_calloc(len + 1, sizeof(char));
357 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
360 memcpy(item, cp, len);
362 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
364 if (silc_pkcs_find_algorithm(item, NULL)) {
365 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
367 payload->pkcs_alg_len = len;
368 payload->pkcs_alg_list = item;
382 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
383 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
384 silc_free(payload->ke_grp_list);
386 return SILC_SKE_STATUS_UNKNOWN_PKCS;
389 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
390 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
392 payload->pkcs_alg_len = rp->pkcs_alg_len;
393 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
396 /* Get supported encryption algorithms */
397 cp = rp->enc_alg_list;
398 if (cp && strchr(cp, ',')) {
402 len = strcspn(cp, ",");
403 item = silc_calloc(len + 1, sizeof(char));
405 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
408 memcpy(item, cp, len);
410 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
412 if (silc_cipher_is_supported(item) == TRUE) {
413 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
415 payload->enc_alg_len = len;
416 payload->enc_alg_list = item;
430 if (!payload->enc_alg_len && !payload->enc_alg_list) {
431 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
432 silc_free(payload->ke_grp_list);
433 silc_free(payload->pkcs_alg_list);
435 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
438 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
441 payload->enc_alg_len = rp->enc_alg_len;
442 payload->enc_alg_list = strdup(rp->enc_alg_list);
445 /* Save selected cipher to security properties */
446 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
447 silc_free(payload->ke_grp_list);
448 silc_free(payload->pkcs_alg_list);
450 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
453 /* Get supported hash algorithms */
454 cp = rp->hash_alg_list;
455 if (cp && strchr(cp, ',')) {
459 len = strcspn(cp, ",");
460 item = silc_calloc(len + 1, sizeof(char));
462 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
465 memcpy(item, cp, len);
467 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
469 if (silc_hash_is_supported(item) == TRUE) {
470 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
472 payload->hash_alg_len = len;
473 payload->hash_alg_list = item;
487 if (!payload->hash_alg_len && !payload->hash_alg_list) {
488 SILC_LOG_DEBUG(("Could not find supported hash alg"));
489 silc_free(payload->ke_grp_list);
490 silc_free(payload->pkcs_alg_list);
491 silc_free(payload->enc_alg_list);
493 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
496 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
499 payload->hash_alg_len = rp->hash_alg_len;
500 payload->hash_alg_list = strdup(rp->hash_alg_list);
503 /* Save selected hash algorithm to security properties */
504 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
505 silc_free(payload->ke_grp_list);
506 silc_free(payload->pkcs_alg_list);
507 silc_free(payload->enc_alg_list);
509 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
512 /* Get supported HMACs */
513 cp = rp->hmac_alg_list;
514 if (cp && strchr(cp, ',')) {
518 len = strcspn(cp, ",");
519 item = silc_calloc(len + 1, sizeof(char));
521 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
524 memcpy(item, cp, len);
526 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
528 if (silc_hmac_is_supported(item) == TRUE) {
529 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
531 payload->hmac_alg_len = len;
532 payload->hmac_alg_list = item;
546 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
547 SILC_LOG_DEBUG(("Could not find supported HMAC"));
548 silc_free(payload->ke_grp_list);
549 silc_free(payload->pkcs_alg_list);
550 silc_free(payload->enc_alg_list);
551 silc_free(payload->hash_alg_list);
553 return SILC_SKE_STATUS_UNKNOWN_HMAC;
556 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
559 payload->hmac_alg_len = rp->hmac_alg_len;
560 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
563 /* Save selected HMACc to security properties */
564 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
565 silc_free(payload->ke_grp_list);
566 silc_free(payload->pkcs_alg_list);
567 silc_free(payload->enc_alg_list);
568 silc_free(payload->hash_alg_list);
570 return SILC_SKE_STATUS_UNKNOWN_HMAC;
573 /* Get supported compression algorithms */
574 cp = rp->comp_alg_list;
575 if (cp && strchr(cp, ',')) {
579 len = strcspn(cp, ",");
580 item = silc_calloc(len + 1, sizeof(char));
582 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
585 memcpy(item, cp, len);
587 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
590 if (!strcmp(item, "none")) {
591 SILC_LOG_DEBUG(("Found Compression `%s'", item));
592 payload->comp_alg_len = len;
593 payload->comp_alg_list = item;
597 if (silc_hmac_is_supported(item) == TRUE) {
598 SILC_LOG_DEBUG(("Found Compression `%s'", item));
599 payload->comp_alg_len = len;
600 payload->comp_alg_list = item;
616 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
617 2 + payload->version_len +
618 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
619 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
620 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
622 /* Save our reply payload */
623 ske->start_payload = payload;
625 return SILC_SKE_STATUS_OK;
628 /* Creates random number such that 1 < rnd < n and at most length
629 of len bits. The rnd sent as argument must be initialized. */
631 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
635 SilcSKEStatus status = SILC_SKE_STATUS_OK;
636 unsigned char string[2048];
640 return SILC_SKE_STATUS_ERROR;
642 SILC_LOG_DEBUG(("Creating random number"));
646 /* Get the random number as string */
647 if (!silc_rng_get_rn_data(ske->rng, l, string, sizeof(string)))
648 return SILC_SKE_STATUS_OUT_OF_MEMORY;
650 /* Decode the string into a MP integer */
651 silc_mp_bin2mp(string, l, rnd);
652 silc_mp_mod_2exp(rnd, rnd, len);
655 if (silc_mp_cmp_ui(rnd, 1) < 0)
656 status = SILC_SKE_STATUS_ERROR;
657 if (silc_mp_cmp(rnd, n) >= 0)
658 status = SILC_SKE_STATUS_ERROR;
660 memset(string, 'F', l);
666 /* Creates a hash value HASH as defined in the SKE protocol. If the
667 `initiator' is TRUE then this function is used to create the HASH_i
668 hash value defined in the protocol. If it is FALSE then this is used
669 to create the HASH value defined by the protocol. */
671 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
672 unsigned char *return_hash,
673 SilcUInt32 *return_hash_len,
676 SilcSKEStatus status = SILC_SKE_STATUS_OK;
678 unsigned char *e, *f, *KEY, *s_data;
679 SilcUInt32 e_len, f_len, KEY_len, s_len;
682 SILC_LOG_DEBUG(("Start"));
684 if (initiator == FALSE) {
685 s_data = (ske->start_payload_copy ?
686 silc_buffer_data(ske->start_payload_copy) : NULL);
687 s_len = (ske->start_payload_copy ?
688 silc_buffer_len(ske->start_payload_copy) : 0);
689 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
690 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
691 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
693 /* Format the buffer used to compute the hash value */
694 buf = silc_buffer_alloc_size(s_len +
695 ske->ke2_payload->pk_len +
696 ske->ke1_payload->pk_len +
697 e_len + f_len + KEY_len);
699 return SILC_SKE_STATUS_OUT_OF_MEMORY;
701 /* Initiator is not required to send its public key */
702 if (!ske->ke1_payload->pk_data) {
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(e, e_len),
709 SILC_STR_DATA(f, f_len),
710 SILC_STR_DATA(KEY, KEY_len),
714 silc_buffer_format(buf,
715 SILC_STR_DATA(s_data, s_len),
716 SILC_STR_DATA(ske->ke2_payload->pk_data,
717 ske->ke2_payload->pk_len),
718 SILC_STR_DATA(ske->ke1_payload->pk_data,
719 ske->ke1_payload->pk_len),
720 SILC_STR_DATA(e, e_len),
721 SILC_STR_DATA(f, f_len),
722 SILC_STR_DATA(KEY, KEY_len),
726 silc_buffer_free(buf);
729 memset(KEY, 0, KEY_len);
733 return SILC_SKE_STATUS_ERROR;
738 memset(KEY, 0, KEY_len);
743 s_data = (ske->start_payload_copy ?
744 silc_buffer_data(ske->start_payload_copy) : NULL);
745 s_len = (ske->start_payload_copy ?
746 silc_buffer_len(ske->start_payload_copy) : 0);
747 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
749 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
751 return SILC_SKE_STATUS_OUT_OF_MEMORY;
753 /* Format the buffer used to compute the hash value */
755 silc_buffer_format(buf,
756 SILC_STR_DATA(s_data, s_len),
757 SILC_STR_DATA(ske->ke1_payload->pk_data,
758 ske->ke1_payload->pk_len),
759 SILC_STR_DATA(e, e_len),
762 silc_buffer_free(buf);
765 return SILC_SKE_STATUS_ERROR;
768 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
775 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
777 *return_hash_len = silc_hash_len(ske->prop->hash);
779 if (initiator == FALSE) {
780 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
782 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
785 silc_buffer_free(buf);
790 /* Generate rekey material */
792 static SilcSKERekeyMaterial
793 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
795 SilcSKERekeyMaterial rekey;
798 /* Create rekey material */
799 rekey = silc_calloc(1, sizeof(*rekey));
804 if (ske->prop->group)
805 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
806 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
807 hash = silc_hash_get_name(ske->prop->hash);
808 rekey->hash = silc_memdup(hash, strlen(hash));
813 if (rekey->pfs == FALSE) {
814 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
815 keymat->enc_key_len / 8);
816 if (!rekey->send_enc_key) {
820 rekey->enc_key_len = keymat->enc_key_len;
826 /* Assembles security properties */
828 static SilcSKEStartPayload
829 silc_ske_assemble_security_properties(SilcSKE ske,
830 SilcSKESecurityPropertyFlag flags,
833 SilcSKEStartPayload rp;
836 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
838 rp = silc_calloc(1, sizeof(*rp));
841 rp->flags = (unsigned char)flags;
843 /* Set random cookie */
844 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
845 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
846 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
847 rp->cookie_len = SILC_SKE_COOKIE_LEN;
849 /* In case IV included flag and session port is set the first 16-bits of
850 cookie will include our session port. */
851 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
852 SILC_PUT16_MSB(ske->session_port, rp->cookie);
855 rp->version = strdup(version);
856 rp->version_len = strlen(version);
858 /* Get supported Key Exhange groups */
859 rp->ke_grp_list = silc_ske_get_supported_groups();
860 rp->ke_grp_len = strlen(rp->ke_grp_list);
862 /* Get supported PKCS algorithms */
863 rp->pkcs_alg_list = silc_pkcs_get_supported();
864 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
866 /* Get supported encryption algorithms */
867 rp->enc_alg_list = silc_cipher_get_supported();
868 rp->enc_alg_len = strlen(rp->enc_alg_list);
870 /* Get supported hash algorithms */
871 rp->hash_alg_list = silc_hash_get_supported();
872 rp->hash_alg_len = strlen(rp->hash_alg_list);
874 /* Get supported HMACs */
875 rp->hmac_alg_list = silc_hmac_get_supported();
876 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
879 /* Get supported compression algorithms */
880 rp->comp_alg_list = strdup("none");
881 rp->comp_alg_len = strlen("none");
883 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
884 2 + rp->version_len +
885 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
886 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
887 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
892 /* Packet retransmission callback. */
894 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
896 SilcSKE ske = context;
898 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
900 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
901 ske->retry_count = 0;
902 ske->retry_timer = SILC_SKE_RETRY_MIN;
903 silc_free(ske->retrans.data);
904 ske->retrans.data = NULL;
905 ske->status = SILC_SKE_STATUS_TIMEOUT;
907 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
909 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
910 silc_fsm_continue_sync(&ske->fsm);
914 SILC_LOG_DEBUG(("Retransmitting packet"));
915 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
916 ske->retrans.data, ske->retrans.data_len);
919 /* Install retransmission timer */
921 static void silc_ske_install_retransmission(SilcSKE ske)
923 if (!silc_packet_stream_is_udp(ske->stream))
926 if (ske->retrans.data) {
927 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
929 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
930 ske, ske->retry_timer, 0);
932 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
933 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
936 /* Sends SILC packet. Handles retransmissions with UDP streams. */
938 static SilcBool silc_ske_packet_send(SilcSKE ske,
940 SilcPacketFlags flags,
941 const unsigned char *data,
946 /* Send the packet */
947 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
949 if (silc_packet_stream_is_udp(ske->stream) &&
950 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
951 silc_free(ske->retrans.data);
952 ske->retrans.type = type;
953 ske->retrans.flags = flags;
954 ske->retrans.data = silc_memdup(data, data_len);
955 ske->retrans.data_len = data_len;
956 silc_ske_install_retransmission(ske);
962 /* Calls completion callback. Completion is called always in this function
963 and must not be called anywhere else. */
965 static void silc_ske_completion(SilcSKE ske)
967 /* Call the completion callback */
968 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
969 if (ske->status != SILC_SKE_STATUS_OK)
970 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
971 ske->callbacks->context);
973 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
974 ske->rekey, ske->callbacks->context);
978 /* SKE FSM destructor. */
980 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
981 void *destructor_context)
983 SilcSKE ske = fsm_context;
984 ske->running = FALSE;
989 /* Key exchange timeout task callback */
991 SILC_TASK_CALLBACK(silc_ske_timeout)
993 SilcSKE ske = context;
995 SILC_LOG_DEBUG(("Timeout"));
998 ske->status = SILC_SKE_STATUS_TIMEOUT;
1000 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1002 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1004 silc_fsm_continue_sync(&ske->fsm);
1007 /* Initiator signature callback */
1009 static void silc_ske_initiator_sign_cb(SilcBool success,
1010 const unsigned char *signature,
1011 SilcUInt32 signature_len,
1014 SilcSKE ske = context;
1019 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1020 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1024 ske->ke1_payload->sign_data = silc_memdup(signature, signature_len);
1025 if (ske->ke1_payload->sign_data)
1026 ske->ke1_payload->sign_len = signature_len;
1028 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1031 /* Responder signature callback */
1033 static void silc_ske_responder_sign_cb(SilcBool success,
1034 const unsigned char *signature,
1035 SilcUInt32 signature_len,
1038 SilcSKE ske = context;
1043 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1044 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1048 ske->ke2_payload->sign_data = silc_memdup(signature, signature_len);
1049 if (ske->ke2_payload->sign_data)
1050 ske->ke2_payload->sign_len = signature_len;
1052 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1055 /* Verify callback */
1057 static void silc_ske_verify_cb(SilcBool success, void *context)
1059 SilcSKE ske = context;
1065 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1067 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1068 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1073 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1074 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1076 silc_fsm_next(&ske->fsm, silc_ske_st_responder_error);
1078 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_error);
1079 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1083 SILC_LOG_DEBUG(("Signature is Ok"));
1084 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1087 /******************************* Protocol API *******************************/
1089 /* Allocates new SKE object. */
1091 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1092 SilcSKR repository, SilcPublicKey public_key,
1093 SilcPrivateKey private_key, void *context)
1097 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1099 if (!rng || !schedule)
1103 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1107 ske = silc_calloc(1, sizeof(*ske));
1110 ske->status = SILC_SKE_STATUS_OK;
1112 ske->repository = repository;
1113 ske->user_data = context;
1114 ske->schedule = schedule;
1115 ske->public_key = public_key;
1116 ske->private_key = private_key;
1117 ske->retry_timer = SILC_SKE_RETRY_MIN;
1123 /* Free's SKE object. */
1125 void silc_ske_free(SilcSKE ske)
1127 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1136 /* If already aborted, destroy the session immediately */
1138 ske->status = SILC_SKE_STATUS_ERROR;
1140 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1142 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1143 silc_fsm_continue_sync(&ske->fsm);
1149 if (ske->refcnt > 0)
1152 /* Free start payload */
1153 if (ske->start_payload)
1154 silc_ske_payload_start_free(ske->start_payload);
1156 /* Free KE payload */
1157 if (ske->ke1_payload)
1158 silc_ske_payload_ke_free(ske->ke1_payload);
1159 if (ske->ke2_payload)
1160 silc_ske_payload_ke_free(ske->ke2_payload);
1161 silc_free(ske->remote_version);
1165 if (ske->prop->group)
1166 silc_ske_group_free(ske->prop->group);
1167 if (ske->prop->cipher)
1168 silc_cipher_free(ske->prop->cipher);
1169 if (ske->prop->hash)
1170 silc_hash_free(ske->prop->hash);
1171 if (ske->prop->hmac)
1172 silc_hmac_free(ske->prop->hmac);
1173 if (ske->prop->public_key)
1174 silc_pkcs_public_key_free(ske->prop->public_key);
1175 silc_free(ske->prop);
1178 silc_ske_free_key_material(ske->keymat);
1179 if (ske->start_payload_copy)
1180 silc_buffer_free(ske->start_payload_copy);
1182 silc_mp_uninit(ske->x);
1186 silc_mp_uninit(ske->KEY);
1187 silc_free(ske->KEY);
1189 silc_free(ske->retrans.data);
1190 silc_free(ske->hash);
1191 silc_free(ske->callbacks);
1193 memset(ske, 'F', sizeof(*ske));
1197 /* Return user context */
1199 void *silc_ske_get_context(SilcSKE ske)
1201 return ske->user_data;
1204 /* Sets protocol callbacks */
1206 void silc_ske_set_callbacks(SilcSKE ske,
1207 SilcSKEVerifyCb verify_key,
1208 SilcSKECompletionCb completed,
1212 silc_free(ske->callbacks);
1213 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1214 if (!ske->callbacks)
1216 ske->callbacks->verify_key = verify_key;
1217 ske->callbacks->completed = completed;
1218 ske->callbacks->context = context;
1222 /******************************** Initiator *********************************/
1224 /* Start protocol. Send our proposal */
1226 SILC_FSM_STATE(silc_ske_st_initiator_start)
1228 SilcSKE ske = fsm_context;
1229 SilcBuffer payload_buf;
1232 SILC_LOG_DEBUG(("Start"));
1236 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1237 return SILC_FSM_CONTINUE;
1240 /* Encode the payload */
1241 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1243 if (status != SILC_SKE_STATUS_OK) {
1244 /** Error encoding Start Payload */
1245 ske->status = status;
1246 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1247 return SILC_FSM_CONTINUE;
1250 /* Save the the payload buffer for future use. It is later used to
1251 compute the HASH value. */
1252 ske->start_payload_copy = payload_buf;
1254 /* Send the packet. */
1255 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1256 silc_buffer_data(payload_buf),
1257 silc_buffer_len(payload_buf))) {
1258 /** Error sending packet */
1259 SILC_LOG_DEBUG(("Error sending packet"));
1260 ske->status = SILC_SKE_STATUS_ERROR;
1261 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1262 return SILC_FSM_CONTINUE;
1265 /* Add key exchange timeout */
1266 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1267 ske, ske->timeout, 0);
1269 /** Wait for responder proposal */
1270 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1271 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1272 return SILC_FSM_WAIT;
1275 /* Phase-1. Receives responder's proposal */
1277 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1279 SilcSKE ske = fsm_context;
1280 SilcSKEStatus status;
1281 SilcSKEStartPayload payload;
1282 SilcSKESecurityProperties prop;
1283 SilcSKEDiffieHellmanGroup group = NULL;
1284 SilcBuffer packet_buf = &ske->packet->buffer;
1285 SilcUInt16 remote_port = 0;
1289 SILC_LOG_DEBUG(("Start"));
1291 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1292 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1293 silc_ske_install_retransmission(ske);
1294 silc_packet_free(ske->packet);
1296 return SILC_FSM_WAIT;
1299 /* Decode the payload */
1300 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1301 if (status != SILC_SKE_STATUS_OK) {
1302 /** Error decoding Start Payload */
1303 silc_packet_free(ske->packet);
1305 ske->status = status;
1306 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1307 return SILC_FSM_CONTINUE;
1310 /* Get remote ID and set it to stream */
1311 if (ske->packet->src_id_len) {
1312 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1313 ske->packet->src_id_type,
1314 (ske->packet->src_id_type == SILC_ID_SERVER ?
1315 (void *)&id.u.server_id : (void *)&id.u.client_id),
1316 (ske->packet->src_id_type == SILC_ID_SERVER ?
1317 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1318 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1319 (ske->packet->src_id_type == SILC_ID_SERVER ?
1320 (void *)&id.u.server_id : (void *)&id.u.client_id));
1323 silc_packet_free(ske->packet);
1326 /* Check that the cookie is returned unmodified. In case IV included
1327 flag and session port has been set, the first two bytes of cookie
1328 are the session port and we ignore them in this check. */
1329 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1330 /* Take remote port */
1331 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1334 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1335 SILC_SKE_COOKIE_LEN - coff)) {
1336 /** Invalid cookie */
1337 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1338 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1339 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1340 return SILC_FSM_CONTINUE;
1343 /* Check version string */
1344 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1345 status = silc_ske_check_version(ske);
1346 if (status != SILC_SKE_STATUS_OK) {
1347 /** Version mismatch */
1348 ske->status = status;
1349 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1350 return SILC_FSM_CONTINUE;
1353 /* Free our KE Start Payload context, we don't need it anymore. */
1354 silc_ske_payload_start_free(ske->start_payload);
1355 ske->start_payload = NULL;
1357 /* Take the selected security properties into use while doing
1358 the key exchange. This is used only while doing the key
1360 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1363 prop->flags = payload->flags;
1364 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1365 if (status != SILC_SKE_STATUS_OK)
1368 prop->group = group;
1369 prop->remote_port = remote_port;
1371 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1372 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1375 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1376 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1379 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1380 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1383 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1384 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1388 /* Save remote's KE Start Payload */
1389 ske->start_payload = payload;
1391 /** Send KE Payload */
1392 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1393 return SILC_FSM_CONTINUE;
1397 silc_ske_payload_start_free(payload);
1399 silc_ske_group_free(group);
1401 silc_cipher_free(prop->cipher);
1403 silc_hash_free(prop->hash);
1405 silc_hmac_free(prop->hmac);
1409 if (status == SILC_SKE_STATUS_OK)
1410 status = SILC_SKE_STATUS_ERROR;
1413 ske->status = status;
1414 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1415 return SILC_FSM_CONTINUE;
1418 /* Phase-2. Send KE payload */
1420 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1422 SilcSKE ske = fsm_context;
1423 SilcSKEStatus status;
1425 SilcSKEKEPayload payload;
1428 SILC_LOG_DEBUG(("Start"));
1430 /* Create the random number x, 1 < x < q. */
1431 x = silc_calloc(1, sizeof(*x));
1433 /** Out of memory */
1434 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1435 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1436 return SILC_FSM_CONTINUE;
1440 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1441 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1443 if (status != SILC_SKE_STATUS_OK) {
1444 /** Error generating random number */
1447 ske->status = status;
1448 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1449 return SILC_FSM_CONTINUE;
1452 /* Encode the result to Key Exchange Payload. */
1454 payload = silc_calloc(1, sizeof(*payload));
1456 /** Out of memory */
1459 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1460 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1461 return SILC_FSM_CONTINUE;
1463 ske->ke1_payload = payload;
1465 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1467 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1468 silc_mp_init(&payload->x);
1469 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1470 &ske->prop->group->group);
1473 /* Get public key */
1474 payload->pk_data = silc_pkcs_public_key_encode(NULL, ske->public_key,
1476 if (!payload->pk_data) {
1477 /** Error encoding public key */
1481 silc_mp_uninit(&payload->x);
1483 ske->ke1_payload = NULL;
1484 ske->status = SILC_SKE_STATUS_ERROR;
1485 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1486 return SILC_FSM_CONTINUE;
1488 payload->pk_len = pk_len;
1489 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1491 /** Send KE1 packet */
1492 silc_fsm_next(fsm, silc_ske_st_initiator_phase2_send);
1494 /* Compute signature data if we are doing mutual authentication */
1495 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1496 unsigned char hash[SILC_HASH_MAXLEN];
1497 SilcUInt32 hash_len;
1499 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1500 SILC_LOG_DEBUG(("Computing HASH_i value"));
1502 /* Compute the hash value */
1503 memset(hash, 0, sizeof(hash));
1504 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1506 SILC_LOG_DEBUG(("Signing HASH_i value"));
1508 /* Sign the hash value */
1509 SILC_FSM_CALL(ske->key_op =
1510 silc_pkcs_sign(ske->private_key, hash, hash_len, FALSE,
1512 silc_ske_initiator_sign_cb, ske));
1516 return SILC_FSM_CONTINUE;
1519 /* Send KE1 packet */
1521 SILC_FSM_STATE(silc_ske_st_initiator_phase2_send)
1523 SilcSKE ske = fsm_context;
1524 SilcSKEStatus status;
1525 SilcBuffer payload_buf;
1526 SilcSKEKEPayload payload;
1528 SILC_LOG_DEBUG(("Start"));
1530 payload = ske->ke1_payload;
1532 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1533 if (status != SILC_SKE_STATUS_OK) {
1534 /** Error encoding KE payload */
1535 silc_mp_uninit(&payload->x);
1536 silc_free(payload->pk_data);
1537 silc_free(payload->sign_data);
1539 ske->ke1_payload = NULL;
1540 ske->status = status;
1541 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1542 return SILC_FSM_CONTINUE;
1545 /* Send the packet. */
1546 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1547 silc_buffer_data(payload_buf),
1548 silc_buffer_len(payload_buf))) {
1549 /** Error sending packet */
1550 SILC_LOG_DEBUG(("Error sending packet"));
1551 ske->status = SILC_SKE_STATUS_ERROR;
1552 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1553 return SILC_FSM_CONTINUE;
1556 silc_buffer_free(payload_buf);
1558 /** Waiting responder's KE payload */
1559 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1560 return SILC_FSM_WAIT;
1563 /* Phase-3. Process responder's KE payload */
1565 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1567 SilcSKE ske = fsm_context;
1568 SilcSKEStatus status;
1569 SilcSKEKEPayload payload;
1571 SilcBuffer packet_buf = &ske->packet->buffer;
1573 SILC_LOG_DEBUG(("Start"));
1575 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1576 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1577 silc_ske_install_retransmission(ske);
1578 silc_packet_free(ske->packet);
1580 return SILC_FSM_WAIT;
1583 /* Decode the payload */
1584 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1585 if (status != SILC_SKE_STATUS_OK) {
1586 /** Error decoding KE payload */
1587 silc_packet_free(ske->packet);
1589 ske->status = status;
1590 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1591 return SILC_FSM_CONTINUE;
1593 silc_packet_free(ske->packet);
1595 ske->ke2_payload = payload;
1597 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1598 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1599 "even though we require it"));
1600 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1604 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1606 /* Compute the shared secret key */
1607 KEY = silc_calloc(1, sizeof(*KEY));
1609 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1612 /* Decode the remote's public key */
1613 if (payload->pk_data &&
1614 !silc_pkcs_public_key_alloc(payload->pk_type,
1615 payload->pk_data, payload->pk_len,
1616 &ske->prop->public_key)) {
1617 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1618 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1622 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1624 SILC_LOG_DEBUG(("Verifying public key"));
1626 /** Waiting public key verification */
1627 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1629 /* If repository is provided, verify the key from there. */
1630 if (ske->repository) {
1633 find = silc_skr_find_alloc();
1635 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1638 silc_skr_find_set_pkcs_type(find,
1639 silc_pkcs_get_type(ske->prop->public_key));
1640 silc_skr_find_set_public_key(find, ske->prop->public_key);
1641 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1643 /* Find key from repository */
1644 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1645 find, silc_ske_skr_callback, ske));
1647 /* Verify from application */
1648 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1649 ske->callbacks->context,
1650 silc_ske_pk_verified, NULL));
1655 /** Process key material */
1656 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1657 return SILC_FSM_CONTINUE;
1660 silc_ske_payload_ke_free(payload);
1661 ske->ke2_payload = NULL;
1663 silc_mp_uninit(ske->KEY);
1664 silc_free(ske->KEY);
1667 if (status == SILC_SKE_STATUS_OK)
1668 return SILC_SKE_STATUS_ERROR;
1671 ske->status = status;
1672 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1673 return SILC_FSM_CONTINUE;
1676 /* Process key material */
1678 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1680 SilcSKE ske = fsm_context;
1681 SilcSKEStatus status;
1682 SilcSKEKEPayload payload;
1683 unsigned char hash[SILC_HASH_MAXLEN];
1684 SilcUInt32 hash_len;
1688 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1689 return SILC_FSM_CONTINUE;
1692 /* Check result of public key verification */
1693 if (ske->status != SILC_SKE_STATUS_OK) {
1694 /** Public key not verified */
1695 SILC_LOG_DEBUG(("Public key verification failed"));
1696 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1697 return SILC_FSM_CONTINUE;
1700 payload = ske->ke2_payload;
1702 /* Compute the HASH value */
1703 SILC_LOG_DEBUG(("Computing HASH value"));
1704 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1705 if (status != SILC_SKE_STATUS_OK)
1707 ske->hash = silc_memdup(hash, hash_len);
1708 ske->hash_len = hash_len;
1711 silc_fsm_next(fsm, silc_ske_st_initiator_phase5);
1713 if (ske->prop->public_key) {
1714 SILC_LOG_DEBUG(("Public key is authentic"));
1715 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1717 /* Verify signature */
1718 SILC_FSM_CALL(ske->key_op =
1719 silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1720 payload->sign_len, hash, hash_len, NULL,
1721 silc_ske_verify_cb, ske));
1725 return SILC_FSM_CONTINUE;
1728 memset(hash, 'F', sizeof(hash));
1729 silc_ske_payload_ke_free(payload);
1730 ske->ke2_payload = NULL;
1732 silc_mp_uninit(ske->KEY);
1733 silc_free(ske->KEY);
1737 memset(ske->hash, 'F', hash_len);
1738 silc_free(ske->hash);
1742 if (status == SILC_SKE_STATUS_OK)
1743 status = SILC_SKE_STATUS_ERROR;
1746 ske->status = status;
1747 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1748 return SILC_FSM_CONTINUE;
1751 /* Process key material */
1753 SILC_FSM_STATE(silc_ske_st_initiator_phase5)
1755 SilcSKE ske = fsm_context;
1756 SilcSKEStatus status;
1757 unsigned char tmp[4];
1758 SilcUInt32 hash_len;
1759 int key_len, block_len;
1761 ske->status = SILC_SKE_STATUS_OK;
1763 /* In case we are doing rekey move to finish it. */
1766 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1767 return SILC_FSM_CONTINUE;
1770 /* Process key material */
1771 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1772 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1773 hash_len = silc_hash_len(ske->prop->hash);
1774 ske->keymat = silc_ske_process_key_material(ske, block_len,
1778 SILC_LOG_ERROR(("Error processing key material"));
1779 status = SILC_SKE_STATUS_ERROR;
1780 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1781 return SILC_FSM_CONTINUE;
1784 /* Send SUCCESS packet */
1785 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, tmp);
1786 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4)) {
1787 /** Error sending packet */
1788 SILC_LOG_DEBUG(("Error sending packet"));
1789 ske->status = SILC_SKE_STATUS_ERROR;
1790 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1791 return SILC_FSM_CONTINUE;
1794 /** Waiting completion */
1795 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1796 return SILC_FSM_WAIT;
1799 /* Protocol completed */
1801 SILC_FSM_STATE(silc_ske_st_initiator_end)
1803 SilcSKE ske = fsm_context;
1805 SILC_LOG_DEBUG(("Start"));
1807 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1808 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1809 silc_ske_install_retransmission(ske);
1810 silc_packet_free(ske->packet);
1812 return SILC_FSM_WAIT;
1815 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1817 silc_packet_free(ske->packet);
1819 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1820 silc_schedule_task_del_by_context(ske->schedule, ske);
1822 /* Call completion */
1823 silc_ske_completion(ske);
1825 return SILC_FSM_FINISH;
1828 /* Aborted by application */
1830 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1832 SilcSKE ske = fsm_context;
1833 unsigned char data[4];
1835 SILC_LOG_DEBUG(("Aborted by caller"));
1837 /* Send FAILURE packet */
1838 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1839 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1841 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1842 silc_schedule_task_del_by_context(ske->schedule, ske);
1844 /* Call completion */
1845 silc_ske_completion(ske);
1847 return SILC_FSM_FINISH;
1850 /* Error occurred. Send error to remote host */
1852 SILC_FSM_STATE(silc_ske_st_initiator_error)
1854 SilcSKE ske = fsm_context;
1855 SilcSKEStatus status;
1856 unsigned char data[4];
1858 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1859 silc_ske_map_status(ske->status), ske->status));
1861 status = ske->status;
1862 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1863 status = SILC_SKE_STATUS_ERROR;
1865 /* Send FAILURE packet */
1866 SILC_PUT32_MSB((SilcUInt32)status, data);
1867 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1869 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1870 silc_schedule_task_del_by_context(ske->schedule, ske);
1872 /* Call completion */
1873 silc_ske_completion(ske);
1875 return SILC_FSM_FINISH;
1878 /* Failure received from remote */
1880 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1882 SilcSKE ske = fsm_context;
1883 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1885 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1886 SILC_GET32_MSB(error, ske->packet->buffer.data);
1887 ske->status = error;
1888 silc_packet_free(ske->packet);
1892 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1893 silc_ske_map_status(ske->status), ske->status));
1895 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1896 silc_schedule_task_del_by_context(ske->schedule, ske);
1898 /* Call completion */
1899 silc_ske_completion(ske);
1901 return SILC_FSM_FINISH;
1904 /* Starts the protocol as initiator */
1906 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1907 SilcPacketStream stream,
1908 SilcSKEParams params,
1909 SilcSKEStartPayload start_payload)
1911 SILC_LOG_DEBUG(("Start SKE as initiator"));
1913 if (!ske || !stream || !params || !params->version)
1916 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1919 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1922 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1923 ske->session_port = params->session_port;
1925 /* Generate security properties if not provided */
1926 if (!start_payload) {
1927 start_payload = silc_ske_assemble_security_properties(ske,
1934 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1935 ske->start_payload = start_payload;
1936 ske->version = params->version;
1937 ske->running = TRUE;
1939 /* Link to packet stream to get key exchange packets */
1940 ske->stream = stream;
1941 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1942 SILC_PACKET_KEY_EXCHANGE,
1943 SILC_PACKET_KEY_EXCHANGE_2,
1944 SILC_PACKET_SUCCESS,
1945 SILC_PACKET_FAILURE, -1);
1947 /* Start SKE as initiator */
1948 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1953 /******************************** Responder *********************************/
1955 /* Start protocol as responder. Wait initiator's start payload */
1957 SILC_FSM_STATE(silc_ske_st_responder_start)
1959 SilcSKE ske = fsm_context;
1961 SILC_LOG_DEBUG(("Start"));
1965 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1966 return SILC_FSM_CONTINUE;
1969 /* Add key exchange timeout */
1970 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1971 ske, ske->timeout, 0);
1973 /** Wait for initiator */
1974 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1975 return SILC_FSM_WAIT;
1978 /* Decode initiator's start payload. Select the security properties from
1979 the initiator's start payload and send our reply start payload back. */
1981 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1983 SilcSKE ske = fsm_context;
1984 SilcSKEStatus status;
1985 SilcSKEStartPayload remote_payload = NULL;
1986 SilcBuffer packet_buf = &ske->packet->buffer;
1989 SILC_LOG_DEBUG(("Start"));
1991 /* Decode the payload */
1992 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1993 if (status != SILC_SKE_STATUS_OK) {
1994 /** Error decoding Start Payload */
1995 silc_packet_free(ske->packet);
1997 ske->status = status;
1998 silc_fsm_next(fsm, silc_ske_st_responder_error);
1999 return SILC_FSM_CONTINUE;
2002 /* Get remote ID and set it to stream */
2003 if (ske->packet->src_id_len) {
2004 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
2005 ske->packet->src_id_type,
2006 (ske->packet->src_id_type == SILC_ID_SERVER ?
2007 (void *)&id.u.server_id : (void *)&id.u.client_id),
2008 (ske->packet->src_id_type == SILC_ID_SERVER ?
2009 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
2010 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
2011 (ske->packet->src_id_type == SILC_ID_SERVER ?
2012 (void *)&id.u.server_id : (void *)&id.u.client_id));
2015 /* Take a copy of the payload buffer for future use. It is used to
2016 compute the HASH value. */
2017 ske->start_payload_copy = silc_buffer_copy(packet_buf);
2019 silc_packet_free(ske->packet);
2022 /* Force the mutual authentication flag if we want to do it. */
2023 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2024 SILC_LOG_DEBUG(("Force mutual authentication"));
2025 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
2028 /* Force PFS flag if we require it */
2029 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
2030 SILC_LOG_DEBUG(("Force PFS"));
2031 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
2034 /* Disable IV Included flag if requested */
2035 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
2036 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
2037 SILC_LOG_DEBUG(("We do not support IV Included flag"));
2038 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
2041 /* Check and select security properties */
2042 status = silc_ske_select_security_properties(ske, remote_payload,
2044 if (status != SILC_SKE_STATUS_OK) {
2045 /** Error selecting proposal */
2046 silc_ske_payload_start_free(remote_payload);
2047 ske->status = status;
2048 silc_fsm_next(fsm, silc_ske_st_responder_error);
2049 return SILC_FSM_CONTINUE;
2052 silc_ske_payload_start_free(remote_payload);
2054 /* Encode our reply payload to send the selected security properties */
2055 status = silc_ske_payload_start_encode(ske, ske->start_payload,
2057 if (status != SILC_SKE_STATUS_OK)
2060 /* Send the packet. */
2061 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
2062 silc_buffer_data(packet_buf),
2063 silc_buffer_len(packet_buf)))
2066 silc_buffer_free(packet_buf);
2068 /** Waiting initiator's KE payload */
2069 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2070 return SILC_FSM_WAIT;
2073 if (ske->prop->group)
2074 silc_ske_group_free(ske->prop->group);
2075 if (ske->prop->cipher)
2076 silc_cipher_free(ske->prop->cipher);
2077 if (ske->prop->hash)
2078 silc_hash_free(ske->prop->hash);
2079 if (ske->prop->hmac)
2080 silc_hmac_free(ske->prop->hmac);
2081 silc_free(ske->prop);
2084 if (status == SILC_SKE_STATUS_OK)
2085 status = SILC_SKE_STATUS_ERROR;
2088 ske->status = status;
2089 silc_fsm_next(fsm, silc_ske_st_responder_error);
2090 return SILC_FSM_CONTINUE;
2093 /* Phase-2. Decode initiator's KE payload */
2095 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2097 SilcSKE ske = fsm_context;
2098 SilcSKEStatus status;
2099 SilcSKEKEPayload recv_payload;
2100 SilcBuffer packet_buf = &ske->packet->buffer;
2102 SILC_LOG_DEBUG(("Start"));
2104 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2105 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2106 silc_ske_install_retransmission(ske);
2107 silc_packet_free(ske->packet);
2109 return SILC_FSM_WAIT;
2112 /* Decode Key Exchange Payload */
2113 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2114 if (status != SILC_SKE_STATUS_OK) {
2115 /** Error decoding KE payload */
2116 silc_packet_free(ske->packet);
2118 ske->status = status;
2119 silc_fsm_next(fsm, silc_ske_st_responder_error);
2120 return SILC_FSM_CONTINUE;
2123 ske->ke1_payload = recv_payload;
2125 silc_packet_free(ske->packet);
2128 /* Verify the received public key and verify the signature if we are
2129 doing mutual authentication. */
2130 if (ske->start_payload &&
2131 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2133 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2135 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2137 /** Public key not provided */
2138 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2139 "certificate), even though we require it"));
2140 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2141 silc_fsm_next(fsm, silc_ske_st_responder_error);
2142 return SILC_FSM_CONTINUE;
2145 /* Decode the remote's public key */
2146 if (recv_payload->pk_data &&
2147 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2148 recv_payload->pk_data,
2149 recv_payload->pk_len,
2150 &ske->prop->public_key)) {
2151 /** Error decoding public key */
2152 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2153 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2154 silc_fsm_next(fsm, silc_ske_st_responder_error);
2155 return SILC_FSM_CONTINUE;
2158 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2160 SILC_LOG_DEBUG(("Verifying public key"));
2162 /** Waiting public key verification */
2163 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2165 /* If repository is provided, verify the key from there. */
2166 if (ske->repository) {
2169 find = silc_skr_find_alloc();
2171 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2172 silc_fsm_next(fsm, silc_ske_st_responder_error);
2173 return SILC_FSM_CONTINUE;
2175 silc_skr_find_set_pkcs_type(find,
2176 silc_pkcs_get_type(ske->prop->public_key));
2177 silc_skr_find_set_public_key(find, ske->prop->public_key);
2178 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2180 /* Find key from repository */
2181 SILC_FSM_CALL(silc_skr_find(ske->repository,
2182 silc_fsm_get_schedule(fsm), find,
2183 silc_ske_skr_callback, ske));
2185 /* Verify from application */
2186 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2187 ske->callbacks->context,
2188 silc_ske_pk_verified, NULL));
2194 /** Generate KE2 payload */
2195 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2196 return SILC_FSM_CONTINUE;
2199 /* Phase-4. Generate KE2 payload, verify signature */
2201 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2203 SilcSKE ske = fsm_context;
2204 SilcSKEStatus status;
2205 SilcSKEKEPayload recv_payload;
2209 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2210 return SILC_FSM_CONTINUE;
2213 /* Check result of public key verification */
2214 if (ske->status != SILC_SKE_STATUS_OK) {
2215 /** Public key not verified */
2216 SILC_LOG_DEBUG(("Public key verification failed"));
2217 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2218 return SILC_FSM_CONTINUE;
2221 recv_payload = ske->ke1_payload;
2223 /** Send KE2 packet */
2224 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2226 /* The public key verification was performed only if the Mutual
2227 Authentication flag is set. */
2228 if (ske->start_payload &&
2229 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2230 unsigned char hash[SILC_HASH_MAXLEN];
2231 SilcUInt32 hash_len;
2233 SILC_LOG_DEBUG(("Public key is authentic"));
2235 /* Compute the hash value */
2236 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2237 if (status != SILC_SKE_STATUS_OK) {
2238 /** Error computing hash */
2239 ske->status = status;
2240 silc_fsm_next(fsm, silc_ske_st_responder_error);
2241 return SILC_FSM_CONTINUE;
2244 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2246 /* Verify signature */
2247 SILC_FSM_CALL(ske->key_op =
2248 silc_pkcs_verify(ske->prop->public_key,
2249 recv_payload->sign_data,
2250 recv_payload->sign_len,
2251 hash, hash_len, NULL,
2252 silc_ske_verify_cb, ske));
2256 return SILC_FSM_CONTINUE;
2259 /* Phase-5. Send KE2 payload */
2261 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2263 SilcSKE ske = fsm_context;
2264 SilcSKEStatus status;
2265 unsigned char hash[SILC_HASH_MAXLEN], *pk;
2266 SilcUInt32 hash_len, pk_len;
2268 SilcSKEKEPayload send_payload;
2270 SILC_LOG_DEBUG(("Start"));
2272 /* Create the random number x, 1 < x < q. */
2273 x = silc_calloc(1, sizeof(*x));
2276 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2277 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2279 if (status != SILC_SKE_STATUS_OK) {
2280 /** Error generating random number */
2283 ske->status = status;
2284 silc_fsm_next(fsm, silc_ske_st_responder_error);
2285 return SILC_FSM_CONTINUE;
2288 /* Save the results for later processing */
2289 send_payload = silc_calloc(1, sizeof(*send_payload));
2291 ske->ke2_payload = send_payload;
2293 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2295 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2296 silc_mp_init(&send_payload->x);
2297 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2298 &ske->prop->group->group);
2300 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2302 /* Compute the shared secret key */
2303 KEY = silc_calloc(1, sizeof(*KEY));
2305 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2306 &ske->prop->group->group);
2309 if (ske->public_key && ske->private_key) {
2310 SILC_LOG_DEBUG(("Getting public key"));
2312 /* Get the public key */
2313 pk = silc_pkcs_public_key_encode(NULL, ske->public_key, &pk_len);
2315 /** Error encoding public key */
2316 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2317 silc_fsm_next(fsm, silc_ske_st_responder_error);
2318 return SILC_FSM_CONTINUE;
2320 ske->ke2_payload->pk_data = pk;
2321 ske->ke2_payload->pk_len = pk_len;
2324 SILC_LOG_DEBUG(("Computing HASH value"));
2326 /* Compute the hash value */
2327 memset(hash, 0, sizeof(hash));
2328 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2329 if (status != SILC_SKE_STATUS_OK) {
2330 /** Error computing hash */
2331 ske->status = status;
2332 silc_fsm_next(fsm, silc_ske_st_responder_error);
2333 return SILC_FSM_CONTINUE;
2335 ske->hash = silc_memdup(hash, hash_len);
2336 ske->hash_len = hash_len;
2338 /** Send KE2 packet */
2339 silc_fsm_next(fsm, silc_ske_st_responder_phase5_send);
2341 if (ske->public_key && ske->private_key) {
2342 SILC_LOG_DEBUG(("Signing HASH value"));
2344 /* Sign the hash value */
2345 SILC_FSM_CALL(ske->key_op =
2346 silc_pkcs_sign(ske->private_key, hash, hash_len, FALSE,
2348 silc_ske_responder_sign_cb, ske));
2352 return SILC_FSM_CONTINUE;
2355 /* Send KE2 packet */
2357 SILC_FSM_STATE(silc_ske_st_responder_phase5_send)
2359 SilcSKE ske = fsm_context;
2360 SilcSKEStatus status;
2361 SilcBuffer payload_buf;
2363 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2365 /* Encode the Key Exchange Payload */
2366 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2368 if (status != SILC_SKE_STATUS_OK) {
2369 /** Error encoding KE payload */
2370 ske->status = status;
2371 silc_fsm_next(fsm, silc_ske_st_responder_error);
2372 return SILC_FSM_CONTINUE;
2375 /* Send the packet. */
2376 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2377 payload_buf->data, silc_buffer_len(payload_buf))) {
2378 SILC_LOG_DEBUG(("Error sending packet"));
2379 ske->status = SILC_SKE_STATUS_ERROR;
2380 silc_fsm_next(fsm, silc_ske_st_responder_error);
2381 return SILC_FSM_CONTINUE;
2384 silc_buffer_free(payload_buf);
2386 /* In case we are doing rekey move to finish it. */
2389 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2390 return SILC_FSM_CONTINUE;
2393 /** Waiting completion */
2394 silc_fsm_next(fsm, silc_ske_st_responder_end);
2395 return SILC_FSM_WAIT;
2398 /* Protocol completed */
2400 SILC_FSM_STATE(silc_ske_st_responder_end)
2402 SilcSKE ske = fsm_context;
2403 unsigned char tmp[4];
2404 SilcUInt32 hash_len, key_len, block_len;
2406 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2407 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2408 silc_ske_install_retransmission(ske);
2409 silc_packet_free(ske->packet);
2411 return SILC_FSM_WAIT;
2413 silc_packet_free(ske->packet);
2416 /* Process key material */
2417 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2418 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2419 hash_len = silc_hash_len(ske->prop->hash);
2420 ske->keymat = silc_ske_process_key_material(ske, block_len,
2424 /** Error processing key material */
2425 ske->status = SILC_SKE_STATUS_ERROR;
2426 silc_fsm_next(fsm, silc_ske_st_responder_error);
2427 return SILC_FSM_CONTINUE;
2430 /* Send SUCCESS packet */
2431 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2432 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2434 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2435 silc_schedule_task_del_by_context(ske->schedule, ske);
2437 /* Call completion */
2438 silc_ske_completion(ske);
2440 return SILC_FSM_FINISH;
2443 /* Aborted by application */
2445 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2447 SilcSKE ske = fsm_context;
2448 unsigned char tmp[4];
2450 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2452 /* Send FAILURE packet */
2453 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2454 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2456 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2457 silc_schedule_task_del_by_context(ske->schedule, ske);
2459 /* Call completion */
2460 silc_ske_completion(ske);
2462 return SILC_FSM_FINISH;
2465 /* Failure received from remote */
2467 SILC_FSM_STATE(silc_ske_st_responder_failure)
2469 SilcSKE ske = fsm_context;
2470 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2472 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2474 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2475 SILC_GET32_MSB(error, ske->packet->buffer.data);
2476 ske->status = error;
2477 silc_packet_free(ske->packet);
2481 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2482 silc_schedule_task_del_by_context(ske->schedule, ske);
2484 /* Call completion */
2485 silc_ske_completion(ske);
2487 return SILC_FSM_FINISH;
2490 /* Error occurred */
2492 SILC_FSM_STATE(silc_ske_st_responder_error)
2494 SilcSKE ske = fsm_context;
2495 unsigned char tmp[4];
2497 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2498 ske->status, silc_ske_map_status(ske->status)));
2500 /* Send FAILURE packet */
2501 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2502 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2503 SILC_PUT32_MSB(ske->status, tmp);
2504 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2506 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2507 silc_schedule_task_del_by_context(ske->schedule, ske);
2509 /* Call completion */
2510 silc_ske_completion(ske);
2512 return SILC_FSM_FINISH;
2515 /* Starts the protocol as responder. */
2517 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2518 SilcPacketStream stream,
2519 SilcSKEParams params)
2521 SILC_LOG_DEBUG(("Start SKE as responder"));
2523 if (!ske || !stream || !params || !params->version)
2526 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2529 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2532 ske->responder = TRUE;
2533 ske->flags = params->flags;
2534 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2535 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2536 ske->session_port = params->session_port;
2537 ske->version = strdup(params->version);
2540 ske->running = TRUE;
2542 /* Link to packet stream to get key exchange packets */
2543 ske->stream = stream;
2544 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2545 SILC_PACKET_KEY_EXCHANGE,
2546 SILC_PACKET_KEY_EXCHANGE_1,
2547 SILC_PACKET_SUCCESS,
2548 SILC_PACKET_FAILURE, -1);
2550 /* Start SKE as responder */
2551 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2556 /***************************** Initiator Rekey ******************************/
2560 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2562 SilcSKE ske = fsm_context;
2565 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2569 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2570 return SILC_FSM_CONTINUE;
2573 /* Add rekey exchange timeout */
2574 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2577 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2580 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2581 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2582 return SILC_FSM_CONTINUE;
2585 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2586 /** Cannot allocate hash */
2587 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2588 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2589 return SILC_FSM_CONTINUE;
2592 /* Send REKEY packet to start rekey protocol */
2593 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2594 /** Error sending packet */
2595 SILC_LOG_DEBUG(("Error sending packet"));
2596 ske->status = SILC_SKE_STATUS_ERROR;
2597 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2598 return SILC_FSM_CONTINUE;
2601 /* If doing rekey without PFS, move directly to the end of the protocol. */
2602 if (!ske->rekey->pfs) {
2603 /** Rekey without PFS */
2604 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2605 return SILC_FSM_CONTINUE;
2608 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2610 if (status != SILC_SKE_STATUS_OK) {
2611 /** Unknown group */
2612 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2613 return SILC_FSM_CONTINUE;
2616 /** Rekey with PFS */
2617 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2618 return SILC_FSM_CONTINUE;
2621 /* Sends REKEY_DONE packet to finish the protocol. */
2623 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2625 SilcSKE ske = fsm_context;
2626 SilcCipher send_key;
2629 SilcUInt32 key_len, block_len, hash_len, x_len;
2630 unsigned char *pfsbuf;
2632 SILC_LOG_DEBUG(("Start"));
2634 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2635 key_len = silc_cipher_get_key_len(send_key);
2636 block_len = silc_cipher_get_block_len(send_key);
2637 hash = ske->prop->hash;
2638 hash_len = silc_hash_len(hash);
2640 /* Process key material */
2641 if (ske->rekey->pfs) {
2643 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2645 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2648 memset(pfsbuf, 0, x_len);
2654 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2655 ske->rekey->enc_key_len / 8,
2661 SILC_LOG_ERROR(("Error processing key material"));
2662 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2663 return SILC_FSM_CONTINUE;
2666 ske->prop->cipher = send_key;
2667 ske->prop->hmac = hmac_send;
2669 /* Get sending keys */
2670 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2671 &hmac_send, NULL, NULL)) {
2672 /** Cannot get keys */
2673 ske->status = SILC_SKE_STATUS_ERROR;
2674 ske->prop->cipher = NULL;
2675 ske->prop->hmac = NULL;
2676 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2677 return SILC_FSM_CONTINUE;
2680 ske->prop->cipher = NULL;
2681 ske->prop->hmac = NULL;
2683 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2684 packet sent after this call will be protected with the new keys. */
2685 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2687 /** Cannot set keys */
2688 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2689 ske->status = SILC_SKE_STATUS_ERROR;
2690 silc_cipher_free(send_key);
2691 silc_hmac_free(hmac_send);
2692 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2693 return SILC_FSM_CONTINUE;
2696 /** Wait for REKEY_DONE */
2697 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2698 return SILC_FSM_WAIT;
2701 /* Rekey protocol end */
2703 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2705 SilcSKE ske = fsm_context;
2706 SilcCipher receive_key;
2707 SilcHmac hmac_receive;
2708 SilcSKERekeyMaterial rekey;
2710 SILC_LOG_DEBUG(("Start"));
2712 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2713 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2714 silc_packet_free(ske->packet);
2716 return SILC_FSM_WAIT;
2719 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2720 ske->prop->cipher = receive_key;
2721 ske->prop->hmac = hmac_receive;
2723 /* Get receiving keys */
2724 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2725 NULL, &hmac_receive, NULL)) {
2726 /** Cannot get keys */
2727 ske->status = SILC_SKE_STATUS_ERROR;
2728 ske->prop->cipher = NULL;
2729 ske->prop->hmac = NULL;
2730 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2731 return SILC_FSM_CONTINUE;
2734 /* Set new receiving keys into use. All packets received after this will
2735 be decrypted with the new keys. */
2736 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2737 hmac_receive, FALSE)) {
2738 /** Cannot set keys */
2739 SILC_LOG_DEBUG(("Cannot set new keys"));
2740 ske->status = SILC_SKE_STATUS_ERROR;
2741 silc_cipher_free(receive_key);
2742 silc_hmac_free(hmac_receive);
2743 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2744 return SILC_FSM_CONTINUE;
2747 SILC_LOG_DEBUG(("Rekey completed successfully"));
2749 /* Generate new rekey material */
2750 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2753 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2754 ske->prop->cipher = NULL;
2755 ske->prop->hmac = NULL;
2756 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2757 return SILC_FSM_CONTINUE;
2759 rekey->pfs = ske->rekey->pfs;
2762 ske->prop->cipher = NULL;
2763 ske->prop->hmac = NULL;
2764 silc_packet_free(ske->packet);
2766 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2767 silc_schedule_task_del_by_context(ske->schedule, ske);
2769 /* Call completion */
2770 silc_ske_completion(ske);
2772 return SILC_FSM_FINISH;
2775 /* Starts rekey protocol as initiator */
2778 silc_ske_rekey_initiator(SilcSKE ske,
2779 SilcPacketStream stream,
2780 SilcSKERekeyMaterial rekey)
2782 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2784 if (!ske || !stream || !rekey) {
2785 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2790 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2793 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2797 ske->responder = FALSE;
2798 ske->running = TRUE;
2799 ske->rekeying = TRUE;
2801 /* Link to packet stream to get key exchange packets */
2802 ske->stream = stream;
2803 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2805 SILC_PACKET_REKEY_DONE,
2806 SILC_PACKET_KEY_EXCHANGE_2,
2807 SILC_PACKET_SUCCESS,
2808 SILC_PACKET_FAILURE, -1);
2810 /* Start SKE rekey as initiator */
2811 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2816 /***************************** Responder Rekey ******************************/
2818 /* Wait for initiator's packet */
2820 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2822 SilcSKE ske = fsm_context;
2824 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2828 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2829 return SILC_FSM_CONTINUE;
2832 /* Add rekey exchange timeout */
2833 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2836 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2838 /* If REKEY packet already received process it directly */
2839 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2840 return SILC_FSM_CONTINUE;
2842 /* Wait for REKEY */
2843 return SILC_FSM_WAIT;
2846 /* Process initiator's REKEY packet */
2848 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2850 SilcSKE ske = fsm_context;
2851 SilcSKEStatus status;
2853 SILC_LOG_DEBUG(("Start"));
2855 if (ske->packet->type != SILC_PACKET_REKEY) {
2856 ske->status = SILC_SKE_STATUS_ERROR;
2857 silc_packet_free(ske->packet);
2859 silc_fsm_next(fsm, silc_ske_st_responder_error);
2860 return SILC_FSM_CONTINUE;
2863 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2866 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2867 silc_fsm_next(fsm, silc_ske_st_responder_error);
2868 return SILC_FSM_CONTINUE;
2871 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2872 /** Cannot allocate hash */
2873 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2874 silc_fsm_next(fsm, silc_ske_st_responder_error);
2875 return SILC_FSM_CONTINUE;
2878 /* If doing rekey without PFS, move directly to the end of the protocol. */
2879 if (!ske->rekey->pfs) {
2880 /** Rekey without PFS */
2881 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2882 return SILC_FSM_CONTINUE;
2885 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2887 if (status != SILC_SKE_STATUS_OK) {
2888 /** Unknown group */
2889 silc_fsm_next(fsm, silc_ske_st_responder_error);
2890 return SILC_FSM_CONTINUE;
2893 /** Rekey with PFS */
2894 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2895 return SILC_FSM_WAIT;
2898 /* Sends REKEY_DONE packet to finish the protocol. */
2900 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2902 SilcSKE ske = fsm_context;
2903 SilcCipher send_key;
2906 SilcUInt32 key_len, block_len, hash_len, x_len;
2907 unsigned char *pfsbuf;
2909 SILC_LOG_DEBUG(("Start"));
2911 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2912 key_len = silc_cipher_get_key_len(send_key);
2913 block_len = silc_cipher_get_block_len(send_key);
2914 hash = ske->prop->hash;
2915 hash_len = silc_hash_len(hash);
2917 /* Process key material */
2918 if (ske->rekey->pfs) {
2920 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2922 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2925 memset(pfsbuf, 0, x_len);
2931 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2932 ske->rekey->enc_key_len / 8,
2938 SILC_LOG_ERROR(("Error processing key material"));
2939 silc_fsm_next(fsm, silc_ske_st_responder_error);
2940 return SILC_FSM_CONTINUE;
2943 ske->prop->cipher = send_key;
2944 ske->prop->hmac = hmac_send;
2946 /* Get sending keys */
2947 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2948 &hmac_send, NULL, NULL)) {
2949 /** Cannot get keys */
2950 ske->status = SILC_SKE_STATUS_ERROR;
2951 ske->prop->cipher = NULL;
2952 ske->prop->hmac = NULL;
2953 silc_fsm_next(fsm, silc_ske_st_responder_error);
2954 return SILC_FSM_CONTINUE;
2957 ske->prop->cipher = NULL;
2958 ske->prop->hmac = NULL;
2960 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2961 packet sent after this call will be protected with the new keys. */
2962 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2964 /** Cannot set keys */
2965 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2966 ske->status = SILC_SKE_STATUS_ERROR;
2967 silc_cipher_free(send_key);
2968 silc_hmac_free(hmac_send);
2969 silc_fsm_next(fsm, silc_ske_st_responder_error);
2970 return SILC_FSM_CONTINUE;
2973 /** Wait for REKEY_DONE */
2974 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2975 return SILC_FSM_WAIT;
2978 /* Rekey protocol end */
2980 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2982 SilcSKE ske = fsm_context;
2983 SilcCipher receive_key;
2984 SilcHmac hmac_receive;
2985 SilcSKERekeyMaterial rekey;
2987 SILC_LOG_DEBUG(("Start"));
2989 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2990 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2991 silc_packet_free(ske->packet);
2993 return SILC_FSM_WAIT;
2996 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2997 ske->prop->cipher = receive_key;
2998 ske->prop->hmac = hmac_receive;
3000 /* Get receiving keys */
3001 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
3002 NULL, &hmac_receive, NULL)) {
3003 /** Cannot get keys */
3004 ske->status = SILC_SKE_STATUS_ERROR;
3005 ske->prop->cipher = NULL;
3006 ske->prop->hmac = NULL;
3007 silc_fsm_next(fsm, silc_ske_st_responder_error);
3008 return SILC_FSM_CONTINUE;
3011 /* Set new receiving keys into use. All packets received after this will
3012 be decrypted with the new keys. */
3013 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3014 hmac_receive, FALSE)) {
3015 /** Cannot set keys */
3016 SILC_LOG_DEBUG(("Cannot set new keys"));
3017 ske->status = SILC_SKE_STATUS_ERROR;
3018 ske->prop->cipher = NULL;
3019 ske->prop->hmac = NULL;
3020 silc_cipher_free(receive_key);
3021 silc_hmac_free(hmac_receive);
3022 silc_fsm_next(fsm, silc_ske_st_responder_error);
3023 return SILC_FSM_CONTINUE;
3026 SILC_LOG_DEBUG(("Rekey completed successfully"));
3028 /* Generate new rekey material */
3029 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3032 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3033 ske->prop->cipher = NULL;
3034 ske->prop->hmac = NULL;
3035 silc_fsm_next(fsm, silc_ske_st_responder_error);
3036 return SILC_FSM_CONTINUE;
3038 rekey->pfs = ske->rekey->pfs;
3041 ske->prop->cipher = NULL;
3042 ske->prop->hmac = NULL;
3043 silc_packet_free(ske->packet);
3045 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3046 silc_schedule_task_del_by_context(ske->schedule, ske);
3048 /* Call completion */
3049 silc_ske_completion(ske);
3051 return SILC_FSM_FINISH;
3054 /* Starts rekey protocol as responder */
3057 silc_ske_rekey_responder(SilcSKE ske,
3058 SilcPacketStream stream,
3059 SilcSKERekeyMaterial rekey,
3062 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3064 if (!ske || !stream || !rekey)
3067 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3070 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3074 ske->responder = TRUE;
3075 ske->running = TRUE;
3076 ske->rekeying = TRUE;
3077 ske->packet = packet;
3079 /* Link to packet stream to get key exchange packets */
3080 ske->stream = stream;
3081 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3083 SILC_PACKET_REKEY_DONE,
3084 SILC_PACKET_KEY_EXCHANGE_1,
3085 SILC_PACKET_SUCCESS,
3086 SILC_PACKET_FAILURE, -1);
3088 /* Start SKE rekey as responder */
3089 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3094 /* Processes the provided key material `data' as the SILC protocol
3095 specification defines. */
3098 silc_ske_process_key_material_data(unsigned char *data,
3099 SilcUInt32 data_len,
3100 SilcUInt32 req_iv_len,
3101 SilcUInt32 req_enc_key_len,
3102 SilcUInt32 req_hmac_key_len,
3106 unsigned char hashd[SILC_HASH_MAXLEN];
3107 SilcUInt32 hash_len = req_hmac_key_len;
3108 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3109 SilcSKEKeyMaterial key;
3111 SILC_LOG_DEBUG(("Start"));
3113 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3116 key = silc_calloc(1, sizeof(*key));
3120 buf = silc_buffer_alloc_size(1 + data_len);
3123 silc_buffer_format(buf,
3124 SILC_STR_UI_CHAR(0),
3125 SILC_STR_DATA(data, data_len),
3129 memset(hashd, 0, sizeof(hashd));
3131 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3132 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3133 memcpy(key->send_iv, hashd, req_iv_len);
3134 memset(hashd, 0, sizeof(hashd));
3136 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3137 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3138 memcpy(key->receive_iv, hashd, req_iv_len);
3139 key->iv_len = req_iv_len;
3141 /* Take the encryption keys. If requested key size is more than
3142 the size of hash length we will distribute more key material
3143 as protocol defines. */
3145 if (enc_key_len > hash_len) {
3147 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3148 k3[SILC_HASH_MAXLEN];
3149 unsigned char *dtmp;
3152 if (enc_key_len > (3 * hash_len))
3155 /* Take first round */
3156 memset(k1, 0, sizeof(k1));
3157 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3159 /* Take second round */
3160 dist = silc_buffer_alloc_size(data_len + hash_len);
3163 silc_buffer_format(dist,
3164 SILC_STR_DATA(data, data_len),
3165 SILC_STR_DATA(k1, hash_len),
3167 memset(k2, 0, sizeof(k2));
3168 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3170 /* Take third round */
3171 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3172 silc_buffer_pull_tail(dist, hash_len);
3173 silc_buffer_pull(dist, data_len + hash_len);
3174 silc_buffer_format(dist,
3175 SILC_STR_DATA(k2, hash_len),
3177 silc_buffer_push(dist, data_len + hash_len);
3178 memset(k3, 0, sizeof(k3));
3179 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3181 /* Then, save the keys */
3182 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3183 memcpy(dtmp, k1, hash_len);
3184 memcpy(dtmp + hash_len, k2, hash_len);
3185 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3187 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3188 memcpy(key->send_enc_key, dtmp, enc_key_len);
3189 key->enc_key_len = req_enc_key_len;
3191 memset(dtmp, 0, (3 * hash_len));
3192 memset(k1, 0, sizeof(k1));
3193 memset(k2, 0, sizeof(k2));
3194 memset(k3, 0, sizeof(k3));
3196 silc_buffer_clear(dist);
3197 silc_buffer_free(dist);
3199 /* Take normal hash as key */
3200 memset(hashd, 0, sizeof(hashd));
3201 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3202 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3203 memcpy(key->send_enc_key, hashd, enc_key_len);
3204 key->enc_key_len = req_enc_key_len;
3208 if (enc_key_len > hash_len) {
3210 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3211 k3[SILC_HASH_MAXLEN];
3212 unsigned char *dtmp;
3215 if (enc_key_len > (3 * hash_len))
3218 /* Take first round */
3219 memset(k1, 0, sizeof(k1));
3220 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3222 /* Take second round */
3223 dist = silc_buffer_alloc_size(data_len + hash_len);
3226 silc_buffer_format(dist,
3227 SILC_STR_DATA(data, data_len),
3228 SILC_STR_DATA(k1, hash_len),
3230 memset(k2, 0, sizeof(k2));
3231 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3233 /* Take third round */
3234 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3235 silc_buffer_pull_tail(dist, hash_len);
3236 silc_buffer_pull(dist, data_len + hash_len);
3237 silc_buffer_format(dist,
3238 SILC_STR_DATA(k2, hash_len),
3240 silc_buffer_push(dist, data_len + hash_len);
3241 memset(k3, 0, sizeof(k3));
3242 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3244 /* Then, save the keys */
3245 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3246 memcpy(dtmp, k1, hash_len);
3247 memcpy(dtmp + hash_len, k2, hash_len);
3248 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3250 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3251 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3252 key->enc_key_len = req_enc_key_len;
3254 memset(dtmp, 0, (3 * hash_len));
3255 memset(k1, 0, sizeof(k1));
3256 memset(k2, 0, sizeof(k2));
3257 memset(k3, 0, sizeof(k3));
3259 silc_buffer_clear(dist);
3260 silc_buffer_free(dist);
3262 /* Take normal hash as key */
3263 memset(hashd, 0, sizeof(hashd));
3264 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3265 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3266 memcpy(key->receive_enc_key, hashd, enc_key_len);
3267 key->enc_key_len = req_enc_key_len;
3270 /* Take HMAC keys */
3271 memset(hashd, 0, sizeof(hashd));
3273 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3274 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3275 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3276 memset(hashd, 0, sizeof(hashd));
3278 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3279 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3280 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3281 key->hmac_key_len = req_hmac_key_len;
3282 memset(hashd, 0, sizeof(hashd));
3284 silc_buffer_clear(buf);
3285 silc_buffer_free(buf);
3287 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3292 /* Processes negotiated key material as protocol specifies. This returns
3293 the actual keys to be used in the SILC. */
3296 silc_ske_process_key_material(SilcSKE ske,
3297 SilcUInt32 req_iv_len,
3298 SilcUInt32 req_enc_key_len,
3299 SilcUInt32 req_hmac_key_len,
3300 SilcSKERekeyMaterial *rekey)
3303 unsigned char *tmpbuf;
3305 SilcSKEKeyMaterial key;
3307 /* Encode KEY to binary data */
3308 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3310 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3313 silc_buffer_format(buf,
3314 SILC_STR_DATA(tmpbuf, klen),
3315 SILC_STR_DATA(ske->hash, ske->hash_len),
3318 /* Process the key material */
3319 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3320 req_iv_len, req_enc_key_len,
3324 memset(tmpbuf, 0, klen);
3326 silc_buffer_clear(buf);
3327 silc_buffer_free(buf);
3330 *rekey = silc_ske_make_rekey_material(ske, key);
3338 /* Free key material structure */
3340 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3346 silc_free(key->send_iv);
3347 if (key->receive_iv)
3348 silc_free(key->receive_iv);
3349 if (key->send_enc_key) {
3350 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3351 silc_free(key->send_enc_key);
3353 if (key->receive_enc_key) {
3354 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3355 silc_free(key->receive_enc_key);
3357 if (key->send_hmac_key) {
3358 memset(key->send_hmac_key, 0, key->hmac_key_len);
3359 silc_free(key->send_hmac_key);
3361 if (key->receive_hmac_key) {
3362 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3363 silc_free(key->receive_hmac_key);
3368 /* Free rekey material */
3370 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3374 if (rekey->send_enc_key) {
3375 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3376 silc_free(rekey->send_enc_key);
3378 silc_free(rekey->hash);
3382 /* Set keys into use */
3384 SilcBool silc_ske_set_keys(SilcSKE ske,
3385 SilcSKEKeyMaterial keymat,
3386 SilcSKESecurityProperties prop,
3387 SilcCipher *ret_send_key,
3388 SilcCipher *ret_receive_key,
3389 SilcHmac *ret_hmac_send,
3390 SilcHmac *ret_hmac_receive,
3393 unsigned char iv[32];
3394 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3396 /* Allocate ciphers to be used in the communication */
3398 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3402 if (ret_receive_key) {
3403 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3408 /* Allocate HMACs */
3409 if (ret_hmac_send) {
3410 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3414 if (ret_hmac_receive) {
3415 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3420 /* Set key material */
3421 memset(iv, 0, sizeof(iv));
3422 if (ske->responder) {
3424 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3425 keymat->enc_key_len, TRUE);
3427 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3428 memcpy(iv, ske->hash, 4);
3429 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3430 silc_cipher_set_iv(*ret_send_key, iv);
3432 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3435 if (ret_receive_key) {
3436 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3437 keymat->enc_key_len, FALSE);
3439 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3440 memcpy(iv, ske->hash, 4);
3441 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3442 silc_cipher_set_iv(*ret_receive_key, iv);
3444 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3448 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3449 keymat->hmac_key_len);
3450 if (ret_hmac_receive)
3451 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3452 keymat->hmac_key_len);
3455 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3456 keymat->enc_key_len, TRUE);
3458 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3459 memcpy(iv, ske->hash, 4);
3460 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3461 silc_cipher_set_iv(*ret_send_key, iv);
3463 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3466 if (ret_receive_key) {
3467 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3468 keymat->enc_key_len, FALSE);
3470 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3471 memcpy(iv, ske->hash, 4);
3472 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3473 silc_cipher_set_iv(*ret_receive_key, iv);
3475 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3479 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3480 keymat->hmac_key_len);
3481 if (ret_hmac_receive)
3482 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3483 keymat->hmac_key_len);
3488 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3495 const char *silc_ske_status_string[] =
3499 "Unexpected error occurred",
3500 "Bad payload in packet",
3501 "Unsupported group",
3502 "Unsupported cipher",
3504 "Unsupported hash function",
3506 "Unsupported public key (or certificate)",
3507 "Incorrect signature",
3508 "Bad or unsupported version",
3512 "Remote did not provide public key",
3513 "Bad reserved field in packet",
3514 "Bad payload length in packet",
3515 "Error computing signature",
3516 "System out of memory",
3517 "Key exchange timeout",
3522 /* Maps status to readable string and returns the string. If string is not
3523 found and empty character string ("") is returned. */
3525 const char *silc_ske_map_status(SilcSKEStatus status)
3529 for (i = 0; silc_ske_status_string[i]; i++)
3531 return silc_ske_status_string[i];
3536 /* Parses remote host's version string. */
3538 SilcBool silc_ske_parse_version(SilcSKE ske,
3539 SilcUInt32 *protocol_version,
3540 char **protocol_version_string,
3541 SilcUInt32 *software_version,
3542 char **software_version_string,
3543 char **vendor_version)
3545 return silc_parse_version_string(ske->remote_version,
3547 protocol_version_string,
3549 software_version_string,
3553 /* Get security properties */
3555 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3560 /* Get key material */
3562 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)