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);
665 /* Creates a hash value HASH as defined in the SKE protocol. If the
666 `initiator' is TRUE then this function is used to create the HASH_i
667 hash value defined in the protocol. If it is FALSE then this is used
668 to create the HASH value defined by the protocol. */
670 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
671 unsigned char *return_hash,
672 SilcUInt32 *return_hash_len,
675 SilcSKEStatus status = SILC_SKE_STATUS_OK;
677 unsigned char *e, *f, *KEY, *s_data;
678 SilcUInt32 e_len, f_len, KEY_len, s_len;
681 SILC_LOG_DEBUG(("Start"));
683 if (initiator == FALSE) {
684 s_data = (ske->start_payload_copy ?
685 silc_buffer_data(ske->start_payload_copy) : NULL);
686 s_len = (ske->start_payload_copy ?
687 silc_buffer_len(ske->start_payload_copy) : 0);
688 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
689 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
690 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
692 /* Format the buffer used to compute the hash value */
693 buf = silc_buffer_alloc_size(s_len +
694 ske->ke2_payload->pk_len +
695 ske->ke1_payload->pk_len +
696 e_len + f_len + KEY_len);
698 return SILC_SKE_STATUS_OUT_OF_MEMORY;
700 /* Initiator is not required to send its public key */
701 if (!ske->ke1_payload->pk_data) {
703 silc_buffer_format(buf,
704 SILC_STR_DATA(s_data, s_len),
705 SILC_STR_DATA(ske->ke2_payload->pk_data,
706 ske->ke2_payload->pk_len),
707 SILC_STR_DATA(e, e_len),
708 SILC_STR_DATA(f, f_len),
709 SILC_STR_DATA(KEY, KEY_len),
713 silc_buffer_format(buf,
714 SILC_STR_DATA(s_data, s_len),
715 SILC_STR_DATA(ske->ke2_payload->pk_data,
716 ske->ke2_payload->pk_len),
717 SILC_STR_DATA(ske->ke1_payload->pk_data,
718 ske->ke1_payload->pk_len),
719 SILC_STR_DATA(e, e_len),
720 SILC_STR_DATA(f, f_len),
721 SILC_STR_DATA(KEY, KEY_len),
725 silc_buffer_free(buf);
728 memset(KEY, 0, KEY_len);
732 return SILC_SKE_STATUS_ERROR;
737 memset(KEY, 0, KEY_len);
742 s_data = (ske->start_payload_copy ?
743 silc_buffer_data(ske->start_payload_copy) : NULL);
744 s_len = (ske->start_payload_copy ?
745 silc_buffer_len(ske->start_payload_copy) : 0);
746 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
748 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
750 return SILC_SKE_STATUS_OUT_OF_MEMORY;
752 /* Format the buffer used to compute the hash value */
754 silc_buffer_format(buf,
755 SILC_STR_DATA(s_data, s_len),
756 SILC_STR_DATA(ske->ke1_payload->pk_data,
757 ske->ke1_payload->pk_len),
758 SILC_STR_DATA(e, e_len),
761 silc_buffer_free(buf);
764 return SILC_SKE_STATUS_ERROR;
767 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
774 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
776 *return_hash_len = silc_hash_len(ske->prop->hash);
778 if (initiator == FALSE) {
779 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
781 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
784 silc_buffer_free(buf);
789 /* Generate rekey material */
791 static SilcSKERekeyMaterial
792 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
794 SilcSKERekeyMaterial rekey;
797 /* Create rekey material */
798 rekey = silc_calloc(1, sizeof(*rekey));
803 if (ske->prop->group)
804 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
805 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
806 hash = silc_hash_get_name(ske->prop->hash);
807 rekey->hash = silc_memdup(hash, strlen(hash));
812 if (rekey->pfs == FALSE) {
813 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
814 keymat->enc_key_len / 8);
815 if (!rekey->send_enc_key) {
819 rekey->enc_key_len = keymat->enc_key_len;
825 /* Assembles security properties */
827 static SilcSKEStartPayload
828 silc_ske_assemble_security_properties(SilcSKE ske,
829 SilcSKESecurityPropertyFlag flags,
832 SilcSKEStartPayload rp;
835 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
837 rp = silc_calloc(1, sizeof(*rp));
840 rp->flags = (unsigned char)flags;
842 /* Set random cookie */
843 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
844 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
845 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
846 rp->cookie_len = SILC_SKE_COOKIE_LEN;
848 /* In case IV included flag and session port is set the first 16-bits of
849 cookie will include our session port. */
850 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
851 SILC_PUT16_MSB(ske->session_port, rp->cookie);
854 rp->version = strdup(version);
855 rp->version_len = strlen(version);
857 /* Get supported Key Exhange groups */
858 rp->ke_grp_list = silc_ske_get_supported_groups();
859 rp->ke_grp_len = strlen(rp->ke_grp_list);
861 /* Get supported PKCS algorithms */
862 rp->pkcs_alg_list = silc_pkcs_get_supported();
863 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
865 /* Get supported encryption algorithms */
866 rp->enc_alg_list = silc_cipher_get_supported(TRUE);
867 rp->enc_alg_len = strlen(rp->enc_alg_list);
869 /* Get supported hash algorithms */
870 rp->hash_alg_list = silc_hash_get_supported();
871 rp->hash_alg_len = strlen(rp->hash_alg_list);
873 /* Get supported HMACs */
874 rp->hmac_alg_list = silc_hmac_get_supported();
875 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
878 /* Get supported compression algorithms */
879 rp->comp_alg_list = strdup("none");
880 rp->comp_alg_len = strlen("none");
882 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
883 2 + rp->version_len +
884 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
885 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
886 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
891 /* Packet retransmission callback. */
893 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
895 SilcSKE ske = context;
897 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
899 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
900 ske->retry_count = 0;
901 ske->retry_timer = SILC_SKE_RETRY_MIN;
902 silc_free(ske->retrans.data);
903 ske->retrans.data = NULL;
904 ske->status = SILC_SKE_STATUS_TIMEOUT;
906 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
908 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
909 silc_fsm_continue_sync(&ske->fsm);
913 SILC_LOG_DEBUG(("Retransmitting packet"));
914 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
915 ske->retrans.data, ske->retrans.data_len);
918 /* Install retransmission timer */
920 static void silc_ske_install_retransmission(SilcSKE ske)
922 if (!silc_packet_stream_is_udp(ske->stream))
925 if (ske->retrans.data) {
926 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
928 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
929 ske, ske->retry_timer, 0);
931 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
932 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
935 /* Sends SILC packet. Handles retransmissions with UDP streams. */
937 static SilcBool silc_ske_packet_send(SilcSKE ske,
939 SilcPacketFlags flags,
940 const unsigned char *data,
945 /* Send the packet */
946 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
948 if (silc_packet_stream_is_udp(ske->stream) &&
949 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
950 silc_free(ske->retrans.data);
951 ske->retrans.type = type;
952 ske->retrans.flags = flags;
953 ske->retrans.data = silc_memdup(data, data_len);
954 ske->retrans.data_len = data_len;
955 silc_ske_install_retransmission(ske);
961 /* Calls completion callback. Completion is called always in this function
962 and must not be called anywhere else. */
964 static void silc_ske_completion(SilcSKE ske)
966 /* Call the completion callback */
967 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
968 if (ske->status != SILC_SKE_STATUS_OK)
969 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
970 ske->callbacks->context);
972 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
973 ske->rekey, ske->callbacks->context);
977 /* SKE FSM destructor. */
979 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
980 void *destructor_context)
982 SilcSKE ske = fsm_context;
983 ske->running = FALSE;
988 /* Key exchange timeout task callback */
990 SILC_TASK_CALLBACK(silc_ske_timeout)
992 SilcSKE ske = context;
994 SILC_LOG_DEBUG(("Timeout"));
997 ske->status = SILC_SKE_STATUS_TIMEOUT;
999 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1001 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1003 silc_fsm_continue_sync(&ske->fsm);
1006 /* Initiator signature callback */
1008 static void silc_ske_initiator_sign_cb(SilcBool success,
1009 const unsigned char *signature,
1010 SilcUInt32 signature_len,
1013 SilcSKE ske = context;
1018 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1019 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1023 ske->ke1_payload->sign_data = silc_memdup(signature, signature_len);
1024 if (ske->ke1_payload->sign_data)
1025 ske->ke1_payload->sign_len = signature_len;
1027 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1030 /* Responder signature callback */
1032 static void silc_ske_responder_sign_cb(SilcBool success,
1033 const unsigned char *signature,
1034 SilcUInt32 signature_len,
1037 SilcSKE ske = context;
1042 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1043 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1047 ske->ke2_payload->sign_data = silc_memdup(signature, signature_len);
1048 if (ske->ke2_payload->sign_data)
1049 ske->ke2_payload->sign_len = signature_len;
1051 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1054 /* Verify callback */
1056 static void silc_ske_verify_cb(SilcBool success, void *context)
1058 SilcSKE ske = context;
1064 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1066 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1067 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1072 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1073 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1075 silc_fsm_next(&ske->fsm, silc_ske_st_responder_error);
1077 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_error);
1078 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1082 SILC_LOG_DEBUG(("Signature is Ok"));
1083 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1086 /******************************* Protocol API *******************************/
1088 /* Allocates new SKE object. */
1090 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1091 SilcSKR repository, SilcPublicKey public_key,
1092 SilcPrivateKey private_key, void *context)
1096 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1098 if (!rng || !schedule)
1102 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1106 ske = silc_calloc(1, sizeof(*ske));
1109 ske->status = SILC_SKE_STATUS_OK;
1111 ske->repository = repository;
1112 ske->user_data = context;
1113 ske->schedule = schedule;
1114 ske->public_key = public_key;
1115 ske->private_key = private_key;
1116 ske->retry_timer = SILC_SKE_RETRY_MIN;
1122 /* Free's SKE object. */
1124 void silc_ske_free(SilcSKE ske)
1126 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1135 /* If already aborted, destroy the session immediately */
1137 ske->status = SILC_SKE_STATUS_ERROR;
1139 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1141 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1142 silc_fsm_continue_sync(&ske->fsm);
1148 if (ske->refcnt > 0)
1151 /* Free start payload */
1152 if (ske->start_payload)
1153 silc_ske_payload_start_free(ske->start_payload);
1155 /* Free KE payload */
1156 if (ske->ke1_payload)
1157 silc_ske_payload_ke_free(ske->ke1_payload);
1158 if (ske->ke2_payload)
1159 silc_ske_payload_ke_free(ske->ke2_payload);
1160 silc_free(ske->remote_version);
1164 if (ske->prop->group)
1165 silc_ske_group_free(ske->prop->group);
1166 if (ske->prop->cipher)
1167 silc_cipher_free(ske->prop->cipher);
1168 if (ske->prop->hash)
1169 silc_hash_free(ske->prop->hash);
1170 if (ske->prop->hmac)
1171 silc_hmac_free(ske->prop->hmac);
1172 if (ske->prop->public_key)
1173 silc_pkcs_public_key_free(ske->prop->public_key);
1174 silc_free(ske->prop);
1177 silc_ske_free_key_material(ske->keymat);
1178 if (ske->start_payload_copy)
1179 silc_buffer_free(ske->start_payload_copy);
1181 silc_mp_uninit(ske->x);
1185 silc_mp_uninit(ske->KEY);
1186 silc_free(ske->KEY);
1188 silc_free(ske->retrans.data);
1189 silc_free(ske->hash);
1190 silc_free(ske->callbacks);
1192 memset(ske, 'F', sizeof(*ske));
1196 /* Return user context */
1198 void *silc_ske_get_context(SilcSKE ske)
1200 return ske->user_data;
1203 /* Sets protocol callbacks */
1205 void silc_ske_set_callbacks(SilcSKE ske,
1206 SilcSKEVerifyCb verify_key,
1207 SilcSKECompletionCb completed,
1211 silc_free(ske->callbacks);
1212 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1213 if (!ske->callbacks)
1215 ske->callbacks->verify_key = verify_key;
1216 ske->callbacks->completed = completed;
1217 ske->callbacks->context = context;
1221 /******************************** Initiator *********************************/
1223 /* Start protocol. Send our proposal */
1225 SILC_FSM_STATE(silc_ske_st_initiator_start)
1227 SilcSKE ske = fsm_context;
1228 SilcBuffer payload_buf;
1231 SILC_LOG_DEBUG(("Start"));
1235 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1236 return SILC_FSM_CONTINUE;
1239 /* Encode the payload */
1240 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1242 if (status != SILC_SKE_STATUS_OK) {
1243 /** Error encoding Start Payload */
1244 ske->status = status;
1245 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1246 return SILC_FSM_CONTINUE;
1249 /* Save the the payload buffer for future use. It is later used to
1250 compute the HASH value. */
1251 ske->start_payload_copy = payload_buf;
1253 /* Send the packet. */
1254 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1255 silc_buffer_data(payload_buf),
1256 silc_buffer_len(payload_buf))) {
1257 /** Error sending packet */
1258 SILC_LOG_DEBUG(("Error sending packet"));
1259 ske->status = SILC_SKE_STATUS_ERROR;
1260 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1261 return SILC_FSM_CONTINUE;
1264 /* Add key exchange timeout */
1265 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1266 ske, ske->timeout, 0);
1268 /** Wait for responder proposal */
1269 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1270 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1271 return SILC_FSM_WAIT;
1274 /* Phase-1. Receives responder's proposal */
1276 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1278 SilcSKE ske = fsm_context;
1279 SilcSKEStatus status;
1280 SilcSKEStartPayload payload;
1281 SilcSKESecurityProperties prop;
1282 SilcSKEDiffieHellmanGroup group = NULL;
1283 SilcBuffer packet_buf = &ske->packet->buffer;
1284 SilcUInt16 remote_port = 0;
1288 SILC_LOG_DEBUG(("Start"));
1290 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1291 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1292 silc_ske_install_retransmission(ske);
1293 silc_packet_free(ske->packet);
1295 return SILC_FSM_WAIT;
1298 /* Decode the payload */
1299 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1300 if (status != SILC_SKE_STATUS_OK) {
1301 /** Error decoding Start Payload */
1302 silc_packet_free(ske->packet);
1304 ske->status = status;
1305 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1306 return SILC_FSM_CONTINUE;
1309 /* Get remote ID and set it to stream */
1310 if (ske->packet->src_id_len) {
1311 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1312 ske->packet->src_id_type,
1313 (ske->packet->src_id_type == SILC_ID_SERVER ?
1314 (void *)&id.u.server_id : (void *)&id.u.client_id),
1315 (ske->packet->src_id_type == SILC_ID_SERVER ?
1316 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1317 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1318 (ske->packet->src_id_type == SILC_ID_SERVER ?
1319 (void *)&id.u.server_id : (void *)&id.u.client_id));
1322 silc_packet_free(ske->packet);
1325 /* Check that the cookie is returned unmodified. In case IV included
1326 flag and session port has been set, the first two bytes of cookie
1327 are the session port and we ignore them in this check. */
1328 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1329 /* Take remote port */
1330 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1333 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1334 SILC_SKE_COOKIE_LEN - coff)) {
1335 /** Invalid cookie */
1336 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1337 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1338 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1339 return SILC_FSM_CONTINUE;
1342 /* Check version string */
1343 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1344 status = silc_ske_check_version(ske);
1345 if (status != SILC_SKE_STATUS_OK) {
1346 /** Version mismatch */
1347 ske->status = status;
1348 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1349 return SILC_FSM_CONTINUE;
1352 /* Free our KE Start Payload context, we don't need it anymore. */
1353 silc_ske_payload_start_free(ske->start_payload);
1354 ske->start_payload = NULL;
1356 /* Take the selected security properties into use while doing
1357 the key exchange. This is used only while doing the key
1359 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1362 prop->flags = payload->flags;
1363 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1364 if (status != SILC_SKE_STATUS_OK)
1367 prop->group = group;
1368 prop->remote_port = remote_port;
1370 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1371 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1374 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1375 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1378 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1379 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1382 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1383 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1387 /* Save remote's KE Start Payload */
1388 ske->start_payload = payload;
1390 /** Send KE Payload */
1391 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1392 return SILC_FSM_CONTINUE;
1396 silc_ske_payload_start_free(payload);
1398 silc_ske_group_free(group);
1400 silc_cipher_free(prop->cipher);
1402 silc_hash_free(prop->hash);
1404 silc_hmac_free(prop->hmac);
1408 if (status == SILC_SKE_STATUS_OK)
1409 status = SILC_SKE_STATUS_ERROR;
1412 ske->status = status;
1413 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1414 return SILC_FSM_CONTINUE;
1417 /* Phase-2. Send KE payload */
1419 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1421 SilcSKE ske = fsm_context;
1422 SilcSKEStatus status;
1424 SilcSKEKEPayload payload;
1427 SILC_LOG_DEBUG(("Start"));
1429 /* Create the random number x, 1 < x < q. */
1430 x = silc_calloc(1, sizeof(*x));
1432 /** Out of memory */
1433 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1434 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1435 return SILC_FSM_CONTINUE;
1439 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1440 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1442 if (status != SILC_SKE_STATUS_OK) {
1443 /** Error generating random number */
1446 ske->status = status;
1447 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1448 return SILC_FSM_CONTINUE;
1451 /* Encode the result to Key Exchange Payload. */
1453 payload = silc_calloc(1, sizeof(*payload));
1455 /** Out of memory */
1458 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1459 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1460 return SILC_FSM_CONTINUE;
1462 ske->ke1_payload = payload;
1464 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1466 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1467 silc_mp_init(&payload->x);
1468 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1469 &ske->prop->group->group);
1472 /* Get public key */
1473 payload->pk_data = silc_pkcs_public_key_encode(NULL, ske->public_key,
1475 if (!payload->pk_data) {
1476 /** Error encoding public key */
1480 silc_mp_uninit(&payload->x);
1482 ske->ke1_payload = NULL;
1483 ske->status = SILC_SKE_STATUS_ERROR;
1484 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1485 return SILC_FSM_CONTINUE;
1487 payload->pk_len = pk_len;
1488 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1490 /** Send KE1 packet */
1491 silc_fsm_next(fsm, silc_ske_st_initiator_phase2_send);
1493 /* Compute signature data if we are doing mutual authentication */
1494 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1495 unsigned char hash[SILC_HASH_MAXLEN];
1496 SilcUInt32 hash_len;
1498 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1499 SILC_LOG_DEBUG(("Computing HASH_i value"));
1501 /* Compute the hash value */
1502 memset(hash, 0, sizeof(hash));
1503 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1505 SILC_LOG_DEBUG(("Signing HASH_i value"));
1507 /* Sign the hash value */
1508 SILC_FSM_CALL(ske->key_op =
1509 silc_pkcs_sign(ske->private_key, hash, hash_len, FALSE,
1510 ske->prop->hash, ske->rng,
1511 silc_ske_initiator_sign_cb, ske));
1515 return SILC_FSM_CONTINUE;
1518 /* Send KE1 packet */
1520 SILC_FSM_STATE(silc_ske_st_initiator_phase2_send)
1522 SilcSKE ske = fsm_context;
1523 SilcSKEStatus status;
1524 SilcBuffer payload_buf;
1525 SilcSKEKEPayload payload;
1527 SILC_LOG_DEBUG(("Start"));
1529 payload = ske->ke1_payload;
1531 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1532 if (status != SILC_SKE_STATUS_OK) {
1533 /** Error encoding KE payload */
1534 silc_mp_uninit(&payload->x);
1535 silc_free(payload->pk_data);
1536 silc_free(payload->sign_data);
1538 ske->ke1_payload = NULL;
1539 ske->status = status;
1540 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1541 return SILC_FSM_CONTINUE;
1544 /* Send the packet. */
1545 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1546 silc_buffer_data(payload_buf),
1547 silc_buffer_len(payload_buf))) {
1548 /** Error sending packet */
1549 SILC_LOG_DEBUG(("Error sending packet"));
1550 ske->status = SILC_SKE_STATUS_ERROR;
1551 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1552 return SILC_FSM_CONTINUE;
1555 silc_buffer_free(payload_buf);
1557 /** Waiting responder's KE payload */
1558 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1559 return SILC_FSM_WAIT;
1562 /* Phase-3. Process responder's KE payload */
1564 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1566 SilcSKE ske = fsm_context;
1567 SilcSKEStatus status;
1568 SilcSKEKEPayload payload;
1570 SilcBuffer packet_buf = &ske->packet->buffer;
1572 SILC_LOG_DEBUG(("Start"));
1574 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1575 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1576 silc_ske_install_retransmission(ske);
1577 silc_packet_free(ske->packet);
1579 return SILC_FSM_WAIT;
1582 /* Decode the payload */
1583 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1584 if (status != SILC_SKE_STATUS_OK) {
1585 /** Error decoding KE payload */
1586 silc_packet_free(ske->packet);
1588 ske->status = status;
1589 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1590 return SILC_FSM_CONTINUE;
1592 silc_packet_free(ske->packet);
1594 ske->ke2_payload = payload;
1596 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1597 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1598 "even though we require it"));
1599 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1603 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1605 /* Compute the shared secret key */
1606 KEY = silc_calloc(1, sizeof(*KEY));
1608 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1611 /* Decode the remote's public key */
1612 if (payload->pk_data &&
1613 !silc_pkcs_public_key_alloc(payload->pk_type,
1614 payload->pk_data, payload->pk_len,
1615 &ske->prop->public_key)) {
1616 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1617 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1621 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1623 SILC_LOG_DEBUG(("Verifying public key"));
1625 /** Waiting public key verification */
1626 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1628 /* If repository is provided, verify the key from there. */
1629 if (ske->repository) {
1632 find = silc_skr_find_alloc();
1634 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1637 silc_skr_find_set_pkcs_type(find,
1638 silc_pkcs_get_type(ske->prop->public_key));
1639 silc_skr_find_set_public_key(find, ske->prop->public_key);
1640 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1642 /* Find key from repository */
1643 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1644 find, silc_ske_skr_callback, ske));
1646 /* Verify from application */
1647 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1648 ske->callbacks->context,
1649 silc_ske_pk_verified, NULL));
1654 /** Process key material */
1655 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1656 return SILC_FSM_CONTINUE;
1659 silc_ske_payload_ke_free(payload);
1660 ske->ke2_payload = NULL;
1662 silc_mp_uninit(ske->KEY);
1663 silc_free(ske->KEY);
1666 if (status == SILC_SKE_STATUS_OK)
1667 return SILC_SKE_STATUS_ERROR;
1670 ske->status = status;
1671 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1672 return SILC_FSM_CONTINUE;
1675 /* Process key material */
1677 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1679 SilcSKE ske = fsm_context;
1680 SilcSKEStatus status;
1681 SilcSKEKEPayload payload;
1682 unsigned char hash[SILC_HASH_MAXLEN];
1683 SilcUInt32 hash_len;
1687 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1688 return SILC_FSM_CONTINUE;
1691 /* Check result of public key verification */
1692 if (ske->status != SILC_SKE_STATUS_OK) {
1693 /** Public key not verified */
1694 SILC_LOG_DEBUG(("Public key verification failed"));
1695 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1696 return SILC_FSM_CONTINUE;
1699 payload = ske->ke2_payload;
1701 /* Compute the HASH value */
1702 SILC_LOG_DEBUG(("Computing HASH value"));
1703 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1704 if (status != SILC_SKE_STATUS_OK)
1706 ske->hash = silc_memdup(hash, hash_len);
1707 ske->hash_len = hash_len;
1710 silc_fsm_next(fsm, silc_ske_st_initiator_phase5);
1712 if (ske->prop->public_key) {
1713 SILC_LOG_DEBUG(("Public key is authentic"));
1714 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1716 /* Verify signature */
1717 SILC_FSM_CALL(ske->key_op =
1718 silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1719 payload->sign_len, hash, hash_len, NULL,
1720 silc_ske_verify_cb, ske));
1724 return SILC_FSM_CONTINUE;
1727 memset(hash, 'F', sizeof(hash));
1728 silc_ske_payload_ke_free(payload);
1729 ske->ke2_payload = NULL;
1731 silc_mp_uninit(ske->KEY);
1732 silc_free(ske->KEY);
1736 memset(ske->hash, 'F', hash_len);
1737 silc_free(ske->hash);
1741 if (status == SILC_SKE_STATUS_OK)
1742 status = SILC_SKE_STATUS_ERROR;
1745 ske->status = status;
1746 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1747 return SILC_FSM_CONTINUE;
1750 /* Process key material */
1752 SILC_FSM_STATE(silc_ske_st_initiator_phase5)
1754 SilcSKE ske = fsm_context;
1755 SilcSKEStatus status;
1756 unsigned char tmp[4];
1757 SilcUInt32 hash_len;
1758 int key_len, block_len;
1760 ske->status = SILC_SKE_STATUS_OK;
1762 /* In case we are doing rekey move to finish it. */
1765 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1766 return SILC_FSM_CONTINUE;
1769 /* Process key material */
1770 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1771 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1772 hash_len = silc_hash_len(ske->prop->hash);
1773 ske->keymat = silc_ske_process_key_material(ske, block_len,
1777 SILC_LOG_ERROR(("Error processing key material"));
1778 status = SILC_SKE_STATUS_ERROR;
1779 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1780 return SILC_FSM_CONTINUE;
1783 /* Send SUCCESS packet */
1784 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, tmp);
1785 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4)) {
1786 /** Error sending packet */
1787 SILC_LOG_DEBUG(("Error sending packet"));
1788 ske->status = SILC_SKE_STATUS_ERROR;
1789 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1790 return SILC_FSM_CONTINUE;
1793 /** Waiting completion */
1794 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1795 return SILC_FSM_WAIT;
1798 /* Protocol completed */
1800 SILC_FSM_STATE(silc_ske_st_initiator_end)
1802 SilcSKE ske = fsm_context;
1804 SILC_LOG_DEBUG(("Start"));
1806 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1807 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1808 silc_ske_install_retransmission(ske);
1809 silc_packet_free(ske->packet);
1811 return SILC_FSM_WAIT;
1814 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1816 silc_packet_free(ske->packet);
1818 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1819 silc_schedule_task_del_by_context(ske->schedule, ske);
1821 /* Call completion */
1822 silc_ske_completion(ske);
1824 return SILC_FSM_FINISH;
1827 /* Aborted by application */
1829 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1831 SilcSKE ske = fsm_context;
1832 unsigned char data[4];
1834 SILC_LOG_DEBUG(("Aborted by caller"));
1836 /* Send FAILURE packet */
1837 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1838 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1840 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1841 silc_schedule_task_del_by_context(ske->schedule, ske);
1843 /* Call completion */
1844 silc_ske_completion(ske);
1846 return SILC_FSM_FINISH;
1849 /* Error occurred. Send error to remote host */
1851 SILC_FSM_STATE(silc_ske_st_initiator_error)
1853 SilcSKE ske = fsm_context;
1854 SilcSKEStatus status;
1855 unsigned char data[4];
1857 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1858 silc_ske_map_status(ske->status), ske->status));
1860 status = ske->status;
1861 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1862 status = SILC_SKE_STATUS_ERROR;
1864 /* Send FAILURE packet */
1865 SILC_PUT32_MSB((SilcUInt32)status, data);
1866 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1868 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1869 silc_schedule_task_del_by_context(ske->schedule, ske);
1871 /* Call completion */
1872 silc_ske_completion(ske);
1874 return SILC_FSM_FINISH;
1877 /* Failure received from remote */
1879 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1881 SilcSKE ske = fsm_context;
1882 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1884 if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
1885 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,
2347 ske->prop->hash, ske->rng,
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 && ske->packet->type == SILC_PACKET_FAILURE &&
2475 silc_buffer_len(&ske->packet->buffer) == 4) {
2476 SILC_GET32_MSB(error, ske->packet->buffer.data);
2477 ske->status = error;
2478 silc_packet_free(ske->packet);
2482 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2483 silc_schedule_task_del_by_context(ske->schedule, ske);
2485 /* Call completion */
2486 silc_ske_completion(ske);
2488 return SILC_FSM_FINISH;
2491 /* Error occurred */
2493 SILC_FSM_STATE(silc_ske_st_responder_error)
2495 SilcSKE ske = fsm_context;
2496 unsigned char tmp[4];
2498 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2499 ske->status, silc_ske_map_status(ske->status)));
2501 /* Send FAILURE packet */
2502 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2503 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2504 SILC_PUT32_MSB(ske->status, tmp);
2505 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2507 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2508 silc_schedule_task_del_by_context(ske->schedule, ske);
2510 /* Call completion */
2511 silc_ske_completion(ske);
2513 return SILC_FSM_FINISH;
2516 /* Starts the protocol as responder. */
2518 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2519 SilcPacketStream stream,
2520 SilcSKEParams params)
2522 SILC_LOG_DEBUG(("Start SKE as responder"));
2524 if (!ske || !stream || !params || !params->version)
2527 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2530 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2533 ske->responder = TRUE;
2534 ske->flags = params->flags;
2535 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2536 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2537 ske->session_port = params->session_port;
2538 ske->version = strdup(params->version);
2541 ske->running = TRUE;
2543 /* Link to packet stream to get key exchange packets */
2544 ske->stream = stream;
2545 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2546 SILC_PACKET_KEY_EXCHANGE,
2547 SILC_PACKET_KEY_EXCHANGE_1,
2548 SILC_PACKET_SUCCESS,
2549 SILC_PACKET_FAILURE, -1);
2551 /* Start SKE as responder */
2552 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2557 /***************************** Initiator Rekey ******************************/
2561 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2563 SilcSKE ske = fsm_context;
2566 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2570 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2571 return SILC_FSM_CONTINUE;
2574 /* Add rekey exchange timeout */
2575 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2578 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2581 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2582 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2583 return SILC_FSM_CONTINUE;
2586 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2587 /** Cannot allocate hash */
2588 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2589 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2590 return SILC_FSM_CONTINUE;
2593 /* Send REKEY packet to start rekey protocol */
2594 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2595 /** Error sending packet */
2596 SILC_LOG_DEBUG(("Error sending packet"));
2597 ske->status = SILC_SKE_STATUS_ERROR;
2598 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2599 return SILC_FSM_CONTINUE;
2602 /* If doing rekey without PFS, move directly to the end of the protocol. */
2603 if (!ske->rekey->pfs) {
2604 /** Rekey without PFS */
2605 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2606 return SILC_FSM_CONTINUE;
2609 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2611 if (status != SILC_SKE_STATUS_OK) {
2612 /** Unknown group */
2613 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2614 return SILC_FSM_CONTINUE;
2617 /** Rekey with PFS */
2618 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2619 return SILC_FSM_CONTINUE;
2622 /* Sends REKEY_DONE packet to finish the protocol. */
2624 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2626 SilcSKE ske = fsm_context;
2627 SilcCipher send_key;
2630 SilcUInt32 key_len, block_len, hash_len, x_len;
2631 unsigned char *pfsbuf;
2633 SILC_LOG_DEBUG(("Start"));
2635 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2636 key_len = silc_cipher_get_key_len(send_key);
2637 block_len = silc_cipher_get_block_len(send_key);
2638 hash = ske->prop->hash;
2639 hash_len = silc_hash_len(hash);
2641 /* Process key material */
2642 if (ske->rekey->pfs) {
2644 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2646 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2649 memset(pfsbuf, 0, x_len);
2655 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2656 ske->rekey->enc_key_len / 8,
2662 SILC_LOG_ERROR(("Error processing key material"));
2663 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2664 return SILC_FSM_CONTINUE;
2667 ske->prop->cipher = send_key;
2668 ske->prop->hmac = hmac_send;
2670 /* Get sending keys */
2671 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2672 &hmac_send, NULL, NULL)) {
2673 /** Cannot get keys */
2674 ske->status = SILC_SKE_STATUS_ERROR;
2675 ske->prop->cipher = NULL;
2676 ske->prop->hmac = NULL;
2677 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2678 return SILC_FSM_CONTINUE;
2681 ske->prop->cipher = NULL;
2682 ske->prop->hmac = NULL;
2684 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2685 packet sent after this call will be protected with the new keys. */
2686 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2688 /** Cannot set keys */
2689 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2690 ske->status = SILC_SKE_STATUS_ERROR;
2691 silc_cipher_free(send_key);
2692 silc_hmac_free(hmac_send);
2693 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2694 return SILC_FSM_CONTINUE;
2697 /** Wait for REKEY_DONE */
2698 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2699 return SILC_FSM_WAIT;
2702 /* Rekey protocol end */
2704 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2706 SilcSKE ske = fsm_context;
2707 SilcCipher receive_key;
2708 SilcHmac hmac_receive;
2709 SilcSKERekeyMaterial rekey;
2711 SILC_LOG_DEBUG(("Start"));
2713 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2714 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2715 silc_packet_free(ske->packet);
2717 return SILC_FSM_WAIT;
2720 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2721 ske->prop->cipher = receive_key;
2722 ske->prop->hmac = hmac_receive;
2724 /* Get receiving keys */
2725 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2726 NULL, &hmac_receive, NULL)) {
2727 /** Cannot get keys */
2728 ske->status = SILC_SKE_STATUS_ERROR;
2729 ske->prop->cipher = NULL;
2730 ske->prop->hmac = NULL;
2731 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2732 return SILC_FSM_CONTINUE;
2735 /* Set new receiving keys into use. All packets received after this will
2736 be decrypted with the new keys. */
2737 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2738 hmac_receive, FALSE)) {
2739 /** Cannot set keys */
2740 SILC_LOG_DEBUG(("Cannot set new keys"));
2741 ske->status = SILC_SKE_STATUS_ERROR;
2742 silc_cipher_free(receive_key);
2743 silc_hmac_free(hmac_receive);
2744 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2745 return SILC_FSM_CONTINUE;
2748 SILC_LOG_DEBUG(("Rekey completed successfully"));
2750 /* Generate new rekey material */
2751 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2754 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2755 ske->prop->cipher = NULL;
2756 ske->prop->hmac = NULL;
2757 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2758 return SILC_FSM_CONTINUE;
2760 rekey->pfs = ske->rekey->pfs;
2763 ske->prop->cipher = NULL;
2764 ske->prop->hmac = NULL;
2765 silc_packet_free(ske->packet);
2767 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2768 silc_schedule_task_del_by_context(ske->schedule, ske);
2770 /* Call completion */
2771 silc_ske_completion(ske);
2773 return SILC_FSM_FINISH;
2776 /* Starts rekey protocol as initiator */
2779 silc_ske_rekey_initiator(SilcSKE ske,
2780 SilcPacketStream stream,
2781 SilcSKERekeyMaterial rekey)
2783 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2785 if (!ske || !stream || !rekey) {
2786 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2791 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2794 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2798 ske->responder = FALSE;
2799 ske->running = TRUE;
2800 ske->rekeying = TRUE;
2802 /* Link to packet stream to get key exchange packets */
2803 ske->stream = stream;
2804 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2806 SILC_PACKET_REKEY_DONE,
2807 SILC_PACKET_KEY_EXCHANGE_2,
2808 SILC_PACKET_SUCCESS,
2809 SILC_PACKET_FAILURE, -1);
2811 /* Start SKE rekey as initiator */
2812 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2817 /***************************** Responder Rekey ******************************/
2819 /* Wait for initiator's packet */
2821 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2823 SilcSKE ske = fsm_context;
2825 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2829 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2830 return SILC_FSM_CONTINUE;
2833 /* Add rekey exchange timeout */
2834 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2837 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2839 /* If REKEY packet already received process it directly */
2840 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2841 return SILC_FSM_CONTINUE;
2843 /* Wait for REKEY */
2844 return SILC_FSM_WAIT;
2847 /* Process initiator's REKEY packet */
2849 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2851 SilcSKE ske = fsm_context;
2852 SilcSKEStatus status;
2854 SILC_LOG_DEBUG(("Start"));
2856 if (ske->packet->type != SILC_PACKET_REKEY) {
2857 ske->status = SILC_SKE_STATUS_ERROR;
2858 silc_packet_free(ske->packet);
2860 silc_fsm_next(fsm, silc_ske_st_responder_error);
2861 return SILC_FSM_CONTINUE;
2864 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2867 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2868 silc_fsm_next(fsm, silc_ske_st_responder_error);
2869 return SILC_FSM_CONTINUE;
2872 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2873 /** Cannot allocate hash */
2874 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2875 silc_fsm_next(fsm, silc_ske_st_responder_error);
2876 return SILC_FSM_CONTINUE;
2879 /* If doing rekey without PFS, move directly to the end of the protocol. */
2880 if (!ske->rekey->pfs) {
2881 /** Rekey without PFS */
2882 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2883 return SILC_FSM_CONTINUE;
2886 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2888 if (status != SILC_SKE_STATUS_OK) {
2889 /** Unknown group */
2890 silc_fsm_next(fsm, silc_ske_st_responder_error);
2891 return SILC_FSM_CONTINUE;
2894 /** Rekey with PFS */
2895 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2896 return SILC_FSM_WAIT;
2899 /* Sends REKEY_DONE packet to finish the protocol. */
2901 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2903 SilcSKE ske = fsm_context;
2904 SilcCipher send_key;
2907 SilcUInt32 key_len, block_len, hash_len, x_len;
2908 unsigned char *pfsbuf;
2910 SILC_LOG_DEBUG(("Start"));
2912 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2913 key_len = silc_cipher_get_key_len(send_key);
2914 block_len = silc_cipher_get_block_len(send_key);
2915 hash = ske->prop->hash;
2916 hash_len = silc_hash_len(hash);
2918 /* Process key material */
2919 if (ske->rekey->pfs) {
2921 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2923 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2926 memset(pfsbuf, 0, x_len);
2932 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2933 ske->rekey->enc_key_len / 8,
2939 SILC_LOG_ERROR(("Error processing key material"));
2940 silc_fsm_next(fsm, silc_ske_st_responder_error);
2941 return SILC_FSM_CONTINUE;
2944 ske->prop->cipher = send_key;
2945 ske->prop->hmac = hmac_send;
2947 /* Get sending keys */
2948 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2949 &hmac_send, NULL, NULL)) {
2950 /** Cannot get keys */
2951 ske->status = SILC_SKE_STATUS_ERROR;
2952 ske->prop->cipher = NULL;
2953 ske->prop->hmac = NULL;
2954 silc_fsm_next(fsm, silc_ske_st_responder_error);
2955 return SILC_FSM_CONTINUE;
2958 ske->prop->cipher = NULL;
2959 ske->prop->hmac = NULL;
2961 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2962 packet sent after this call will be protected with the new keys. */
2963 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2965 /** Cannot set keys */
2966 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2967 ske->status = SILC_SKE_STATUS_ERROR;
2968 silc_cipher_free(send_key);
2969 silc_hmac_free(hmac_send);
2970 silc_fsm_next(fsm, silc_ske_st_responder_error);
2971 return SILC_FSM_CONTINUE;
2974 /** Wait for REKEY_DONE */
2975 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2976 return SILC_FSM_WAIT;
2979 /* Rekey protocol end */
2981 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2983 SilcSKE ske = fsm_context;
2984 SilcCipher receive_key;
2985 SilcHmac hmac_receive;
2986 SilcSKERekeyMaterial rekey;
2988 SILC_LOG_DEBUG(("Start"));
2990 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2991 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2992 silc_packet_free(ske->packet);
2994 return SILC_FSM_WAIT;
2997 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2998 ske->prop->cipher = receive_key;
2999 ske->prop->hmac = hmac_receive;
3001 /* Get receiving keys */
3002 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
3003 NULL, &hmac_receive, NULL)) {
3004 /** Cannot get keys */
3005 ske->status = SILC_SKE_STATUS_ERROR;
3006 ske->prop->cipher = NULL;
3007 ske->prop->hmac = NULL;
3008 silc_fsm_next(fsm, silc_ske_st_responder_error);
3009 return SILC_FSM_CONTINUE;
3012 /* Set new receiving keys into use. All packets received after this will
3013 be decrypted with the new keys. */
3014 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3015 hmac_receive, FALSE)) {
3016 /** Cannot set keys */
3017 SILC_LOG_DEBUG(("Cannot set new keys"));
3018 ske->status = SILC_SKE_STATUS_ERROR;
3019 ske->prop->cipher = NULL;
3020 ske->prop->hmac = NULL;
3021 silc_cipher_free(receive_key);
3022 silc_hmac_free(hmac_receive);
3023 silc_fsm_next(fsm, silc_ske_st_responder_error);
3024 return SILC_FSM_CONTINUE;
3027 SILC_LOG_DEBUG(("Rekey completed successfully"));
3029 /* Generate new rekey material */
3030 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3033 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3034 ske->prop->cipher = NULL;
3035 ske->prop->hmac = NULL;
3036 silc_fsm_next(fsm, silc_ske_st_responder_error);
3037 return SILC_FSM_CONTINUE;
3039 rekey->pfs = ske->rekey->pfs;
3042 ske->prop->cipher = NULL;
3043 ske->prop->hmac = NULL;
3044 silc_packet_free(ske->packet);
3046 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3047 silc_schedule_task_del_by_context(ske->schedule, ske);
3049 /* Call completion */
3050 silc_ske_completion(ske);
3052 return SILC_FSM_FINISH;
3055 /* Starts rekey protocol as responder */
3058 silc_ske_rekey_responder(SilcSKE ske,
3059 SilcPacketStream stream,
3060 SilcSKERekeyMaterial rekey,
3063 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3065 if (!ske || !stream || !rekey)
3068 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3071 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3075 ske->responder = TRUE;
3076 ske->running = TRUE;
3077 ske->rekeying = TRUE;
3078 ske->packet = packet;
3080 /* Link to packet stream to get key exchange packets */
3081 ske->stream = stream;
3082 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3084 SILC_PACKET_REKEY_DONE,
3085 SILC_PACKET_KEY_EXCHANGE_1,
3086 SILC_PACKET_SUCCESS,
3087 SILC_PACKET_FAILURE, -1);
3089 /* Start SKE rekey as responder */
3090 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3095 /* Processes the provided key material `data' as the SILC protocol
3096 specification defines. */
3099 silc_ske_process_key_material_data(unsigned char *data,
3100 SilcUInt32 data_len,
3101 SilcUInt32 req_iv_len,
3102 SilcUInt32 req_enc_key_len,
3103 SilcUInt32 req_hmac_key_len,
3107 unsigned char hashd[SILC_HASH_MAXLEN];
3108 SilcUInt32 hash_len = req_hmac_key_len;
3109 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3110 SilcSKEKeyMaterial key;
3112 SILC_LOG_DEBUG(("Start"));
3114 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3117 key = silc_calloc(1, sizeof(*key));
3121 buf = silc_buffer_alloc_size(1 + data_len);
3124 silc_buffer_format(buf,
3125 SILC_STR_UI_CHAR(0),
3126 SILC_STR_DATA(data, data_len),
3130 memset(hashd, 0, sizeof(hashd));
3132 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3133 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3134 memcpy(key->send_iv, hashd, req_iv_len);
3135 memset(hashd, 0, sizeof(hashd));
3137 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3138 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3139 memcpy(key->receive_iv, hashd, req_iv_len);
3140 key->iv_len = req_iv_len;
3142 /* Take the encryption keys. If requested key size is more than
3143 the size of hash length we will distribute more key material
3144 as protocol defines. */
3146 if (enc_key_len > hash_len) {
3148 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3149 k3[SILC_HASH_MAXLEN];
3150 unsigned char *dtmp;
3153 if (enc_key_len > (3 * hash_len))
3156 /* Take first round */
3157 memset(k1, 0, sizeof(k1));
3158 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3160 /* Take second round */
3161 dist = silc_buffer_alloc_size(data_len + hash_len);
3164 silc_buffer_format(dist,
3165 SILC_STR_DATA(data, data_len),
3166 SILC_STR_DATA(k1, hash_len),
3168 memset(k2, 0, sizeof(k2));
3169 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3171 /* Take third round */
3172 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3173 silc_buffer_pull_tail(dist, hash_len);
3174 silc_buffer_pull(dist, data_len + hash_len);
3175 silc_buffer_format(dist,
3176 SILC_STR_DATA(k2, hash_len),
3178 silc_buffer_push(dist, data_len + hash_len);
3179 memset(k3, 0, sizeof(k3));
3180 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3182 /* Then, save the keys */
3183 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3184 memcpy(dtmp, k1, hash_len);
3185 memcpy(dtmp + hash_len, k2, hash_len);
3186 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3188 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3189 memcpy(key->send_enc_key, dtmp, enc_key_len);
3190 key->enc_key_len = req_enc_key_len;
3192 memset(dtmp, 0, (3 * hash_len));
3193 memset(k1, 0, sizeof(k1));
3194 memset(k2, 0, sizeof(k2));
3195 memset(k3, 0, sizeof(k3));
3197 silc_buffer_clear(dist);
3198 silc_buffer_free(dist);
3200 /* Take normal hash as key */
3201 memset(hashd, 0, sizeof(hashd));
3202 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3203 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3204 memcpy(key->send_enc_key, hashd, enc_key_len);
3205 key->enc_key_len = req_enc_key_len;
3209 if (enc_key_len > hash_len) {
3211 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3212 k3[SILC_HASH_MAXLEN];
3213 unsigned char *dtmp;
3216 if (enc_key_len > (3 * hash_len))
3219 /* Take first round */
3220 memset(k1, 0, sizeof(k1));
3221 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3223 /* Take second round */
3224 dist = silc_buffer_alloc_size(data_len + hash_len);
3227 silc_buffer_format(dist,
3228 SILC_STR_DATA(data, data_len),
3229 SILC_STR_DATA(k1, hash_len),
3231 memset(k2, 0, sizeof(k2));
3232 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3234 /* Take third round */
3235 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3236 silc_buffer_pull_tail(dist, hash_len);
3237 silc_buffer_pull(dist, data_len + hash_len);
3238 silc_buffer_format(dist,
3239 SILC_STR_DATA(k2, hash_len),
3241 silc_buffer_push(dist, data_len + hash_len);
3242 memset(k3, 0, sizeof(k3));
3243 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3245 /* Then, save the keys */
3246 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3247 memcpy(dtmp, k1, hash_len);
3248 memcpy(dtmp + hash_len, k2, hash_len);
3249 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3251 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3252 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3253 key->enc_key_len = req_enc_key_len;
3255 memset(dtmp, 0, (3 * hash_len));
3256 memset(k1, 0, sizeof(k1));
3257 memset(k2, 0, sizeof(k2));
3258 memset(k3, 0, sizeof(k3));
3260 silc_buffer_clear(dist);
3261 silc_buffer_free(dist);
3263 /* Take normal hash as key */
3264 memset(hashd, 0, sizeof(hashd));
3265 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3266 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3267 memcpy(key->receive_enc_key, hashd, enc_key_len);
3268 key->enc_key_len = req_enc_key_len;
3271 /* Take HMAC keys */
3272 memset(hashd, 0, sizeof(hashd));
3274 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3275 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3276 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3277 memset(hashd, 0, sizeof(hashd));
3279 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3280 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3281 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3282 key->hmac_key_len = req_hmac_key_len;
3283 memset(hashd, 0, sizeof(hashd));
3285 silc_buffer_clear(buf);
3286 silc_buffer_free(buf);
3288 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3293 /* Processes negotiated key material as protocol specifies. This returns
3294 the actual keys to be used in the SILC. */
3297 silc_ske_process_key_material(SilcSKE ske,
3298 SilcUInt32 req_iv_len,
3299 SilcUInt32 req_enc_key_len,
3300 SilcUInt32 req_hmac_key_len,
3301 SilcSKERekeyMaterial *rekey)
3304 unsigned char *tmpbuf;
3306 SilcSKEKeyMaterial key;
3308 /* Encode KEY to binary data */
3309 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3311 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3314 silc_buffer_format(buf,
3315 SILC_STR_DATA(tmpbuf, klen),
3316 SILC_STR_DATA(ske->hash, ske->hash_len),
3319 /* Process the key material */
3320 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3321 req_iv_len, req_enc_key_len,
3325 memset(tmpbuf, 0, klen);
3327 silc_buffer_clear(buf);
3328 silc_buffer_free(buf);
3331 *rekey = silc_ske_make_rekey_material(ske, key);
3339 /* Free key material structure */
3341 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3347 silc_free(key->send_iv);
3348 if (key->receive_iv)
3349 silc_free(key->receive_iv);
3350 if (key->send_enc_key) {
3351 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3352 silc_free(key->send_enc_key);
3354 if (key->receive_enc_key) {
3355 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3356 silc_free(key->receive_enc_key);
3358 if (key->send_hmac_key) {
3359 memset(key->send_hmac_key, 0, key->hmac_key_len);
3360 silc_free(key->send_hmac_key);
3362 if (key->receive_hmac_key) {
3363 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3364 silc_free(key->receive_hmac_key);
3369 /* Free rekey material */
3371 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3375 if (rekey->send_enc_key) {
3376 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3377 silc_free(rekey->send_enc_key);
3379 silc_free(rekey->hash);
3383 /* Set keys into use */
3385 SilcBool silc_ske_set_keys(SilcSKE ske,
3386 SilcSKEKeyMaterial keymat,
3387 SilcSKESecurityProperties prop,
3388 SilcCipher *ret_send_key,
3389 SilcCipher *ret_receive_key,
3390 SilcHmac *ret_hmac_send,
3391 SilcHmac *ret_hmac_receive,
3394 unsigned char iv[SILC_HASH_MAXLEN];
3395 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3397 /* Allocate ciphers to be used in the communication */
3399 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3403 if (ret_receive_key) {
3404 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3409 /* Allocate HMACs */
3410 if (ret_hmac_send) {
3411 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3415 if (ret_hmac_receive) {
3416 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3423 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3427 /* Set key material */
3428 memset(iv, 0, sizeof(iv));
3429 if (ske->responder) {
3431 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3432 keymat->enc_key_len, TRUE);
3434 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3436 if (!ske->rekeying) {
3438 memcpy(iv, ske->hash, 4);
3440 memcpy(iv + 4, keymat->receive_iv, 8);
3442 /* Rekey, recompute the truncated hash value. */
3443 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3445 memcpy(iv + 4, keymat->receive_iv, 8);
3447 memset(iv + 4, 0, 12);
3450 silc_cipher_set_iv(*ret_send_key, iv);
3453 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3456 if (ret_receive_key) {
3457 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3458 keymat->enc_key_len, FALSE);
3460 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3462 if (!ske->rekeying) {
3464 memcpy(iv, ske->hash, 4);
3466 memcpy(iv + 4, keymat->send_iv, 8);
3468 /* Rekey, recompute the truncated hash value. */
3469 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3471 memcpy(iv + 4, keymat->send_iv, 8);
3473 memset(iv + 4, 0, 12);
3476 silc_cipher_set_iv(*ret_receive_key, iv);
3479 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3483 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3484 keymat->hmac_key_len);
3485 if (ret_hmac_receive)
3486 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3487 keymat->hmac_key_len);
3490 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3491 keymat->enc_key_len, TRUE);
3493 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3495 if (!ske->rekeying) {
3497 memcpy(iv, ske->hash, 4);
3499 memcpy(iv + 4, keymat->send_iv, 8);
3501 /* Rekey, recompute the truncated hash value. */
3502 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3504 memcpy(iv + 4, keymat->send_iv, 8);
3506 memset(iv + 4, 0, 12);
3509 silc_cipher_set_iv(*ret_send_key, iv);
3512 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3515 if (ret_receive_key) {
3516 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3517 keymat->enc_key_len, FALSE);
3519 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3521 if (!ske->rekeying) {
3522 /* Set IV. If IV Included flag was negotiated we only set the
3523 truncated hash value. */
3524 memcpy(iv, ske->hash, 4);
3526 memcpy(iv + 4, keymat->receive_iv, 8);
3528 /* Rekey, recompute the truncated hash value. */
3529 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3531 memcpy(iv + 4, keymat->receive_iv, 8);
3533 memset(iv + 4, 0, 12);
3536 silc_cipher_set_iv(*ret_receive_key, iv);
3539 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3543 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3544 keymat->hmac_key_len);
3545 if (ret_hmac_receive)
3546 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3547 keymat->hmac_key_len);
3553 const char *silc_ske_status_string[] =
3557 "Unexpected error occurred",
3558 "Bad payload in packet",
3559 "Unsupported group",
3560 "Unsupported cipher",
3562 "Unsupported hash function",
3564 "Unsupported public key (or certificate)",
3565 "Incorrect signature",
3566 "Bad or unsupported version",
3570 "Remote did not provide public key",
3571 "Bad reserved field in packet",
3572 "Bad payload length in packet",
3573 "Error computing signature",
3574 "System out of memory",
3575 "Key exchange timeout",
3580 /* Maps status to readable string and returns the string. If string is not
3581 found and empty character string ("") is returned. */
3583 const char *silc_ske_map_status(SilcSKEStatus status)
3587 for (i = 0; silc_ske_status_string[i]; i++)
3589 return silc_ske_status_string[i];
3594 /* Parses remote host's version string. */
3596 SilcBool silc_ske_parse_version(SilcSKE ske,
3597 SilcUInt32 *protocol_version,
3598 char **protocol_version_string,
3599 SilcUInt32 *software_version,
3600 char **software_version_string,
3601 char **vendor_version)
3603 return silc_parse_version_string(ske->remote_version,
3605 protocol_version_string,
3607 software_version_string,
3611 /* Get security properties */
3613 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3618 /* Get key material */
3620 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)