5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
23 #include "groups_internal.h"
25 /************************** Types and definitions ***************************/
27 /* Structure to hold all SKE callbacks. */
28 struct SilcSKECallbacksStruct {
29 SilcSKEVerifyCb verify_key;
30 SilcSKECompletionCb completed;
34 /************************ Static utility functions **************************/
37 SILC_FSM_STATE(silc_ske_st_initiator_start);
38 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
39 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
40 SILC_FSM_STATE(silc_ske_st_initiator_phase2_send);
41 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
42 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
43 SILC_FSM_STATE(silc_ske_st_initiator_phase5);
44 SILC_FSM_STATE(silc_ske_st_initiator_end);
45 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
46 SILC_FSM_STATE(silc_ske_st_initiator_error);
47 SILC_FSM_STATE(silc_ske_st_initiator_failure);
48 SILC_FSM_STATE(silc_ske_st_responder_start);
49 SILC_FSM_STATE(silc_ske_st_responder_phase1);
50 SILC_FSM_STATE(silc_ske_st_responder_phase2);
51 SILC_FSM_STATE(silc_ske_st_responder_phase4);
52 SILC_FSM_STATE(silc_ske_st_responder_phase5);
53 SILC_FSM_STATE(silc_ske_st_responder_phase5_send);
54 SILC_FSM_STATE(silc_ske_st_responder_end);
55 SILC_FSM_STATE(silc_ske_st_responder_aborted);
56 SILC_FSM_STATE(silc_ske_st_responder_failure);
57 SILC_FSM_STATE(silc_ske_st_responder_error);
58 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
59 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done);
60 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end);
61 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait);
62 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
63 SILC_FSM_STATE(silc_ske_st_rekey_responder_done);
64 SILC_FSM_STATE(silc_ske_st_rekey_responder_end);
65 SILC_TASK_CALLBACK(silc_ske_packet_send_retry);
68 silc_ske_process_key_material(SilcSKE ske,
69 SilcUInt32 req_iv_len,
70 SilcUInt32 req_enc_key_len,
71 SilcUInt32 req_hmac_key_len,
72 SilcSKERekeyMaterial *rekey);
73 static SilcBool silc_ske_packet_send(SilcSKE ske,
75 SilcPacketFlags flags,
76 const unsigned char *data,
81 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
82 SilcPacketStream stream,
84 void *callback_context,
87 SilcSKE ske = callback_context;
89 /* Clear retransmission */
90 ske->retry_timer = SILC_SKE_RETRY_MIN;
92 silc_schedule_task_del_by_callback(ske->schedule,
93 silc_ske_packet_send_retry);
95 /* Signal for new packet */
98 /* Check if we were aborted */
100 silc_packet_free(packet);
104 silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
106 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
108 silc_fsm_continue_sync(&ske->fsm);
112 /* See if received failure from remote */
113 if (packet->type == SILC_PACKET_FAILURE) {
115 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
117 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
120 /* Handle rekey and SUCCESS packets synchronously. After SUCCESS packets
121 they keys are taken into use immediately, hence the synchronous
122 processing to get the keys in use as soon as possible. */
123 if (ske->rekeying || packet->type == SILC_PACKET_SUCCESS)
124 silc_fsm_continue_sync(&ske->fsm);
126 silc_fsm_continue(&ske->fsm);
131 /* Packet stream callbacks */
132 static SilcPacketCallbacks silc_ske_stream_cbs =
134 silc_ske_packet_receive, NULL, NULL
137 /* Aborts SKE protocol */
139 static void silc_ske_abort(SilcAsyncOperation op, void *context)
141 SilcSKE ske = context;
143 silc_async_abort(ske->key_op, NULL, NULL);
147 /* Public key verification completion callback */
149 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
150 void *completion_context)
152 ske->status = status;
153 SILC_FSM_CALL_CONTINUE(&ske->fsm);
156 /* SKR find callback */
158 static void silc_ske_skr_callback(SilcSKR repository,
160 SilcSKRStatus status,
161 SilcDList keys, void *context)
163 SilcSKE ske = context;
165 silc_skr_find_free(find);
167 if (status != SILC_SKR_OK) {
168 if (ske->callbacks->verify_key) {
169 /* Verify from application */
170 ske->callbacks->verify_key(ske, ske->prop->public_key,
171 ske->callbacks->context,
172 silc_ske_pk_verified, NULL);
178 silc_dlist_uninit(keys);
181 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
182 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
183 SILC_FSM_CALL_CONTINUE(&ske->fsm);
186 /* Checks remote and local versions */
188 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
190 SilcUInt32 r_software_version = 0;
191 char *r_software_string = NULL;
193 if (!ske->remote_version || !ske->version)
194 return SILC_SKE_STATUS_BAD_VERSION;
196 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
198 &r_software_string, NULL))
199 return SILC_SKE_STATUS_BAD_VERSION;
201 return SILC_SKE_STATUS_OK;
204 /* Selects the supported security properties from the initiator's Key
205 Exchange Start Payload. A responder function. Saves our reply
206 start payload to ske->start_payload. */
209 silc_ske_select_security_properties(SilcSKE ske,
210 SilcSKEStartPayload remote_payload,
211 SilcSKESecurityProperties *prop)
213 SilcSKEStatus status;
214 SilcSKEStartPayload rp, payload;
218 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
222 /* Check for mandatory fields */
223 if (!rp->ke_grp_len) {
224 SILC_LOG_DEBUG(("KE group not defined in payload"));
225 return SILC_SKE_STATUS_BAD_PAYLOAD;
227 if (!rp->pkcs_alg_len) {
228 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
229 return SILC_SKE_STATUS_BAD_PAYLOAD;
231 if (!rp->enc_alg_len) {
232 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
233 return SILC_SKE_STATUS_BAD_PAYLOAD;
235 if (!rp->hash_alg_len) {
236 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
237 return SILC_SKE_STATUS_BAD_PAYLOAD;
239 if (!rp->hmac_alg_len) {
240 SILC_LOG_DEBUG(("HMAC not defined in payload"));
241 return SILC_SKE_STATUS_BAD_PAYLOAD;
244 /* Allocate security properties */
245 *prop = silc_calloc(1, sizeof(**prop));
247 return SILC_SKE_STATUS_OUT_OF_MEMORY;
249 /* Allocate our reply start payload */
250 payload = silc_calloc(1, sizeof(*payload));
253 return SILC_SKE_STATUS_OUT_OF_MEMORY;
256 /* Check version string */
257 ske->remote_version = silc_memdup(rp->version, rp->version_len);
258 status = silc_ske_check_version(ske);
259 if (status != SILC_SKE_STATUS_OK) {
260 ske->status = status;
264 /* Flags are returned unchanged. */
265 (*prop)->flags = payload->flags = rp->flags;
267 /* Take cookie, we must return it to sender unmodified. */
268 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
269 if (!payload->cookie) {
270 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
273 payload->cookie_len = SILC_SKE_COOKIE_LEN;
274 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
276 /* In case IV included flag and session port is set the first 16-bits of
277 cookie will include our session port. */
278 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
279 /* Take remote port */
280 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
283 SILC_PUT16_MSB(ske->session_port, payload->cookie);
286 /* Put our version to our reply */
287 payload->version = strdup(ske->version);
288 if (!payload->version) {
289 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
292 payload->version_len = strlen(ske->version);
294 /* Get supported Key Exchange groups */
295 cp = rp->ke_grp_list;
296 if (cp && strchr(cp, ',')) {
300 len = strcspn(cp, ",");
301 item = silc_calloc(len + 1, sizeof(char));
303 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
306 memcpy(item, cp, len);
308 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
310 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
311 SILC_LOG_DEBUG(("Found KE group `%s'", item));
313 payload->ke_grp_len = len;
314 payload->ke_grp_list = item;
328 if (!payload->ke_grp_len && !payload->ke_grp_list) {
329 SILC_LOG_DEBUG(("Could not find supported KE group"));
331 return SILC_SKE_STATUS_UNKNOWN_GROUP;
334 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
335 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
337 payload->ke_grp_len = rp->ke_grp_len;
338 payload->ke_grp_list = strdup(rp->ke_grp_list);
341 /* Save group to security properties */
342 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
343 if (status != SILC_SKE_STATUS_OK) {
345 return SILC_SKE_STATUS_UNKNOWN_GROUP;
348 /* Get supported PKCS algorithms */
349 cp = rp->pkcs_alg_list;
350 if (cp && strchr(cp, ',')) {
354 len = strcspn(cp, ",");
355 item = silc_calloc(len + 1, sizeof(char));
357 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
360 memcpy(item, cp, len);
362 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
364 if (silc_pkcs_find_algorithm(item, NULL)) {
365 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
367 payload->pkcs_alg_len = len;
368 payload->pkcs_alg_list = item;
382 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
383 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
384 silc_free(payload->ke_grp_list);
386 return SILC_SKE_STATUS_UNKNOWN_PKCS;
389 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
390 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
392 payload->pkcs_alg_len = rp->pkcs_alg_len;
393 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
396 /* Get supported encryption algorithms */
397 cp = rp->enc_alg_list;
398 if (cp && strchr(cp, ',')) {
402 len = strcspn(cp, ",");
403 item = silc_calloc(len + 1, sizeof(char));
405 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
408 memcpy(item, cp, len);
410 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
412 if (silc_cipher_is_supported(item) == TRUE) {
413 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
415 payload->enc_alg_len = len;
416 payload->enc_alg_list = item;
430 if (!payload->enc_alg_len && !payload->enc_alg_list) {
431 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
432 silc_free(payload->ke_grp_list);
433 silc_free(payload->pkcs_alg_list);
435 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
438 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
441 payload->enc_alg_len = rp->enc_alg_len;
442 payload->enc_alg_list = strdup(rp->enc_alg_list);
445 /* Save selected cipher to security properties */
446 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
447 silc_free(payload->ke_grp_list);
448 silc_free(payload->pkcs_alg_list);
450 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
453 /* Get supported hash algorithms */
454 cp = rp->hash_alg_list;
455 if (cp && strchr(cp, ',')) {
459 len = strcspn(cp, ",");
460 item = silc_calloc(len + 1, sizeof(char));
462 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
465 memcpy(item, cp, len);
467 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
469 if (silc_hash_is_supported(item) == TRUE) {
470 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
472 payload->hash_alg_len = len;
473 payload->hash_alg_list = item;
487 if (!payload->hash_alg_len && !payload->hash_alg_list) {
488 SILC_LOG_DEBUG(("Could not find supported hash alg"));
489 silc_free(payload->ke_grp_list);
490 silc_free(payload->pkcs_alg_list);
491 silc_free(payload->enc_alg_list);
493 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
496 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
499 payload->hash_alg_len = rp->hash_alg_len;
500 payload->hash_alg_list = strdup(rp->hash_alg_list);
503 /* Save selected hash algorithm to security properties */
504 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
505 silc_free(payload->ke_grp_list);
506 silc_free(payload->pkcs_alg_list);
507 silc_free(payload->enc_alg_list);
509 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
512 /* Get supported HMACs */
513 cp = rp->hmac_alg_list;
514 if (cp && strchr(cp, ',')) {
518 len = strcspn(cp, ",");
519 item = silc_calloc(len + 1, sizeof(char));
521 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
524 memcpy(item, cp, len);
526 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
528 if (silc_hmac_is_supported(item) == TRUE) {
529 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
531 payload->hmac_alg_len = len;
532 payload->hmac_alg_list = item;
546 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
547 SILC_LOG_DEBUG(("Could not find supported HMAC"));
548 silc_free(payload->ke_grp_list);
549 silc_free(payload->pkcs_alg_list);
550 silc_free(payload->enc_alg_list);
551 silc_free(payload->hash_alg_list);
553 return SILC_SKE_STATUS_UNKNOWN_HMAC;
556 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
559 payload->hmac_alg_len = rp->hmac_alg_len;
560 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
563 /* Save selected HMACc to security properties */
564 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
565 silc_free(payload->ke_grp_list);
566 silc_free(payload->pkcs_alg_list);
567 silc_free(payload->enc_alg_list);
568 silc_free(payload->hash_alg_list);
570 return SILC_SKE_STATUS_UNKNOWN_HMAC;
573 /* Get supported compression algorithms */
574 cp = rp->comp_alg_list;
575 if (cp && strchr(cp, ',')) {
579 len = strcspn(cp, ",");
580 item = silc_calloc(len + 1, sizeof(char));
582 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
585 memcpy(item, cp, len);
587 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
590 if (!strcmp(item, "none")) {
591 SILC_LOG_DEBUG(("Found Compression `%s'", item));
592 payload->comp_alg_len = len;
593 payload->comp_alg_list = item;
597 if (silc_hmac_is_supported(item) == TRUE) {
598 SILC_LOG_DEBUG(("Found Compression `%s'", item));
599 payload->comp_alg_len = len;
600 payload->comp_alg_list = item;
616 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
617 2 + payload->version_len +
618 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
619 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
620 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
622 /* Save our reply payload */
623 ske->start_payload = payload;
625 return SILC_SKE_STATUS_OK;
628 /* Creates random number such that 1 < rnd < n and at most length
629 of len bits. The rnd sent as argument must be initialized. */
631 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
635 SilcSKEStatus status = SILC_SKE_STATUS_OK;
636 unsigned char string[2048];
640 return SILC_SKE_STATUS_ERROR;
642 SILC_LOG_DEBUG(("Creating random number"));
646 /* Get the random number as string */
647 if (!silc_rng_get_rn_data(ske->rng, l, string, sizeof(string)))
648 return SILC_SKE_STATUS_OUT_OF_MEMORY;
650 /* Decode the string into a MP integer */
651 silc_mp_bin2mp(string, l, rnd);
652 silc_mp_mod_2exp(rnd, rnd, len);
655 if (silc_mp_cmp_ui(rnd, 1) < 0)
656 status = SILC_SKE_STATUS_ERROR;
657 if (silc_mp_cmp(rnd, n) >= 0)
658 status = SILC_SKE_STATUS_ERROR;
660 memset(string, 'F', l);
665 /* Creates a hash value HASH as defined in the SKE protocol. If the
666 `initiator' is TRUE then this function is used to create the HASH_i
667 hash value defined in the protocol. If it is FALSE then this is used
668 to create the HASH value defined by the protocol. */
670 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
671 unsigned char *return_hash,
672 SilcUInt32 *return_hash_len,
675 SilcSKEStatus status = SILC_SKE_STATUS_OK;
677 unsigned char *e, *f, *KEY, *s_data;
678 SilcUInt32 e_len, f_len, KEY_len, s_len;
681 SILC_LOG_DEBUG(("Start"));
683 if (initiator == FALSE) {
684 s_data = (ske->start_payload_copy ?
685 silc_buffer_data(ske->start_payload_copy) : NULL);
686 s_len = (ske->start_payload_copy ?
687 silc_buffer_len(ske->start_payload_copy) : 0);
688 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
689 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
690 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
692 /* Format the buffer used to compute the hash value */
693 buf = silc_buffer_alloc_size(s_len +
694 ske->ke2_payload->pk_len +
695 ske->ke1_payload->pk_len +
696 e_len + f_len + KEY_len);
698 return SILC_SKE_STATUS_OUT_OF_MEMORY;
700 /* Initiator is not required to send its public key */
701 if (!ske->ke1_payload->pk_data) {
703 silc_buffer_format(buf,
704 SILC_STR_DATA(s_data, s_len),
705 SILC_STR_DATA(ske->ke2_payload->pk_data,
706 ske->ke2_payload->pk_len),
707 SILC_STR_DATA(e, e_len),
708 SILC_STR_DATA(f, f_len),
709 SILC_STR_DATA(KEY, KEY_len),
713 silc_buffer_format(buf,
714 SILC_STR_DATA(s_data, s_len),
715 SILC_STR_DATA(ske->ke2_payload->pk_data,
716 ske->ke2_payload->pk_len),
717 SILC_STR_DATA(ske->ke1_payload->pk_data,
718 ske->ke1_payload->pk_len),
719 SILC_STR_DATA(e, e_len),
720 SILC_STR_DATA(f, f_len),
721 SILC_STR_DATA(KEY, KEY_len),
725 silc_buffer_free(buf);
728 memset(KEY, 0, KEY_len);
732 return SILC_SKE_STATUS_ERROR;
737 memset(KEY, 0, KEY_len);
742 s_data = (ske->start_payload_copy ?
743 silc_buffer_data(ske->start_payload_copy) : NULL);
744 s_len = (ske->start_payload_copy ?
745 silc_buffer_len(ske->start_payload_copy) : 0);
746 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
748 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
750 return SILC_SKE_STATUS_OUT_OF_MEMORY;
752 /* Format the buffer used to compute the hash value */
754 silc_buffer_format(buf,
755 SILC_STR_DATA(s_data, s_len),
756 SILC_STR_DATA(ske->ke1_payload->pk_data,
757 ske->ke1_payload->pk_len),
758 SILC_STR_DATA(e, e_len),
761 silc_buffer_free(buf);
764 return SILC_SKE_STATUS_ERROR;
767 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
774 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
776 *return_hash_len = silc_hash_len(ske->prop->hash);
778 if (initiator == FALSE) {
779 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
781 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
784 silc_buffer_free(buf);
789 /* Generate rekey material */
791 static SilcSKERekeyMaterial
792 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
794 SilcSKERekeyMaterial rekey;
797 /* Create rekey material */
798 rekey = silc_calloc(1, sizeof(*rekey));
803 if (ske->prop->group)
804 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
805 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
806 hash = silc_hash_get_name(ske->prop->hash);
807 rekey->hash = silc_memdup(hash, strlen(hash));
812 if (rekey->pfs == FALSE) {
813 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
814 keymat->enc_key_len / 8);
815 if (!rekey->send_enc_key) {
819 rekey->enc_key_len = keymat->enc_key_len;
825 /* Assembles security properties */
827 static SilcSKEStartPayload
828 silc_ske_assemble_security_properties(SilcSKE ske,
829 SilcSKESecurityPropertyFlag flags,
832 SilcSKEStartPayload rp;
835 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
837 rp = silc_calloc(1, sizeof(*rp));
840 rp->flags = (unsigned char)flags;
842 /* Set random cookie */
843 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
844 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
845 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
846 rp->cookie_len = SILC_SKE_COOKIE_LEN;
848 /* In case IV included flag and session port is set the first 16-bits of
849 cookie will include our session port. */
850 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
851 SILC_PUT16_MSB(ske->session_port, rp->cookie);
854 rp->version = strdup(version);
855 rp->version_len = strlen(version);
857 /* Get supported Key Exhange groups */
858 rp->ke_grp_list = silc_ske_get_supported_groups();
859 rp->ke_grp_len = strlen(rp->ke_grp_list);
861 /* Get supported PKCS algorithms */
862 rp->pkcs_alg_list = silc_pkcs_get_supported();
863 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
865 /* Get supported encryption algorithms */
866 rp->enc_alg_list = silc_cipher_get_supported(TRUE);
867 rp->enc_alg_len = strlen(rp->enc_alg_list);
869 /* Get supported hash algorithms */
870 rp->hash_alg_list = silc_hash_get_supported();
871 rp->hash_alg_len = strlen(rp->hash_alg_list);
873 /* Get supported HMACs */
874 rp->hmac_alg_list = silc_hmac_get_supported();
875 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
878 /* Get supported compression algorithms */
879 rp->comp_alg_list = strdup("none");
880 rp->comp_alg_len = strlen("none");
882 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
883 2 + rp->version_len +
884 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
885 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
886 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
891 /* Packet retransmission callback. */
893 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
895 SilcSKE ske = context;
897 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
899 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
900 ske->retry_count = 0;
901 ske->retry_timer = SILC_SKE_RETRY_MIN;
902 silc_free(ske->retrans.data);
903 ske->retrans.data = NULL;
904 ske->status = SILC_SKE_STATUS_TIMEOUT;
906 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
908 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
909 silc_fsm_continue_sync(&ske->fsm);
913 SILC_LOG_DEBUG(("Retransmitting packet"));
914 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
915 ske->retrans.data, ske->retrans.data_len);
918 /* Install retransmission timer */
920 static void silc_ske_install_retransmission(SilcSKE ske)
922 if (!silc_packet_stream_is_udp(ske->stream))
925 if (ske->retrans.data) {
926 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
928 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
929 ske, ske->retry_timer, 0);
931 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
932 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
935 /* Sends SILC packet. Handles retransmissions with UDP streams. */
937 static SilcBool silc_ske_packet_send(SilcSKE ske,
939 SilcPacketFlags flags,
940 const unsigned char *data,
945 /* Send the packet */
946 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
948 if (silc_packet_stream_is_udp(ske->stream) &&
949 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
950 silc_free(ske->retrans.data);
951 ske->retrans.type = type;
952 ske->retrans.flags = flags;
953 ske->retrans.data = silc_memdup(data, data_len);
954 ske->retrans.data_len = data_len;
955 silc_ske_install_retransmission(ske);
961 /* Calls completion callback. Completion is called always in this function
962 and must not be called anywhere else. */
964 static void silc_ske_completion(SilcSKE ske)
966 /* Call the completion callback */
967 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
968 if (ske->status != SILC_SKE_STATUS_OK)
969 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
970 ske->callbacks->context);
972 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
973 ske->rekey, ske->callbacks->context);
977 /* SKE FSM destructor. */
979 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
980 void *destructor_context)
982 SilcSKE ske = fsm_context;
983 ske->running = FALSE;
988 /* Key exchange timeout task callback */
990 SILC_TASK_CALLBACK(silc_ske_timeout)
992 SilcSKE ske = context;
994 SILC_LOG_DEBUG(("Timeout"));
997 ske->status = SILC_SKE_STATUS_TIMEOUT;
999 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1001 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1003 silc_fsm_continue_sync(&ske->fsm);
1006 /* Initiator signature callback */
1008 static void silc_ske_initiator_sign_cb(SilcBool success,
1009 const unsigned char *signature,
1010 SilcUInt32 signature_len,
1013 SilcSKE ske = context;
1018 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1019 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1023 ske->ke1_payload->sign_data = silc_memdup(signature, signature_len);
1024 if (ske->ke1_payload->sign_data)
1025 ske->ke1_payload->sign_len = signature_len;
1027 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1030 /* Responder signature callback */
1032 static void silc_ske_responder_sign_cb(SilcBool success,
1033 const unsigned char *signature,
1034 SilcUInt32 signature_len,
1037 SilcSKE ske = context;
1042 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1043 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1047 ske->ke2_payload->sign_data = silc_memdup(signature, signature_len);
1048 if (ske->ke2_payload->sign_data)
1049 ske->ke2_payload->sign_len = signature_len;
1051 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1054 /* Verify callback */
1056 static void silc_ske_verify_cb(SilcBool success, void *context)
1058 SilcSKE ske = context;
1064 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1066 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1067 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1072 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1073 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1075 silc_fsm_next(&ske->fsm, silc_ske_st_responder_error);
1077 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_error);
1078 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1082 SILC_LOG_DEBUG(("Signature is Ok"));
1083 SILC_FSM_CALL_CONTINUE(&ske->fsm);
1086 /******************************* Protocol API *******************************/
1088 /* Allocates new SKE object. */
1090 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1091 SilcSKR repository, SilcPublicKey public_key,
1092 SilcPrivateKey private_key, void *context)
1096 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1098 if (!rng || !schedule)
1102 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1106 ske = silc_calloc(1, sizeof(*ske));
1109 ske->status = SILC_SKE_STATUS_OK;
1111 ske->repository = repository;
1112 ske->user_data = context;
1113 ske->schedule = schedule;
1114 ske->public_key = public_key;
1115 ske->private_key = private_key;
1116 ske->retry_timer = SILC_SKE_RETRY_MIN;
1122 /* Free's SKE object. */
1124 void silc_ske_free(SilcSKE ske)
1126 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1135 /* If already aborted, destroy the session immediately */
1137 ske->status = SILC_SKE_STATUS_ERROR;
1139 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1141 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1142 silc_fsm_continue_sync(&ske->fsm);
1148 if (ske->refcnt > 0)
1151 /* Free start payload */
1152 if (ske->start_payload)
1153 silc_ske_payload_start_free(ske->start_payload);
1155 /* Free KE payload */
1156 if (ske->ke1_payload)
1157 silc_ske_payload_ke_free(ske->ke1_payload);
1158 if (ske->ke2_payload)
1159 silc_ske_payload_ke_free(ske->ke2_payload);
1160 silc_free(ske->remote_version);
1164 if (ske->prop->group)
1165 silc_ske_group_free(ske->prop->group);
1166 if (ske->prop->cipher)
1167 silc_cipher_free(ske->prop->cipher);
1168 if (ske->prop->hash)
1169 silc_hash_free(ske->prop->hash);
1170 if (ske->prop->hmac)
1171 silc_hmac_free(ske->prop->hmac);
1172 if (ske->prop->public_key)
1173 silc_pkcs_public_key_free(ske->prop->public_key);
1174 silc_free(ske->prop);
1177 silc_ske_free_key_material(ske->keymat);
1178 if (ske->start_payload_copy)
1179 silc_buffer_free(ske->start_payload_copy);
1181 silc_mp_uninit(ske->x);
1185 silc_mp_uninit(ske->KEY);
1186 silc_free(ske->KEY);
1188 silc_free(ske->retrans.data);
1189 silc_free(ske->hash);
1190 silc_free(ske->callbacks);
1192 memset(ske, 'F', sizeof(*ske));
1196 /* Return user context */
1198 void *silc_ske_get_context(SilcSKE ske)
1200 return ske->user_data;
1203 /* Sets protocol callbacks */
1205 void silc_ske_set_callbacks(SilcSKE ske,
1206 SilcSKEVerifyCb verify_key,
1207 SilcSKECompletionCb completed,
1211 silc_free(ske->callbacks);
1212 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1213 if (!ske->callbacks)
1215 ske->callbacks->verify_key = verify_key;
1216 ske->callbacks->completed = completed;
1217 ske->callbacks->context = context;
1221 /******************************** Initiator *********************************/
1223 /* Start protocol. Send our proposal */
1225 SILC_FSM_STATE(silc_ske_st_initiator_start)
1227 SilcSKE ske = fsm_context;
1228 SilcBuffer payload_buf;
1231 SILC_LOG_DEBUG(("Start"));
1235 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1236 return SILC_FSM_CONTINUE;
1239 /* Encode the payload */
1240 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1242 if (status != SILC_SKE_STATUS_OK) {
1243 /** Error encoding Start Payload */
1244 ske->status = status;
1245 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1246 return SILC_FSM_CONTINUE;
1249 /* Save the the payload buffer for future use. It is later used to
1250 compute the HASH value. */
1251 ske->start_payload_copy = payload_buf;
1253 /* Send the packet. */
1254 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1255 silc_buffer_data(payload_buf),
1256 silc_buffer_len(payload_buf))) {
1257 /** Error sending packet */
1258 SILC_LOG_DEBUG(("Error sending packet"));
1259 ske->status = SILC_SKE_STATUS_ERROR;
1260 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1261 return SILC_FSM_CONTINUE;
1264 /* Add key exchange timeout */
1265 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1266 ske, ske->timeout, 0);
1268 /** Wait for responder proposal */
1269 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1270 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1271 return SILC_FSM_WAIT;
1274 /* Phase-1. Receives responder's proposal */
1276 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1278 SilcSKE ske = fsm_context;
1279 SilcSKEStatus status;
1280 SilcSKEStartPayload payload;
1281 SilcSKESecurityProperties prop;
1282 SilcSKEDiffieHellmanGroup group = NULL;
1283 SilcBuffer packet_buf = &ske->packet->buffer;
1284 SilcUInt16 remote_port = 0;
1288 SILC_LOG_DEBUG(("Start"));
1290 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1291 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1292 silc_ske_install_retransmission(ske);
1293 silc_packet_free(ske->packet);
1295 return SILC_FSM_WAIT;
1298 /* Decode the payload */
1299 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1300 if (status != SILC_SKE_STATUS_OK) {
1301 /** Error decoding Start Payload */
1302 silc_packet_free(ske->packet);
1304 ske->status = status;
1305 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1306 return SILC_FSM_CONTINUE;
1309 /* Get remote ID and set it to stream */
1310 if (ske->packet->src_id_len) {
1311 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1312 ske->packet->src_id_type,
1313 (ske->packet->src_id_type == SILC_ID_SERVER ?
1314 (void *)&id.u.server_id : (void *)&id.u.client_id),
1315 (ske->packet->src_id_type == SILC_ID_SERVER ?
1316 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1317 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1318 (ske->packet->src_id_type == SILC_ID_SERVER ?
1319 (void *)&id.u.server_id : (void *)&id.u.client_id));
1322 silc_packet_free(ske->packet);
1325 /* Check that the cookie is returned unmodified. In case IV included
1326 flag and session port has been set, the first two bytes of cookie
1327 are the session port and we ignore them in this check. */
1328 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1329 /* Take remote port */
1330 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1333 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1334 SILC_SKE_COOKIE_LEN - coff)) {
1335 /** Invalid cookie */
1336 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1337 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1338 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1339 return SILC_FSM_CONTINUE;
1342 /* Check version string */
1343 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1344 status = silc_ske_check_version(ske);
1345 if (status != SILC_SKE_STATUS_OK) {
1346 /** Version mismatch */
1347 ske->status = status;
1348 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1349 return SILC_FSM_CONTINUE;
1352 /* Free our KE Start Payload context, we don't need it anymore. */
1353 silc_ske_payload_start_free(ske->start_payload);
1354 ske->start_payload = NULL;
1356 /* Take the selected security properties into use while doing
1357 the key exchange. This is used only while doing the key
1359 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1362 prop->flags = payload->flags;
1363 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1364 if (status != SILC_SKE_STATUS_OK)
1367 prop->group = group;
1368 prop->remote_port = remote_port;
1370 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1371 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1374 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1375 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1378 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1379 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1382 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1383 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1387 /* Save remote's KE Start Payload */
1388 ske->start_payload = payload;
1390 /** Send KE Payload */
1391 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1392 return SILC_FSM_CONTINUE;
1396 silc_ske_payload_start_free(payload);
1398 silc_ske_group_free(group);
1400 silc_cipher_free(prop->cipher);
1402 silc_hash_free(prop->hash);
1404 silc_hmac_free(prop->hmac);
1408 if (status == SILC_SKE_STATUS_OK)
1409 status = SILC_SKE_STATUS_ERROR;
1412 ske->status = status;
1413 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1414 return SILC_FSM_CONTINUE;
1417 /* Phase-2. Send KE payload */
1419 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1421 SilcSKE ske = fsm_context;
1422 SilcSKEStatus status;
1424 SilcSKEKEPayload payload;
1427 SILC_LOG_DEBUG(("Start"));
1429 /* Create the random number x, 1 < x < q. */
1430 x = silc_calloc(1, sizeof(*x));
1432 /** Out of memory */
1433 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1434 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1435 return SILC_FSM_CONTINUE;
1439 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1440 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1442 if (status != SILC_SKE_STATUS_OK) {
1443 /** Error generating random number */
1446 ske->status = status;
1447 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1448 return SILC_FSM_CONTINUE;
1451 /* Encode the result to Key Exchange Payload. */
1453 payload = silc_calloc(1, sizeof(*payload));
1455 /** Out of memory */
1458 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1459 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1460 return SILC_FSM_CONTINUE;
1462 ske->ke1_payload = payload;
1464 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1466 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1467 silc_mp_init(&payload->x);
1468 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1469 &ske->prop->group->group);
1472 /* Get public key */
1473 payload->pk_data = silc_pkcs_public_key_encode(NULL, ske->public_key,
1475 if (!payload->pk_data) {
1476 /** Error encoding public key */
1480 silc_mp_uninit(&payload->x);
1482 ske->ke1_payload = NULL;
1483 ske->status = SILC_SKE_STATUS_ERROR;
1484 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1485 return SILC_FSM_CONTINUE;
1487 payload->pk_len = pk_len;
1488 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1490 /** Send KE1 packet */
1491 silc_fsm_next(fsm, silc_ske_st_initiator_phase2_send);
1493 /* Compute signature data if we are doing mutual authentication */
1494 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1495 unsigned char hash[SILC_HASH_MAXLEN];
1496 SilcUInt32 hash_len;
1498 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1499 SILC_LOG_DEBUG(("Computing HASH_i value"));
1501 /* Compute the hash value */
1502 memset(hash, 0, sizeof(hash));
1503 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1505 SILC_LOG_DEBUG(("Signing HASH_i value"));
1507 /* Sign the hash value */
1508 SILC_FSM_CALL(ske->key_op =
1509 silc_pkcs_sign(ske->private_key, hash, hash_len, FALSE,
1510 ske->prop->hash, ske->rng,
1511 silc_ske_initiator_sign_cb, ske));
1515 return SILC_FSM_CONTINUE;
1518 /* Send KE1 packet */
1520 SILC_FSM_STATE(silc_ske_st_initiator_phase2_send)
1522 SilcSKE ske = fsm_context;
1523 SilcSKEStatus status;
1524 SilcBuffer payload_buf;
1525 SilcSKEKEPayload payload;
1527 SILC_LOG_DEBUG(("Start"));
1529 payload = ske->ke1_payload;
1531 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1532 if (status != SILC_SKE_STATUS_OK) {
1533 /** Error encoding KE payload */
1534 silc_mp_uninit(&payload->x);
1535 silc_free(payload->pk_data);
1536 silc_free(payload->sign_data);
1538 ske->ke1_payload = NULL;
1539 ske->status = status;
1540 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1541 return SILC_FSM_CONTINUE;
1544 /* Send the packet. */
1545 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1546 silc_buffer_data(payload_buf),
1547 silc_buffer_len(payload_buf))) {
1548 /** Error sending packet */
1549 SILC_LOG_DEBUG(("Error sending packet"));
1550 ske->status = SILC_SKE_STATUS_ERROR;
1551 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1552 return SILC_FSM_CONTINUE;
1555 silc_buffer_free(payload_buf);
1557 /** Waiting responder's KE payload */
1558 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1559 return SILC_FSM_WAIT;
1562 /* Phase-3. Process responder's KE payload */
1564 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1566 SilcSKE ske = fsm_context;
1567 SilcSKEStatus status;
1568 SilcSKEKEPayload payload;
1570 SilcBuffer packet_buf = &ske->packet->buffer;
1572 SILC_LOG_DEBUG(("Start"));
1574 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1575 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1576 silc_ske_install_retransmission(ske);
1577 silc_packet_free(ske->packet);
1579 return SILC_FSM_WAIT;
1582 /* Decode the payload */
1583 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1584 if (status != SILC_SKE_STATUS_OK) {
1585 /** Error decoding KE payload */
1586 silc_packet_free(ske->packet);
1588 ske->status = status;
1589 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1590 return SILC_FSM_CONTINUE;
1592 silc_packet_free(ske->packet);
1594 ske->ke2_payload = payload;
1596 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1597 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1598 "even though we require it"));
1599 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1603 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1605 /* Compute the shared secret key */
1606 KEY = silc_calloc(1, sizeof(*KEY));
1608 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1611 /* Decode the remote's public key */
1612 if (payload->pk_data &&
1613 !silc_pkcs_public_key_alloc(payload->pk_type,
1614 payload->pk_data, payload->pk_len,
1615 &ske->prop->public_key)) {
1616 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1617 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1621 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1623 SILC_LOG_DEBUG(("Verifying public key"));
1625 /** Waiting public key verification */
1626 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1628 /* If repository is provided, verify the key from there. */
1629 if (ske->repository) {
1632 find = silc_skr_find_alloc();
1634 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1637 silc_skr_find_set_pkcs_type(find,
1638 silc_pkcs_get_type(ske->prop->public_key));
1639 silc_skr_find_set_public_key(find, ske->prop->public_key);
1640 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1642 /* Find key from repository */
1643 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1644 find, silc_ske_skr_callback, ske));
1646 /* Verify from application */
1647 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1648 ske->callbacks->context,
1649 silc_ske_pk_verified, NULL));
1654 /** Process key material */
1655 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1656 return SILC_FSM_CONTINUE;
1659 silc_ske_payload_ke_free(payload);
1660 ske->ke2_payload = NULL;
1662 silc_mp_uninit(ske->KEY);
1663 silc_free(ske->KEY);
1666 if (status == SILC_SKE_STATUS_OK)
1667 return SILC_SKE_STATUS_ERROR;
1670 ske->status = status;
1671 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1672 return SILC_FSM_CONTINUE;
1675 /* Process key material */
1677 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1679 SilcSKE ske = fsm_context;
1680 SilcSKEStatus status;
1681 SilcSKEKEPayload payload;
1682 unsigned char hash[SILC_HASH_MAXLEN];
1683 SilcUInt32 hash_len;
1687 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1688 return SILC_FSM_CONTINUE;
1691 /* Check result of public key verification */
1692 if (ske->status != SILC_SKE_STATUS_OK) {
1693 /** Public key not verified */
1694 SILC_LOG_DEBUG(("Public key verification failed"));
1695 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1696 return SILC_FSM_CONTINUE;
1699 payload = ske->ke2_payload;
1701 /* Compute the HASH value */
1702 SILC_LOG_DEBUG(("Computing HASH value"));
1703 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1704 if (status != SILC_SKE_STATUS_OK)
1706 ske->hash = silc_memdup(hash, hash_len);
1707 ske->hash_len = hash_len;
1710 silc_fsm_next(fsm, silc_ske_st_initiator_phase5);
1712 if (ske->prop->public_key) {
1713 SILC_LOG_DEBUG(("Public key is authentic"));
1714 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1716 /* Verify signature */
1717 SILC_FSM_CALL(ske->key_op =
1718 silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1719 payload->sign_len, hash, hash_len, NULL,
1720 silc_ske_verify_cb, ske));
1724 return SILC_FSM_CONTINUE;
1727 memset(hash, 'F', sizeof(hash));
1728 silc_ske_payload_ke_free(payload);
1729 ske->ke2_payload = NULL;
1731 silc_mp_uninit(ske->KEY);
1732 silc_free(ske->KEY);
1736 memset(ske->hash, 'F', hash_len);
1737 silc_free(ske->hash);
1741 if (status == SILC_SKE_STATUS_OK)
1742 status = SILC_SKE_STATUS_ERROR;
1745 ske->status = status;
1746 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1747 return SILC_FSM_CONTINUE;
1750 /* Process key material */
1752 SILC_FSM_STATE(silc_ske_st_initiator_phase5)
1754 SilcSKE ske = fsm_context;
1755 SilcSKEStatus status;
1756 unsigned char tmp[4];
1757 SilcUInt32 hash_len;
1758 int key_len, block_len;
1760 ske->status = SILC_SKE_STATUS_OK;
1762 /* In case we are doing rekey move to finish it. */
1765 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1766 return SILC_FSM_CONTINUE;
1769 /* Process key material */
1770 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1771 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1772 hash_len = silc_hash_len(ske->prop->hash);
1773 ske->keymat = silc_ske_process_key_material(ske, block_len,
1777 SILC_LOG_ERROR(("Error processing key material"));
1778 status = SILC_SKE_STATUS_ERROR;
1779 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1780 return SILC_FSM_CONTINUE;
1783 /* Send SUCCESS packet */
1784 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, tmp);
1785 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4)) {
1786 /** Error sending packet */
1787 SILC_LOG_DEBUG(("Error sending packet"));
1788 ske->status = SILC_SKE_STATUS_ERROR;
1789 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1790 return SILC_FSM_CONTINUE;
1793 /** Waiting completion */
1794 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1795 return SILC_FSM_WAIT;
1798 /* Protocol completed */
1800 SILC_FSM_STATE(silc_ske_st_initiator_end)
1802 SilcSKE ske = fsm_context;
1804 SILC_LOG_DEBUG(("Start"));
1806 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1807 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1808 silc_ske_install_retransmission(ske);
1809 silc_packet_free(ske->packet);
1811 return SILC_FSM_WAIT;
1814 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1816 silc_packet_free(ske->packet);
1818 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1819 silc_schedule_task_del_by_context(ske->schedule, ske);
1821 /* Call completion */
1822 silc_ske_completion(ske);
1824 return SILC_FSM_FINISH;
1827 /* Aborted by application */
1829 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1831 SilcSKE ske = fsm_context;
1832 unsigned char data[4];
1834 SILC_LOG_DEBUG(("Aborted by caller"));
1836 /* Send FAILURE packet */
1837 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1838 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1840 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1841 silc_schedule_task_del_by_context(ske->schedule, ske);
1843 /* Call completion */
1844 silc_ske_completion(ske);
1846 return SILC_FSM_FINISH;
1849 /* Error occurred. Send error to remote host */
1851 SILC_FSM_STATE(silc_ske_st_initiator_error)
1853 SilcSKE ske = fsm_context;
1854 SilcSKEStatus status;
1855 unsigned char data[4];
1857 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1858 silc_ske_map_status(ske->status), ske->status));
1860 status = ske->status;
1861 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1862 status = SILC_SKE_STATUS_ERROR;
1864 /* Send FAILURE packet */
1865 SILC_PUT32_MSB((SilcUInt32)status, data);
1866 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1868 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1869 silc_schedule_task_del_by_context(ske->schedule, ske);
1871 /* Call completion */
1872 silc_ske_completion(ske);
1874 return SILC_FSM_FINISH;
1877 /* Failure received from remote */
1879 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1881 SilcSKE ske = fsm_context;
1882 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1884 if (ske->packet && 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 the received public key and verify the signature if we are
2128 doing mutual authentication. */
2129 if (ske->start_payload &&
2130 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2132 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2134 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2136 /** Public key not provided */
2137 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2138 "certificate), even though we require it"));
2139 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2140 silc_fsm_next(fsm, silc_ske_st_responder_error);
2141 return SILC_FSM_CONTINUE;
2144 /* Decode the remote's public key */
2145 if (recv_payload->pk_data &&
2146 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2147 recv_payload->pk_data,
2148 recv_payload->pk_len,
2149 &ske->prop->public_key)) {
2150 /** Error decoding public key */
2151 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2152 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2153 silc_fsm_next(fsm, silc_ske_st_responder_error);
2154 return SILC_FSM_CONTINUE;
2157 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2159 SILC_LOG_DEBUG(("Verifying public key"));
2161 /** Waiting public key verification */
2162 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2164 /* If repository is provided, verify the key from there. */
2165 if (ske->repository) {
2168 find = silc_skr_find_alloc();
2170 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2171 silc_fsm_next(fsm, silc_ske_st_responder_error);
2172 return SILC_FSM_CONTINUE;
2174 silc_skr_find_set_pkcs_type(find,
2175 silc_pkcs_get_type(ske->prop->public_key));
2176 silc_skr_find_set_public_key(find, ske->prop->public_key);
2177 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2179 /* Find key from repository */
2180 SILC_FSM_CALL(silc_skr_find(ske->repository,
2181 silc_fsm_get_schedule(fsm), find,
2182 silc_ske_skr_callback, ske));
2184 /* Verify from application */
2185 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2186 ske->callbacks->context,
2187 silc_ske_pk_verified, NULL));
2193 /** Generate KE2 payload */
2194 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2195 return SILC_FSM_CONTINUE;
2198 /* Phase-4. Generate KE2 payload, verify signature */
2200 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2202 SilcSKE ske = fsm_context;
2203 SilcSKEStatus status;
2204 SilcSKEKEPayload recv_payload;
2208 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2209 return SILC_FSM_CONTINUE;
2212 /* Check result of public key verification */
2213 if (ske->status != SILC_SKE_STATUS_OK) {
2214 /** Public key not verified */
2215 SILC_LOG_DEBUG(("Public key verification failed"));
2216 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2217 return SILC_FSM_CONTINUE;
2220 recv_payload = ske->ke1_payload;
2222 /** Send KE2 packet */
2223 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2225 /* The public key verification was performed only if the Mutual
2226 Authentication flag is set. */
2227 if (ske->start_payload &&
2228 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2229 unsigned char hash[SILC_HASH_MAXLEN];
2230 SilcUInt32 hash_len;
2232 SILC_LOG_DEBUG(("Public key is authentic"));
2234 /* Compute the hash value */
2235 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2236 if (status != SILC_SKE_STATUS_OK) {
2237 /** Error computing hash */
2238 ske->status = status;
2239 silc_fsm_next(fsm, silc_ske_st_responder_error);
2240 return SILC_FSM_CONTINUE;
2243 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2245 /* Verify signature */
2246 SILC_FSM_CALL(ske->key_op =
2247 silc_pkcs_verify(ske->prop->public_key,
2248 recv_payload->sign_data,
2249 recv_payload->sign_len,
2250 hash, hash_len, NULL,
2251 silc_ske_verify_cb, ske));
2255 return SILC_FSM_CONTINUE;
2258 /* Phase-5. Send KE2 payload */
2260 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2262 SilcSKE ske = fsm_context;
2263 SilcSKEStatus status;
2264 unsigned char hash[SILC_HASH_MAXLEN], *pk;
2265 SilcUInt32 hash_len, pk_len;
2267 SilcSKEKEPayload send_payload;
2269 SILC_LOG_DEBUG(("Start"));
2271 /* Create the random number x, 1 < x < q. */
2272 x = silc_calloc(1, sizeof(*x));
2275 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2276 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2278 if (status != SILC_SKE_STATUS_OK) {
2279 /** Error generating random number */
2282 ske->status = status;
2283 silc_fsm_next(fsm, silc_ske_st_responder_error);
2284 return SILC_FSM_CONTINUE;
2287 /* Save the results for later processing */
2288 send_payload = silc_calloc(1, sizeof(*send_payload));
2290 ske->ke2_payload = send_payload;
2292 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2294 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2295 silc_mp_init(&send_payload->x);
2296 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2297 &ske->prop->group->group);
2299 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2301 /* Compute the shared secret key */
2302 KEY = silc_calloc(1, sizeof(*KEY));
2304 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2305 &ske->prop->group->group);
2308 if (ske->public_key && ske->private_key) {
2309 SILC_LOG_DEBUG(("Getting public key"));
2311 /* Get the public key */
2312 pk = silc_pkcs_public_key_encode(NULL, ske->public_key, &pk_len);
2314 /** Error encoding public key */
2315 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2316 silc_fsm_next(fsm, silc_ske_st_responder_error);
2317 return SILC_FSM_CONTINUE;
2319 ske->ke2_payload->pk_data = pk;
2320 ske->ke2_payload->pk_len = pk_len;
2323 SILC_LOG_DEBUG(("Computing HASH value"));
2325 /* Compute the hash value */
2326 memset(hash, 0, sizeof(hash));
2327 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2328 if (status != SILC_SKE_STATUS_OK) {
2329 /** Error computing hash */
2330 ske->status = status;
2331 silc_fsm_next(fsm, silc_ske_st_responder_error);
2332 return SILC_FSM_CONTINUE;
2334 ske->hash = silc_memdup(hash, hash_len);
2335 ske->hash_len = hash_len;
2337 /** Send KE2 packet */
2338 silc_fsm_next(fsm, silc_ske_st_responder_phase5_send);
2340 if (ske->public_key && ske->private_key) {
2341 SILC_LOG_DEBUG(("Signing HASH value"));
2343 /* Sign the hash value */
2344 SILC_FSM_CALL(ske->key_op =
2345 silc_pkcs_sign(ske->private_key, hash, hash_len, FALSE,
2346 ske->prop->hash, ske->rng,
2347 silc_ske_responder_sign_cb, ske));
2351 return SILC_FSM_CONTINUE;
2354 /* Send KE2 packet */
2356 SILC_FSM_STATE(silc_ske_st_responder_phase5_send)
2358 SilcSKE ske = fsm_context;
2359 SilcSKEStatus status;
2360 SilcBuffer payload_buf;
2362 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2364 /* Encode the Key Exchange Payload */
2365 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2367 if (status != SILC_SKE_STATUS_OK) {
2368 /** Error encoding KE payload */
2369 ske->status = status;
2370 silc_fsm_next(fsm, silc_ske_st_responder_error);
2371 return SILC_FSM_CONTINUE;
2374 /* Send the packet. */
2375 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2376 payload_buf->data, silc_buffer_len(payload_buf))) {
2377 SILC_LOG_DEBUG(("Error sending packet"));
2378 ske->status = SILC_SKE_STATUS_ERROR;
2379 silc_fsm_next(fsm, silc_ske_st_responder_error);
2380 return SILC_FSM_CONTINUE;
2383 silc_buffer_free(payload_buf);
2385 /* In case we are doing rekey move to finish it. */
2388 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2389 return SILC_FSM_CONTINUE;
2392 /** Waiting completion */
2393 silc_fsm_next(fsm, silc_ske_st_responder_end);
2394 return SILC_FSM_WAIT;
2397 /* Protocol completed */
2399 SILC_FSM_STATE(silc_ske_st_responder_end)
2401 SilcSKE ske = fsm_context;
2402 unsigned char tmp[4];
2403 SilcUInt32 hash_len, key_len, block_len;
2405 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2406 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2407 silc_ske_install_retransmission(ske);
2408 silc_packet_free(ske->packet);
2410 return SILC_FSM_WAIT;
2412 silc_packet_free(ske->packet);
2415 /* Process key material */
2416 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2417 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2418 hash_len = silc_hash_len(ske->prop->hash);
2419 ske->keymat = silc_ske_process_key_material(ske, block_len,
2423 /** Error processing key material */
2424 ske->status = SILC_SKE_STATUS_ERROR;
2425 silc_fsm_next(fsm, silc_ske_st_responder_error);
2426 return SILC_FSM_CONTINUE;
2429 /* Send SUCCESS packet */
2430 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2431 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2433 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2434 silc_schedule_task_del_by_context(ske->schedule, ske);
2436 /* Call completion */
2437 silc_ske_completion(ske);
2439 return SILC_FSM_FINISH;
2442 /* Aborted by application */
2444 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2446 SilcSKE ske = fsm_context;
2447 unsigned char tmp[4];
2449 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2451 /* Send FAILURE packet */
2452 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2453 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2455 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2456 silc_schedule_task_del_by_context(ske->schedule, ske);
2458 /* Call completion */
2459 silc_ske_completion(ske);
2461 return SILC_FSM_FINISH;
2464 /* Failure received from remote */
2466 SILC_FSM_STATE(silc_ske_st_responder_failure)
2468 SilcSKE ske = fsm_context;
2469 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2471 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2473 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2474 SILC_GET32_MSB(error, ske->packet->buffer.data);
2475 ske->status = error;
2476 silc_packet_free(ske->packet);
2480 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2481 silc_schedule_task_del_by_context(ske->schedule, ske);
2483 /* Call completion */
2484 silc_ske_completion(ske);
2486 return SILC_FSM_FINISH;
2489 /* Error occurred */
2491 SILC_FSM_STATE(silc_ske_st_responder_error)
2493 SilcSKE ske = fsm_context;
2494 unsigned char tmp[4];
2496 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2497 ske->status, silc_ske_map_status(ske->status)));
2499 /* Send FAILURE packet */
2500 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2501 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2502 SILC_PUT32_MSB(ske->status, tmp);
2503 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2505 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2506 silc_schedule_task_del_by_context(ske->schedule, ske);
2508 /* Call completion */
2509 silc_ske_completion(ske);
2511 return SILC_FSM_FINISH;
2514 /* Starts the protocol as responder. */
2516 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2517 SilcPacketStream stream,
2518 SilcSKEParams params)
2520 SILC_LOG_DEBUG(("Start SKE as responder"));
2522 if (!ske || !stream || !params || !params->version)
2525 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2528 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2531 ske->responder = TRUE;
2532 ske->flags = params->flags;
2533 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2534 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2535 ske->session_port = params->session_port;
2536 ske->version = strdup(params->version);
2539 ske->running = TRUE;
2541 /* Link to packet stream to get key exchange packets */
2542 ske->stream = stream;
2543 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2544 SILC_PACKET_KEY_EXCHANGE,
2545 SILC_PACKET_KEY_EXCHANGE_1,
2546 SILC_PACKET_SUCCESS,
2547 SILC_PACKET_FAILURE, -1);
2549 /* Start SKE as responder */
2550 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2555 /***************************** Initiator Rekey ******************************/
2559 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2561 SilcSKE ske = fsm_context;
2564 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2568 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2569 return SILC_FSM_CONTINUE;
2572 /* Add rekey exchange timeout */
2573 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2576 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2579 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2580 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2581 return SILC_FSM_CONTINUE;
2584 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2585 /** Cannot allocate hash */
2586 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2587 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2588 return SILC_FSM_CONTINUE;
2591 /* Send REKEY packet to start rekey protocol */
2592 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2593 /** Error sending packet */
2594 SILC_LOG_DEBUG(("Error sending packet"));
2595 ske->status = SILC_SKE_STATUS_ERROR;
2596 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2597 return SILC_FSM_CONTINUE;
2600 /* If doing rekey without PFS, move directly to the end of the protocol. */
2601 if (!ske->rekey->pfs) {
2602 /** Rekey without PFS */
2603 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2604 return SILC_FSM_CONTINUE;
2607 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2609 if (status != SILC_SKE_STATUS_OK) {
2610 /** Unknown group */
2611 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2612 return SILC_FSM_CONTINUE;
2615 /** Rekey with PFS */
2616 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2617 return SILC_FSM_CONTINUE;
2620 /* Sends REKEY_DONE packet to finish the protocol. */
2622 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2624 SilcSKE ske = fsm_context;
2625 SilcCipher send_key;
2628 SilcUInt32 key_len, block_len, hash_len, x_len;
2629 unsigned char *pfsbuf;
2631 SILC_LOG_DEBUG(("Start"));
2633 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2634 key_len = silc_cipher_get_key_len(send_key);
2635 block_len = silc_cipher_get_block_len(send_key);
2636 hash = ske->prop->hash;
2637 hash_len = silc_hash_len(hash);
2639 /* Process key material */
2640 if (ske->rekey->pfs) {
2642 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2644 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2647 memset(pfsbuf, 0, x_len);
2653 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2654 ske->rekey->enc_key_len / 8,
2660 SILC_LOG_ERROR(("Error processing key material"));
2661 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2662 return SILC_FSM_CONTINUE;
2665 ske->prop->cipher = send_key;
2666 ske->prop->hmac = hmac_send;
2668 /* Get sending keys */
2669 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2670 &hmac_send, NULL, NULL)) {
2671 /** Cannot get keys */
2672 ske->status = SILC_SKE_STATUS_ERROR;
2673 ske->prop->cipher = NULL;
2674 ske->prop->hmac = NULL;
2675 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2676 return SILC_FSM_CONTINUE;
2679 ske->prop->cipher = NULL;
2680 ske->prop->hmac = NULL;
2682 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2683 packet sent after this call will be protected with the new keys. */
2684 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2686 /** Cannot set keys */
2687 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2688 ske->status = SILC_SKE_STATUS_ERROR;
2689 silc_cipher_free(send_key);
2690 silc_hmac_free(hmac_send);
2691 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2692 return SILC_FSM_CONTINUE;
2695 /** Wait for REKEY_DONE */
2696 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2697 return SILC_FSM_WAIT;
2700 /* Rekey protocol end */
2702 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2704 SilcSKE ske = fsm_context;
2705 SilcCipher receive_key;
2706 SilcHmac hmac_receive;
2707 SilcSKERekeyMaterial rekey;
2709 SILC_LOG_DEBUG(("Start"));
2711 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2712 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2713 silc_packet_free(ske->packet);
2715 return SILC_FSM_WAIT;
2718 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2719 ske->prop->cipher = receive_key;
2720 ske->prop->hmac = hmac_receive;
2722 /* Get receiving keys */
2723 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2724 NULL, &hmac_receive, NULL)) {
2725 /** Cannot get keys */
2726 ske->status = SILC_SKE_STATUS_ERROR;
2727 ske->prop->cipher = NULL;
2728 ske->prop->hmac = NULL;
2729 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2730 return SILC_FSM_CONTINUE;
2733 /* Set new receiving keys into use. All packets received after this will
2734 be decrypted with the new keys. */
2735 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2736 hmac_receive, FALSE)) {
2737 /** Cannot set keys */
2738 SILC_LOG_DEBUG(("Cannot set new keys"));
2739 ske->status = SILC_SKE_STATUS_ERROR;
2740 silc_cipher_free(receive_key);
2741 silc_hmac_free(hmac_receive);
2742 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2743 return SILC_FSM_CONTINUE;
2746 SILC_LOG_DEBUG(("Rekey completed successfully"));
2748 /* Generate new rekey material */
2749 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2752 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2753 ske->prop->cipher = NULL;
2754 ske->prop->hmac = NULL;
2755 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2756 return SILC_FSM_CONTINUE;
2758 rekey->pfs = ske->rekey->pfs;
2761 ske->prop->cipher = NULL;
2762 ske->prop->hmac = NULL;
2763 silc_packet_free(ske->packet);
2765 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2766 silc_schedule_task_del_by_context(ske->schedule, ske);
2768 /* Call completion */
2769 silc_ske_completion(ske);
2771 return SILC_FSM_FINISH;
2774 /* Starts rekey protocol as initiator */
2777 silc_ske_rekey_initiator(SilcSKE ske,
2778 SilcPacketStream stream,
2779 SilcSKERekeyMaterial rekey)
2781 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2783 if (!ske || !stream || !rekey) {
2784 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2789 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2792 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2796 ske->responder = FALSE;
2797 ske->running = TRUE;
2798 ske->rekeying = TRUE;
2800 /* Link to packet stream to get key exchange packets */
2801 ske->stream = stream;
2802 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2804 SILC_PACKET_REKEY_DONE,
2805 SILC_PACKET_KEY_EXCHANGE_2,
2806 SILC_PACKET_SUCCESS,
2807 SILC_PACKET_FAILURE, -1);
2809 /* Start SKE rekey as initiator */
2810 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2815 /***************************** Responder Rekey ******************************/
2817 /* Wait for initiator's packet */
2819 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2821 SilcSKE ske = fsm_context;
2823 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2827 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2828 return SILC_FSM_CONTINUE;
2831 /* Add rekey exchange timeout */
2832 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2835 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2837 /* If REKEY packet already received process it directly */
2838 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2839 return SILC_FSM_CONTINUE;
2841 /* Wait for REKEY */
2842 return SILC_FSM_WAIT;
2845 /* Process initiator's REKEY packet */
2847 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2849 SilcSKE ske = fsm_context;
2850 SilcSKEStatus status;
2852 SILC_LOG_DEBUG(("Start"));
2854 if (ske->packet->type != SILC_PACKET_REKEY) {
2855 ske->status = SILC_SKE_STATUS_ERROR;
2856 silc_packet_free(ske->packet);
2858 silc_fsm_next(fsm, silc_ske_st_responder_error);
2859 return SILC_FSM_CONTINUE;
2862 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2865 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2866 silc_fsm_next(fsm, silc_ske_st_responder_error);
2867 return SILC_FSM_CONTINUE;
2870 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2871 /** Cannot allocate hash */
2872 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2873 silc_fsm_next(fsm, silc_ske_st_responder_error);
2874 return SILC_FSM_CONTINUE;
2877 /* If doing rekey without PFS, move directly to the end of the protocol. */
2878 if (!ske->rekey->pfs) {
2879 /** Rekey without PFS */
2880 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2881 return SILC_FSM_CONTINUE;
2884 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2886 if (status != SILC_SKE_STATUS_OK) {
2887 /** Unknown group */
2888 silc_fsm_next(fsm, silc_ske_st_responder_error);
2889 return SILC_FSM_CONTINUE;
2892 /** Rekey with PFS */
2893 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2894 return SILC_FSM_WAIT;
2897 /* Sends REKEY_DONE packet to finish the protocol. */
2899 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2901 SilcSKE ske = fsm_context;
2902 SilcCipher send_key;
2905 SilcUInt32 key_len, block_len, hash_len, x_len;
2906 unsigned char *pfsbuf;
2908 SILC_LOG_DEBUG(("Start"));
2910 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2911 key_len = silc_cipher_get_key_len(send_key);
2912 block_len = silc_cipher_get_block_len(send_key);
2913 hash = ske->prop->hash;
2914 hash_len = silc_hash_len(hash);
2916 /* Process key material */
2917 if (ske->rekey->pfs) {
2919 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2921 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2924 memset(pfsbuf, 0, x_len);
2930 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2931 ske->rekey->enc_key_len / 8,
2937 SILC_LOG_ERROR(("Error processing key material"));
2938 silc_fsm_next(fsm, silc_ske_st_responder_error);
2939 return SILC_FSM_CONTINUE;
2942 ske->prop->cipher = send_key;
2943 ske->prop->hmac = hmac_send;
2945 /* Get sending keys */
2946 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2947 &hmac_send, NULL, NULL)) {
2948 /** Cannot get keys */
2949 ske->status = SILC_SKE_STATUS_ERROR;
2950 ske->prop->cipher = NULL;
2951 ske->prop->hmac = NULL;
2952 silc_fsm_next(fsm, silc_ske_st_responder_error);
2953 return SILC_FSM_CONTINUE;
2956 ske->prop->cipher = NULL;
2957 ske->prop->hmac = NULL;
2959 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2960 packet sent after this call will be protected with the new keys. */
2961 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2963 /** Cannot set keys */
2964 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2965 ske->status = SILC_SKE_STATUS_ERROR;
2966 silc_cipher_free(send_key);
2967 silc_hmac_free(hmac_send);
2968 silc_fsm_next(fsm, silc_ske_st_responder_error);
2969 return SILC_FSM_CONTINUE;
2972 /** Wait for REKEY_DONE */
2973 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2974 return SILC_FSM_WAIT;
2977 /* Rekey protocol end */
2979 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2981 SilcSKE ske = fsm_context;
2982 SilcCipher receive_key;
2983 SilcHmac hmac_receive;
2984 SilcSKERekeyMaterial rekey;
2986 SILC_LOG_DEBUG(("Start"));
2988 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2989 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2990 silc_packet_free(ske->packet);
2992 return SILC_FSM_WAIT;
2995 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2996 ske->prop->cipher = receive_key;
2997 ske->prop->hmac = hmac_receive;
2999 /* Get receiving keys */
3000 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
3001 NULL, &hmac_receive, NULL)) {
3002 /** Cannot get keys */
3003 ske->status = SILC_SKE_STATUS_ERROR;
3004 ske->prop->cipher = NULL;
3005 ske->prop->hmac = NULL;
3006 silc_fsm_next(fsm, silc_ske_st_responder_error);
3007 return SILC_FSM_CONTINUE;
3010 /* Set new receiving keys into use. All packets received after this will
3011 be decrypted with the new keys. */
3012 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3013 hmac_receive, FALSE)) {
3014 /** Cannot set keys */
3015 SILC_LOG_DEBUG(("Cannot set new keys"));
3016 ske->status = SILC_SKE_STATUS_ERROR;
3017 ske->prop->cipher = NULL;
3018 ske->prop->hmac = NULL;
3019 silc_cipher_free(receive_key);
3020 silc_hmac_free(hmac_receive);
3021 silc_fsm_next(fsm, silc_ske_st_responder_error);
3022 return SILC_FSM_CONTINUE;
3025 SILC_LOG_DEBUG(("Rekey completed successfully"));
3027 /* Generate new rekey material */
3028 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3031 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3032 ske->prop->cipher = NULL;
3033 ske->prop->hmac = NULL;
3034 silc_fsm_next(fsm, silc_ske_st_responder_error);
3035 return SILC_FSM_CONTINUE;
3037 rekey->pfs = ske->rekey->pfs;
3040 ske->prop->cipher = NULL;
3041 ske->prop->hmac = NULL;
3042 silc_packet_free(ske->packet);
3044 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3045 silc_schedule_task_del_by_context(ske->schedule, ske);
3047 /* Call completion */
3048 silc_ske_completion(ske);
3050 return SILC_FSM_FINISH;
3053 /* Starts rekey protocol as responder */
3056 silc_ske_rekey_responder(SilcSKE ske,
3057 SilcPacketStream stream,
3058 SilcSKERekeyMaterial rekey,
3061 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3063 if (!ske || !stream || !rekey)
3066 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3069 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3073 ske->responder = TRUE;
3074 ske->running = TRUE;
3075 ske->rekeying = TRUE;
3076 ske->packet = packet;
3078 /* Link to packet stream to get key exchange packets */
3079 ske->stream = stream;
3080 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3082 SILC_PACKET_REKEY_DONE,
3083 SILC_PACKET_KEY_EXCHANGE_1,
3084 SILC_PACKET_SUCCESS,
3085 SILC_PACKET_FAILURE, -1);
3087 /* Start SKE rekey as responder */
3088 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3093 /* Processes the provided key material `data' as the SILC protocol
3094 specification defines. */
3097 silc_ske_process_key_material_data(unsigned char *data,
3098 SilcUInt32 data_len,
3099 SilcUInt32 req_iv_len,
3100 SilcUInt32 req_enc_key_len,
3101 SilcUInt32 req_hmac_key_len,
3105 unsigned char hashd[SILC_HASH_MAXLEN];
3106 SilcUInt32 hash_len = req_hmac_key_len;
3107 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3108 SilcSKEKeyMaterial key;
3110 SILC_LOG_DEBUG(("Start"));
3112 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3115 key = silc_calloc(1, sizeof(*key));
3119 buf = silc_buffer_alloc_size(1 + data_len);
3122 silc_buffer_format(buf,
3123 SILC_STR_UI_CHAR(0),
3124 SILC_STR_DATA(data, data_len),
3128 memset(hashd, 0, sizeof(hashd));
3130 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3131 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3132 memcpy(key->send_iv, hashd, req_iv_len);
3133 memset(hashd, 0, sizeof(hashd));
3135 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3136 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3137 memcpy(key->receive_iv, hashd, req_iv_len);
3138 key->iv_len = req_iv_len;
3140 /* Take the encryption keys. If requested key size is more than
3141 the size of hash length we will distribute more key material
3142 as protocol defines. */
3144 if (enc_key_len > hash_len) {
3146 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3147 k3[SILC_HASH_MAXLEN];
3148 unsigned char *dtmp;
3151 if (enc_key_len > (3 * hash_len))
3154 /* Take first round */
3155 memset(k1, 0, sizeof(k1));
3156 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3158 /* Take second round */
3159 dist = silc_buffer_alloc_size(data_len + hash_len);
3162 silc_buffer_format(dist,
3163 SILC_STR_DATA(data, data_len),
3164 SILC_STR_DATA(k1, hash_len),
3166 memset(k2, 0, sizeof(k2));
3167 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3169 /* Take third round */
3170 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3171 silc_buffer_pull_tail(dist, hash_len);
3172 silc_buffer_pull(dist, data_len + hash_len);
3173 silc_buffer_format(dist,
3174 SILC_STR_DATA(k2, hash_len),
3176 silc_buffer_push(dist, data_len + hash_len);
3177 memset(k3, 0, sizeof(k3));
3178 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3180 /* Then, save the keys */
3181 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3182 memcpy(dtmp, k1, hash_len);
3183 memcpy(dtmp + hash_len, k2, hash_len);
3184 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3186 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3187 memcpy(key->send_enc_key, dtmp, enc_key_len);
3188 key->enc_key_len = req_enc_key_len;
3190 memset(dtmp, 0, (3 * hash_len));
3191 memset(k1, 0, sizeof(k1));
3192 memset(k2, 0, sizeof(k2));
3193 memset(k3, 0, sizeof(k3));
3195 silc_buffer_clear(dist);
3196 silc_buffer_free(dist);
3198 /* Take normal hash as key */
3199 memset(hashd, 0, sizeof(hashd));
3200 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3201 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3202 memcpy(key->send_enc_key, hashd, enc_key_len);
3203 key->enc_key_len = req_enc_key_len;
3207 if (enc_key_len > hash_len) {
3209 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3210 k3[SILC_HASH_MAXLEN];
3211 unsigned char *dtmp;
3214 if (enc_key_len > (3 * hash_len))
3217 /* Take first round */
3218 memset(k1, 0, sizeof(k1));
3219 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3221 /* Take second round */
3222 dist = silc_buffer_alloc_size(data_len + hash_len);
3225 silc_buffer_format(dist,
3226 SILC_STR_DATA(data, data_len),
3227 SILC_STR_DATA(k1, hash_len),
3229 memset(k2, 0, sizeof(k2));
3230 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3232 /* Take third round */
3233 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3234 silc_buffer_pull_tail(dist, hash_len);
3235 silc_buffer_pull(dist, data_len + hash_len);
3236 silc_buffer_format(dist,
3237 SILC_STR_DATA(k2, hash_len),
3239 silc_buffer_push(dist, data_len + hash_len);
3240 memset(k3, 0, sizeof(k3));
3241 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3243 /* Then, save the keys */
3244 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3245 memcpy(dtmp, k1, hash_len);
3246 memcpy(dtmp + hash_len, k2, hash_len);
3247 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3249 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3250 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3251 key->enc_key_len = req_enc_key_len;
3253 memset(dtmp, 0, (3 * hash_len));
3254 memset(k1, 0, sizeof(k1));
3255 memset(k2, 0, sizeof(k2));
3256 memset(k3, 0, sizeof(k3));
3258 silc_buffer_clear(dist);
3259 silc_buffer_free(dist);
3261 /* Take normal hash as key */
3262 memset(hashd, 0, sizeof(hashd));
3263 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3264 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3265 memcpy(key->receive_enc_key, hashd, enc_key_len);
3266 key->enc_key_len = req_enc_key_len;
3269 /* Take HMAC keys */
3270 memset(hashd, 0, sizeof(hashd));
3272 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3273 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3274 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3275 memset(hashd, 0, sizeof(hashd));
3277 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3278 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3279 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3280 key->hmac_key_len = req_hmac_key_len;
3281 memset(hashd, 0, sizeof(hashd));
3283 silc_buffer_clear(buf);
3284 silc_buffer_free(buf);
3286 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3291 /* Processes negotiated key material as protocol specifies. This returns
3292 the actual keys to be used in the SILC. */
3295 silc_ske_process_key_material(SilcSKE ske,
3296 SilcUInt32 req_iv_len,
3297 SilcUInt32 req_enc_key_len,
3298 SilcUInt32 req_hmac_key_len,
3299 SilcSKERekeyMaterial *rekey)
3302 unsigned char *tmpbuf;
3304 SilcSKEKeyMaterial key;
3306 /* Encode KEY to binary data */
3307 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3309 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3312 silc_buffer_format(buf,
3313 SILC_STR_DATA(tmpbuf, klen),
3314 SILC_STR_DATA(ske->hash, ske->hash_len),
3317 /* Process the key material */
3318 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3319 req_iv_len, req_enc_key_len,
3323 memset(tmpbuf, 0, klen);
3325 silc_buffer_clear(buf);
3326 silc_buffer_free(buf);
3329 *rekey = silc_ske_make_rekey_material(ske, key);
3337 /* Free key material structure */
3339 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3345 silc_free(key->send_iv);
3346 if (key->receive_iv)
3347 silc_free(key->receive_iv);
3348 if (key->send_enc_key) {
3349 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3350 silc_free(key->send_enc_key);
3352 if (key->receive_enc_key) {
3353 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3354 silc_free(key->receive_enc_key);
3356 if (key->send_hmac_key) {
3357 memset(key->send_hmac_key, 0, key->hmac_key_len);
3358 silc_free(key->send_hmac_key);
3360 if (key->receive_hmac_key) {
3361 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3362 silc_free(key->receive_hmac_key);
3367 /* Free rekey material */
3369 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3373 if (rekey->send_enc_key) {
3374 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3375 silc_free(rekey->send_enc_key);
3377 silc_free(rekey->hash);
3381 /* Set keys into use */
3383 SilcBool silc_ske_set_keys(SilcSKE ske,
3384 SilcSKEKeyMaterial keymat,
3385 SilcSKESecurityProperties prop,
3386 SilcCipher *ret_send_key,
3387 SilcCipher *ret_receive_key,
3388 SilcHmac *ret_hmac_send,
3389 SilcHmac *ret_hmac_receive,
3392 unsigned char iv[32];
3393 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3395 /* Allocate ciphers to be used in the communication */
3397 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3401 if (ret_receive_key) {
3402 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3407 /* Allocate HMACs */
3408 if (ret_hmac_send) {
3409 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3413 if (ret_hmac_receive) {
3414 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3419 /* Set key material */
3420 memset(iv, 0, sizeof(iv));
3421 if (ske->responder) {
3423 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3424 keymat->enc_key_len, TRUE);
3426 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3427 memcpy(iv, ske->hash, 4);
3428 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3429 silc_cipher_set_iv(*ret_send_key, iv);
3431 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3434 if (ret_receive_key) {
3435 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3436 keymat->enc_key_len, FALSE);
3438 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3439 memcpy(iv, ske->hash, 4);
3440 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3441 silc_cipher_set_iv(*ret_receive_key, iv);
3443 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3447 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3448 keymat->hmac_key_len);
3449 if (ret_hmac_receive)
3450 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3451 keymat->hmac_key_len);
3454 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3455 keymat->enc_key_len, TRUE);
3457 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3458 memcpy(iv, ske->hash, 4);
3459 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3460 silc_cipher_set_iv(*ret_send_key, iv);
3462 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3465 if (ret_receive_key) {
3466 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3467 keymat->enc_key_len, FALSE);
3469 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3470 memcpy(iv, ske->hash, 4);
3471 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3472 silc_cipher_set_iv(*ret_receive_key, iv);
3474 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3478 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3479 keymat->hmac_key_len);
3480 if (ret_hmac_receive)
3481 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3482 keymat->hmac_key_len);
3487 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3494 const char *silc_ske_status_string[] =
3498 "Unexpected error occurred",
3499 "Bad payload in packet",
3500 "Unsupported group",
3501 "Unsupported cipher",
3503 "Unsupported hash function",
3505 "Unsupported public key (or certificate)",
3506 "Incorrect signature",
3507 "Bad or unsupported version",
3511 "Remote did not provide public key",
3512 "Bad reserved field in packet",
3513 "Bad payload length in packet",
3514 "Error computing signature",
3515 "System out of memory",
3516 "Key exchange timeout",
3521 /* Maps status to readable string and returns the string. If string is not
3522 found and empty character string ("") is returned. */
3524 const char *silc_ske_map_status(SilcSKEStatus status)
3528 for (i = 0; silc_ske_status_string[i]; i++)
3530 return silc_ske_status_string[i];
3535 /* Parses remote host's version string. */
3537 SilcBool silc_ske_parse_version(SilcSKE ske,
3538 SilcUInt32 *protocol_version,
3539 char **protocol_version_string,
3540 SilcUInt32 *software_version,
3541 char **software_version_string,
3542 char **vendor_version)
3544 return silc_parse_version_string(ske->remote_version,
3546 protocol_version_string,
3548 software_version_string,
3552 /* Get security properties */
3554 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3559 /* Get key material */
3561 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)