5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2008 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
23 #include "groups_internal.h"
25 /************************** Types and definitions ***************************/
27 /* Structure to hold all SKE callbacks. */
28 struct SilcSKECallbacksStruct {
29 SilcSKEVerifyCb verify_key;
30 SilcSKECompletionCb completed;
34 /************************ Static utility functions **************************/
37 SILC_FSM_STATE(silc_ske_st_initiator_start);
38 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
39 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
40 SILC_FSM_STATE(silc_ske_st_initiator_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 memset(hash, 'F', sizeof(hash));
1727 silc_ske_payload_ke_free(payload);
1728 ske->ke2_payload = NULL;
1730 silc_mp_uninit(ske->KEY);
1731 silc_free(ske->KEY);
1735 memset(ske->hash, 'F', hash_len);
1736 silc_free(ske->hash);
1740 if (status == SILC_SKE_STATUS_OK)
1741 status = SILC_SKE_STATUS_ERROR;
1744 ske->status = status;
1745 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1746 return SILC_FSM_CONTINUE;
1749 /* Process key material */
1751 SILC_FSM_STATE(silc_ske_st_initiator_phase5)
1753 SilcSKE ske = fsm_context;
1754 SilcSKEStatus status;
1755 unsigned char tmp[4];
1756 SilcUInt32 hash_len;
1757 int key_len, block_len;
1759 ske->status = SILC_SKE_STATUS_OK;
1761 /* In case we are doing rekey move to finish it. */
1764 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1765 return SILC_FSM_CONTINUE;
1768 /* Process key material */
1769 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1770 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1771 hash_len = silc_hash_len(ske->prop->hash);
1772 ske->keymat = silc_ske_process_key_material(ske, block_len,
1776 SILC_LOG_ERROR(("Error processing key material"));
1777 status = SILC_SKE_STATUS_ERROR;
1778 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1779 return SILC_FSM_CONTINUE;
1782 /* Send SUCCESS packet */
1783 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, tmp);
1784 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4)) {
1785 /** Error sending packet */
1786 SILC_LOG_DEBUG(("Error sending packet"));
1787 ske->status = SILC_SKE_STATUS_ERROR;
1788 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1789 return SILC_FSM_CONTINUE;
1792 /** Waiting completion */
1793 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1794 return SILC_FSM_WAIT;
1797 /* Protocol completed */
1799 SILC_FSM_STATE(silc_ske_st_initiator_end)
1801 SilcSKE ske = fsm_context;
1803 SILC_LOG_DEBUG(("Start"));
1805 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1806 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1807 silc_ske_install_retransmission(ske);
1808 silc_packet_free(ske->packet);
1810 return SILC_FSM_WAIT;
1813 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1815 silc_packet_free(ske->packet);
1817 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1818 silc_schedule_task_del_by_context(ske->schedule, ske);
1820 /* Call completion */
1821 silc_ske_completion(ske);
1823 return SILC_FSM_FINISH;
1826 /* Aborted by application */
1828 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1830 SilcSKE ske = fsm_context;
1831 unsigned char data[4];
1833 SILC_LOG_DEBUG(("Aborted by caller"));
1835 /* Send FAILURE packet */
1836 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1837 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1839 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1840 silc_schedule_task_del_by_context(ske->schedule, ske);
1842 /* Call completion */
1843 silc_ske_completion(ske);
1845 return SILC_FSM_FINISH;
1848 /* Error occurred. Send error to remote host */
1850 SILC_FSM_STATE(silc_ske_st_initiator_error)
1852 SilcSKE ske = fsm_context;
1853 SilcSKEStatus status;
1854 unsigned char data[4];
1856 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1857 silc_ske_map_status(ske->status), ske->status));
1859 status = ske->status;
1860 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1861 status = SILC_SKE_STATUS_ERROR;
1863 /* Send FAILURE packet */
1864 SILC_PUT32_MSB((SilcUInt32)status, data);
1865 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1867 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1868 silc_schedule_task_del_by_context(ske->schedule, ske);
1870 /* Call completion */
1871 silc_ske_completion(ske);
1873 return SILC_FSM_FINISH;
1876 /* Failure received from remote */
1878 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1880 SilcSKE ske = fsm_context;
1881 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1883 if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
1884 silc_buffer_len(&ske->packet->buffer) == 4) {
1885 SILC_GET32_MSB(error, ske->packet->buffer.data);
1886 ske->status = error;
1887 silc_packet_free(ske->packet);
1891 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1892 silc_ske_map_status(ske->status), ske->status));
1894 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1895 silc_schedule_task_del_by_context(ske->schedule, ske);
1897 /* Call completion */
1898 silc_ske_completion(ske);
1900 return SILC_FSM_FINISH;
1903 /* Starts the protocol as initiator */
1905 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1906 SilcPacketStream stream,
1907 SilcSKEParams params,
1908 SilcSKEStartPayload start_payload)
1910 SILC_LOG_DEBUG(("Start SKE as initiator"));
1912 if (!ske || !stream || !params || !params->version)
1915 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1918 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1921 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1922 ske->session_port = params->session_port;
1924 /* Generate security properties if not provided */
1925 if (!start_payload) {
1926 start_payload = silc_ske_assemble_security_properties(ske,
1933 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1934 ske->start_payload = start_payload;
1935 ske->version = params->version;
1936 ske->running = TRUE;
1938 /* Link to packet stream to get key exchange packets */
1939 ske->stream = stream;
1940 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1941 SILC_PACKET_KEY_EXCHANGE,
1942 SILC_PACKET_KEY_EXCHANGE_2,
1943 SILC_PACKET_SUCCESS,
1944 SILC_PACKET_FAILURE, -1);
1946 /* Start SKE as initiator */
1947 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1952 /******************************** Responder *********************************/
1954 /* Start protocol as responder. Wait initiator's start payload */
1956 SILC_FSM_STATE(silc_ske_st_responder_start)
1958 SilcSKE ske = fsm_context;
1960 SILC_LOG_DEBUG(("Start"));
1964 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1965 return SILC_FSM_CONTINUE;
1968 /* Add key exchange timeout */
1969 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1970 ske, ske->timeout, 0);
1972 /** Wait for initiator */
1973 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1974 return SILC_FSM_WAIT;
1977 /* Decode initiator's start payload. Select the security properties from
1978 the initiator's start payload and send our reply start payload back. */
1980 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1982 SilcSKE ske = fsm_context;
1983 SilcSKEStatus status;
1984 SilcSKEStartPayload remote_payload = NULL;
1985 SilcBuffer packet_buf = &ske->packet->buffer;
1988 SILC_LOG_DEBUG(("Start"));
1990 /* Decode the payload */
1991 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1992 if (status != SILC_SKE_STATUS_OK) {
1993 /** Error decoding Start Payload */
1994 silc_packet_free(ske->packet);
1996 ske->status = status;
1997 silc_fsm_next(fsm, silc_ske_st_responder_error);
1998 return SILC_FSM_CONTINUE;
2001 /* Get remote ID and set it to stream */
2002 if (ske->packet->src_id_len) {
2003 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
2004 ske->packet->src_id_type,
2005 (ske->packet->src_id_type == SILC_ID_SERVER ?
2006 (void *)&id.u.server_id : (void *)&id.u.client_id),
2007 (ske->packet->src_id_type == SILC_ID_SERVER ?
2008 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
2009 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
2010 (ske->packet->src_id_type == SILC_ID_SERVER ?
2011 (void *)&id.u.server_id : (void *)&id.u.client_id));
2014 /* Take a copy of the payload buffer for future use. It is used to
2015 compute the HASH value. */
2016 ske->start_payload_copy = silc_buffer_copy(packet_buf);
2018 silc_packet_free(ske->packet);
2021 /* Force the mutual authentication flag if we want to do it. */
2022 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2023 SILC_LOG_DEBUG(("Force mutual authentication"));
2024 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
2027 /* Force PFS flag if we require it */
2028 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
2029 SILC_LOG_DEBUG(("Force PFS"));
2030 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
2033 /* Disable IV Included flag if requested */
2034 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
2035 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
2036 SILC_LOG_DEBUG(("We do not support IV Included flag"));
2037 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
2040 /* Check and select security properties */
2041 status = silc_ske_select_security_properties(ske, remote_payload,
2043 if (status != SILC_SKE_STATUS_OK) {
2044 /** Error selecting proposal */
2045 silc_ske_payload_start_free(remote_payload);
2046 ske->status = status;
2047 silc_fsm_next(fsm, silc_ske_st_responder_error);
2048 return SILC_FSM_CONTINUE;
2051 silc_ske_payload_start_free(remote_payload);
2053 /* Encode our reply payload to send the selected security properties */
2054 status = silc_ske_payload_start_encode(ske, ske->start_payload,
2056 if (status != SILC_SKE_STATUS_OK)
2059 /* Send the packet. */
2060 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
2061 silc_buffer_data(packet_buf),
2062 silc_buffer_len(packet_buf)))
2065 silc_buffer_free(packet_buf);
2067 /** Waiting initiator's KE payload */
2068 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2069 return SILC_FSM_WAIT;
2072 if (ske->prop->group)
2073 silc_ske_group_free(ske->prop->group);
2074 if (ske->prop->cipher)
2075 silc_cipher_free(ske->prop->cipher);
2076 if (ske->prop->hash)
2077 silc_hash_free(ske->prop->hash);
2078 if (ske->prop->hmac)
2079 silc_hmac_free(ske->prop->hmac);
2080 silc_free(ske->prop);
2083 if (status == SILC_SKE_STATUS_OK)
2084 status = SILC_SKE_STATUS_ERROR;
2087 ske->status = status;
2088 silc_fsm_next(fsm, silc_ske_st_responder_error);
2089 return SILC_FSM_CONTINUE;
2092 /* Phase-2. Decode initiator's KE payload */
2094 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2096 SilcSKE ske = fsm_context;
2097 SilcSKEStatus status;
2098 SilcSKEKEPayload recv_payload;
2099 SilcBuffer packet_buf = &ske->packet->buffer;
2101 SILC_LOG_DEBUG(("Start"));
2103 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2104 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2105 silc_ske_install_retransmission(ske);
2106 silc_packet_free(ske->packet);
2108 return SILC_FSM_WAIT;
2111 /* Decode Key Exchange Payload */
2112 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2113 if (status != SILC_SKE_STATUS_OK) {
2114 /** Error decoding KE payload */
2115 silc_packet_free(ske->packet);
2117 ske->status = status;
2118 silc_fsm_next(fsm, silc_ske_st_responder_error);
2119 return SILC_FSM_CONTINUE;
2122 ske->ke1_payload = recv_payload;
2124 silc_packet_free(ske->packet);
2127 /* Verify public key, except in rekey, when it is not sent */
2129 if (!recv_payload->pk_data) {
2130 /** Public key not provided */
2131 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2132 "certificate), even though we require it"));
2133 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2134 silc_fsm_next(fsm, silc_ske_st_responder_error);
2135 return SILC_FSM_CONTINUE;
2138 /* Decode the remote's public key */
2139 if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2140 recv_payload->pk_data,
2141 recv_payload->pk_len,
2142 &ske->prop->public_key)) {
2143 /** Error decoding public key */
2144 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2145 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2146 silc_fsm_next(fsm, silc_ske_st_responder_error);
2147 return SILC_FSM_CONTINUE;
2150 SILC_LOG_DEBUG(("Verifying public key"));
2152 /** Waiting public key verification */
2153 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2155 /* If repository is provided, verify the key from there. */
2156 if (ske->repository) {
2159 find = silc_skr_find_alloc();
2161 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2162 silc_fsm_next(fsm, silc_ske_st_responder_error);
2163 return SILC_FSM_CONTINUE;
2165 silc_skr_find_set_pkcs_type(find,
2166 silc_pkcs_get_type(ske->prop->public_key));
2167 silc_skr_find_set_public_key(find, ske->prop->public_key);
2168 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2170 /* Find key from repository */
2171 SILC_FSM_CALL(silc_skr_find(ske->repository,
2172 silc_fsm_get_schedule(fsm), find,
2173 silc_ske_skr_callback, ske));
2175 /* Verify from application */
2176 if (ske->callbacks->verify_key)
2177 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2178 ske->callbacks->context,
2179 silc_ske_pk_verified, NULL));
2183 /** Generate KE2 payload */
2184 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2185 return SILC_FSM_CONTINUE;
2188 /* Phase-4. Generate KE2 payload, verify signature */
2190 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2192 SilcSKE ske = fsm_context;
2193 SilcSKEStatus status;
2194 SilcSKEKEPayload recv_payload;
2198 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2199 return SILC_FSM_CONTINUE;
2202 /* Check result of public key verification */
2203 if (ske->status != SILC_SKE_STATUS_OK) {
2204 /** Public key not verified */
2205 SILC_LOG_DEBUG(("Public key verification failed"));
2206 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2207 return SILC_FSM_CONTINUE;
2210 recv_payload = ske->ke1_payload;
2212 /** Send KE2 packet */
2213 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2215 /* The public key verification was performed only if the Mutual
2216 Authentication flag is set. */
2217 if (ske->start_payload &&
2218 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2219 unsigned char hash[SILC_HASH_MAXLEN];
2220 SilcUInt32 hash_len;
2222 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2224 /* Compute the hash value */
2225 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2226 if (status != SILC_SKE_STATUS_OK) {
2227 /** Error computing hash */
2228 ske->status = status;
2229 silc_fsm_next(fsm, silc_ske_st_responder_error);
2230 return SILC_FSM_CONTINUE;
2233 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2235 /* Verify signature */
2236 SILC_FSM_CALL(ske->key_op =
2237 silc_pkcs_verify_async(ske->prop->public_key,
2238 recv_payload->sign_data,
2239 recv_payload->sign_len,
2240 hash, hash_len, FALSE, NULL,
2241 silc_ske_verify_cb, ske));
2245 return SILC_FSM_CONTINUE;
2248 /* Phase-5. Send KE2 payload */
2250 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2252 SilcSKE ske = fsm_context;
2253 SilcSKEStatus status;
2254 unsigned char hash[SILC_HASH_MAXLEN], *pk;
2255 SilcUInt32 hash_len, pk_len;
2257 SilcSKEKEPayload send_payload;
2259 SILC_LOG_DEBUG(("Start"));
2261 /* Create the random number x, 1 < x < q. */
2262 x = silc_calloc(1, sizeof(*x));
2265 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2266 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2268 if (status != SILC_SKE_STATUS_OK) {
2269 /** Error generating random number */
2272 ske->status = status;
2273 silc_fsm_next(fsm, silc_ske_st_responder_error);
2274 return SILC_FSM_CONTINUE;
2277 /* Save the results for later processing */
2278 send_payload = silc_calloc(1, sizeof(*send_payload));
2280 ske->ke2_payload = send_payload;
2282 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2284 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2285 silc_mp_init(&send_payload->x);
2286 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2287 &ske->prop->group->group);
2289 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2291 /* Compute the shared secret key */
2292 KEY = silc_calloc(1, sizeof(*KEY));
2294 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2295 &ske->prop->group->group);
2298 if (ske->public_key && ske->private_key) {
2299 SILC_LOG_DEBUG(("Getting public key"));
2301 /* Get the public key */
2302 pk = silc_pkcs_public_key_encode(NULL, ske->public_key, &pk_len);
2304 /** Error encoding public key */
2305 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2306 silc_fsm_next(fsm, silc_ske_st_responder_error);
2307 return SILC_FSM_CONTINUE;
2309 ske->ke2_payload->pk_data = pk;
2310 ske->ke2_payload->pk_len = pk_len;
2313 SILC_LOG_DEBUG(("Computing HASH value"));
2315 /* Compute the hash value */
2316 memset(hash, 0, sizeof(hash));
2317 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2318 if (status != SILC_SKE_STATUS_OK) {
2319 /** Error computing hash */
2320 ske->status = status;
2321 silc_fsm_next(fsm, silc_ske_st_responder_error);
2322 return SILC_FSM_CONTINUE;
2324 ske->hash = silc_memdup(hash, hash_len);
2325 ske->hash_len = hash_len;
2327 /** Send KE2 packet */
2328 silc_fsm_next(fsm, silc_ske_st_responder_phase5_send);
2330 if (ske->public_key && ske->private_key) {
2331 SILC_LOG_DEBUG(("Signing HASH value"));
2333 /* Sign the hash value */
2334 SILC_FSM_CALL(ske->key_op =
2335 silc_pkcs_sign_async(ske->private_key, hash, hash_len, FALSE,
2336 ske->prop->hash, ske->rng,
2337 silc_ske_responder_sign_cb, ske));
2341 return SILC_FSM_CONTINUE;
2344 /* Send KE2 packet */
2346 SILC_FSM_STATE(silc_ske_st_responder_phase5_send)
2348 SilcSKE ske = fsm_context;
2349 SilcSKEStatus status;
2350 SilcBuffer payload_buf;
2352 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2354 /* Encode the Key Exchange Payload */
2355 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2357 if (status != SILC_SKE_STATUS_OK) {
2358 /** Error encoding KE payload */
2359 ske->status = status;
2360 silc_fsm_next(fsm, silc_ske_st_responder_error);
2361 return SILC_FSM_CONTINUE;
2364 /* Send the packet. */
2365 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2366 payload_buf->data, silc_buffer_len(payload_buf))) {
2367 SILC_LOG_DEBUG(("Error sending packet"));
2368 ske->status = SILC_SKE_STATUS_ERROR;
2369 silc_fsm_next(fsm, silc_ske_st_responder_error);
2370 return SILC_FSM_CONTINUE;
2373 silc_buffer_free(payload_buf);
2375 /* In case we are doing rekey move to finish it. */
2378 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2379 return SILC_FSM_CONTINUE;
2382 /** Waiting completion */
2383 silc_fsm_next(fsm, silc_ske_st_responder_end);
2384 return SILC_FSM_WAIT;
2387 /* Protocol completed */
2389 SILC_FSM_STATE(silc_ske_st_responder_end)
2391 SilcSKE ske = fsm_context;
2392 unsigned char tmp[4];
2393 SilcUInt32 hash_len, key_len, block_len;
2395 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2396 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2397 silc_ske_install_retransmission(ske);
2398 silc_packet_free(ske->packet);
2400 return SILC_FSM_WAIT;
2402 silc_packet_free(ske->packet);
2405 /* Process key material */
2406 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2407 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2408 hash_len = silc_hash_len(ske->prop->hash);
2409 ske->keymat = silc_ske_process_key_material(ske, block_len,
2413 /** Error processing key material */
2414 ske->status = SILC_SKE_STATUS_ERROR;
2415 silc_fsm_next(fsm, silc_ske_st_responder_error);
2416 return SILC_FSM_CONTINUE;
2419 /* Send SUCCESS packet */
2420 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2421 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2423 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2424 silc_schedule_task_del_by_context(ske->schedule, ske);
2426 /* Call completion */
2427 silc_ske_completion(ske);
2429 return SILC_FSM_FINISH;
2432 /* Aborted by application */
2434 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2436 SilcSKE ske = fsm_context;
2437 unsigned char tmp[4];
2439 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2441 /* Send FAILURE packet */
2442 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2443 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2445 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2446 silc_schedule_task_del_by_context(ske->schedule, ske);
2448 /* Call completion */
2449 silc_ske_completion(ske);
2451 return SILC_FSM_FINISH;
2454 /* Failure received from remote */
2456 SILC_FSM_STATE(silc_ske_st_responder_failure)
2458 SilcSKE ske = fsm_context;
2459 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2461 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2463 if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
2464 silc_buffer_len(&ske->packet->buffer) == 4) {
2465 SILC_GET32_MSB(error, ske->packet->buffer.data);
2466 ske->status = error;
2467 silc_packet_free(ske->packet);
2471 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2472 silc_schedule_task_del_by_context(ske->schedule, ske);
2474 /* Call completion */
2475 silc_ske_completion(ske);
2477 return SILC_FSM_FINISH;
2480 /* Error occurred */
2482 SILC_FSM_STATE(silc_ske_st_responder_error)
2484 SilcSKE ske = fsm_context;
2485 unsigned char tmp[4];
2487 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2488 ske->status, silc_ske_map_status(ske->status)));
2490 /* Send FAILURE packet */
2491 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2492 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2493 SILC_PUT32_MSB(ske->status, tmp);
2494 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2496 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2497 silc_schedule_task_del_by_context(ske->schedule, ske);
2499 /* Call completion */
2500 silc_ske_completion(ske);
2502 return SILC_FSM_FINISH;
2505 /* Starts the protocol as responder. */
2507 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2508 SilcPacketStream stream,
2509 SilcSKEParams params)
2511 SILC_LOG_DEBUG(("Start SKE as responder"));
2513 if (!ske || !stream || !params || !params->version)
2516 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2519 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2522 ske->responder = TRUE;
2523 ske->flags = params->flags;
2524 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2525 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2526 ske->session_port = params->session_port;
2527 ske->version = strdup(params->version);
2530 ske->running = TRUE;
2532 /* Link to packet stream to get key exchange packets */
2533 ske->stream = stream;
2534 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2535 SILC_PACKET_KEY_EXCHANGE,
2536 SILC_PACKET_KEY_EXCHANGE_1,
2537 SILC_PACKET_SUCCESS,
2538 SILC_PACKET_FAILURE, -1);
2540 /* Start SKE as responder */
2541 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2546 /***************************** Initiator Rekey ******************************/
2550 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2552 SilcSKE ske = fsm_context;
2555 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2559 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2560 return SILC_FSM_CONTINUE;
2563 /* Add rekey exchange timeout */
2564 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2567 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2570 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2571 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2572 return SILC_FSM_CONTINUE;
2575 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2576 /** Cannot allocate hash */
2577 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2578 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2579 return SILC_FSM_CONTINUE;
2582 /* Send REKEY packet to start rekey protocol */
2583 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2584 /** Error sending packet */
2585 SILC_LOG_DEBUG(("Error sending packet"));
2586 ske->status = SILC_SKE_STATUS_ERROR;
2587 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2588 return SILC_FSM_CONTINUE;
2591 /* If doing rekey without PFS, move directly to the end of the protocol. */
2592 if (!ske->rekey->pfs) {
2593 /** Rekey without PFS */
2594 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2595 return SILC_FSM_CONTINUE;
2598 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2600 if (status != SILC_SKE_STATUS_OK) {
2601 /** Unknown group */
2602 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2603 return SILC_FSM_CONTINUE;
2606 /** Rekey with PFS */
2607 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2608 return SILC_FSM_CONTINUE;
2611 /* Sends REKEY_DONE packet to finish the protocol. */
2613 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2615 SilcSKE ske = fsm_context;
2616 SilcCipher send_key;
2619 SilcUInt32 key_len, block_len, hash_len, x_len;
2620 unsigned char *pfsbuf;
2622 SILC_LOG_DEBUG(("Start"));
2624 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2625 key_len = silc_cipher_get_key_len(send_key);
2626 block_len = silc_cipher_get_block_len(send_key);
2627 hash = ske->prop->hash;
2628 hash_len = silc_hash_len(hash);
2630 /* Process key material */
2631 if (ske->rekey->pfs) {
2633 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2635 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2638 memset(pfsbuf, 0, x_len);
2644 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2645 ske->rekey->enc_key_len / 8,
2651 SILC_LOG_ERROR(("Error processing key material"));
2652 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2653 return SILC_FSM_CONTINUE;
2656 ske->prop->cipher = send_key;
2657 ske->prop->hmac = hmac_send;
2659 /* Get sending keys */
2660 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2661 &hmac_send, NULL, NULL)) {
2662 /** Cannot get keys */
2663 ske->status = SILC_SKE_STATUS_ERROR;
2664 ske->prop->cipher = NULL;
2665 ske->prop->hmac = NULL;
2666 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2667 return SILC_FSM_CONTINUE;
2670 ske->prop->cipher = NULL;
2671 ske->prop->hmac = NULL;
2673 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2674 packet sent after this call will be protected with the new keys. */
2675 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2677 /** Cannot set keys */
2678 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2679 ske->status = SILC_SKE_STATUS_ERROR;
2680 silc_cipher_free(send_key);
2681 silc_hmac_free(hmac_send);
2682 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2683 return SILC_FSM_CONTINUE;
2686 /** Wait for REKEY_DONE */
2687 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2688 return SILC_FSM_WAIT;
2691 /* Rekey protocol end */
2693 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2695 SilcSKE ske = fsm_context;
2696 SilcCipher receive_key;
2697 SilcHmac hmac_receive;
2698 SilcSKERekeyMaterial rekey;
2700 SILC_LOG_DEBUG(("Start"));
2702 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2703 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2704 silc_packet_free(ske->packet);
2706 return SILC_FSM_WAIT;
2709 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2710 ske->prop->cipher = receive_key;
2711 ske->prop->hmac = hmac_receive;
2713 /* Get receiving keys */
2714 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2715 NULL, &hmac_receive, NULL)) {
2716 /** Cannot get keys */
2717 ske->status = SILC_SKE_STATUS_ERROR;
2718 ske->prop->cipher = NULL;
2719 ske->prop->hmac = NULL;
2720 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2721 return SILC_FSM_CONTINUE;
2724 /* Set new receiving keys into use. All packets received after this will
2725 be decrypted with the new keys. */
2726 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2727 hmac_receive, FALSE)) {
2728 /** Cannot set keys */
2729 SILC_LOG_DEBUG(("Cannot set new keys"));
2730 ske->status = SILC_SKE_STATUS_ERROR;
2731 silc_cipher_free(receive_key);
2732 silc_hmac_free(hmac_receive);
2733 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2734 return SILC_FSM_CONTINUE;
2737 SILC_LOG_DEBUG(("Rekey completed successfully"));
2739 /* Generate new rekey material */
2740 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2743 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2744 ske->prop->cipher = NULL;
2745 ske->prop->hmac = NULL;
2746 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2747 return SILC_FSM_CONTINUE;
2749 rekey->pfs = ske->rekey->pfs;
2752 ske->prop->cipher = NULL;
2753 ske->prop->hmac = NULL;
2754 silc_packet_free(ske->packet);
2756 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2757 silc_schedule_task_del_by_context(ske->schedule, ske);
2759 /* Call completion */
2760 silc_ske_completion(ske);
2762 return SILC_FSM_FINISH;
2765 /* Starts rekey protocol as initiator */
2768 silc_ske_rekey_initiator(SilcSKE ske,
2769 SilcPacketStream stream,
2770 SilcSKERekeyMaterial rekey)
2772 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2774 if (!ske || !stream || !rekey) {
2775 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2780 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2783 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2787 ske->responder = FALSE;
2788 ske->running = TRUE;
2789 ske->rekeying = TRUE;
2791 /* Link to packet stream to get key exchange packets */
2792 ske->stream = stream;
2793 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2795 SILC_PACKET_REKEY_DONE,
2796 SILC_PACKET_KEY_EXCHANGE_2,
2797 SILC_PACKET_SUCCESS,
2798 SILC_PACKET_FAILURE, -1);
2800 /* Start SKE rekey as initiator */
2801 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2806 /***************************** Responder Rekey ******************************/
2808 /* Wait for initiator's packet */
2810 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2812 SilcSKE ske = fsm_context;
2814 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2818 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2819 return SILC_FSM_CONTINUE;
2822 /* Add rekey exchange timeout */
2823 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2826 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2828 /* If REKEY packet already received process it directly */
2829 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2830 return SILC_FSM_CONTINUE;
2832 /* Wait for REKEY */
2833 return SILC_FSM_WAIT;
2836 /* Process initiator's REKEY packet */
2838 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2840 SilcSKE ske = fsm_context;
2841 SilcSKEStatus status;
2843 SILC_LOG_DEBUG(("Start"));
2845 if (ske->packet->type != SILC_PACKET_REKEY) {
2846 ske->status = SILC_SKE_STATUS_ERROR;
2847 silc_packet_free(ske->packet);
2849 silc_fsm_next(fsm, silc_ske_st_responder_error);
2850 return SILC_FSM_CONTINUE;
2853 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2856 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2857 silc_fsm_next(fsm, silc_ske_st_responder_error);
2858 return SILC_FSM_CONTINUE;
2861 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2862 /** Cannot allocate hash */
2863 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2864 silc_fsm_next(fsm, silc_ske_st_responder_error);
2865 return SILC_FSM_CONTINUE;
2868 /* If doing rekey without PFS, move directly to the end of the protocol. */
2869 if (!ske->rekey->pfs) {
2870 /** Rekey without PFS */
2871 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2872 return SILC_FSM_CONTINUE;
2875 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2877 if (status != SILC_SKE_STATUS_OK) {
2878 /** Unknown group */
2879 silc_fsm_next(fsm, silc_ske_st_responder_error);
2880 return SILC_FSM_CONTINUE;
2883 /** Rekey with PFS */
2884 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2885 return SILC_FSM_WAIT;
2888 /* Sends REKEY_DONE packet to finish the protocol. */
2890 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2892 SilcSKE ske = fsm_context;
2893 SilcCipher send_key;
2896 SilcUInt32 key_len, block_len, hash_len, x_len;
2897 unsigned char *pfsbuf;
2899 SILC_LOG_DEBUG(("Start"));
2901 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2902 key_len = silc_cipher_get_key_len(send_key);
2903 block_len = silc_cipher_get_block_len(send_key);
2904 hash = ske->prop->hash;
2905 hash_len = silc_hash_len(hash);
2907 /* Process key material */
2908 if (ske->rekey->pfs) {
2910 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2912 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2915 memset(pfsbuf, 0, x_len);
2921 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2922 ske->rekey->enc_key_len / 8,
2928 SILC_LOG_ERROR(("Error processing key material"));
2929 silc_fsm_next(fsm, silc_ske_st_responder_error);
2930 return SILC_FSM_CONTINUE;
2933 ske->prop->cipher = send_key;
2934 ske->prop->hmac = hmac_send;
2936 /* Get sending keys */
2937 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2938 &hmac_send, NULL, NULL)) {
2939 /** Cannot get keys */
2940 ske->status = SILC_SKE_STATUS_ERROR;
2941 ske->prop->cipher = NULL;
2942 ske->prop->hmac = NULL;
2943 silc_fsm_next(fsm, silc_ske_st_responder_error);
2944 return SILC_FSM_CONTINUE;
2947 ske->prop->cipher = NULL;
2948 ske->prop->hmac = NULL;
2950 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2951 packet sent after this call will be protected with the new keys. */
2952 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2954 /** Cannot set keys */
2955 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2956 ske->status = SILC_SKE_STATUS_ERROR;
2957 silc_cipher_free(send_key);
2958 silc_hmac_free(hmac_send);
2959 silc_fsm_next(fsm, silc_ske_st_responder_error);
2960 return SILC_FSM_CONTINUE;
2963 /** Wait for REKEY_DONE */
2964 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2965 return SILC_FSM_WAIT;
2968 /* Rekey protocol end */
2970 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2972 SilcSKE ske = fsm_context;
2973 SilcCipher receive_key;
2974 SilcHmac hmac_receive;
2975 SilcSKERekeyMaterial rekey;
2977 SILC_LOG_DEBUG(("Start"));
2979 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2980 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2981 silc_packet_free(ske->packet);
2983 return SILC_FSM_WAIT;
2986 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2987 ske->prop->cipher = receive_key;
2988 ske->prop->hmac = hmac_receive;
2990 /* Get receiving keys */
2991 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2992 NULL, &hmac_receive, NULL)) {
2993 /** Cannot get keys */
2994 ske->status = SILC_SKE_STATUS_ERROR;
2995 ske->prop->cipher = NULL;
2996 ske->prop->hmac = NULL;
2997 silc_fsm_next(fsm, silc_ske_st_responder_error);
2998 return SILC_FSM_CONTINUE;
3001 /* Set new receiving keys into use. All packets received after this will
3002 be decrypted with the new keys. */
3003 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3004 hmac_receive, FALSE)) {
3005 /** Cannot set keys */
3006 SILC_LOG_DEBUG(("Cannot set new keys"));
3007 ske->status = SILC_SKE_STATUS_ERROR;
3008 ske->prop->cipher = NULL;
3009 ske->prop->hmac = NULL;
3010 silc_cipher_free(receive_key);
3011 silc_hmac_free(hmac_receive);
3012 silc_fsm_next(fsm, silc_ske_st_responder_error);
3013 return SILC_FSM_CONTINUE;
3016 SILC_LOG_DEBUG(("Rekey completed successfully"));
3018 /* Generate new rekey material */
3019 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3022 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3023 ske->prop->cipher = NULL;
3024 ske->prop->hmac = NULL;
3025 silc_fsm_next(fsm, silc_ske_st_responder_error);
3026 return SILC_FSM_CONTINUE;
3028 rekey->pfs = ske->rekey->pfs;
3031 ske->prop->cipher = NULL;
3032 ske->prop->hmac = NULL;
3033 silc_packet_free(ske->packet);
3035 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3036 silc_schedule_task_del_by_context(ske->schedule, ske);
3038 /* Call completion */
3039 silc_ske_completion(ske);
3041 return SILC_FSM_FINISH;
3044 /* Starts rekey protocol as responder */
3047 silc_ske_rekey_responder(SilcSKE ske,
3048 SilcPacketStream stream,
3049 SilcSKERekeyMaterial rekey,
3052 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3054 if (!ske || !stream || !rekey)
3057 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3060 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3064 ske->responder = TRUE;
3065 ske->running = TRUE;
3066 ske->rekeying = TRUE;
3067 ske->packet = packet;
3069 /* Link to packet stream to get key exchange packets */
3070 ske->stream = stream;
3071 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3073 SILC_PACKET_REKEY_DONE,
3074 SILC_PACKET_KEY_EXCHANGE_1,
3075 SILC_PACKET_SUCCESS,
3076 SILC_PACKET_FAILURE, -1);
3078 /* Start SKE rekey as responder */
3079 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3084 /* Processes the provided key material `data' as the SILC protocol
3085 specification defines. */
3088 silc_ske_process_key_material_data(unsigned char *data,
3089 SilcUInt32 data_len,
3090 SilcUInt32 req_iv_len,
3091 SilcUInt32 req_enc_key_len,
3092 SilcUInt32 req_hmac_key_len,
3096 unsigned char hashd[SILC_HASH_MAXLEN];
3097 SilcUInt32 hash_len = req_hmac_key_len;
3098 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3099 SilcSKEKeyMaterial key;
3101 SILC_LOG_DEBUG(("Start"));
3103 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3106 key = silc_calloc(1, sizeof(*key));
3110 buf = silc_buffer_alloc_size(1 + data_len);
3113 silc_buffer_format(buf,
3114 SILC_STR_UI_CHAR(0),
3115 SILC_STR_DATA(data, data_len),
3119 memset(hashd, 0, sizeof(hashd));
3121 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3122 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3123 memcpy(key->send_iv, hashd, req_iv_len);
3124 memset(hashd, 0, sizeof(hashd));
3126 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3127 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3128 memcpy(key->receive_iv, hashd, req_iv_len);
3129 key->iv_len = req_iv_len;
3131 /* Take the encryption keys. If requested key size is more than
3132 the size of hash length we will distribute more key material
3133 as protocol defines. */
3135 if (enc_key_len > hash_len) {
3137 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3138 k3[SILC_HASH_MAXLEN];
3139 unsigned char *dtmp;
3142 if (enc_key_len > (3 * hash_len))
3145 /* Take first round */
3146 memset(k1, 0, sizeof(k1));
3147 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3149 /* Take second round */
3150 dist = silc_buffer_alloc_size(data_len + hash_len);
3153 silc_buffer_format(dist,
3154 SILC_STR_DATA(data, data_len),
3155 SILC_STR_DATA(k1, hash_len),
3157 memset(k2, 0, sizeof(k2));
3158 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3160 /* Take third round */
3161 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3162 silc_buffer_pull_tail(dist, hash_len);
3163 silc_buffer_pull(dist, data_len + hash_len);
3164 silc_buffer_format(dist,
3165 SILC_STR_DATA(k2, hash_len),
3167 silc_buffer_push(dist, data_len + hash_len);
3168 memset(k3, 0, sizeof(k3));
3169 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3171 /* Then, save the keys */
3172 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3173 memcpy(dtmp, k1, hash_len);
3174 memcpy(dtmp + hash_len, k2, hash_len);
3175 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3177 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3178 memcpy(key->send_enc_key, dtmp, enc_key_len);
3179 key->enc_key_len = req_enc_key_len;
3181 memset(dtmp, 0, (3 * hash_len));
3182 memset(k1, 0, sizeof(k1));
3183 memset(k2, 0, sizeof(k2));
3184 memset(k3, 0, sizeof(k3));
3186 silc_buffer_clear(dist);
3187 silc_buffer_free(dist);
3189 /* Take normal hash as key */
3190 memset(hashd, 0, sizeof(hashd));
3191 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3192 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3193 memcpy(key->send_enc_key, hashd, enc_key_len);
3194 key->enc_key_len = req_enc_key_len;
3198 if (enc_key_len > hash_len) {
3200 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3201 k3[SILC_HASH_MAXLEN];
3202 unsigned char *dtmp;
3205 if (enc_key_len > (3 * hash_len))
3208 /* Take first round */
3209 memset(k1, 0, sizeof(k1));
3210 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3212 /* Take second round */
3213 dist = silc_buffer_alloc_size(data_len + hash_len);
3216 silc_buffer_format(dist,
3217 SILC_STR_DATA(data, data_len),
3218 SILC_STR_DATA(k1, hash_len),
3220 memset(k2, 0, sizeof(k2));
3221 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3223 /* Take third round */
3224 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3225 silc_buffer_pull_tail(dist, hash_len);
3226 silc_buffer_pull(dist, data_len + hash_len);
3227 silc_buffer_format(dist,
3228 SILC_STR_DATA(k2, hash_len),
3230 silc_buffer_push(dist, data_len + hash_len);
3231 memset(k3, 0, sizeof(k3));
3232 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3234 /* Then, save the keys */
3235 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3236 memcpy(dtmp, k1, hash_len);
3237 memcpy(dtmp + hash_len, k2, hash_len);
3238 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3240 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3241 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3242 key->enc_key_len = req_enc_key_len;
3244 memset(dtmp, 0, (3 * hash_len));
3245 memset(k1, 0, sizeof(k1));
3246 memset(k2, 0, sizeof(k2));
3247 memset(k3, 0, sizeof(k3));
3249 silc_buffer_clear(dist);
3250 silc_buffer_free(dist);
3252 /* Take normal hash as key */
3253 memset(hashd, 0, sizeof(hashd));
3254 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3255 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3256 memcpy(key->receive_enc_key, hashd, enc_key_len);
3257 key->enc_key_len = req_enc_key_len;
3260 /* Take HMAC keys */
3261 memset(hashd, 0, sizeof(hashd));
3263 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3264 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3265 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3266 memset(hashd, 0, sizeof(hashd));
3268 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3269 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3270 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3271 key->hmac_key_len = req_hmac_key_len;
3272 memset(hashd, 0, sizeof(hashd));
3274 silc_buffer_clear(buf);
3275 silc_buffer_free(buf);
3277 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3282 /* Processes negotiated key material as protocol specifies. This returns
3283 the actual keys to be used in the SILC. */
3286 silc_ske_process_key_material(SilcSKE ske,
3287 SilcUInt32 req_iv_len,
3288 SilcUInt32 req_enc_key_len,
3289 SilcUInt32 req_hmac_key_len,
3290 SilcSKERekeyMaterial *rekey)
3293 unsigned char *tmpbuf;
3295 SilcSKEKeyMaterial key;
3297 /* Encode KEY to binary data */
3298 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3300 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3303 silc_buffer_format(buf,
3304 SILC_STR_DATA(tmpbuf, klen),
3305 SILC_STR_DATA(ske->hash, ske->hash_len),
3308 /* Process the key material */
3309 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3310 req_iv_len, req_enc_key_len,
3314 memset(tmpbuf, 0, klen);
3316 silc_buffer_clear(buf);
3317 silc_buffer_free(buf);
3320 *rekey = silc_ske_make_rekey_material(ske, key);
3328 /* Free key material structure */
3330 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3336 silc_free(key->send_iv);
3337 if (key->receive_iv)
3338 silc_free(key->receive_iv);
3339 if (key->send_enc_key) {
3340 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3341 silc_free(key->send_enc_key);
3343 if (key->receive_enc_key) {
3344 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3345 silc_free(key->receive_enc_key);
3347 if (key->send_hmac_key) {
3348 memset(key->send_hmac_key, 0, key->hmac_key_len);
3349 silc_free(key->send_hmac_key);
3351 if (key->receive_hmac_key) {
3352 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3353 silc_free(key->receive_hmac_key);
3358 /* Free rekey material */
3360 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3364 if (rekey->send_enc_key) {
3365 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3366 silc_free(rekey->send_enc_key);
3368 silc_free(rekey->hash);
3372 /* Set keys into use */
3374 SilcBool silc_ske_set_keys(SilcSKE ske,
3375 SilcSKEKeyMaterial keymat,
3376 SilcSKESecurityProperties prop,
3377 SilcCipher *ret_send_key,
3378 SilcCipher *ret_receive_key,
3379 SilcHmac *ret_hmac_send,
3380 SilcHmac *ret_hmac_receive,
3383 unsigned char iv[SILC_HASH_MAXLEN];
3384 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3386 /* Allocate ciphers to be used in the communication */
3388 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3392 if (ret_receive_key) {
3393 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3398 /* Allocate HMACs */
3399 if (ret_hmac_send) {
3400 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3404 if (ret_hmac_receive) {
3405 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3412 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3416 /* Set key material */
3417 memset(iv, 0, sizeof(iv));
3418 if (ske->responder) {
3420 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3421 keymat->enc_key_len, TRUE);
3423 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3425 if (!ske->rekeying) {
3427 memcpy(iv, ske->hash, 4);
3429 memcpy(iv + 4, keymat->receive_iv, 8);
3431 /* Rekey, recompute the truncated hash value. */
3432 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3434 memcpy(iv + 4, keymat->receive_iv, 8);
3436 memset(iv + 4, 0, 12);
3439 silc_cipher_set_iv(*ret_send_key, iv);
3442 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3445 if (ret_receive_key) {
3446 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3447 keymat->enc_key_len, FALSE);
3449 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3451 if (!ske->rekeying) {
3453 memcpy(iv, ske->hash, 4);
3455 memcpy(iv + 4, keymat->send_iv, 8);
3457 /* Rekey, recompute the truncated hash value. */
3458 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3460 memcpy(iv + 4, keymat->send_iv, 8);
3462 memset(iv + 4, 0, 12);
3465 silc_cipher_set_iv(*ret_receive_key, iv);
3468 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3472 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3473 keymat->hmac_key_len);
3474 if (ret_hmac_receive)
3475 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3476 keymat->hmac_key_len);
3479 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3480 keymat->enc_key_len, TRUE);
3482 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3484 if (!ske->rekeying) {
3486 memcpy(iv, ske->hash, 4);
3488 memcpy(iv + 4, keymat->send_iv, 8);
3490 /* Rekey, recompute the truncated hash value. */
3491 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3493 memcpy(iv + 4, keymat->send_iv, 8);
3495 memset(iv + 4, 0, 12);
3498 silc_cipher_set_iv(*ret_send_key, iv);
3501 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3504 if (ret_receive_key) {
3505 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3506 keymat->enc_key_len, FALSE);
3508 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3510 if (!ske->rekeying) {
3511 /* Set IV. If IV Included flag was negotiated we only set the
3512 truncated hash value. */
3513 memcpy(iv, ske->hash, 4);
3515 memcpy(iv + 4, keymat->receive_iv, 8);
3517 /* Rekey, recompute the truncated hash value. */
3518 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3520 memcpy(iv + 4, keymat->receive_iv, 8);
3522 memset(iv + 4, 0, 12);
3525 silc_cipher_set_iv(*ret_receive_key, iv);
3528 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3532 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3533 keymat->hmac_key_len);
3534 if (ret_hmac_receive)
3535 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3536 keymat->hmac_key_len);
3542 const char *silc_ske_status_string[] =
3546 "Unexpected error occurred",
3547 "Bad payload in packet",
3548 "Unsupported group",
3549 "Unsupported cipher",
3551 "Unsupported hash function",
3553 "Unsupported public key (or certificate)",
3554 "Incorrect signature",
3555 "Bad or unsupported version",
3559 "Remote did not provide public key",
3560 "Bad reserved field in packet",
3561 "Bad payload length in packet",
3562 "Error computing signature",
3563 "System out of memory",
3564 "Key exchange timeout",
3569 /* Maps status to readable string and returns the string. If string is not
3570 found and empty character string ("") is returned. */
3572 const char *silc_ske_map_status(SilcSKEStatus status)
3576 for (i = 0; silc_ske_status_string[i]; i++)
3578 return silc_ske_status_string[i];
3583 /* Parses remote host's version string. */
3585 SilcBool silc_ske_parse_version(SilcSKE ske,
3586 SilcUInt32 *protocol_version,
3587 char **protocol_version_string,
3588 SilcUInt32 *software_version,
3589 char **software_version_string,
3590 char **vendor_version)
3592 return silc_parse_version_string(ske->remote_version,
3594 protocol_version_string,
3596 software_version_string,
3600 /* Get security properties */
3602 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3607 /* Get key material */
3609 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)