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_phase3);
41 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
42 SILC_FSM_STATE(silc_ske_st_initiator_end);
43 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
44 SILC_FSM_STATE(silc_ske_st_initiator_error);
45 SILC_FSM_STATE(silc_ske_st_initiator_failure);
46 SILC_FSM_STATE(silc_ske_st_responder_start);
47 SILC_FSM_STATE(silc_ske_st_responder_phase1);
48 SILC_FSM_STATE(silc_ske_st_responder_phase2);
49 SILC_FSM_STATE(silc_ske_st_responder_phase4);
50 SILC_FSM_STATE(silc_ske_st_responder_phase5);
51 SILC_FSM_STATE(silc_ske_st_responder_end);
52 SILC_FSM_STATE(silc_ske_st_responder_aborted);
53 SILC_FSM_STATE(silc_ske_st_responder_failure);
54 SILC_FSM_STATE(silc_ske_st_responder_error);
55 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
56 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done);
57 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end);
58 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait);
59 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
60 SILC_FSM_STATE(silc_ske_st_rekey_responder_done);
61 SILC_FSM_STATE(silc_ske_st_rekey_responder_end);
62 SILC_TASK_CALLBACK(silc_ske_packet_send_retry);
65 silc_ske_process_key_material(SilcSKE ske,
66 SilcUInt32 req_iv_len,
67 SilcUInt32 req_enc_key_len,
68 SilcUInt32 req_hmac_key_len,
69 SilcSKERekeyMaterial *rekey);
70 static SilcBool silc_ske_packet_send(SilcSKE ske,
72 SilcPacketFlags flags,
73 const unsigned char *data,
77 * Notify the owner of the ske that we failed. Ensures that we don't make the
78 * same callout twice, as the notification callback routines are not designed
79 * to handle that case.
81 static void silc_ske_notify_failure(SilcSKE ske)
83 SILC_LOG_DEBUG(("Notifying SKE %p owner of failure (failure_notified = %lu)",
84 ske, ske->failure_notified));
87 * First, check if we have already made a failure callout. If so, then we
90 if (ske->failure_notified)
94 * Mark ourselves as having already sent the failure notification here and
97 ske->failure_notified = TRUE;
99 SILC_LOG_DEBUG(("Deliver failure notification for SKE %p (%s)",
100 ske, ske->responder ? "responder" : "initiator"));
103 * Finally, make the call to the owner's registered failure callback.
106 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
108 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
111 /* Packet callback */
113 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
114 SilcPacketStream stream,
116 void *callback_context,
119 SilcSKE ske = callback_context;
121 /* Clear retransmission */
122 ske->retry_timer = SILC_SKE_RETRY_MIN;
123 ske->retry_count = 0;
124 silc_schedule_task_del_by_callback(ske->schedule,
125 silc_ske_packet_send_retry);
127 /* Signal for new packet */
128 ske->packet = packet;
130 /* Check if we were aborted */
132 silc_packet_free(packet);
136 silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
138 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
140 silc_fsm_continue_sync(&ske->fsm);
144 /* See if received failure from remote */
145 if (packet->type == SILC_PACKET_FAILURE)
146 silc_ske_notify_failure(ske);
148 /* Handle rekey and SUCCESS packets synchronously. After SUCCESS packets
149 they keys are taken into use immediately, hence the synchronous
150 processing to get the keys in use as soon as possible. */
151 if (ske->rekeying || packet->type == SILC_PACKET_SUCCESS)
152 silc_fsm_continue_sync(&ske->fsm);
154 silc_fsm_continue(&ske->fsm);
159 /* Packet stream callbacks */
160 static SilcPacketCallbacks silc_ske_stream_cbs =
162 silc_ske_packet_receive, NULL, NULL
165 /* Aborts SKE protocol */
167 static void silc_ske_abort(SilcAsyncOperation op, void *context)
169 SilcSKE ske = context;
173 /* Public key verification completion callback */
175 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
176 void *completion_context)
178 ske->status = status;
179 SILC_FSM_CALL_CONTINUE(&ske->fsm);
182 /* SKR find callback */
184 static void silc_ske_skr_callback(SilcSKR repository,
186 SilcSKRStatus status,
187 SilcDList keys, void *context)
189 SilcSKE ske = context;
191 silc_skr_find_free(find);
193 if (status != SILC_SKR_OK) {
194 if (ske->callbacks->verify_key) {
195 /* Verify from application */
196 ske->callbacks->verify_key(ske, ske->prop->public_key,
197 ske->callbacks->context,
198 silc_ske_pk_verified, NULL);
204 silc_dlist_uninit(keys);
207 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
208 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
209 SILC_FSM_CALL_CONTINUE(&ske->fsm);
212 /* Checks remote and local versions */
214 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
216 if (!ske->remote_version || !ske->version)
217 return SILC_SKE_STATUS_BAD_VERSION;
219 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
221 return SILC_SKE_STATUS_BAD_VERSION;
223 return SILC_SKE_STATUS_OK;
226 /* Selects the supported security properties from the initiator's Key
227 Exchange Start Payload. A responder function. Saves our reply
228 start payload to ske->start_payload. */
231 silc_ske_select_security_properties(SilcSKE ske,
232 SilcSKEStartPayload remote_payload,
233 SilcSKESecurityProperties *prop)
235 SilcSKEStatus status;
236 SilcSKEStartPayload rp, payload;
240 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
244 /* Check for mandatory fields */
245 if (!rp->ke_grp_len) {
246 SILC_LOG_DEBUG(("KE group not defined in payload"));
247 return SILC_SKE_STATUS_BAD_PAYLOAD;
249 if (!rp->pkcs_alg_len) {
250 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
251 return SILC_SKE_STATUS_BAD_PAYLOAD;
253 if (!rp->enc_alg_len) {
254 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
255 return SILC_SKE_STATUS_BAD_PAYLOAD;
257 if (!rp->hash_alg_len) {
258 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
259 return SILC_SKE_STATUS_BAD_PAYLOAD;
261 if (!rp->hmac_alg_len) {
262 SILC_LOG_DEBUG(("HMAC not defined in payload"));
263 return SILC_SKE_STATUS_BAD_PAYLOAD;
266 /* Allocate security properties */
267 *prop = silc_calloc(1, sizeof(**prop));
269 return SILC_SKE_STATUS_OUT_OF_MEMORY;
271 /* Allocate our reply start payload */
272 payload = silc_calloc(1, sizeof(*payload));
275 return SILC_SKE_STATUS_OUT_OF_MEMORY;
278 /* Check version string */
279 ske->remote_version = silc_memdup(rp->version, rp->version_len);
280 status = silc_ske_check_version(ske);
281 if (status != SILC_SKE_STATUS_OK) {
282 ske->status = status;
286 /* Flags are returned unchanged. */
287 (*prop)->flags = payload->flags = rp->flags;
289 /* Take cookie, we must return it to sender unmodified. */
290 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
291 if (!payload->cookie) {
292 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
295 payload->cookie_len = SILC_SKE_COOKIE_LEN;
296 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
298 /* In case IV included flag and session port is set the first 16-bits of
299 cookie will include our session port. */
300 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
301 /* Take remote port */
302 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
305 SILC_PUT16_MSB(ske->session_port, payload->cookie);
308 /* Put our version to our reply */
309 payload->version = strdup(ske->version);
310 if (!payload->version) {
311 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
314 payload->version_len = strlen(ske->version);
316 /* Get supported Key Exchange groups */
317 cp = rp->ke_grp_list;
318 if (cp && strchr(cp, ',')) {
322 len = strcspn(cp, ",");
323 item = silc_calloc(len + 1, sizeof(char));
325 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
328 memcpy(item, cp, len);
330 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
332 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
333 SILC_LOG_DEBUG(("Found KE group `%s'", item));
335 payload->ke_grp_len = len;
336 payload->ke_grp_list = item;
350 if (!payload->ke_grp_len && !payload->ke_grp_list) {
351 SILC_LOG_DEBUG(("Could not find supported KE group"));
353 return SILC_SKE_STATUS_UNKNOWN_GROUP;
356 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
357 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
359 payload->ke_grp_len = rp->ke_grp_len;
360 payload->ke_grp_list = strdup(rp->ke_grp_list);
363 /* Save group to security properties */
364 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
365 if (status != SILC_SKE_STATUS_OK) {
367 return SILC_SKE_STATUS_UNKNOWN_GROUP;
370 /* Get supported PKCS algorithms */
371 cp = rp->pkcs_alg_list;
372 if (cp && strchr(cp, ',')) {
376 len = strcspn(cp, ",");
377 item = silc_calloc(len + 1, sizeof(char));
379 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
382 memcpy(item, cp, len);
384 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
386 if (silc_pkcs_find_algorithm(item, NULL)) {
387 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
389 payload->pkcs_alg_len = len;
390 payload->pkcs_alg_list = item;
404 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
405 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
406 silc_free(payload->ke_grp_list);
408 return SILC_SKE_STATUS_UNKNOWN_PKCS;
411 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
412 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
414 payload->pkcs_alg_len = rp->pkcs_alg_len;
415 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
418 /* Get supported encryption algorithms */
419 cp = rp->enc_alg_list;
420 if (cp && strchr(cp, ',')) {
424 len = strcspn(cp, ",");
425 item = silc_calloc(len + 1, sizeof(char));
427 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
430 memcpy(item, cp, len);
432 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
434 if (silc_cipher_is_supported(item) == TRUE) {
435 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
437 payload->enc_alg_len = len;
438 payload->enc_alg_list = item;
452 if (!payload->enc_alg_len && !payload->enc_alg_list) {
453 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
454 silc_free(payload->ke_grp_list);
455 silc_free(payload->pkcs_alg_list);
457 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
460 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
463 payload->enc_alg_len = rp->enc_alg_len;
464 payload->enc_alg_list = strdup(rp->enc_alg_list);
467 /* Save selected cipher to security properties */
468 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
469 silc_free(payload->ke_grp_list);
470 silc_free(payload->pkcs_alg_list);
472 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
475 /* Get supported hash algorithms */
476 cp = rp->hash_alg_list;
477 if (cp && strchr(cp, ',')) {
481 len = strcspn(cp, ",");
482 item = silc_calloc(len + 1, sizeof(char));
484 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
487 memcpy(item, cp, len);
489 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
491 if (silc_hash_is_supported(item) == TRUE) {
492 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
494 payload->hash_alg_len = len;
495 payload->hash_alg_list = item;
509 if (!payload->hash_alg_len && !payload->hash_alg_list) {
510 SILC_LOG_DEBUG(("Could not find supported hash alg"));
511 silc_free(payload->ke_grp_list);
512 silc_free(payload->pkcs_alg_list);
513 silc_free(payload->enc_alg_list);
515 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
518 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
521 payload->hash_alg_len = rp->hash_alg_len;
522 payload->hash_alg_list = strdup(rp->hash_alg_list);
525 /* Save selected hash algorithm to security properties */
526 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
527 silc_free(payload->ke_grp_list);
528 silc_free(payload->pkcs_alg_list);
529 silc_free(payload->enc_alg_list);
531 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
534 /* Get supported HMACs */
535 cp = rp->hmac_alg_list;
536 if (cp && strchr(cp, ',')) {
540 len = strcspn(cp, ",");
541 item = silc_calloc(len + 1, sizeof(char));
543 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
546 memcpy(item, cp, len);
548 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
550 if (silc_hmac_is_supported(item) == TRUE) {
551 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
553 payload->hmac_alg_len = len;
554 payload->hmac_alg_list = item;
568 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
569 SILC_LOG_DEBUG(("Could not find supported HMAC"));
570 silc_free(payload->ke_grp_list);
571 silc_free(payload->pkcs_alg_list);
572 silc_free(payload->enc_alg_list);
573 silc_free(payload->hash_alg_list);
575 return SILC_SKE_STATUS_UNKNOWN_HMAC;
578 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
581 payload->hmac_alg_len = rp->hmac_alg_len;
582 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
585 /* Save selected HMACc to security properties */
586 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
587 silc_free(payload->ke_grp_list);
588 silc_free(payload->pkcs_alg_list);
589 silc_free(payload->enc_alg_list);
590 silc_free(payload->hash_alg_list);
592 return SILC_SKE_STATUS_UNKNOWN_HMAC;
595 /* Get supported compression algorithms */
596 cp = rp->comp_alg_list;
597 if (cp && strchr(cp, ',')) {
601 len = strcspn(cp, ",");
602 item = silc_calloc(len + 1, sizeof(char));
604 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
607 memcpy(item, cp, len);
609 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
612 if (!strcmp(item, "none")) {
613 SILC_LOG_DEBUG(("Found Compression `%s'", item));
614 payload->comp_alg_len = len;
615 payload->comp_alg_list = item;
619 if (silc_hmac_is_supported(item) == TRUE) {
620 SILC_LOG_DEBUG(("Found Compression `%s'", item));
621 payload->comp_alg_len = len;
622 payload->comp_alg_list = item;
638 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
639 2 + payload->version_len +
640 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
641 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
642 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
644 /* Save our reply payload */
645 ske->start_payload = payload;
647 return SILC_SKE_STATUS_OK;
650 /* Creates random number such that 1 < rnd < n and at most length
651 of len bits. The rnd sent as argument must be initialized. */
653 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
657 SilcSKEStatus status = SILC_SKE_STATUS_OK;
658 unsigned char *string;
662 return SILC_SKE_STATUS_ERROR;
664 SILC_LOG_DEBUG(("Creating random number"));
668 /* Get the random number as string */
669 string = silc_rng_get_rn_data(ske->rng, l);
671 return SILC_SKE_STATUS_OUT_OF_MEMORY;
673 /* Decode the string into a MP integer */
674 silc_mp_bin2mp(string, l, rnd);
675 silc_mp_mod_2exp(rnd, rnd, len);
678 if (silc_mp_cmp_ui(rnd, 1) < 0)
679 status = SILC_SKE_STATUS_ERROR;
680 if (silc_mp_cmp(rnd, n) >= 0)
681 status = SILC_SKE_STATUS_ERROR;
683 memset(string, 'F', l);
689 /* Creates a hash value HASH as defined in the SKE protocol. If the
690 `initiator' is TRUE then this function is used to create the HASH_i
691 hash value defined in the protocol. If it is FALSE then this is used
692 to create the HASH value defined by the protocol. */
694 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
695 unsigned char *return_hash,
696 SilcUInt32 *return_hash_len,
699 SilcSKEStatus status = SILC_SKE_STATUS_OK;
701 unsigned char *e, *f, *KEY, *s_data;
702 SilcUInt32 e_len, f_len, KEY_len, s_len;
705 SILC_LOG_DEBUG(("Start"));
707 if (initiator == FALSE) {
708 s_data = (ske->start_payload_copy ?
709 silc_buffer_data(ske->start_payload_copy) : NULL);
710 s_len = (ske->start_payload_copy ?
711 silc_buffer_len(ske->start_payload_copy) : 0);
712 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
713 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
714 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
716 /* Format the buffer used to compute the hash value */
717 buf = silc_buffer_alloc_size(s_len +
718 ske->ke2_payload->pk_len +
719 ske->ke1_payload->pk_len +
720 e_len + f_len + KEY_len);
722 return SILC_SKE_STATUS_OUT_OF_MEMORY;
724 /* Initiator is not required to send its public key */
725 if (!ske->ke1_payload->pk_data) {
727 silc_buffer_format(buf,
728 SILC_STR_DATA(s_data, s_len),
729 SILC_STR_DATA(ske->ke2_payload->pk_data,
730 ske->ke2_payload->pk_len),
731 SILC_STR_DATA(e, e_len),
732 SILC_STR_DATA(f, f_len),
733 SILC_STR_DATA(KEY, KEY_len),
737 silc_buffer_format(buf,
738 SILC_STR_DATA(s_data, s_len),
739 SILC_STR_DATA(ske->ke2_payload->pk_data,
740 ske->ke2_payload->pk_len),
741 SILC_STR_DATA(ske->ke1_payload->pk_data,
742 ske->ke1_payload->pk_len),
743 SILC_STR_DATA(e, e_len),
744 SILC_STR_DATA(f, f_len),
745 SILC_STR_DATA(KEY, KEY_len),
749 silc_buffer_free(buf);
752 memset(KEY, 0, KEY_len);
756 return SILC_SKE_STATUS_ERROR;
761 memset(KEY, 0, KEY_len);
766 s_data = (ske->start_payload_copy ?
767 silc_buffer_data(ske->start_payload_copy) : NULL);
768 s_len = (ske->start_payload_copy ?
769 silc_buffer_len(ske->start_payload_copy) : 0);
770 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
772 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
774 return SILC_SKE_STATUS_OUT_OF_MEMORY;
776 /* Format the buffer used to compute the hash value */
778 silc_buffer_format(buf,
779 SILC_STR_DATA(s_data, s_len),
780 SILC_STR_DATA(ske->ke1_payload->pk_data,
781 ske->ke1_payload->pk_len),
782 SILC_STR_DATA(e, e_len),
785 silc_buffer_free(buf);
788 return SILC_SKE_STATUS_ERROR;
791 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
798 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
800 *return_hash_len = silc_hash_len(ske->prop->hash);
802 if (initiator == FALSE) {
803 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
805 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
808 silc_buffer_free(buf);
813 /* Generate rekey material */
815 static SilcSKERekeyMaterial
816 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
818 SilcSKERekeyMaterial rekey;
821 /* Create rekey material */
822 rekey = silc_calloc(1, sizeof(*rekey));
827 if (ske->prop->group)
828 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
829 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
830 hash = silc_hash_get_name(ske->prop->hash);
831 rekey->hash = silc_memdup(hash, strlen(hash));
836 if (rekey->pfs == FALSE) {
837 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
838 keymat->enc_key_len / 8);
839 if (!rekey->send_enc_key) {
843 rekey->enc_key_len = keymat->enc_key_len;
849 /* Assembles security properties */
851 static SilcSKEStartPayload
852 silc_ske_assemble_security_properties(SilcSKE ske,
853 SilcSKESecurityPropertyFlag flags,
856 SilcSKEStartPayload rp;
859 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
861 rp = silc_calloc(1, sizeof(*rp));
864 rp->flags = (unsigned char)flags;
866 /* Set random cookie */
867 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
868 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
869 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
870 rp->cookie_len = SILC_SKE_COOKIE_LEN;
872 /* In case IV included flag and session port is set the first 16-bits of
873 cookie will include our session port. */
874 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
875 SILC_PUT16_MSB(ske->session_port, rp->cookie);
878 rp->version = strdup(version);
879 rp->version_len = strlen(version);
881 /* Get supported Key Exhange groups */
882 rp->ke_grp_list = silc_ske_get_supported_groups();
883 rp->ke_grp_len = strlen(rp->ke_grp_list);
885 /* Get supported PKCS algorithms */
886 rp->pkcs_alg_list = silc_pkcs_get_supported();
887 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
889 /* Get supported encryption algorithms */
890 rp->enc_alg_list = silc_cipher_get_supported();
891 rp->enc_alg_len = strlen(rp->enc_alg_list);
893 /* Get supported hash algorithms */
894 rp->hash_alg_list = silc_hash_get_supported();
895 rp->hash_alg_len = strlen(rp->hash_alg_list);
897 /* Get supported HMACs */
898 rp->hmac_alg_list = silc_hmac_get_supported();
899 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
902 /* Get supported compression algorithms */
903 rp->comp_alg_list = strdup("none");
904 rp->comp_alg_len = strlen("none");
906 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
907 2 + rp->version_len +
908 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
909 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
910 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
915 /* Packet retransmission callback. */
917 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
919 SilcSKE ske = context;
921 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
923 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
924 ske->retry_count = 0;
925 ske->retry_timer = SILC_SKE_RETRY_MIN;
926 silc_free(ske->retrans.data);
927 ske->retrans.data = NULL;
928 ske->status = SILC_SKE_STATUS_TIMEOUT;
929 silc_ske_notify_failure(ske);
930 silc_fsm_continue_sync(&ske->fsm);
934 SILC_LOG_DEBUG(("Retransmitting packet"));
935 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
936 ske->retrans.data, ske->retrans.data_len);
939 /* Install retransmission timer */
941 static void silc_ske_install_retransmission(SilcSKE ske)
943 if (!silc_packet_stream_is_udp(ske->stream))
946 if (ske->retrans.data) {
947 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
949 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
950 ske, ske->retry_timer, 0);
952 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
953 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
956 /* Sends SILC packet. Handles retransmissions with UDP streams. */
958 static SilcBool silc_ske_packet_send(SilcSKE ske,
960 SilcPacketFlags flags,
961 const unsigned char *data,
966 /* Send the packet */
967 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
969 if (silc_packet_stream_is_udp(ske->stream) &&
970 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
971 silc_free(ske->retrans.data);
972 ske->retrans.type = type;
973 ske->retrans.flags = flags;
974 ske->retrans.data = silc_memdup(data, data_len);
975 ske->retrans.data_len = data_len;
976 silc_ske_install_retransmission(ske);
982 /* Calls completion callback. Completion is called always in this function
983 and must not be called anywhere else. */
985 static void silc_ske_completion(SilcSKE ske)
987 /* Call the completion callback */
988 if (!ske->aborted && ske->callbacks->completed) {
989 if (ske->status != SILC_SKE_STATUS_OK)
990 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
991 ske->callbacks->context);
993 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
994 ske->rekey, ske->callbacks->context);
998 /* SKE FSM destructor. */
1000 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
1001 void *destructor_context)
1003 SilcSKE ske = fsm_context;
1007 /* Key exchange timeout task callback */
1009 SILC_TASK_CALLBACK(silc_ske_timeout)
1011 SilcSKE ske = context;
1013 SILC_LOG_DEBUG(("Timeout"));
1016 ske->status = SILC_SKE_STATUS_TIMEOUT;
1017 silc_ske_notify_failure(ske);
1019 silc_fsm_continue_sync(&ske->fsm);
1022 /******************************* Protocol API *******************************/
1024 /* Allocates new SKE object. */
1026 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1027 SilcSKR repository, SilcPublicKey public_key,
1028 SilcPrivateKey private_key, void *context)
1032 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1034 if (!rng || !schedule)
1038 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1042 ske = silc_calloc(1, sizeof(*ske));
1045 ske->status = SILC_SKE_STATUS_OK;
1047 ske->repository = repository;
1048 ske->user_data = context;
1049 ske->schedule = schedule;
1050 ske->public_key = public_key;
1051 ske->private_key = private_key;
1052 ske->retry_timer = SILC_SKE_RETRY_MIN;
1058 /* Free's SKE object. */
1060 void silc_ske_free(SilcSKE ske)
1065 SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu",
1066 ske, ske->aborted, ske->refcnt));
1070 * If already aborted, destroy the session immediately. Only do the
1071 * notification work if we have not already though, as doing so twice
1072 * results in memory corruption. We may have silc_ske_free called
1073 * twice, once when the abort is requested, and then again when the
1074 * FSM finish routine is called. We have to be prepared to handle
1078 ske->status = SILC_SKE_STATUS_ERROR;
1080 silc_ske_notify_failure(ske);
1082 if (silc_fsm_is_started(&ske->fsm))
1083 silc_fsm_continue_sync(&ske->fsm);
1085 SILC_LOG_DEBUG(("Not continuing FSM as it's finished for SKE %p", ske));
1089 if (ske->refcnt > 0)
1092 /* Free start payload */
1093 if (ske->start_payload)
1094 silc_ske_payload_start_free(ske->start_payload);
1096 /* Free KE payload */
1097 if (ske->ke1_payload)
1098 silc_ske_payload_ke_free(ske->ke1_payload);
1099 if (ske->ke2_payload)
1100 silc_ske_payload_ke_free(ske->ke2_payload);
1101 silc_free(ske->remote_version);
1105 if (ske->prop->group)
1106 silc_ske_group_free(ske->prop->group);
1107 if (ske->prop->cipher)
1108 silc_cipher_free(ske->prop->cipher);
1109 if (ske->prop->hash)
1110 silc_hash_free(ske->prop->hash);
1111 if (ske->prop->hmac)
1112 silc_hmac_free(ske->prop->hmac);
1113 if (ske->prop->public_key)
1114 silc_pkcs_public_key_free(ske->prop->public_key);
1115 silc_free(ske->prop);
1118 silc_ske_free_key_material(ske->keymat);
1119 if (ske->start_payload_copy)
1120 silc_buffer_free(ske->start_payload_copy);
1122 silc_mp_uninit(ske->x);
1126 silc_mp_uninit(ske->KEY);
1127 silc_free(ske->KEY);
1129 silc_free(ske->retrans.data);
1130 silc_free(ske->hash);
1131 silc_free(ske->callbacks);
1133 memset(ske, 0xdd, sizeof(*ske));
1137 /* Return user context */
1139 void *silc_ske_get_context(SilcSKE ske)
1141 return ske->user_data;
1144 /* Sets protocol callbacks */
1146 void silc_ske_set_callbacks(SilcSKE ske,
1147 SilcSKEVerifyCb verify_key,
1148 SilcSKECompletionCb completed,
1152 silc_free(ske->callbacks);
1153 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1154 if (!ske->callbacks)
1156 ske->callbacks->verify_key = verify_key;
1157 ske->callbacks->completed = completed;
1158 ske->callbacks->context = context;
1162 /******************************** Initiator *********************************/
1164 /* Start protocol. Send our proposal */
1166 SILC_FSM_STATE(silc_ske_st_initiator_start)
1168 SilcSKE ske = fsm_context;
1169 SilcBuffer payload_buf;
1172 SILC_LOG_DEBUG(("Start"));
1176 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1177 return SILC_FSM_CONTINUE;
1180 /* Encode the payload */
1181 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1183 if (status != SILC_SKE_STATUS_OK) {
1184 /** Error encoding Start Payload */
1185 ske->status = status;
1186 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1187 return SILC_FSM_CONTINUE;
1190 /* Save the the payload buffer for future use. It is later used to
1191 compute the HASH value. */
1192 ske->start_payload_copy = payload_buf;
1194 /* Send the packet. */
1195 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1196 silc_buffer_data(payload_buf),
1197 silc_buffer_len(payload_buf))) {
1198 /** Error sending packet */
1199 SILC_LOG_DEBUG(("Error sending packet"));
1200 ske->status = SILC_SKE_STATUS_ERROR;
1201 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1202 return SILC_FSM_CONTINUE;
1205 /* Add key exchange timeout */
1206 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1207 ske, ske->timeout, 0);
1209 /** Wait for responder proposal */
1210 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1211 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1212 return SILC_FSM_WAIT;
1215 /* Phase-1. Receives responder's proposal */
1217 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1219 SilcSKE ske = fsm_context;
1220 SilcSKEStatus status;
1221 SilcSKEStartPayload payload;
1222 SilcSKESecurityProperties prop;
1223 SilcSKEDiffieHellmanGroup group = NULL;
1224 SilcBuffer packet_buf = &ske->packet->buffer;
1225 SilcUInt16 remote_port = 0;
1229 SILC_LOG_DEBUG(("Start"));
1231 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1232 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1233 silc_ske_install_retransmission(ske);
1234 silc_packet_free(ske->packet);
1236 return SILC_FSM_WAIT;
1239 /* Decode the payload */
1240 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1241 if (status != SILC_SKE_STATUS_OK) {
1242 /** Error decoding Start Payload */
1243 silc_packet_free(ske->packet);
1245 ske->status = status;
1246 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1247 return SILC_FSM_CONTINUE;
1250 /* Get remote ID and set it to stream */
1251 if (ske->packet->src_id_len) {
1252 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1253 ske->packet->src_id_type,
1254 (ske->packet->src_id_type == SILC_ID_SERVER ?
1255 (void *)&id.u.server_id : (void *)&id.u.client_id),
1256 (ske->packet->src_id_type == SILC_ID_SERVER ?
1257 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1258 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1259 (ske->packet->src_id_type == SILC_ID_SERVER ?
1260 (void *)&id.u.server_id : (void *)&id.u.client_id));
1263 silc_packet_free(ske->packet);
1266 /* Check that the cookie is returned unmodified. In case IV included
1267 flag and session port has been set, the first two bytes of cookie
1268 are the session port and we ignore them in this check. */
1269 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1270 /* Take remote port */
1271 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1274 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1275 SILC_SKE_COOKIE_LEN - coff)) {
1276 /** Invalid cookie */
1277 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1278 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1279 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1280 return SILC_FSM_CONTINUE;
1283 /* Check version string */
1284 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1285 status = silc_ske_check_version(ske);
1286 if (status != SILC_SKE_STATUS_OK) {
1287 /** Version mismatch */
1288 ske->status = status;
1289 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1290 return SILC_FSM_CONTINUE;
1293 /* Free our KE Start Payload context, we don't need it anymore. */
1294 silc_ske_payload_start_free(ske->start_payload);
1295 ske->start_payload = NULL;
1297 /* Take the selected security properties into use while doing
1298 the key exchange. This is used only while doing the key
1300 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1303 prop->flags = payload->flags;
1304 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1305 if (status != SILC_SKE_STATUS_OK)
1308 prop->group = group;
1309 prop->remote_port = remote_port;
1311 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1312 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1315 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1316 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1319 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1320 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1323 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1324 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1328 /* Save remote's KE Start Payload */
1329 ske->start_payload = payload;
1331 /** Send KE Payload */
1332 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1333 return SILC_FSM_CONTINUE;
1337 silc_ske_payload_start_free(payload);
1339 silc_ske_group_free(group);
1341 silc_cipher_free(prop->cipher);
1343 silc_hash_free(prop->hash);
1345 silc_hmac_free(prop->hmac);
1349 if (status == SILC_SKE_STATUS_OK)
1350 status = SILC_SKE_STATUS_ERROR;
1353 ske->status = status;
1354 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1355 return SILC_FSM_CONTINUE;
1358 /* Phase-2. Send KE payload */
1360 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1362 SilcSKE ske = fsm_context;
1363 SilcSKEStatus status;
1364 SilcBuffer payload_buf;
1366 SilcSKEKEPayload payload;
1369 SILC_LOG_DEBUG(("Start"));
1371 /* Create the random number x, 1 < x < q. */
1372 x = silc_calloc(1, sizeof(*x));
1374 /** Out of memory */
1375 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1376 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1377 return SILC_FSM_CONTINUE;
1381 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1382 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1384 if (status != SILC_SKE_STATUS_OK) {
1385 /** Error generating random number */
1388 ske->status = status;
1389 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1390 return SILC_FSM_CONTINUE;
1393 /* Encode the result to Key Exchange Payload. */
1395 payload = silc_calloc(1, sizeof(*payload));
1397 /** Out of memory */
1400 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1401 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1402 return SILC_FSM_CONTINUE;
1404 ske->ke1_payload = payload;
1406 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1408 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1409 silc_mp_init(&payload->x);
1410 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1411 &ske->prop->group->group);
1413 /* Get public key */
1414 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1415 if (!payload->pk_data) {
1416 /** Error encoding public key */
1419 silc_mp_uninit(&payload->x);
1421 ske->ke1_payload = NULL;
1422 ske->status = SILC_SKE_STATUS_ERROR;
1423 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1424 return SILC_FSM_CONTINUE;
1426 payload->pk_len = pk_len;
1427 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1429 /* Compute signature data if we are doing mutual authentication */
1430 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1431 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1432 SilcUInt32 hash_len, sign_len;
1434 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1435 SILC_LOG_DEBUG(("Computing HASH_i value"));
1437 /* Compute the hash value */
1438 memset(hash, 0, sizeof(hash));
1439 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1441 SILC_LOG_DEBUG(("Signing HASH_i value"));
1443 /* Sign the hash value */
1444 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1445 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1446 /** Error computing signature */
1449 silc_mp_uninit(&payload->x);
1450 silc_free(payload->pk_data);
1452 ske->ke1_payload = NULL;
1453 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1454 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1455 return SILC_FSM_CONTINUE;
1457 payload->sign_data = silc_memdup(sign, sign_len);
1458 if (payload->sign_data)
1459 payload->sign_len = sign_len;
1460 memset(sign, 0, sizeof(sign));
1463 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1464 if (status != SILC_SKE_STATUS_OK) {
1465 /** Error encoding KE payload */
1468 silc_mp_uninit(&payload->x);
1469 silc_free(payload->pk_data);
1470 silc_free(payload->sign_data);
1472 ske->ke1_payload = NULL;
1473 ske->status = status;
1474 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1475 return SILC_FSM_CONTINUE;
1480 /* Check for backwards compatibility */
1482 /* Send the packet. */
1483 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1484 silc_buffer_data(payload_buf),
1485 silc_buffer_len(payload_buf))) {
1486 /** Error sending packet */
1487 SILC_LOG_DEBUG(("Error sending packet"));
1488 ske->status = SILC_SKE_STATUS_ERROR;
1489 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1490 return SILC_FSM_CONTINUE;
1493 silc_buffer_free(payload_buf);
1495 /** Waiting responder's KE payload */
1496 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1497 return SILC_FSM_WAIT;
1500 /* Phase-3. Process responder's KE payload */
1502 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1504 SilcSKE ske = fsm_context;
1505 SilcSKEStatus status;
1506 SilcSKEKEPayload payload;
1508 SilcBuffer packet_buf = &ske->packet->buffer;
1510 SILC_LOG_DEBUG(("Start"));
1512 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1513 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1514 silc_ske_install_retransmission(ske);
1515 silc_packet_free(ske->packet);
1517 return SILC_FSM_WAIT;
1520 /* Decode the payload */
1521 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1522 if (status != SILC_SKE_STATUS_OK) {
1523 /** Error decoding KE payload */
1524 silc_packet_free(ske->packet);
1526 ske->status = status;
1527 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1528 return SILC_FSM_CONTINUE;
1530 silc_packet_free(ske->packet);
1532 ske->ke2_payload = payload;
1534 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1535 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1536 "even though we require it"));
1537 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1541 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1543 /* Compute the shared secret key */
1544 KEY = silc_calloc(1, sizeof(*KEY));
1546 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1549 /* Decode the remote's public key */
1550 if (payload->pk_data &&
1551 !silc_pkcs_public_key_alloc(payload->pk_type,
1552 payload->pk_data, payload->pk_len,
1553 &ske->prop->public_key)) {
1554 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1555 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1559 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1561 SILC_LOG_DEBUG(("Verifying public key"));
1563 /** Waiting public key verification */
1564 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1566 /* If repository is provided, verify the key from there. */
1567 if (ske->repository) {
1570 find = silc_skr_find_alloc();
1572 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1575 silc_skr_find_set_pkcs_type(find,
1576 silc_pkcs_get_type(ske->prop->public_key));
1577 silc_skr_find_set_public_key(find, ske->prop->public_key);
1578 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1580 /* Find key from repository */
1581 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1582 find, silc_ske_skr_callback, ske));
1584 /* Verify from application */
1585 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1586 ske->callbacks->context,
1587 silc_ske_pk_verified, NULL));
1592 /** Process key material */
1593 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1594 return SILC_FSM_CONTINUE;
1597 silc_ske_payload_ke_free(payload);
1598 ske->ke2_payload = NULL;
1600 silc_mp_uninit(ske->KEY);
1601 silc_free(ske->KEY);
1604 if (status == SILC_SKE_STATUS_OK)
1605 return SILC_SKE_STATUS_ERROR;
1608 ske->status = status;
1609 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1610 return SILC_FSM_CONTINUE;
1613 /* Process key material */
1615 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1617 SilcSKE ske = fsm_context;
1618 SilcSKEStatus status;
1619 SilcSKEKEPayload payload;
1620 unsigned char hash[SILC_HASH_MAXLEN];
1621 SilcUInt32 hash_len;
1622 int key_len, block_len;
1626 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1627 return SILC_FSM_CONTINUE;
1630 /* Check result of public key verification */
1631 if (ske->status != SILC_SKE_STATUS_OK) {
1632 /** Public key not verified */
1633 SILC_LOG_DEBUG(("Public key verification failed"));
1634 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1635 return SILC_FSM_CONTINUE;
1638 payload = ske->ke2_payload;
1640 /* Compute the HASH value */
1641 SILC_LOG_DEBUG(("Computing HASH value"));
1642 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1643 if (status != SILC_SKE_STATUS_OK)
1645 ske->hash = silc_memdup(hash, hash_len);
1646 ske->hash_len = hash_len;
1648 if (ske->prop->public_key) {
1649 SILC_LOG_DEBUG(("Public key is authentic"));
1650 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1652 /* Verify signature */
1653 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1654 payload->sign_len, hash, hash_len, NULL)) {
1655 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1656 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1660 SILC_LOG_DEBUG(("Signature is Ok"));
1661 memset(hash, 'F', hash_len);
1664 ske->status = SILC_SKE_STATUS_OK;
1666 /* In case we are doing rekey move to finish it. */
1669 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1670 return SILC_FSM_CONTINUE;
1673 /* Process key material */
1674 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1675 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1676 hash_len = silc_hash_len(ske->prop->hash);
1677 ske->keymat = silc_ske_process_key_material(ske, block_len,
1681 SILC_LOG_ERROR(("Error processing key material"));
1682 status = SILC_SKE_STATUS_ERROR;
1686 /* Send SUCCESS packet */
1687 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1688 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1689 /** Error sending packet */
1690 SILC_LOG_DEBUG(("Error sending packet"));
1691 ske->status = SILC_SKE_STATUS_ERROR;
1692 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1693 return SILC_FSM_CONTINUE;
1696 /** Waiting completion */
1697 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1698 return SILC_FSM_WAIT;
1701 memset(hash, 'F', sizeof(hash));
1702 silc_ske_payload_ke_free(payload);
1703 ske->ke2_payload = NULL;
1705 silc_mp_uninit(ske->KEY);
1706 silc_free(ske->KEY);
1710 memset(ske->hash, 'F', hash_len);
1711 silc_free(ske->hash);
1715 if (status == SILC_SKE_STATUS_OK)
1716 status = SILC_SKE_STATUS_ERROR;
1719 ske->status = status;
1720 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1721 return SILC_FSM_CONTINUE;
1724 /* Protocol completed */
1726 SILC_FSM_STATE(silc_ske_st_initiator_end)
1728 SilcSKE ske = fsm_context;
1730 SILC_LOG_DEBUG(("Start"));
1732 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1733 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1734 silc_ske_install_retransmission(ske);
1735 silc_packet_free(ske->packet);
1737 return SILC_FSM_WAIT;
1740 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1742 silc_packet_free(ske->packet);
1744 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1745 silc_schedule_task_del_by_context(ske->schedule, ske);
1747 /* Call completion */
1748 silc_ske_completion(ske);
1750 return SILC_FSM_FINISH;
1753 /* Aborted by application */
1755 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1757 SilcSKE ske = fsm_context;
1758 unsigned char data[4];
1760 SILC_LOG_DEBUG(("Aborted by caller"));
1762 /* Send FAILURE packet */
1763 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1764 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1766 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1767 silc_schedule_task_del_by_context(ske->schedule, ske);
1769 /* Call completion */
1770 silc_ske_completion(ske);
1772 return SILC_FSM_FINISH;
1775 /* Error occurred. Send error to remote host */
1777 SILC_FSM_STATE(silc_ske_st_initiator_error)
1779 SilcSKE ske = fsm_context;
1780 SilcSKEStatus status;
1781 unsigned char data[4];
1783 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1784 silc_ske_map_status(ske->status), ske->status));
1786 status = ske->status;
1787 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1788 status = SILC_SKE_STATUS_ERROR;
1790 /* Send FAILURE packet */
1791 SILC_PUT32_MSB((SilcUInt32)status, data);
1792 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1794 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1795 silc_schedule_task_del_by_context(ske->schedule, ske);
1797 /* Call completion */
1798 silc_ske_completion(ske);
1800 return SILC_FSM_FINISH;
1803 /* Failure received from remote */
1805 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1807 SilcSKE ske = fsm_context;
1808 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1810 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1811 SILC_GET32_MSB(error, ske->packet->buffer.data);
1812 ske->status = error;
1813 silc_packet_free(ske->packet);
1817 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1818 silc_ske_map_status(ske->status), ske->status));
1820 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1821 silc_schedule_task_del_by_context(ske->schedule, ske);
1823 /* Call completion */
1824 silc_ske_completion(ske);
1826 return SILC_FSM_FINISH;
1829 /* Starts the protocol as initiator */
1831 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1832 SilcPacketStream stream,
1833 SilcSKEParams params,
1834 SilcSKEStartPayload start_payload)
1836 SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; "
1837 "start_payload=%p", ske, stream, params, start_payload));
1839 if (!ske || !stream || !params || !params->version)
1842 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1845 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1848 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1849 ske->session_port = params->session_port;
1851 /* Generate security properties if not provided */
1852 if (!start_payload) {
1853 start_payload = silc_ske_assemble_security_properties(ske,
1860 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1861 ske->start_payload = start_payload;
1862 ske->version = params->version;
1865 /* Link to packet stream to get key exchange packets */
1866 ske->stream = stream;
1867 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1868 SILC_PACKET_KEY_EXCHANGE,
1869 SILC_PACKET_KEY_EXCHANGE_2,
1870 SILC_PACKET_SUCCESS,
1871 SILC_PACKET_FAILURE, -1);
1873 /* Start SKE as initiator */
1874 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1879 /******************************** Responder *********************************/
1881 /* Start protocol as responder. Wait initiator's start payload */
1883 SILC_FSM_STATE(silc_ske_st_responder_start)
1885 SilcSKE ske = fsm_context;
1887 SILC_LOG_DEBUG(("Start"));
1891 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1892 return SILC_FSM_CONTINUE;
1895 /* Add key exchange timeout */
1896 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1897 ske, ske->timeout, 0);
1899 /** Wait for initiator */
1900 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1901 return SILC_FSM_WAIT;
1904 /* Decode initiator's start payload. Select the security properties from
1905 the initiator's start payload and send our reply start payload back. */
1907 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1909 SilcSKE ske = fsm_context;
1910 SilcSKEStatus status;
1911 SilcSKEStartPayload remote_payload = NULL;
1912 SilcBuffer packet_buf = &ske->packet->buffer;
1915 SILC_LOG_DEBUG(("Start"));
1917 /* Decode the payload */
1918 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1919 if (status != SILC_SKE_STATUS_OK) {
1920 /** Error decoding Start Payload */
1921 silc_packet_free(ske->packet);
1923 ske->status = status;
1924 silc_fsm_next(fsm, silc_ske_st_responder_error);
1925 return SILC_FSM_CONTINUE;
1928 /* Get remote ID and set it to stream */
1929 if (ske->packet->src_id_len) {
1930 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1931 ske->packet->src_id_type,
1932 (ske->packet->src_id_type == SILC_ID_SERVER ?
1933 (void *)&id.u.server_id : (void *)&id.u.client_id),
1934 (ske->packet->src_id_type == SILC_ID_SERVER ?
1935 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1936 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1937 (ske->packet->src_id_type == SILC_ID_SERVER ?
1938 (void *)&id.u.server_id : (void *)&id.u.client_id));
1941 /* Take a copy of the payload buffer for future use. It is used to
1942 compute the HASH value. */
1943 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1945 silc_packet_free(ske->packet);
1948 /* Force the mutual authentication flag if we want to do it. */
1949 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1950 SILC_LOG_DEBUG(("Force mutual authentication"));
1951 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1954 /* Force PFS flag if we require it */
1955 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1956 SILC_LOG_DEBUG(("Force PFS"));
1957 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1960 /* Disable IV Included flag if requested */
1961 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1962 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1963 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1964 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1967 /* Check and select security properties */
1968 status = silc_ske_select_security_properties(ske, remote_payload,
1970 if (status != SILC_SKE_STATUS_OK) {
1971 /** Error selecting proposal */
1972 silc_ske_payload_start_free(remote_payload);
1973 ske->status = status;
1974 silc_fsm_next(fsm, silc_ske_st_responder_error);
1975 return SILC_FSM_CONTINUE;
1978 silc_ske_payload_start_free(remote_payload);
1980 /* Encode our reply payload to send the selected security properties */
1981 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1983 if (status != SILC_SKE_STATUS_OK)
1986 /* Send the packet. */
1987 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1988 silc_buffer_data(packet_buf),
1989 silc_buffer_len(packet_buf)))
1992 silc_buffer_free(packet_buf);
1994 /** Waiting initiator's KE payload */
1995 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1996 return SILC_FSM_WAIT;
1999 if (ske->prop->group)
2000 silc_ske_group_free(ske->prop->group);
2001 if (ske->prop->cipher)
2002 silc_cipher_free(ske->prop->cipher);
2003 if (ske->prop->hash)
2004 silc_hash_free(ske->prop->hash);
2005 if (ske->prop->hmac)
2006 silc_hmac_free(ske->prop->hmac);
2007 silc_free(ske->prop);
2010 if (status == SILC_SKE_STATUS_OK)
2011 status = SILC_SKE_STATUS_ERROR;
2014 ske->status = status;
2015 silc_fsm_next(fsm, silc_ske_st_responder_error);
2016 return SILC_FSM_CONTINUE;
2019 /* Phase-2. Decode initiator's KE payload */
2021 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2023 SilcSKE ske = fsm_context;
2024 SilcSKEStatus status;
2025 SilcSKEKEPayload recv_payload;
2026 SilcBuffer packet_buf = &ske->packet->buffer;
2028 SILC_LOG_DEBUG(("Start"));
2030 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2031 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2032 silc_ske_install_retransmission(ske);
2033 silc_packet_free(ske->packet);
2035 return SILC_FSM_WAIT;
2038 /* Decode Key Exchange Payload */
2039 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2040 if (status != SILC_SKE_STATUS_OK) {
2041 /** Error decoding KE payload */
2042 silc_packet_free(ske->packet);
2044 ske->status = status;
2045 silc_fsm_next(fsm, silc_ske_st_responder_error);
2046 return SILC_FSM_CONTINUE;
2049 ske->ke1_payload = recv_payload;
2051 silc_packet_free(ske->packet);
2054 /* Verify public key, except in rekey, when it is not sent */
2056 if (!recv_payload->pk_data) {
2057 /** Public key not provided */
2058 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2059 "certificate), even though we require it"));
2060 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2061 silc_fsm_next(fsm, silc_ske_st_responder_error);
2062 return SILC_FSM_CONTINUE;
2065 /* Decode the remote's public key */
2066 if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2067 recv_payload->pk_data,
2068 recv_payload->pk_len,
2069 &ske->prop->public_key)) {
2070 /** Error decoding public key */
2071 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2072 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2073 silc_fsm_next(fsm, silc_ske_st_responder_error);
2074 return SILC_FSM_CONTINUE;
2077 SILC_LOG_DEBUG(("Verifying public key"));
2079 /** Waiting public key verification */
2080 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2082 /* If repository is provided, verify the key from there. */
2083 if (ske->repository) {
2086 find = silc_skr_find_alloc();
2088 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2089 silc_fsm_next(fsm, silc_ske_st_responder_error);
2090 return SILC_FSM_CONTINUE;
2092 silc_skr_find_set_pkcs_type(find,
2093 silc_pkcs_get_type(ske->prop->public_key));
2094 silc_skr_find_set_public_key(find, ske->prop->public_key);
2095 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2097 /* Find key from repository */
2098 SILC_FSM_CALL(silc_skr_find(ske->repository,
2099 silc_fsm_get_schedule(fsm), find,
2100 silc_ske_skr_callback, ske));
2102 /* Verify from application */
2103 if (ske->callbacks->verify_key)
2104 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2105 ske->callbacks->context,
2106 silc_ske_pk_verified, NULL));
2110 /** Generate KE2 payload */
2111 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2112 return SILC_FSM_CONTINUE;
2115 /* Phase-4. Generate KE2 payload */
2117 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2119 SilcSKE ske = fsm_context;
2120 SilcSKEStatus status;
2121 SilcSKEKEPayload recv_payload, send_payload;
2126 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2127 return SILC_FSM_CONTINUE;
2130 /* Check result of public key verification */
2131 if (ske->status != SILC_SKE_STATUS_OK) {
2132 /** Public key not verified */
2133 SILC_LOG_DEBUG(("Public key verification failed"));
2134 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2135 return SILC_FSM_CONTINUE;
2138 recv_payload = ske->ke1_payload;
2140 /* The public key verification was performed only if the Mutual
2141 Authentication flag is set. */
2142 if (ske->start_payload &&
2143 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2144 unsigned char hash[SILC_HASH_MAXLEN];
2145 SilcUInt32 hash_len;
2147 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2149 /* Compute the hash value */
2150 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2151 if (status != SILC_SKE_STATUS_OK) {
2152 /** Error computing hash */
2153 ske->status = status;
2154 silc_fsm_next(fsm, silc_ske_st_responder_error);
2155 return SILC_FSM_CONTINUE;
2158 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2160 /* Verify signature */
2161 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2162 recv_payload->sign_len, hash, hash_len, NULL)) {
2163 /** Incorrect signature */
2164 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2165 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2166 silc_fsm_next(fsm, silc_ske_st_responder_error);
2167 return SILC_FSM_CONTINUE;
2170 SILC_LOG_DEBUG(("Signature is Ok"));
2172 memset(hash, 'F', hash_len);
2175 /* Create the random number x, 1 < x < q. */
2176 x = silc_calloc(1, sizeof(*x));
2179 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2180 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2182 if (status != SILC_SKE_STATUS_OK) {
2183 /** Error generating random number */
2186 ske->status = status;
2187 silc_fsm_next(fsm, silc_ske_st_responder_error);
2188 return SILC_FSM_CONTINUE;
2191 /* Save the results for later processing */
2192 send_payload = silc_calloc(1, sizeof(*send_payload));
2194 ske->ke2_payload = send_payload;
2196 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2198 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2199 silc_mp_init(&send_payload->x);
2200 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2201 &ske->prop->group->group);
2203 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2205 /* Compute the shared secret key */
2206 KEY = silc_calloc(1, sizeof(*KEY));
2208 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2209 &ske->prop->group->group);
2212 /** Send KE2 payload */
2213 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2214 return SILC_FSM_CONTINUE;
2217 /* Phase-5. Send KE2 payload */
2219 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2221 SilcSKE ske = fsm_context;
2222 SilcSKEStatus status;
2223 SilcBuffer payload_buf;
2224 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2225 SilcUInt32 hash_len, sign_len, pk_len;
2227 SILC_LOG_DEBUG(("Start"));
2229 if (ske->public_key && ske->private_key) {
2230 SILC_LOG_DEBUG(("Getting public key"));
2232 /* Get the public key */
2233 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2235 /** Error encoding public key */
2236 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2237 silc_fsm_next(fsm, silc_ske_st_responder_error);
2238 return SILC_FSM_CONTINUE;
2240 ske->ke2_payload->pk_data = pk;
2241 ske->ke2_payload->pk_len = pk_len;
2244 SILC_LOG_DEBUG(("Computing HASH value"));
2246 /* Compute the hash value */
2247 memset(hash, 0, sizeof(hash));
2248 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2249 if (status != SILC_SKE_STATUS_OK) {
2250 /** Error computing hash */
2251 ske->status = status;
2252 silc_fsm_next(fsm, silc_ske_st_responder_error);
2253 return SILC_FSM_CONTINUE;
2255 ske->hash = silc_memdup(hash, hash_len);
2256 ske->hash_len = hash_len;
2258 if (ske->public_key && ske->private_key) {
2259 SILC_LOG_DEBUG(("Signing HASH value"));
2261 /* Sign the hash value */
2262 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2263 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2264 /** Error computing signature */
2265 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2266 silc_fsm_next(fsm, silc_ske_st_responder_error);
2267 return SILC_FSM_CONTINUE;
2269 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2270 ske->ke2_payload->sign_len = sign_len;
2271 memset(sign, 0, sizeof(sign));
2273 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2275 /* Encode the Key Exchange Payload */
2276 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2278 if (status != SILC_SKE_STATUS_OK) {
2279 /** Error encoding KE payload */
2280 ske->status = status;
2281 silc_fsm_next(fsm, silc_ske_st_responder_error);
2282 return SILC_FSM_CONTINUE;
2285 /* Send the packet. */
2286 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2287 payload_buf->data, silc_buffer_len(payload_buf))) {
2288 SILC_LOG_DEBUG(("Error sending packet"));
2289 ske->status = SILC_SKE_STATUS_ERROR;
2290 silc_fsm_next(fsm, silc_ske_st_responder_error);
2291 return SILC_FSM_CONTINUE;
2294 silc_buffer_free(payload_buf);
2296 /* In case we are doing rekey move to finish it. */
2299 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2300 return SILC_FSM_CONTINUE;
2303 /** Waiting completion */
2304 silc_fsm_next(fsm, silc_ske_st_responder_end);
2305 return SILC_FSM_WAIT;
2308 /* Protocol completed */
2310 SILC_FSM_STATE(silc_ske_st_responder_end)
2312 SilcSKE ske = fsm_context;
2313 unsigned char tmp[4];
2314 SilcUInt32 hash_len, key_len, block_len;
2316 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2317 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2318 silc_ske_install_retransmission(ske);
2319 silc_packet_free(ske->packet);
2321 return SILC_FSM_WAIT;
2323 silc_packet_free(ske->packet);
2326 /* Process key material */
2327 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2328 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2329 hash_len = silc_hash_len(ske->prop->hash);
2330 ske->keymat = silc_ske_process_key_material(ske, block_len,
2334 /** Error processing key material */
2335 ske->status = SILC_SKE_STATUS_ERROR;
2336 silc_fsm_next(fsm, silc_ske_st_responder_error);
2337 return SILC_FSM_CONTINUE;
2340 /* Send SUCCESS packet */
2341 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2342 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2344 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2345 silc_schedule_task_del_by_context(ske->schedule, ske);
2347 /* Call completion */
2348 silc_ske_completion(ske);
2350 return SILC_FSM_FINISH;
2353 /* Aborted by application */
2355 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2357 SilcSKE ske = fsm_context;
2358 unsigned char tmp[4];
2360 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2362 /* Send FAILURE packet */
2363 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2364 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2366 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2367 silc_schedule_task_del_by_context(ske->schedule, ske);
2369 /* Call completion */
2370 silc_ske_completion(ske);
2372 return SILC_FSM_FINISH;
2375 /* Failure received from remote */
2377 SILC_FSM_STATE(silc_ske_st_responder_failure)
2379 SilcSKE ske = fsm_context;
2380 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2382 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2384 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2385 SILC_GET32_MSB(error, ske->packet->buffer.data);
2386 ske->status = error;
2387 silc_packet_free(ske->packet);
2391 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2392 silc_schedule_task_del_by_context(ske->schedule, ske);
2394 /* Call completion */
2395 silc_ske_completion(ske);
2397 return SILC_FSM_FINISH;
2400 /* Error occurred */
2402 SILC_FSM_STATE(silc_ske_st_responder_error)
2404 SilcSKE ske = fsm_context;
2405 unsigned char tmp[4];
2407 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2408 ske->status, silc_ske_map_status(ske->status)));
2410 /* Send FAILURE packet */
2411 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2412 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2413 SILC_PUT32_MSB(ske->status, tmp);
2414 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2416 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2417 silc_schedule_task_del_by_context(ske->schedule, ske);
2419 /* Call completion */
2420 silc_ske_completion(ske);
2422 return SILC_FSM_FINISH;
2425 /* Starts the protocol as responder. */
2427 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2428 SilcPacketStream stream,
2429 SilcSKEParams params)
2431 SILC_LOG_DEBUG(("Start SKE as responder"));
2433 if (!ske || !stream || !params || !params->version)
2436 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2439 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2442 ske->responder = TRUE;
2443 ske->flags = params->flags;
2444 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2445 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2446 ske->session_port = params->session_port;
2447 ske->version = params->version;
2452 /* Link to packet stream to get key exchange packets */
2453 ske->stream = stream;
2454 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2455 SILC_PACKET_KEY_EXCHANGE,
2456 SILC_PACKET_KEY_EXCHANGE_1,
2457 SILC_PACKET_SUCCESS,
2458 SILC_PACKET_FAILURE, -1);
2460 /* Start SKE as responder */
2461 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2466 /***************************** Initiator Rekey ******************************/
2470 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2472 SilcSKE ske = fsm_context;
2475 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2479 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2480 return SILC_FSM_CONTINUE;
2483 /* Add rekey exchange timeout */
2484 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2487 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2490 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2491 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2492 return SILC_FSM_CONTINUE;
2495 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2496 /** Cannot allocate hash */
2497 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2498 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2499 return SILC_FSM_CONTINUE;
2502 /* Send REKEY packet to start rekey protocol */
2503 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2504 /** Error sending packet */
2505 SILC_LOG_DEBUG(("Error sending packet"));
2506 ske->status = SILC_SKE_STATUS_ERROR;
2507 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2508 return SILC_FSM_CONTINUE;
2511 /* If doing rekey without PFS, move directly to the end of the protocol. */
2512 if (!ske->rekey->pfs) {
2513 /** Rekey without PFS */
2514 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2515 return SILC_FSM_CONTINUE;
2518 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2520 if (status != SILC_SKE_STATUS_OK) {
2521 /** Unknown group */
2522 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2523 return SILC_FSM_CONTINUE;
2526 /** Rekey with PFS */
2527 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2528 return SILC_FSM_CONTINUE;
2531 /* Sends REKEY_DONE packet to finish the protocol. */
2533 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2535 SilcSKE ske = fsm_context;
2536 SilcCipher send_key;
2539 SilcUInt32 key_len, block_len, hash_len, x_len;
2540 unsigned char *pfsbuf;
2542 SILC_LOG_DEBUG(("Start"));
2544 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2545 key_len = silc_cipher_get_key_len(send_key);
2546 block_len = silc_cipher_get_block_len(send_key);
2547 hash = ske->prop->hash;
2548 hash_len = silc_hash_len(hash);
2550 /* Process key material */
2551 if (ske->rekey->pfs) {
2553 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2555 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2558 memset(pfsbuf, 0, x_len);
2564 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2565 ske->rekey->enc_key_len / 8,
2571 SILC_LOG_ERROR(("Error processing key material"));
2572 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2573 return SILC_FSM_CONTINUE;
2576 ske->prop->cipher = send_key;
2577 ske->prop->hmac = hmac_send;
2579 /* Get sending keys */
2580 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2581 &hmac_send, NULL, NULL)) {
2582 /** Cannot get keys */
2583 ske->status = SILC_SKE_STATUS_ERROR;
2584 ske->prop->cipher = NULL;
2585 ske->prop->hmac = NULL;
2586 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2587 return SILC_FSM_CONTINUE;
2590 ske->prop->cipher = NULL;
2591 ske->prop->hmac = NULL;
2593 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2594 packet sent after this call will be protected with the new keys. */
2595 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2597 /** Cannot set keys */
2598 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2599 ske->status = SILC_SKE_STATUS_ERROR;
2600 silc_cipher_free(send_key);
2601 silc_hmac_free(hmac_send);
2602 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2603 return SILC_FSM_CONTINUE;
2606 /** Wait for REKEY_DONE */
2607 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2608 return SILC_FSM_WAIT;
2611 /* Rekey protocol end */
2613 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2615 SilcSKE ske = fsm_context;
2616 SilcCipher receive_key;
2617 SilcHmac hmac_receive;
2618 SilcSKERekeyMaterial rekey;
2620 SILC_LOG_DEBUG(("Start"));
2622 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2623 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2624 silc_packet_free(ske->packet);
2626 return SILC_FSM_WAIT;
2629 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2630 ske->prop->cipher = receive_key;
2631 ske->prop->hmac = hmac_receive;
2633 /* Get receiving keys */
2634 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2635 NULL, &hmac_receive, NULL)) {
2636 /** Cannot get keys */
2637 ske->status = SILC_SKE_STATUS_ERROR;
2638 ske->prop->cipher = NULL;
2639 ske->prop->hmac = NULL;
2640 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2641 return SILC_FSM_CONTINUE;
2644 /* Set new receiving keys into use. All packets received after this will
2645 be decrypted with the new keys. */
2646 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2647 hmac_receive, FALSE)) {
2648 /** Cannot set keys */
2649 SILC_LOG_DEBUG(("Cannot set new keys"));
2650 ske->status = SILC_SKE_STATUS_ERROR;
2651 silc_cipher_free(receive_key);
2652 silc_hmac_free(hmac_receive);
2653 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2654 return SILC_FSM_CONTINUE;
2657 SILC_LOG_DEBUG(("Rekey completed successfully"));
2659 /* Generate new rekey material */
2660 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2663 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
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;
2669 rekey->pfs = ske->rekey->pfs;
2672 ske->prop->cipher = NULL;
2673 ske->prop->hmac = NULL;
2674 silc_packet_free(ske->packet);
2676 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2677 silc_schedule_task_del_by_context(ske->schedule, ske);
2679 /* Call completion */
2680 silc_ske_completion(ske);
2682 return SILC_FSM_FINISH;
2685 /* Starts rekey protocol as initiator */
2688 silc_ske_rekey_initiator(SilcSKE ske,
2689 SilcPacketStream stream,
2690 SilcSKERekeyMaterial rekey)
2692 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2694 if (!ske || !stream || !rekey) {
2695 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2700 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2703 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2707 ske->responder = FALSE;
2708 ske->rekeying = TRUE;
2711 /* Link to packet stream to get key exchange packets */
2712 ske->stream = stream;
2713 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2715 SILC_PACKET_REKEY_DONE,
2716 SILC_PACKET_KEY_EXCHANGE_2,
2717 SILC_PACKET_SUCCESS,
2718 SILC_PACKET_FAILURE, -1);
2720 /* Start SKE rekey as initiator */
2721 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2726 /***************************** Responder Rekey ******************************/
2728 /* Wait for initiator's packet */
2730 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2732 SilcSKE ske = fsm_context;
2734 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2738 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2739 return SILC_FSM_CONTINUE;
2742 /* Add rekey exchange timeout */
2743 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2746 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2748 /* If REKEY packet already received process it directly */
2749 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2750 return SILC_FSM_CONTINUE;
2752 /* Wait for REKEY */
2753 return SILC_FSM_WAIT;
2756 /* Process initiator's REKEY packet */
2758 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2760 SilcSKE ske = fsm_context;
2761 SilcSKEStatus status;
2763 SILC_LOG_DEBUG(("Start"));
2765 if (ske->packet->type != SILC_PACKET_REKEY) {
2766 ske->status = SILC_SKE_STATUS_ERROR;
2767 silc_packet_free(ske->packet);
2769 silc_fsm_next(fsm, silc_ske_st_responder_error);
2770 return SILC_FSM_CONTINUE;
2773 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2776 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2777 silc_fsm_next(fsm, silc_ske_st_responder_error);
2778 return SILC_FSM_CONTINUE;
2781 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2782 /** Cannot allocate hash */
2783 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2784 silc_fsm_next(fsm, silc_ske_st_responder_error);
2785 return SILC_FSM_CONTINUE;
2788 /* If doing rekey without PFS, move directly to the end of the protocol. */
2789 if (!ske->rekey->pfs) {
2790 /** Rekey without PFS */
2791 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2792 return SILC_FSM_CONTINUE;
2795 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2797 if (status != SILC_SKE_STATUS_OK) {
2798 /** Unknown group */
2799 silc_fsm_next(fsm, silc_ske_st_responder_error);
2800 return SILC_FSM_CONTINUE;
2803 /** Rekey with PFS */
2804 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2805 return SILC_FSM_WAIT;
2808 /* Sends REKEY_DONE packet to finish the protocol. */
2810 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2812 SilcSKE ske = fsm_context;
2813 SilcCipher send_key;
2816 SilcUInt32 key_len, block_len, hash_len, x_len;
2817 unsigned char *pfsbuf;
2819 SILC_LOG_DEBUG(("Start"));
2821 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2822 key_len = silc_cipher_get_key_len(send_key);
2823 block_len = silc_cipher_get_block_len(send_key);
2824 hash = ske->prop->hash;
2825 hash_len = silc_hash_len(hash);
2827 /* Process key material */
2828 if (ske->rekey->pfs) {
2830 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2832 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2835 memset(pfsbuf, 0, x_len);
2841 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2842 ske->rekey->enc_key_len / 8,
2848 SILC_LOG_ERROR(("Error processing key material"));
2849 silc_fsm_next(fsm, silc_ske_st_responder_error);
2850 return SILC_FSM_CONTINUE;
2853 ske->prop->cipher = send_key;
2854 ske->prop->hmac = hmac_send;
2856 /* Get sending keys */
2857 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2858 &hmac_send, NULL, NULL)) {
2859 /** Cannot get keys */
2860 ske->status = SILC_SKE_STATUS_ERROR;
2861 ske->prop->cipher = NULL;
2862 ske->prop->hmac = NULL;
2863 silc_fsm_next(fsm, silc_ske_st_responder_error);
2864 return SILC_FSM_CONTINUE;
2867 ske->prop->cipher = NULL;
2868 ske->prop->hmac = NULL;
2870 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2871 packet sent after this call will be protected with the new keys. */
2872 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2874 /** Cannot set keys */
2875 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2876 ske->status = SILC_SKE_STATUS_ERROR;
2877 silc_cipher_free(send_key);
2878 silc_hmac_free(hmac_send);
2879 silc_fsm_next(fsm, silc_ske_st_responder_error);
2880 return SILC_FSM_CONTINUE;
2883 /** Wait for REKEY_DONE */
2884 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2885 return SILC_FSM_WAIT;
2888 /* Rekey protocol end */
2890 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2892 SilcSKE ske = fsm_context;
2893 SilcCipher receive_key;
2894 SilcHmac hmac_receive;
2895 SilcSKERekeyMaterial rekey;
2897 SILC_LOG_DEBUG(("Start"));
2899 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2900 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2901 silc_packet_free(ske->packet);
2903 return SILC_FSM_WAIT;
2906 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2907 ske->prop->cipher = receive_key;
2908 ske->prop->hmac = hmac_receive;
2910 /* Get receiving keys */
2911 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2912 NULL, &hmac_receive, NULL)) {
2913 /** Cannot get keys */
2914 ske->status = SILC_SKE_STATUS_ERROR;
2915 ske->prop->cipher = NULL;
2916 ske->prop->hmac = NULL;
2917 silc_fsm_next(fsm, silc_ske_st_responder_error);
2918 return SILC_FSM_CONTINUE;
2921 /* Set new receiving keys into use. All packets received after this will
2922 be decrypted with the new keys. */
2923 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2924 hmac_receive, FALSE)) {
2925 /** Cannot set keys */
2926 SILC_LOG_DEBUG(("Cannot set new keys"));
2927 ske->status = SILC_SKE_STATUS_ERROR;
2928 ske->prop->cipher = NULL;
2929 ske->prop->hmac = NULL;
2930 silc_cipher_free(receive_key);
2931 silc_hmac_free(hmac_receive);
2932 silc_fsm_next(fsm, silc_ske_st_responder_error);
2933 return SILC_FSM_CONTINUE;
2936 SILC_LOG_DEBUG(("Rekey completed successfully"));
2938 /* Generate new rekey material */
2939 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2942 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2943 ske->prop->cipher = NULL;
2944 ske->prop->hmac = NULL;
2945 silc_fsm_next(fsm, silc_ske_st_responder_error);
2946 return SILC_FSM_CONTINUE;
2948 rekey->pfs = ske->rekey->pfs;
2951 ske->prop->cipher = NULL;
2952 ske->prop->hmac = NULL;
2953 silc_packet_free(ske->packet);
2955 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2956 silc_schedule_task_del_by_context(ske->schedule, ske);
2958 /* Call completion */
2959 silc_ske_completion(ske);
2961 return SILC_FSM_FINISH;
2964 /* Starts rekey protocol as responder */
2967 silc_ske_rekey_responder(SilcSKE ske,
2968 SilcPacketStream stream,
2969 SilcSKERekeyMaterial rekey,
2972 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2974 if (!ske || !stream || !rekey)
2977 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2980 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2984 ske->responder = TRUE;
2985 ske->rekeying = TRUE;
2986 ske->packet = packet;
2989 /* Link to packet stream to get key exchange packets */
2990 ske->stream = stream;
2991 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2993 SILC_PACKET_REKEY_DONE,
2994 SILC_PACKET_KEY_EXCHANGE_1,
2995 SILC_PACKET_SUCCESS,
2996 SILC_PACKET_FAILURE, -1);
2998 /* Start SKE rekey as responder */
2999 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3004 /* Processes the provided key material `data' as the SILC protocol
3005 specification defines. */
3008 silc_ske_process_key_material_data(unsigned char *data,
3009 SilcUInt32 data_len,
3010 SilcUInt32 req_iv_len,
3011 SilcUInt32 req_enc_key_len,
3012 SilcUInt32 req_hmac_key_len,
3016 unsigned char hashd[SILC_HASH_MAXLEN];
3017 SilcUInt32 hash_len = req_hmac_key_len;
3018 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3019 SilcSKEKeyMaterial key;
3021 SILC_LOG_DEBUG(("Start"));
3023 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3026 key = silc_calloc(1, sizeof(*key));
3030 buf = silc_buffer_alloc_size(1 + data_len);
3033 silc_buffer_format(buf,
3034 SILC_STR_UI_CHAR(0),
3035 SILC_STR_DATA(data, data_len),
3039 memset(hashd, 0, sizeof(hashd));
3041 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3042 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3043 memcpy(key->send_iv, hashd, req_iv_len);
3044 memset(hashd, 0, sizeof(hashd));
3046 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3047 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3048 memcpy(key->receive_iv, hashd, req_iv_len);
3049 key->iv_len = req_iv_len;
3051 /* Take the encryption keys. If requested key size is more than
3052 the size of hash length we will distribute more key material
3053 as protocol defines. */
3055 if (enc_key_len > hash_len) {
3057 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3058 k3[SILC_HASH_MAXLEN];
3059 unsigned char *dtmp;
3062 if (enc_key_len > (3 * hash_len))
3065 /* Take first round */
3066 memset(k1, 0, sizeof(k1));
3067 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3069 /* Take second round */
3070 dist = silc_buffer_alloc_size(data_len + hash_len);
3073 silc_buffer_format(dist,
3074 SILC_STR_DATA(data, data_len),
3075 SILC_STR_DATA(k1, hash_len),
3077 memset(k2, 0, sizeof(k2));
3078 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3080 /* Take third round */
3081 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3082 silc_buffer_pull_tail(dist, hash_len);
3083 silc_buffer_pull(dist, data_len + hash_len);
3084 silc_buffer_format(dist,
3085 SILC_STR_DATA(k2, hash_len),
3087 silc_buffer_push(dist, data_len + hash_len);
3088 memset(k3, 0, sizeof(k3));
3089 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3091 /* Then, save the keys */
3092 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3093 memcpy(dtmp, k1, hash_len);
3094 memcpy(dtmp + hash_len, k2, hash_len);
3095 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3097 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3098 memcpy(key->send_enc_key, dtmp, enc_key_len);
3099 key->enc_key_len = req_enc_key_len;
3101 memset(dtmp, 0, (3 * hash_len));
3102 memset(k1, 0, sizeof(k1));
3103 memset(k2, 0, sizeof(k2));
3104 memset(k3, 0, sizeof(k3));
3106 silc_buffer_clear(dist);
3107 silc_buffer_free(dist);
3109 /* Take normal hash as key */
3110 memset(hashd, 0, sizeof(hashd));
3111 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3112 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3113 memcpy(key->send_enc_key, hashd, enc_key_len);
3114 key->enc_key_len = req_enc_key_len;
3118 if (enc_key_len > hash_len) {
3120 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3121 k3[SILC_HASH_MAXLEN];
3122 unsigned char *dtmp;
3125 if (enc_key_len > (3 * hash_len))
3128 /* Take first round */
3129 memset(k1, 0, sizeof(k1));
3130 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3132 /* Take second round */
3133 dist = silc_buffer_alloc_size(data_len + hash_len);
3136 silc_buffer_format(dist,
3137 SILC_STR_DATA(data, data_len),
3138 SILC_STR_DATA(k1, hash_len),
3140 memset(k2, 0, sizeof(k2));
3141 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3143 /* Take third round */
3144 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3145 silc_buffer_pull_tail(dist, hash_len);
3146 silc_buffer_pull(dist, data_len + hash_len);
3147 silc_buffer_format(dist,
3148 SILC_STR_DATA(k2, hash_len),
3150 silc_buffer_push(dist, data_len + hash_len);
3151 memset(k3, 0, sizeof(k3));
3152 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3154 /* Then, save the keys */
3155 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3156 memcpy(dtmp, k1, hash_len);
3157 memcpy(dtmp + hash_len, k2, hash_len);
3158 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3160 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3161 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3162 key->enc_key_len = req_enc_key_len;
3164 memset(dtmp, 0, (3 * hash_len));
3165 memset(k1, 0, sizeof(k1));
3166 memset(k2, 0, sizeof(k2));
3167 memset(k3, 0, sizeof(k3));
3169 silc_buffer_clear(dist);
3170 silc_buffer_free(dist);
3172 /* Take normal hash as key */
3173 memset(hashd, 0, sizeof(hashd));
3174 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3175 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3176 memcpy(key->receive_enc_key, hashd, enc_key_len);
3177 key->enc_key_len = req_enc_key_len;
3180 /* Take HMAC keys */
3181 memset(hashd, 0, sizeof(hashd));
3183 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3184 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3185 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3186 memset(hashd, 0, sizeof(hashd));
3188 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3189 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3190 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3191 key->hmac_key_len = req_hmac_key_len;
3192 memset(hashd, 0, sizeof(hashd));
3194 silc_buffer_clear(buf);
3195 silc_buffer_free(buf);
3197 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3202 /* Processes negotiated key material as protocol specifies. This returns
3203 the actual keys to be used in the SILC. */
3206 silc_ske_process_key_material(SilcSKE ske,
3207 SilcUInt32 req_iv_len,
3208 SilcUInt32 req_enc_key_len,
3209 SilcUInt32 req_hmac_key_len,
3210 SilcSKERekeyMaterial *rekey)
3213 unsigned char *tmpbuf;
3215 SilcSKEKeyMaterial key;
3217 /* Encode KEY to binary data */
3218 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3220 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3223 silc_buffer_format(buf,
3224 SILC_STR_DATA(tmpbuf, klen),
3225 SILC_STR_DATA(ske->hash, ske->hash_len),
3228 /* Process the key material */
3229 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3230 req_iv_len, req_enc_key_len,
3234 memset(tmpbuf, 0, klen);
3236 silc_buffer_clear(buf);
3237 silc_buffer_free(buf);
3240 *rekey = silc_ske_make_rekey_material(ske, key);
3248 /* Free key material structure */
3250 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3256 silc_free(key->send_iv);
3257 if (key->receive_iv)
3258 silc_free(key->receive_iv);
3259 if (key->send_enc_key) {
3260 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3261 silc_free(key->send_enc_key);
3263 if (key->receive_enc_key) {
3264 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3265 silc_free(key->receive_enc_key);
3267 if (key->send_hmac_key) {
3268 memset(key->send_hmac_key, 0, key->hmac_key_len);
3269 silc_free(key->send_hmac_key);
3271 if (key->receive_hmac_key) {
3272 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3273 silc_free(key->receive_hmac_key);
3278 /* Free rekey material */
3280 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3284 if (rekey->send_enc_key) {
3285 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3286 silc_free(rekey->send_enc_key);
3288 silc_free(rekey->hash);
3292 /* Set keys into use */
3294 SilcBool silc_ske_set_keys(SilcSKE ske,
3295 SilcSKEKeyMaterial keymat,
3296 SilcSKESecurityProperties prop,
3297 SilcCipher *ret_send_key,
3298 SilcCipher *ret_receive_key,
3299 SilcHmac *ret_hmac_send,
3300 SilcHmac *ret_hmac_receive,
3303 unsigned char iv[SILC_HASH_MAXLEN];
3304 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3306 /* Allocate ciphers to be used in the communication */
3308 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3312 if (ret_receive_key) {
3313 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3318 /* Allocate HMACs */
3319 if (ret_hmac_send) {
3320 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3324 if (ret_hmac_receive) {
3325 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3332 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3336 /* Set key material */
3337 memset(iv, 0, sizeof(iv));
3338 if (ske->responder) {
3340 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3341 keymat->enc_key_len, TRUE);
3343 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3345 if (!ske->rekeying) {
3347 memcpy(iv, ske->hash, 4);
3349 memcpy(iv + 4, keymat->receive_iv, 8);
3351 /* Rekey, recompute the truncated hash value. */
3352 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3354 memcpy(iv + 4, keymat->receive_iv, 8);
3356 memset(iv + 4, 0, 12);
3359 silc_cipher_set_iv(*ret_send_key, iv);
3362 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3365 if (ret_receive_key) {
3366 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3367 keymat->enc_key_len, FALSE);
3369 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3371 if (!ske->rekeying) {
3373 memcpy(iv, ske->hash, 4);
3375 memcpy(iv + 4, keymat->send_iv, 8);
3377 /* Rekey, recompute the truncated hash value. */
3378 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3380 memcpy(iv + 4, keymat->send_iv, 8);
3382 memset(iv + 4, 0, 12);
3385 silc_cipher_set_iv(*ret_receive_key, iv);
3388 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3392 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3393 keymat->hmac_key_len);
3394 if (ret_hmac_receive)
3395 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3396 keymat->hmac_key_len);
3399 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3400 keymat->enc_key_len, TRUE);
3402 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3404 if (!ske->rekeying) {
3406 memcpy(iv, ske->hash, 4);
3408 memcpy(iv + 4, keymat->send_iv, 8);
3410 /* Rekey, recompute the truncated hash value. */
3411 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3413 memcpy(iv + 4, keymat->send_iv, 8);
3415 memset(iv + 4, 0, 12);
3418 silc_cipher_set_iv(*ret_send_key, iv);
3421 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3424 if (ret_receive_key) {
3425 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3426 keymat->enc_key_len, FALSE);
3428 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3430 if (!ske->rekeying) {
3431 /* Set IV. If IV Included flag was negotiated we only set the
3432 truncated hash value. */
3433 memcpy(iv, ske->hash, 4);
3435 memcpy(iv + 4, keymat->receive_iv, 8);
3437 /* Rekey, recompute the truncated hash value. */
3438 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3440 memcpy(iv + 4, keymat->receive_iv, 8);
3442 memset(iv + 4, 0, 12);
3445 silc_cipher_set_iv(*ret_receive_key, iv);
3448 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3452 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3453 keymat->hmac_key_len);
3454 if (ret_hmac_receive)
3455 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3456 keymat->hmac_key_len);
3462 const char *silc_ske_status_string[] =
3466 "Unexpected error occurred",
3467 "Bad payload in packet",
3468 "Unsupported group",
3469 "Unsupported cipher",
3471 "Unsupported hash function",
3473 "Unsupported public key (or certificate)",
3474 "Incorrect signature",
3475 "Bad or unsupported version",
3479 "Remote did not provide public key",
3480 "Bad reserved field in packet",
3481 "Bad payload length in packet",
3482 "Error computing signature",
3483 "System out of memory",
3484 "Key exchange timeout",
3489 /* Maps status to readable string and returns the string. If string is not
3490 found and empty character string ("") is returned. */
3492 const char *silc_ske_map_status(SilcSKEStatus status)
3496 for (i = 0; silc_ske_status_string[i]; i++)
3498 return silc_ske_status_string[i];
3503 /* Parses remote host's version string. */
3505 SilcBool silc_ske_parse_version(SilcSKE ske,
3506 SilcUInt32 *protocol_version,
3507 char **protocol_version_string,
3508 SilcUInt32 *software_version,
3509 char **software_version_string,
3510 char **vendor_version)
3512 return silc_parse_version_string(ske->remote_version,
3514 protocol_version_string,
3516 software_version_string,
3520 /* Get security properties */
3522 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3527 /* Get key material */
3529 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)