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_async(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_async(ske->prop->public_key,
1720 payload->sign_len, hash,
1721 hash_len, FALSE, NULL,
1722 silc_ske_verify_cb, ske));
1726 return SILC_FSM_CONTINUE;
1729 memset(hash, 'F', sizeof(hash));
1730 silc_ske_payload_ke_free(payload);
1731 ske->ke2_payload = NULL;
1733 silc_mp_uninit(ske->KEY);
1734 silc_free(ske->KEY);
1738 memset(ske->hash, 'F', hash_len);
1739 silc_free(ske->hash);
1743 if (status == SILC_SKE_STATUS_OK)
1744 status = SILC_SKE_STATUS_ERROR;
1747 ske->status = status;
1748 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1749 return SILC_FSM_CONTINUE;
1752 /* Process key material */
1754 SILC_FSM_STATE(silc_ske_st_initiator_phase5)
1756 SilcSKE ske = fsm_context;
1757 SilcSKEStatus status;
1758 unsigned char tmp[4];
1759 SilcUInt32 hash_len;
1760 int key_len, block_len;
1762 ske->status = SILC_SKE_STATUS_OK;
1764 /* In case we are doing rekey move to finish it. */
1767 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1768 return SILC_FSM_CONTINUE;
1771 /* Process key material */
1772 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1773 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1774 hash_len = silc_hash_len(ske->prop->hash);
1775 ske->keymat = silc_ske_process_key_material(ske, block_len,
1779 SILC_LOG_ERROR(("Error processing key material"));
1780 status = SILC_SKE_STATUS_ERROR;
1781 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1782 return SILC_FSM_CONTINUE;
1785 /* Send SUCCESS packet */
1786 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, tmp);
1787 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4)) {
1788 /** Error sending packet */
1789 SILC_LOG_DEBUG(("Error sending packet"));
1790 ske->status = SILC_SKE_STATUS_ERROR;
1791 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1792 return SILC_FSM_CONTINUE;
1795 /** Waiting completion */
1796 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1797 return SILC_FSM_WAIT;
1800 /* Protocol completed */
1802 SILC_FSM_STATE(silc_ske_st_initiator_end)
1804 SilcSKE ske = fsm_context;
1806 SILC_LOG_DEBUG(("Start"));
1808 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1809 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1810 silc_ske_install_retransmission(ske);
1811 silc_packet_free(ske->packet);
1813 return SILC_FSM_WAIT;
1816 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1818 silc_packet_free(ske->packet);
1820 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1821 silc_schedule_task_del_by_context(ske->schedule, ske);
1823 /* Call completion */
1824 silc_ske_completion(ske);
1826 return SILC_FSM_FINISH;
1829 /* Aborted by application */
1831 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1833 SilcSKE ske = fsm_context;
1834 unsigned char data[4];
1836 SILC_LOG_DEBUG(("Aborted by caller"));
1838 /* Send FAILURE packet */
1839 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1840 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1842 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1843 silc_schedule_task_del_by_context(ske->schedule, ske);
1845 /* Call completion */
1846 silc_ske_completion(ske);
1848 return SILC_FSM_FINISH;
1851 /* Error occurred. Send error to remote host */
1853 SILC_FSM_STATE(silc_ske_st_initiator_error)
1855 SilcSKE ske = fsm_context;
1856 SilcSKEStatus status;
1857 unsigned char data[4];
1859 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1860 silc_ske_map_status(ske->status), ske->status));
1862 status = ske->status;
1863 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1864 status = SILC_SKE_STATUS_ERROR;
1866 /* Send FAILURE packet */
1867 SILC_PUT32_MSB((SilcUInt32)status, data);
1868 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1870 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1871 silc_schedule_task_del_by_context(ske->schedule, ske);
1873 /* Call completion */
1874 silc_ske_completion(ske);
1876 return SILC_FSM_FINISH;
1879 /* Failure received from remote */
1881 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1883 SilcSKE ske = fsm_context;
1884 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1886 if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
1887 silc_buffer_len(&ske->packet->buffer) == 4) {
1888 SILC_GET32_MSB(error, ske->packet->buffer.data);
1889 ske->status = error;
1890 silc_packet_free(ske->packet);
1894 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1895 silc_ske_map_status(ske->status), ske->status));
1897 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1898 silc_schedule_task_del_by_context(ske->schedule, ske);
1900 /* Call completion */
1901 silc_ske_completion(ske);
1903 return SILC_FSM_FINISH;
1906 /* Starts the protocol as initiator */
1908 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1909 SilcPacketStream stream,
1910 SilcSKEParams params,
1911 SilcSKEStartPayload start_payload)
1913 SILC_LOG_DEBUG(("Start SKE as initiator"));
1915 if (!ske || !stream || !params || !params->version)
1918 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1921 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1924 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1925 ske->session_port = params->session_port;
1927 /* Generate security properties if not provided */
1928 if (!start_payload) {
1929 start_payload = silc_ske_assemble_security_properties(ske,
1936 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1937 ske->start_payload = start_payload;
1938 ske->version = params->version;
1939 ske->running = TRUE;
1941 /* Link to packet stream to get key exchange packets */
1942 ske->stream = stream;
1943 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1944 SILC_PACKET_KEY_EXCHANGE,
1945 SILC_PACKET_KEY_EXCHANGE_2,
1946 SILC_PACKET_SUCCESS,
1947 SILC_PACKET_FAILURE, -1);
1949 /* Start SKE as initiator */
1950 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1955 /******************************** Responder *********************************/
1957 /* Start protocol as responder. Wait initiator's start payload */
1959 SILC_FSM_STATE(silc_ske_st_responder_start)
1961 SilcSKE ske = fsm_context;
1963 SILC_LOG_DEBUG(("Start"));
1967 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1968 return SILC_FSM_CONTINUE;
1971 /* Add key exchange timeout */
1972 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1973 ske, ske->timeout, 0);
1975 /** Wait for initiator */
1976 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1977 return SILC_FSM_WAIT;
1980 /* Decode initiator's start payload. Select the security properties from
1981 the initiator's start payload and send our reply start payload back. */
1983 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1985 SilcSKE ske = fsm_context;
1986 SilcSKEStatus status;
1987 SilcSKEStartPayload remote_payload = NULL;
1988 SilcBuffer packet_buf = &ske->packet->buffer;
1991 SILC_LOG_DEBUG(("Start"));
1993 /* Decode the payload */
1994 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1995 if (status != SILC_SKE_STATUS_OK) {
1996 /** Error decoding Start Payload */
1997 silc_packet_free(ske->packet);
1999 ske->status = status;
2000 silc_fsm_next(fsm, silc_ske_st_responder_error);
2001 return SILC_FSM_CONTINUE;
2004 /* Get remote ID and set it to stream */
2005 if (ske->packet->src_id_len) {
2006 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
2007 ske->packet->src_id_type,
2008 (ske->packet->src_id_type == SILC_ID_SERVER ?
2009 (void *)&id.u.server_id : (void *)&id.u.client_id),
2010 (ske->packet->src_id_type == SILC_ID_SERVER ?
2011 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
2012 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
2013 (ske->packet->src_id_type == SILC_ID_SERVER ?
2014 (void *)&id.u.server_id : (void *)&id.u.client_id));
2017 /* Take a copy of the payload buffer for future use. It is used to
2018 compute the HASH value. */
2019 ske->start_payload_copy = silc_buffer_copy(packet_buf);
2021 silc_packet_free(ske->packet);
2024 /* Force the mutual authentication flag if we want to do it. */
2025 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2026 SILC_LOG_DEBUG(("Force mutual authentication"));
2027 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
2030 /* Force PFS flag if we require it */
2031 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
2032 SILC_LOG_DEBUG(("Force PFS"));
2033 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
2036 /* Disable IV Included flag if requested */
2037 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
2038 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
2039 SILC_LOG_DEBUG(("We do not support IV Included flag"));
2040 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
2043 /* Check and select security properties */
2044 status = silc_ske_select_security_properties(ske, remote_payload,
2046 if (status != SILC_SKE_STATUS_OK) {
2047 /** Error selecting proposal */
2048 silc_ske_payload_start_free(remote_payload);
2049 ske->status = status;
2050 silc_fsm_next(fsm, silc_ske_st_responder_error);
2051 return SILC_FSM_CONTINUE;
2054 silc_ske_payload_start_free(remote_payload);
2056 /* Encode our reply payload to send the selected security properties */
2057 status = silc_ske_payload_start_encode(ske, ske->start_payload,
2059 if (status != SILC_SKE_STATUS_OK)
2062 /* Send the packet. */
2063 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
2064 silc_buffer_data(packet_buf),
2065 silc_buffer_len(packet_buf)))
2068 silc_buffer_free(packet_buf);
2070 /** Waiting initiator's KE payload */
2071 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2072 return SILC_FSM_WAIT;
2075 if (ske->prop->group)
2076 silc_ske_group_free(ske->prop->group);
2077 if (ske->prop->cipher)
2078 silc_cipher_free(ske->prop->cipher);
2079 if (ske->prop->hash)
2080 silc_hash_free(ske->prop->hash);
2081 if (ske->prop->hmac)
2082 silc_hmac_free(ske->prop->hmac);
2083 silc_free(ske->prop);
2086 if (status == SILC_SKE_STATUS_OK)
2087 status = SILC_SKE_STATUS_ERROR;
2090 ske->status = status;
2091 silc_fsm_next(fsm, silc_ske_st_responder_error);
2092 return SILC_FSM_CONTINUE;
2095 /* Phase-2. Decode initiator's KE payload */
2097 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2099 SilcSKE ske = fsm_context;
2100 SilcSKEStatus status;
2101 SilcSKEKEPayload recv_payload;
2102 SilcBuffer packet_buf = &ske->packet->buffer;
2104 SILC_LOG_DEBUG(("Start"));
2106 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2107 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2108 silc_ske_install_retransmission(ske);
2109 silc_packet_free(ske->packet);
2111 return SILC_FSM_WAIT;
2114 /* Decode Key Exchange Payload */
2115 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2116 if (status != SILC_SKE_STATUS_OK) {
2117 /** Error decoding KE payload */
2118 silc_packet_free(ske->packet);
2120 ske->status = status;
2121 silc_fsm_next(fsm, silc_ske_st_responder_error);
2122 return SILC_FSM_CONTINUE;
2125 ske->ke1_payload = recv_payload;
2127 silc_packet_free(ske->packet);
2130 /* Verify the received public key and verify the signature if we are
2131 doing mutual authentication. */
2132 if (ske->start_payload &&
2133 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2135 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2137 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2139 /** Public key not provided */
2140 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2141 "certificate), even though we require it"));
2142 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2143 silc_fsm_next(fsm, silc_ske_st_responder_error);
2144 return SILC_FSM_CONTINUE;
2147 /* Decode the remote's public key */
2148 if (recv_payload->pk_data &&
2149 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2150 recv_payload->pk_data,
2151 recv_payload->pk_len,
2152 &ske->prop->public_key)) {
2153 /** Error decoding public key */
2154 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2155 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2156 silc_fsm_next(fsm, silc_ske_st_responder_error);
2157 return SILC_FSM_CONTINUE;
2160 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2162 SILC_LOG_DEBUG(("Verifying public key"));
2164 /** Waiting public key verification */
2165 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2167 /* If repository is provided, verify the key from there. */
2168 if (ske->repository) {
2171 find = silc_skr_find_alloc();
2173 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2174 silc_fsm_next(fsm, silc_ske_st_responder_error);
2175 return SILC_FSM_CONTINUE;
2177 silc_skr_find_set_pkcs_type(find,
2178 silc_pkcs_get_type(ske->prop->public_key));
2179 silc_skr_find_set_public_key(find, ske->prop->public_key);
2180 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2182 /* Find key from repository */
2183 SILC_FSM_CALL(silc_skr_find(ske->repository,
2184 silc_fsm_get_schedule(fsm), find,
2185 silc_ske_skr_callback, ske));
2187 /* Verify from application */
2188 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2189 ske->callbacks->context,
2190 silc_ske_pk_verified, NULL));
2196 /** Generate KE2 payload */
2197 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2198 return SILC_FSM_CONTINUE;
2201 /* Phase-4. Generate KE2 payload, verify signature */
2203 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2205 SilcSKE ske = fsm_context;
2206 SilcSKEStatus status;
2207 SilcSKEKEPayload recv_payload;
2211 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2212 return SILC_FSM_CONTINUE;
2215 /* Check result of public key verification */
2216 if (ske->status != SILC_SKE_STATUS_OK) {
2217 /** Public key not verified */
2218 SILC_LOG_DEBUG(("Public key verification failed"));
2219 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2220 return SILC_FSM_CONTINUE;
2223 recv_payload = ske->ke1_payload;
2225 /** Send KE2 packet */
2226 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2228 /* The public key verification was performed only if the Mutual
2229 Authentication flag is set. */
2230 if (ske->start_payload &&
2231 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2232 unsigned char hash[SILC_HASH_MAXLEN];
2233 SilcUInt32 hash_len;
2235 SILC_LOG_DEBUG(("Public key is authentic"));
2237 /* Compute the hash value */
2238 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2239 if (status != SILC_SKE_STATUS_OK) {
2240 /** Error computing hash */
2241 ske->status = status;
2242 silc_fsm_next(fsm, silc_ske_st_responder_error);
2243 return SILC_FSM_CONTINUE;
2246 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2248 /* Verify signature */
2249 SILC_FSM_CALL(ske->key_op =
2250 silc_pkcs_verify_async(ske->prop->public_key,
2251 recv_payload->sign_data,
2252 recv_payload->sign_len,
2253 hash, hash_len, FALSE, NULL,
2254 silc_ske_verify_cb, ske));
2258 return SILC_FSM_CONTINUE;
2261 /* Phase-5. Send KE2 payload */
2263 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2265 SilcSKE ske = fsm_context;
2266 SilcSKEStatus status;
2267 unsigned char hash[SILC_HASH_MAXLEN], *pk;
2268 SilcUInt32 hash_len, pk_len;
2270 SilcSKEKEPayload send_payload;
2272 SILC_LOG_DEBUG(("Start"));
2274 /* Create the random number x, 1 < x < q. */
2275 x = silc_calloc(1, sizeof(*x));
2278 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2279 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2281 if (status != SILC_SKE_STATUS_OK) {
2282 /** Error generating random number */
2285 ske->status = status;
2286 silc_fsm_next(fsm, silc_ske_st_responder_error);
2287 return SILC_FSM_CONTINUE;
2290 /* Save the results for later processing */
2291 send_payload = silc_calloc(1, sizeof(*send_payload));
2293 ske->ke2_payload = send_payload;
2295 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2297 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2298 silc_mp_init(&send_payload->x);
2299 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2300 &ske->prop->group->group);
2302 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2304 /* Compute the shared secret key */
2305 KEY = silc_calloc(1, sizeof(*KEY));
2307 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2308 &ske->prop->group->group);
2311 if (ske->public_key && ske->private_key) {
2312 SILC_LOG_DEBUG(("Getting public key"));
2314 /* Get the public key */
2315 pk = silc_pkcs_public_key_encode(NULL, ske->public_key, &pk_len);
2317 /** Error encoding public key */
2318 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2319 silc_fsm_next(fsm, silc_ske_st_responder_error);
2320 return SILC_FSM_CONTINUE;
2322 ske->ke2_payload->pk_data = pk;
2323 ske->ke2_payload->pk_len = pk_len;
2326 SILC_LOG_DEBUG(("Computing HASH value"));
2328 /* Compute the hash value */
2329 memset(hash, 0, sizeof(hash));
2330 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2331 if (status != SILC_SKE_STATUS_OK) {
2332 /** Error computing hash */
2333 ske->status = status;
2334 silc_fsm_next(fsm, silc_ske_st_responder_error);
2335 return SILC_FSM_CONTINUE;
2337 ske->hash = silc_memdup(hash, hash_len);
2338 ske->hash_len = hash_len;
2340 /** Send KE2 packet */
2341 silc_fsm_next(fsm, silc_ske_st_responder_phase5_send);
2343 if (ske->public_key && ske->private_key) {
2344 SILC_LOG_DEBUG(("Signing HASH value"));
2346 /* Sign the hash value */
2347 SILC_FSM_CALL(ske->key_op =
2348 silc_pkcs_sign_async(ske->private_key, hash, hash_len, FALSE,
2349 ske->prop->hash, ske->rng,
2350 silc_ske_responder_sign_cb, ske));
2354 return SILC_FSM_CONTINUE;
2357 /* Send KE2 packet */
2359 SILC_FSM_STATE(silc_ske_st_responder_phase5_send)
2361 SilcSKE ske = fsm_context;
2362 SilcSKEStatus status;
2363 SilcBuffer payload_buf;
2365 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2367 /* Encode the Key Exchange Payload */
2368 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2370 if (status != SILC_SKE_STATUS_OK) {
2371 /** Error encoding KE payload */
2372 ske->status = status;
2373 silc_fsm_next(fsm, silc_ske_st_responder_error);
2374 return SILC_FSM_CONTINUE;
2377 /* Send the packet. */
2378 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2379 payload_buf->data, silc_buffer_len(payload_buf))) {
2380 SILC_LOG_DEBUG(("Error sending packet"));
2381 ske->status = SILC_SKE_STATUS_ERROR;
2382 silc_fsm_next(fsm, silc_ske_st_responder_error);
2383 return SILC_FSM_CONTINUE;
2386 silc_buffer_free(payload_buf);
2388 /* In case we are doing rekey move to finish it. */
2391 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2392 return SILC_FSM_CONTINUE;
2395 /** Waiting completion */
2396 silc_fsm_next(fsm, silc_ske_st_responder_end);
2397 return SILC_FSM_WAIT;
2400 /* Protocol completed */
2402 SILC_FSM_STATE(silc_ske_st_responder_end)
2404 SilcSKE ske = fsm_context;
2405 unsigned char tmp[4];
2406 SilcUInt32 hash_len, key_len, block_len;
2408 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2409 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2410 silc_ske_install_retransmission(ske);
2411 silc_packet_free(ske->packet);
2413 return SILC_FSM_WAIT;
2415 silc_packet_free(ske->packet);
2418 /* Process key material */
2419 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2420 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2421 hash_len = silc_hash_len(ske->prop->hash);
2422 ske->keymat = silc_ske_process_key_material(ske, block_len,
2426 /** Error processing key material */
2427 ske->status = SILC_SKE_STATUS_ERROR;
2428 silc_fsm_next(fsm, silc_ske_st_responder_error);
2429 return SILC_FSM_CONTINUE;
2432 /* Send SUCCESS packet */
2433 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2434 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2436 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2437 silc_schedule_task_del_by_context(ske->schedule, ske);
2439 /* Call completion */
2440 silc_ske_completion(ske);
2442 return SILC_FSM_FINISH;
2445 /* Aborted by application */
2447 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2449 SilcSKE ske = fsm_context;
2450 unsigned char tmp[4];
2452 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2454 /* Send FAILURE packet */
2455 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2456 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2458 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2459 silc_schedule_task_del_by_context(ske->schedule, ske);
2461 /* Call completion */
2462 silc_ske_completion(ske);
2464 return SILC_FSM_FINISH;
2467 /* Failure received from remote */
2469 SILC_FSM_STATE(silc_ske_st_responder_failure)
2471 SilcSKE ske = fsm_context;
2472 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2474 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2476 if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
2477 silc_buffer_len(&ske->packet->buffer) == 4) {
2478 SILC_GET32_MSB(error, ske->packet->buffer.data);
2479 ske->status = error;
2480 silc_packet_free(ske->packet);
2484 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2485 silc_schedule_task_del_by_context(ske->schedule, ske);
2487 /* Call completion */
2488 silc_ske_completion(ske);
2490 return SILC_FSM_FINISH;
2493 /* Error occurred */
2495 SILC_FSM_STATE(silc_ske_st_responder_error)
2497 SilcSKE ske = fsm_context;
2498 unsigned char tmp[4];
2500 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2501 ske->status, silc_ske_map_status(ske->status)));
2503 /* Send FAILURE packet */
2504 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2505 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2506 SILC_PUT32_MSB(ske->status, tmp);
2507 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2509 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2510 silc_schedule_task_del_by_context(ske->schedule, ske);
2512 /* Call completion */
2513 silc_ske_completion(ske);
2515 return SILC_FSM_FINISH;
2518 /* Starts the protocol as responder. */
2520 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2521 SilcPacketStream stream,
2522 SilcSKEParams params)
2524 SILC_LOG_DEBUG(("Start SKE as responder"));
2526 if (!ske || !stream || !params || !params->version)
2529 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2532 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2535 ske->responder = TRUE;
2536 ske->flags = params->flags;
2537 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2538 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2539 ske->session_port = params->session_port;
2540 ske->version = strdup(params->version);
2543 ske->running = TRUE;
2545 /* Link to packet stream to get key exchange packets */
2546 ske->stream = stream;
2547 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2548 SILC_PACKET_KEY_EXCHANGE,
2549 SILC_PACKET_KEY_EXCHANGE_1,
2550 SILC_PACKET_SUCCESS,
2551 SILC_PACKET_FAILURE, -1);
2553 /* Start SKE as responder */
2554 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2559 /***************************** Initiator Rekey ******************************/
2563 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2565 SilcSKE ske = fsm_context;
2568 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2572 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2573 return SILC_FSM_CONTINUE;
2576 /* Add rekey exchange timeout */
2577 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2580 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2583 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2584 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2585 return SILC_FSM_CONTINUE;
2588 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2589 /** Cannot allocate hash */
2590 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2591 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2592 return SILC_FSM_CONTINUE;
2595 /* Send REKEY packet to start rekey protocol */
2596 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2597 /** Error sending packet */
2598 SILC_LOG_DEBUG(("Error sending packet"));
2599 ske->status = SILC_SKE_STATUS_ERROR;
2600 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2601 return SILC_FSM_CONTINUE;
2604 /* If doing rekey without PFS, move directly to the end of the protocol. */
2605 if (!ske->rekey->pfs) {
2606 /** Rekey without PFS */
2607 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2608 return SILC_FSM_CONTINUE;
2611 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2613 if (status != SILC_SKE_STATUS_OK) {
2614 /** Unknown group */
2615 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2616 return SILC_FSM_CONTINUE;
2619 /** Rekey with PFS */
2620 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2621 return SILC_FSM_CONTINUE;
2624 /* Sends REKEY_DONE packet to finish the protocol. */
2626 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2628 SilcSKE ske = fsm_context;
2629 SilcCipher send_key;
2632 SilcUInt32 key_len, block_len, hash_len, x_len;
2633 unsigned char *pfsbuf;
2635 SILC_LOG_DEBUG(("Start"));
2637 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2638 key_len = silc_cipher_get_key_len(send_key);
2639 block_len = silc_cipher_get_block_len(send_key);
2640 hash = ske->prop->hash;
2641 hash_len = silc_hash_len(hash);
2643 /* Process key material */
2644 if (ske->rekey->pfs) {
2646 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2648 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2651 memset(pfsbuf, 0, x_len);
2657 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2658 ske->rekey->enc_key_len / 8,
2664 SILC_LOG_ERROR(("Error processing key material"));
2665 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2666 return SILC_FSM_CONTINUE;
2669 ske->prop->cipher = send_key;
2670 ske->prop->hmac = hmac_send;
2672 /* Get sending keys */
2673 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2674 &hmac_send, NULL, NULL)) {
2675 /** Cannot get keys */
2676 ske->status = SILC_SKE_STATUS_ERROR;
2677 ske->prop->cipher = NULL;
2678 ske->prop->hmac = NULL;
2679 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2680 return SILC_FSM_CONTINUE;
2683 ske->prop->cipher = NULL;
2684 ske->prop->hmac = NULL;
2686 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2687 packet sent after this call will be protected with the new keys. */
2688 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2690 /** Cannot set keys */
2691 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2692 ske->status = SILC_SKE_STATUS_ERROR;
2693 silc_cipher_free(send_key);
2694 silc_hmac_free(hmac_send);
2695 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2696 return SILC_FSM_CONTINUE;
2699 /** Wait for REKEY_DONE */
2700 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2701 return SILC_FSM_WAIT;
2704 /* Rekey protocol end */
2706 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2708 SilcSKE ske = fsm_context;
2709 SilcCipher receive_key;
2710 SilcHmac hmac_receive;
2711 SilcSKERekeyMaterial rekey;
2713 SILC_LOG_DEBUG(("Start"));
2715 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2716 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2717 silc_packet_free(ske->packet);
2719 return SILC_FSM_WAIT;
2722 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2723 ske->prop->cipher = receive_key;
2724 ske->prop->hmac = hmac_receive;
2726 /* Get receiving keys */
2727 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2728 NULL, &hmac_receive, NULL)) {
2729 /** Cannot get keys */
2730 ske->status = SILC_SKE_STATUS_ERROR;
2731 ske->prop->cipher = NULL;
2732 ske->prop->hmac = NULL;
2733 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2734 return SILC_FSM_CONTINUE;
2737 /* Set new receiving keys into use. All packets received after this will
2738 be decrypted with the new keys. */
2739 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2740 hmac_receive, FALSE)) {
2741 /** Cannot set keys */
2742 SILC_LOG_DEBUG(("Cannot set new keys"));
2743 ske->status = SILC_SKE_STATUS_ERROR;
2744 silc_cipher_free(receive_key);
2745 silc_hmac_free(hmac_receive);
2746 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2747 return SILC_FSM_CONTINUE;
2750 SILC_LOG_DEBUG(("Rekey completed successfully"));
2752 /* Generate new rekey material */
2753 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2756 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2757 ske->prop->cipher = NULL;
2758 ske->prop->hmac = NULL;
2759 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2760 return SILC_FSM_CONTINUE;
2762 rekey->pfs = ske->rekey->pfs;
2765 ske->prop->cipher = NULL;
2766 ske->prop->hmac = NULL;
2767 silc_packet_free(ske->packet);
2769 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2770 silc_schedule_task_del_by_context(ske->schedule, ske);
2772 /* Call completion */
2773 silc_ske_completion(ske);
2775 return SILC_FSM_FINISH;
2778 /* Starts rekey protocol as initiator */
2781 silc_ske_rekey_initiator(SilcSKE ske,
2782 SilcPacketStream stream,
2783 SilcSKERekeyMaterial rekey)
2785 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2787 if (!ske || !stream || !rekey) {
2788 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2793 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2796 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2800 ske->responder = FALSE;
2801 ske->running = TRUE;
2802 ske->rekeying = TRUE;
2804 /* Link to packet stream to get key exchange packets */
2805 ske->stream = stream;
2806 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2808 SILC_PACKET_REKEY_DONE,
2809 SILC_PACKET_KEY_EXCHANGE_2,
2810 SILC_PACKET_SUCCESS,
2811 SILC_PACKET_FAILURE, -1);
2813 /* Start SKE rekey as initiator */
2814 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2819 /***************************** Responder Rekey ******************************/
2821 /* Wait for initiator's packet */
2823 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2825 SilcSKE ske = fsm_context;
2827 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2831 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2832 return SILC_FSM_CONTINUE;
2835 /* Add rekey exchange timeout */
2836 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2839 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2841 /* If REKEY packet already received process it directly */
2842 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2843 return SILC_FSM_CONTINUE;
2845 /* Wait for REKEY */
2846 return SILC_FSM_WAIT;
2849 /* Process initiator's REKEY packet */
2851 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2853 SilcSKE ske = fsm_context;
2854 SilcSKEStatus status;
2856 SILC_LOG_DEBUG(("Start"));
2858 if (ske->packet->type != SILC_PACKET_REKEY) {
2859 ske->status = SILC_SKE_STATUS_ERROR;
2860 silc_packet_free(ske->packet);
2862 silc_fsm_next(fsm, silc_ske_st_responder_error);
2863 return SILC_FSM_CONTINUE;
2866 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2869 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2870 silc_fsm_next(fsm, silc_ske_st_responder_error);
2871 return SILC_FSM_CONTINUE;
2874 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2875 /** Cannot allocate hash */
2876 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2877 silc_fsm_next(fsm, silc_ske_st_responder_error);
2878 return SILC_FSM_CONTINUE;
2881 /* If doing rekey without PFS, move directly to the end of the protocol. */
2882 if (!ske->rekey->pfs) {
2883 /** Rekey without PFS */
2884 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2885 return SILC_FSM_CONTINUE;
2888 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2890 if (status != SILC_SKE_STATUS_OK) {
2891 /** Unknown group */
2892 silc_fsm_next(fsm, silc_ske_st_responder_error);
2893 return SILC_FSM_CONTINUE;
2896 /** Rekey with PFS */
2897 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2898 return SILC_FSM_WAIT;
2901 /* Sends REKEY_DONE packet to finish the protocol. */
2903 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2905 SilcSKE ske = fsm_context;
2906 SilcCipher send_key;
2909 SilcUInt32 key_len, block_len, hash_len, x_len;
2910 unsigned char *pfsbuf;
2912 SILC_LOG_DEBUG(("Start"));
2914 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2915 key_len = silc_cipher_get_key_len(send_key);
2916 block_len = silc_cipher_get_block_len(send_key);
2917 hash = ske->prop->hash;
2918 hash_len = silc_hash_len(hash);
2920 /* Process key material */
2921 if (ske->rekey->pfs) {
2923 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2925 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2928 memset(pfsbuf, 0, x_len);
2934 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2935 ske->rekey->enc_key_len / 8,
2941 SILC_LOG_ERROR(("Error processing key material"));
2942 silc_fsm_next(fsm, silc_ske_st_responder_error);
2943 return SILC_FSM_CONTINUE;
2946 ske->prop->cipher = send_key;
2947 ske->prop->hmac = hmac_send;
2949 /* Get sending keys */
2950 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2951 &hmac_send, NULL, NULL)) {
2952 /** Cannot get keys */
2953 ske->status = SILC_SKE_STATUS_ERROR;
2954 ske->prop->cipher = NULL;
2955 ske->prop->hmac = NULL;
2956 silc_fsm_next(fsm, silc_ske_st_responder_error);
2957 return SILC_FSM_CONTINUE;
2960 ske->prop->cipher = NULL;
2961 ske->prop->hmac = NULL;
2963 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2964 packet sent after this call will be protected with the new keys. */
2965 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2967 /** Cannot set keys */
2968 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2969 ske->status = SILC_SKE_STATUS_ERROR;
2970 silc_cipher_free(send_key);
2971 silc_hmac_free(hmac_send);
2972 silc_fsm_next(fsm, silc_ske_st_responder_error);
2973 return SILC_FSM_CONTINUE;
2976 /** Wait for REKEY_DONE */
2977 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2978 return SILC_FSM_WAIT;
2981 /* Rekey protocol end */
2983 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2985 SilcSKE ske = fsm_context;
2986 SilcCipher receive_key;
2987 SilcHmac hmac_receive;
2988 SilcSKERekeyMaterial rekey;
2990 SILC_LOG_DEBUG(("Start"));
2992 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2993 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2994 silc_packet_free(ske->packet);
2996 return SILC_FSM_WAIT;
2999 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
3000 ske->prop->cipher = receive_key;
3001 ske->prop->hmac = hmac_receive;
3003 /* Get receiving keys */
3004 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
3005 NULL, &hmac_receive, NULL)) {
3006 /** Cannot get keys */
3007 ske->status = SILC_SKE_STATUS_ERROR;
3008 ske->prop->cipher = NULL;
3009 ske->prop->hmac = NULL;
3010 silc_fsm_next(fsm, silc_ske_st_responder_error);
3011 return SILC_FSM_CONTINUE;
3014 /* Set new receiving keys into use. All packets received after this will
3015 be decrypted with the new keys. */
3016 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3017 hmac_receive, FALSE)) {
3018 /** Cannot set keys */
3019 SILC_LOG_DEBUG(("Cannot set new keys"));
3020 ske->status = SILC_SKE_STATUS_ERROR;
3021 ske->prop->cipher = NULL;
3022 ske->prop->hmac = NULL;
3023 silc_cipher_free(receive_key);
3024 silc_hmac_free(hmac_receive);
3025 silc_fsm_next(fsm, silc_ske_st_responder_error);
3026 return SILC_FSM_CONTINUE;
3029 SILC_LOG_DEBUG(("Rekey completed successfully"));
3031 /* Generate new rekey material */
3032 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3035 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3036 ske->prop->cipher = NULL;
3037 ske->prop->hmac = NULL;
3038 silc_fsm_next(fsm, silc_ske_st_responder_error);
3039 return SILC_FSM_CONTINUE;
3041 rekey->pfs = ske->rekey->pfs;
3044 ske->prop->cipher = NULL;
3045 ske->prop->hmac = NULL;
3046 silc_packet_free(ske->packet);
3048 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3049 silc_schedule_task_del_by_context(ske->schedule, ske);
3051 /* Call completion */
3052 silc_ske_completion(ske);
3054 return SILC_FSM_FINISH;
3057 /* Starts rekey protocol as responder */
3060 silc_ske_rekey_responder(SilcSKE ske,
3061 SilcPacketStream stream,
3062 SilcSKERekeyMaterial rekey,
3065 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3067 if (!ske || !stream || !rekey)
3070 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3073 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3077 ske->responder = TRUE;
3078 ske->running = TRUE;
3079 ske->rekeying = TRUE;
3080 ske->packet = packet;
3082 /* Link to packet stream to get key exchange packets */
3083 ske->stream = stream;
3084 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3086 SILC_PACKET_REKEY_DONE,
3087 SILC_PACKET_KEY_EXCHANGE_1,
3088 SILC_PACKET_SUCCESS,
3089 SILC_PACKET_FAILURE, -1);
3091 /* Start SKE rekey as responder */
3092 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3097 /* Processes the provided key material `data' as the SILC protocol
3098 specification defines. */
3101 silc_ske_process_key_material_data(unsigned char *data,
3102 SilcUInt32 data_len,
3103 SilcUInt32 req_iv_len,
3104 SilcUInt32 req_enc_key_len,
3105 SilcUInt32 req_hmac_key_len,
3109 unsigned char hashd[SILC_HASH_MAXLEN];
3110 SilcUInt32 hash_len = req_hmac_key_len;
3111 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3112 SilcSKEKeyMaterial key;
3114 SILC_LOG_DEBUG(("Start"));
3116 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3119 key = silc_calloc(1, sizeof(*key));
3123 buf = silc_buffer_alloc_size(1 + data_len);
3126 silc_buffer_format(buf,
3127 SILC_STR_UI_CHAR(0),
3128 SILC_STR_DATA(data, data_len),
3132 memset(hashd, 0, sizeof(hashd));
3134 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3135 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3136 memcpy(key->send_iv, hashd, req_iv_len);
3137 memset(hashd, 0, sizeof(hashd));
3139 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3140 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3141 memcpy(key->receive_iv, hashd, req_iv_len);
3142 key->iv_len = req_iv_len;
3144 /* Take the encryption keys. If requested key size is more than
3145 the size of hash length we will distribute more key material
3146 as protocol defines. */
3148 if (enc_key_len > hash_len) {
3150 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3151 k3[SILC_HASH_MAXLEN];
3152 unsigned char *dtmp;
3155 if (enc_key_len > (3 * hash_len))
3158 /* Take first round */
3159 memset(k1, 0, sizeof(k1));
3160 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3162 /* Take second round */
3163 dist = silc_buffer_alloc_size(data_len + hash_len);
3166 silc_buffer_format(dist,
3167 SILC_STR_DATA(data, data_len),
3168 SILC_STR_DATA(k1, hash_len),
3170 memset(k2, 0, sizeof(k2));
3171 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3173 /* Take third round */
3174 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3175 silc_buffer_pull_tail(dist, hash_len);
3176 silc_buffer_pull(dist, data_len + hash_len);
3177 silc_buffer_format(dist,
3178 SILC_STR_DATA(k2, hash_len),
3180 silc_buffer_push(dist, data_len + hash_len);
3181 memset(k3, 0, sizeof(k3));
3182 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3184 /* Then, save the keys */
3185 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3186 memcpy(dtmp, k1, hash_len);
3187 memcpy(dtmp + hash_len, k2, hash_len);
3188 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3190 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3191 memcpy(key->send_enc_key, dtmp, enc_key_len);
3192 key->enc_key_len = req_enc_key_len;
3194 memset(dtmp, 0, (3 * hash_len));
3195 memset(k1, 0, sizeof(k1));
3196 memset(k2, 0, sizeof(k2));
3197 memset(k3, 0, sizeof(k3));
3199 silc_buffer_clear(dist);
3200 silc_buffer_free(dist);
3202 /* Take normal hash as key */
3203 memset(hashd, 0, sizeof(hashd));
3204 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3205 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3206 memcpy(key->send_enc_key, hashd, enc_key_len);
3207 key->enc_key_len = req_enc_key_len;
3211 if (enc_key_len > hash_len) {
3213 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3214 k3[SILC_HASH_MAXLEN];
3215 unsigned char *dtmp;
3218 if (enc_key_len > (3 * hash_len))
3221 /* Take first round */
3222 memset(k1, 0, sizeof(k1));
3223 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3225 /* Take second round */
3226 dist = silc_buffer_alloc_size(data_len + hash_len);
3229 silc_buffer_format(dist,
3230 SILC_STR_DATA(data, data_len),
3231 SILC_STR_DATA(k1, hash_len),
3233 memset(k2, 0, sizeof(k2));
3234 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3236 /* Take third round */
3237 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3238 silc_buffer_pull_tail(dist, hash_len);
3239 silc_buffer_pull(dist, data_len + hash_len);
3240 silc_buffer_format(dist,
3241 SILC_STR_DATA(k2, hash_len),
3243 silc_buffer_push(dist, data_len + hash_len);
3244 memset(k3, 0, sizeof(k3));
3245 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3247 /* Then, save the keys */
3248 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3249 memcpy(dtmp, k1, hash_len);
3250 memcpy(dtmp + hash_len, k2, hash_len);
3251 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3253 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3254 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3255 key->enc_key_len = req_enc_key_len;
3257 memset(dtmp, 0, (3 * hash_len));
3258 memset(k1, 0, sizeof(k1));
3259 memset(k2, 0, sizeof(k2));
3260 memset(k3, 0, sizeof(k3));
3262 silc_buffer_clear(dist);
3263 silc_buffer_free(dist);
3265 /* Take normal hash as key */
3266 memset(hashd, 0, sizeof(hashd));
3267 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3268 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3269 memcpy(key->receive_enc_key, hashd, enc_key_len);
3270 key->enc_key_len = req_enc_key_len;
3273 /* Take HMAC keys */
3274 memset(hashd, 0, sizeof(hashd));
3276 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3277 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3278 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3279 memset(hashd, 0, sizeof(hashd));
3281 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3282 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3283 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3284 key->hmac_key_len = req_hmac_key_len;
3285 memset(hashd, 0, sizeof(hashd));
3287 silc_buffer_clear(buf);
3288 silc_buffer_free(buf);
3290 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3295 /* Processes negotiated key material as protocol specifies. This returns
3296 the actual keys to be used in the SILC. */
3299 silc_ske_process_key_material(SilcSKE ske,
3300 SilcUInt32 req_iv_len,
3301 SilcUInt32 req_enc_key_len,
3302 SilcUInt32 req_hmac_key_len,
3303 SilcSKERekeyMaterial *rekey)
3306 unsigned char *tmpbuf;
3308 SilcSKEKeyMaterial key;
3310 /* Encode KEY to binary data */
3311 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3313 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3316 silc_buffer_format(buf,
3317 SILC_STR_DATA(tmpbuf, klen),
3318 SILC_STR_DATA(ske->hash, ske->hash_len),
3321 /* Process the key material */
3322 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3323 req_iv_len, req_enc_key_len,
3327 memset(tmpbuf, 0, klen);
3329 silc_buffer_clear(buf);
3330 silc_buffer_free(buf);
3333 *rekey = silc_ske_make_rekey_material(ske, key);
3341 /* Free key material structure */
3343 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3349 silc_free(key->send_iv);
3350 if (key->receive_iv)
3351 silc_free(key->receive_iv);
3352 if (key->send_enc_key) {
3353 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3354 silc_free(key->send_enc_key);
3356 if (key->receive_enc_key) {
3357 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3358 silc_free(key->receive_enc_key);
3360 if (key->send_hmac_key) {
3361 memset(key->send_hmac_key, 0, key->hmac_key_len);
3362 silc_free(key->send_hmac_key);
3364 if (key->receive_hmac_key) {
3365 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3366 silc_free(key->receive_hmac_key);
3371 /* Free rekey material */
3373 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3377 if (rekey->send_enc_key) {
3378 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3379 silc_free(rekey->send_enc_key);
3381 silc_free(rekey->hash);
3385 /* Set keys into use */
3387 SilcBool silc_ske_set_keys(SilcSKE ske,
3388 SilcSKEKeyMaterial keymat,
3389 SilcSKESecurityProperties prop,
3390 SilcCipher *ret_send_key,
3391 SilcCipher *ret_receive_key,
3392 SilcHmac *ret_hmac_send,
3393 SilcHmac *ret_hmac_receive,
3396 unsigned char iv[SILC_HASH_MAXLEN];
3397 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3399 /* Allocate ciphers to be used in the communication */
3401 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3405 if (ret_receive_key) {
3406 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3411 /* Allocate HMACs */
3412 if (ret_hmac_send) {
3413 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3417 if (ret_hmac_receive) {
3418 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3425 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3429 /* Set key material */
3430 memset(iv, 0, sizeof(iv));
3431 if (ske->responder) {
3433 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3434 keymat->enc_key_len, TRUE);
3436 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3438 if (!ske->rekeying) {
3440 memcpy(iv, ske->hash, 4);
3442 memcpy(iv + 4, keymat->receive_iv, 8);
3444 /* Rekey, recompute the truncated hash value. */
3445 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3447 memcpy(iv + 4, keymat->receive_iv, 8);
3449 memset(iv + 4, 0, 12);
3452 silc_cipher_set_iv(*ret_send_key, iv);
3455 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3458 if (ret_receive_key) {
3459 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3460 keymat->enc_key_len, FALSE);
3462 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3464 if (!ske->rekeying) {
3466 memcpy(iv, ske->hash, 4);
3468 memcpy(iv + 4, keymat->send_iv, 8);
3470 /* Rekey, recompute the truncated hash value. */
3471 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3473 memcpy(iv + 4, keymat->send_iv, 8);
3475 memset(iv + 4, 0, 12);
3478 silc_cipher_set_iv(*ret_receive_key, iv);
3481 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3485 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3486 keymat->hmac_key_len);
3487 if (ret_hmac_receive)
3488 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3489 keymat->hmac_key_len);
3492 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3493 keymat->enc_key_len, TRUE);
3495 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3497 if (!ske->rekeying) {
3499 memcpy(iv, ske->hash, 4);
3501 memcpy(iv + 4, keymat->send_iv, 8);
3503 /* Rekey, recompute the truncated hash value. */
3504 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3506 memcpy(iv + 4, keymat->send_iv, 8);
3508 memset(iv + 4, 0, 12);
3511 silc_cipher_set_iv(*ret_send_key, iv);
3514 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3517 if (ret_receive_key) {
3518 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3519 keymat->enc_key_len, FALSE);
3521 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3523 if (!ske->rekeying) {
3524 /* Set IV. If IV Included flag was negotiated we only set the
3525 truncated hash value. */
3526 memcpy(iv, ske->hash, 4);
3528 memcpy(iv + 4, keymat->receive_iv, 8);
3530 /* Rekey, recompute the truncated hash value. */
3531 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3533 memcpy(iv + 4, keymat->receive_iv, 8);
3535 memset(iv + 4, 0, 12);
3538 silc_cipher_set_iv(*ret_receive_key, iv);
3541 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3545 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3546 keymat->hmac_key_len);
3547 if (ret_hmac_receive)
3548 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3549 keymat->hmac_key_len);
3555 const char *silc_ske_status_string[] =
3559 "Unexpected error occurred",
3560 "Bad payload in packet",
3561 "Unsupported group",
3562 "Unsupported cipher",
3564 "Unsupported hash function",
3566 "Unsupported public key (or certificate)",
3567 "Incorrect signature",
3568 "Bad or unsupported version",
3572 "Remote did not provide public key",
3573 "Bad reserved field in packet",
3574 "Bad payload length in packet",
3575 "Error computing signature",
3576 "System out of memory",
3577 "Key exchange timeout",
3582 /* Maps status to readable string and returns the string. If string is not
3583 found and empty character string ("") is returned. */
3585 const char *silc_ske_map_status(SilcSKEStatus status)
3589 for (i = 0; silc_ske_status_string[i]; i++)
3591 return silc_ske_status_string[i];
3596 /* Parses remote host's version string. */
3598 SilcBool silc_ske_parse_version(SilcSKE ske,
3599 SilcUInt32 *protocol_version,
3600 char **protocol_version_string,
3601 SilcUInt32 *software_version,
3602 char **software_version_string,
3603 char **vendor_version)
3605 return silc_parse_version_string(ske->remote_version,
3607 protocol_version_string,
3609 software_version_string,
3613 /* Get security properties */
3615 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3620 /* Get key material */
3622 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)