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 = %d)",
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 silc_packet_free(ske->packet);
1815 ske->status = error;
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 silc_packet_free(ske->packet);
2389 ske->status = error;
2390 if (ske->status == SILC_SKE_STATUS_OK)
2391 ske->status = SILC_SKE_STATUS_ERROR;
2393 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2394 silc_schedule_task_del_by_context(ske->schedule, ske);
2396 /* Call completion */
2397 silc_ske_completion(ske);
2399 return SILC_FSM_FINISH;
2402 /* Error occurred */
2404 SILC_FSM_STATE(silc_ske_st_responder_error)
2406 SilcSKE ske = fsm_context;
2407 unsigned char tmp[4];
2409 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2410 ske->status, silc_ske_map_status(ske->status)));
2412 /* Send FAILURE packet */
2413 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2414 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2415 SILC_PUT32_MSB(ske->status, tmp);
2416 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2418 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2419 silc_schedule_task_del_by_context(ske->schedule, ske);
2421 /* Call completion */
2422 silc_ske_completion(ske);
2424 return SILC_FSM_FINISH;
2427 /* Starts the protocol as responder. */
2429 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2430 SilcPacketStream stream,
2431 SilcSKEParams params)
2433 SILC_LOG_DEBUG(("Start SKE as responder"));
2435 if (!ske || !stream || !params || !params->version)
2438 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2441 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2444 ske->responder = TRUE;
2445 ske->flags = params->flags;
2446 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2447 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2448 ske->session_port = params->session_port;
2449 ske->version = params->version;
2454 /* Link to packet stream to get key exchange packets */
2455 ske->stream = stream;
2456 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2457 SILC_PACKET_KEY_EXCHANGE,
2458 SILC_PACKET_KEY_EXCHANGE_1,
2459 SILC_PACKET_SUCCESS,
2460 SILC_PACKET_FAILURE, -1);
2462 /* Start SKE as responder */
2463 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2468 /***************************** Initiator Rekey ******************************/
2472 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2474 SilcSKE ske = fsm_context;
2477 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2481 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2482 return SILC_FSM_CONTINUE;
2485 /* Add rekey exchange timeout */
2486 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2489 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2492 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2493 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2494 return SILC_FSM_CONTINUE;
2497 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2498 /** Cannot allocate hash */
2499 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2500 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2501 return SILC_FSM_CONTINUE;
2504 /* Send REKEY packet to start rekey protocol */
2505 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2506 /** Error sending packet */
2507 SILC_LOG_DEBUG(("Error sending packet"));
2508 ske->status = SILC_SKE_STATUS_ERROR;
2509 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2510 return SILC_FSM_CONTINUE;
2513 /* If doing rekey without PFS, move directly to the end of the protocol. */
2514 if (!ske->rekey->pfs) {
2515 /** Rekey without PFS */
2516 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2517 return SILC_FSM_CONTINUE;
2520 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2522 if (status != SILC_SKE_STATUS_OK) {
2523 /** Unknown group */
2524 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2525 return SILC_FSM_CONTINUE;
2528 /** Rekey with PFS */
2529 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2530 return SILC_FSM_CONTINUE;
2533 /* Sends REKEY_DONE packet to finish the protocol. */
2535 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2537 SilcSKE ske = fsm_context;
2538 SilcCipher send_key;
2541 SilcUInt32 key_len, block_len, hash_len, x_len;
2542 unsigned char *pfsbuf;
2544 SILC_LOG_DEBUG(("Start"));
2546 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2547 key_len = silc_cipher_get_key_len(send_key);
2548 block_len = silc_cipher_get_block_len(send_key);
2549 hash = ske->prop->hash;
2550 hash_len = silc_hash_len(hash);
2552 /* Process key material */
2553 if (ske->rekey->pfs) {
2555 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2557 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2560 memset(pfsbuf, 0, x_len);
2566 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2567 ske->rekey->enc_key_len / 8,
2573 SILC_LOG_ERROR(("Error processing key material"));
2574 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2575 return SILC_FSM_CONTINUE;
2578 ske->prop->cipher = send_key;
2579 ske->prop->hmac = hmac_send;
2581 /* Get sending keys */
2582 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2583 &hmac_send, NULL, NULL)) {
2584 /** Cannot get keys */
2585 ske->status = SILC_SKE_STATUS_ERROR;
2586 ske->prop->cipher = NULL;
2587 ske->prop->hmac = NULL;
2588 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2589 return SILC_FSM_CONTINUE;
2592 ske->prop->cipher = NULL;
2593 ske->prop->hmac = NULL;
2595 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2596 packet sent after this call will be protected with the new keys. */
2597 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2599 /** Cannot set keys */
2600 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2601 ske->status = SILC_SKE_STATUS_ERROR;
2602 silc_cipher_free(send_key);
2603 silc_hmac_free(hmac_send);
2604 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2605 return SILC_FSM_CONTINUE;
2608 /** Wait for REKEY_DONE */
2609 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2610 return SILC_FSM_WAIT;
2613 /* Rekey protocol end */
2615 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2617 SilcSKE ske = fsm_context;
2618 SilcCipher receive_key;
2619 SilcHmac hmac_receive;
2620 SilcSKERekeyMaterial rekey;
2622 SILC_LOG_DEBUG(("Start"));
2624 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2625 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2626 silc_packet_free(ske->packet);
2628 return SILC_FSM_WAIT;
2631 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2632 ske->prop->cipher = receive_key;
2633 ske->prop->hmac = hmac_receive;
2635 /* Get receiving keys */
2636 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2637 NULL, &hmac_receive, NULL)) {
2638 /** Cannot get keys */
2639 ske->status = SILC_SKE_STATUS_ERROR;
2640 ske->prop->cipher = NULL;
2641 ske->prop->hmac = NULL;
2642 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2643 return SILC_FSM_CONTINUE;
2646 /* Set new receiving keys into use. All packets received after this will
2647 be decrypted with the new keys. */
2648 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2649 hmac_receive, FALSE)) {
2650 /** Cannot set keys */
2651 SILC_LOG_DEBUG(("Cannot set new keys"));
2652 ske->status = SILC_SKE_STATUS_ERROR;
2653 silc_cipher_free(receive_key);
2654 silc_hmac_free(hmac_receive);
2655 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2656 return SILC_FSM_CONTINUE;
2659 SILC_LOG_DEBUG(("Rekey completed successfully"));
2661 /* Generate new rekey material */
2662 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2665 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2666 ske->prop->cipher = NULL;
2667 ske->prop->hmac = NULL;
2668 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2669 return SILC_FSM_CONTINUE;
2671 rekey->pfs = ske->rekey->pfs;
2674 ske->prop->cipher = NULL;
2675 ske->prop->hmac = NULL;
2676 silc_packet_free(ske->packet);
2678 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2679 silc_schedule_task_del_by_context(ske->schedule, ske);
2681 /* Call completion */
2682 silc_ske_completion(ske);
2684 return SILC_FSM_FINISH;
2687 /* Starts rekey protocol as initiator */
2690 silc_ske_rekey_initiator(SilcSKE ske,
2691 SilcPacketStream stream,
2692 SilcSKERekeyMaterial rekey)
2694 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2696 if (!ske || !stream || !rekey) {
2697 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2702 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2705 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2709 ske->responder = FALSE;
2710 ske->rekeying = TRUE;
2713 /* Link to packet stream to get key exchange packets */
2714 ske->stream = stream;
2715 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2717 SILC_PACKET_REKEY_DONE,
2718 SILC_PACKET_KEY_EXCHANGE_2,
2719 SILC_PACKET_SUCCESS,
2720 SILC_PACKET_FAILURE, -1);
2722 /* Start SKE rekey as initiator */
2723 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2728 /***************************** Responder Rekey ******************************/
2730 /* Wait for initiator's packet */
2732 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2734 SilcSKE ske = fsm_context;
2736 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2740 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2741 return SILC_FSM_CONTINUE;
2744 /* Add rekey exchange timeout */
2745 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2748 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2750 /* If REKEY packet already received process it directly */
2751 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2752 return SILC_FSM_CONTINUE;
2754 /* Wait for REKEY */
2755 return SILC_FSM_WAIT;
2758 /* Process initiator's REKEY packet */
2760 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2762 SilcSKE ske = fsm_context;
2763 SilcSKEStatus status;
2765 SILC_LOG_DEBUG(("Start"));
2767 if (ske->packet->type != SILC_PACKET_REKEY) {
2768 ske->status = SILC_SKE_STATUS_ERROR;
2769 silc_packet_free(ske->packet);
2771 silc_fsm_next(fsm, silc_ske_st_responder_error);
2772 return SILC_FSM_CONTINUE;
2775 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2778 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2779 silc_fsm_next(fsm, silc_ske_st_responder_error);
2780 return SILC_FSM_CONTINUE;
2783 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2784 /** Cannot allocate hash */
2785 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2786 silc_fsm_next(fsm, silc_ske_st_responder_error);
2787 return SILC_FSM_CONTINUE;
2790 /* If doing rekey without PFS, move directly to the end of the protocol. */
2791 if (!ske->rekey->pfs) {
2792 /** Rekey without PFS */
2793 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2794 return SILC_FSM_CONTINUE;
2797 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2799 if (status != SILC_SKE_STATUS_OK) {
2800 /** Unknown group */
2801 silc_fsm_next(fsm, silc_ske_st_responder_error);
2802 return SILC_FSM_CONTINUE;
2805 /** Rekey with PFS */
2806 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2807 return SILC_FSM_WAIT;
2810 /* Sends REKEY_DONE packet to finish the protocol. */
2812 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2814 SilcSKE ske = fsm_context;
2815 SilcCipher send_key;
2818 SilcUInt32 key_len, block_len, hash_len, x_len;
2819 unsigned char *pfsbuf;
2821 SILC_LOG_DEBUG(("Start"));
2823 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2824 key_len = silc_cipher_get_key_len(send_key);
2825 block_len = silc_cipher_get_block_len(send_key);
2826 hash = ske->prop->hash;
2827 hash_len = silc_hash_len(hash);
2829 /* Process key material */
2830 if (ske->rekey->pfs) {
2832 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2834 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2837 memset(pfsbuf, 0, x_len);
2843 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2844 ske->rekey->enc_key_len / 8,
2850 SILC_LOG_ERROR(("Error processing key material"));
2851 silc_fsm_next(fsm, silc_ske_st_responder_error);
2852 return SILC_FSM_CONTINUE;
2855 ske->prop->cipher = send_key;
2856 ske->prop->hmac = hmac_send;
2858 /* Get sending keys */
2859 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2860 &hmac_send, NULL, NULL)) {
2861 /** Cannot get keys */
2862 ske->status = SILC_SKE_STATUS_ERROR;
2863 ske->prop->cipher = NULL;
2864 ske->prop->hmac = NULL;
2865 silc_fsm_next(fsm, silc_ske_st_responder_error);
2866 return SILC_FSM_CONTINUE;
2869 ske->prop->cipher = NULL;
2870 ske->prop->hmac = NULL;
2872 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2873 packet sent after this call will be protected with the new keys. */
2874 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2876 /** Cannot set keys */
2877 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2878 ske->status = SILC_SKE_STATUS_ERROR;
2879 silc_cipher_free(send_key);
2880 silc_hmac_free(hmac_send);
2881 silc_fsm_next(fsm, silc_ske_st_responder_error);
2882 return SILC_FSM_CONTINUE;
2885 /** Wait for REKEY_DONE */
2886 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2887 return SILC_FSM_WAIT;
2890 /* Rekey protocol end */
2892 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2894 SilcSKE ske = fsm_context;
2895 SilcCipher receive_key;
2896 SilcHmac hmac_receive;
2897 SilcSKERekeyMaterial rekey;
2899 SILC_LOG_DEBUG(("Start"));
2901 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2902 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2903 silc_packet_free(ske->packet);
2905 return SILC_FSM_WAIT;
2908 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2909 ske->prop->cipher = receive_key;
2910 ske->prop->hmac = hmac_receive;
2912 /* Get receiving keys */
2913 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2914 NULL, &hmac_receive, NULL)) {
2915 /** Cannot get keys */
2916 ske->status = SILC_SKE_STATUS_ERROR;
2917 ske->prop->cipher = NULL;
2918 ske->prop->hmac = NULL;
2919 silc_fsm_next(fsm, silc_ske_st_responder_error);
2920 return SILC_FSM_CONTINUE;
2923 /* Set new receiving keys into use. All packets received after this will
2924 be decrypted with the new keys. */
2925 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2926 hmac_receive, FALSE)) {
2927 /** Cannot set keys */
2928 SILC_LOG_DEBUG(("Cannot set new keys"));
2929 ske->status = SILC_SKE_STATUS_ERROR;
2930 ske->prop->cipher = NULL;
2931 ske->prop->hmac = NULL;
2932 silc_cipher_free(receive_key);
2933 silc_hmac_free(hmac_receive);
2934 silc_fsm_next(fsm, silc_ske_st_responder_error);
2935 return SILC_FSM_CONTINUE;
2938 SILC_LOG_DEBUG(("Rekey completed successfully"));
2940 /* Generate new rekey material */
2941 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2944 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2945 ske->prop->cipher = NULL;
2946 ske->prop->hmac = NULL;
2947 silc_fsm_next(fsm, silc_ske_st_responder_error);
2948 return SILC_FSM_CONTINUE;
2950 rekey->pfs = ske->rekey->pfs;
2953 ske->prop->cipher = NULL;
2954 ske->prop->hmac = NULL;
2955 silc_packet_free(ske->packet);
2957 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2958 silc_schedule_task_del_by_context(ske->schedule, ske);
2960 /* Call completion */
2961 silc_ske_completion(ske);
2963 return SILC_FSM_FINISH;
2966 /* Starts rekey protocol as responder */
2969 silc_ske_rekey_responder(SilcSKE ske,
2970 SilcPacketStream stream,
2971 SilcSKERekeyMaterial rekey,
2974 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2976 if (!ske || !stream || !rekey)
2979 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2982 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2986 ske->responder = TRUE;
2987 ske->rekeying = TRUE;
2988 ske->packet = packet;
2991 /* Link to packet stream to get key exchange packets */
2992 ske->stream = stream;
2993 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2995 SILC_PACKET_REKEY_DONE,
2996 SILC_PACKET_KEY_EXCHANGE_1,
2997 SILC_PACKET_SUCCESS,
2998 SILC_PACKET_FAILURE, -1);
3000 /* Start SKE rekey as responder */
3001 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3006 /* Processes the provided key material `data' as the SILC protocol
3007 specification defines. */
3010 silc_ske_process_key_material_data(unsigned char *data,
3011 SilcUInt32 data_len,
3012 SilcUInt32 req_iv_len,
3013 SilcUInt32 req_enc_key_len,
3014 SilcUInt32 req_hmac_key_len,
3018 unsigned char hashd[SILC_HASH_MAXLEN];
3019 SilcUInt32 hash_len = req_hmac_key_len;
3020 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3021 SilcSKEKeyMaterial key;
3023 SILC_LOG_DEBUG(("Start"));
3025 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3028 key = silc_calloc(1, sizeof(*key));
3032 buf = silc_buffer_alloc_size(1 + data_len);
3035 silc_buffer_format(buf,
3036 SILC_STR_UI_CHAR(0),
3037 SILC_STR_DATA(data, data_len),
3041 memset(hashd, 0, sizeof(hashd));
3043 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3044 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3045 memcpy(key->send_iv, hashd, req_iv_len);
3046 memset(hashd, 0, sizeof(hashd));
3048 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3049 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3050 memcpy(key->receive_iv, hashd, req_iv_len);
3051 key->iv_len = req_iv_len;
3053 /* Take the encryption keys. If requested key size is more than
3054 the size of hash length we will distribute more key material
3055 as protocol defines. */
3057 if (enc_key_len > hash_len) {
3059 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3060 k3[SILC_HASH_MAXLEN];
3061 unsigned char *dtmp;
3064 if (enc_key_len > (3 * hash_len))
3067 /* Take first round */
3068 memset(k1, 0, sizeof(k1));
3069 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3071 /* Take second round */
3072 dist = silc_buffer_alloc_size(data_len + hash_len);
3075 silc_buffer_format(dist,
3076 SILC_STR_DATA(data, data_len),
3077 SILC_STR_DATA(k1, hash_len),
3079 memset(k2, 0, sizeof(k2));
3080 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3082 /* Take third round */
3083 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3084 silc_buffer_pull_tail(dist, hash_len);
3085 silc_buffer_pull(dist, data_len + hash_len);
3086 silc_buffer_format(dist,
3087 SILC_STR_DATA(k2, hash_len),
3089 silc_buffer_push(dist, data_len + hash_len);
3090 memset(k3, 0, sizeof(k3));
3091 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3093 /* Then, save the keys */
3094 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3095 memcpy(dtmp, k1, hash_len);
3096 memcpy(dtmp + hash_len, k2, hash_len);
3097 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3099 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3100 memcpy(key->send_enc_key, dtmp, enc_key_len);
3101 key->enc_key_len = req_enc_key_len;
3103 memset(dtmp, 0, (3 * hash_len));
3104 memset(k1, 0, sizeof(k1));
3105 memset(k2, 0, sizeof(k2));
3106 memset(k3, 0, sizeof(k3));
3108 silc_buffer_clear(dist);
3109 silc_buffer_free(dist);
3111 /* Take normal hash as key */
3112 memset(hashd, 0, sizeof(hashd));
3113 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3114 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3115 memcpy(key->send_enc_key, hashd, enc_key_len);
3116 key->enc_key_len = req_enc_key_len;
3120 if (enc_key_len > hash_len) {
3122 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3123 k3[SILC_HASH_MAXLEN];
3124 unsigned char *dtmp;
3127 if (enc_key_len > (3 * hash_len))
3130 /* Take first round */
3131 memset(k1, 0, sizeof(k1));
3132 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3134 /* Take second round */
3135 dist = silc_buffer_alloc_size(data_len + hash_len);
3138 silc_buffer_format(dist,
3139 SILC_STR_DATA(data, data_len),
3140 SILC_STR_DATA(k1, hash_len),
3142 memset(k2, 0, sizeof(k2));
3143 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3145 /* Take third round */
3146 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3147 silc_buffer_pull_tail(dist, hash_len);
3148 silc_buffer_pull(dist, data_len + hash_len);
3149 silc_buffer_format(dist,
3150 SILC_STR_DATA(k2, hash_len),
3152 silc_buffer_push(dist, data_len + hash_len);
3153 memset(k3, 0, sizeof(k3));
3154 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3156 /* Then, save the keys */
3157 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3158 memcpy(dtmp, k1, hash_len);
3159 memcpy(dtmp + hash_len, k2, hash_len);
3160 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3162 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3163 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3164 key->enc_key_len = req_enc_key_len;
3166 memset(dtmp, 0, (3 * hash_len));
3167 memset(k1, 0, sizeof(k1));
3168 memset(k2, 0, sizeof(k2));
3169 memset(k3, 0, sizeof(k3));
3171 silc_buffer_clear(dist);
3172 silc_buffer_free(dist);
3174 /* Take normal hash as key */
3175 memset(hashd, 0, sizeof(hashd));
3176 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3177 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3178 memcpy(key->receive_enc_key, hashd, enc_key_len);
3179 key->enc_key_len = req_enc_key_len;
3182 /* Take HMAC keys */
3183 memset(hashd, 0, sizeof(hashd));
3185 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3186 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3187 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3188 memset(hashd, 0, sizeof(hashd));
3190 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3191 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3192 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3193 key->hmac_key_len = req_hmac_key_len;
3194 memset(hashd, 0, sizeof(hashd));
3196 silc_buffer_clear(buf);
3197 silc_buffer_free(buf);
3199 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3204 /* Processes negotiated key material as protocol specifies. This returns
3205 the actual keys to be used in the SILC. */
3208 silc_ske_process_key_material(SilcSKE ske,
3209 SilcUInt32 req_iv_len,
3210 SilcUInt32 req_enc_key_len,
3211 SilcUInt32 req_hmac_key_len,
3212 SilcSKERekeyMaterial *rekey)
3215 unsigned char *tmpbuf;
3217 SilcSKEKeyMaterial key;
3219 /* Encode KEY to binary data */
3220 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3222 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3225 silc_buffer_format(buf,
3226 SILC_STR_DATA(tmpbuf, klen),
3227 SILC_STR_DATA(ske->hash, ske->hash_len),
3230 /* Process the key material */
3231 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3232 req_iv_len, req_enc_key_len,
3236 memset(tmpbuf, 0, klen);
3238 silc_buffer_clear(buf);
3239 silc_buffer_free(buf);
3242 *rekey = silc_ske_make_rekey_material(ske, key);
3250 /* Free key material structure */
3252 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3258 silc_free(key->send_iv);
3259 if (key->receive_iv)
3260 silc_free(key->receive_iv);
3261 if (key->send_enc_key) {
3262 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3263 silc_free(key->send_enc_key);
3265 if (key->receive_enc_key) {
3266 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3267 silc_free(key->receive_enc_key);
3269 if (key->send_hmac_key) {
3270 memset(key->send_hmac_key, 0, key->hmac_key_len);
3271 silc_free(key->send_hmac_key);
3273 if (key->receive_hmac_key) {
3274 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3275 silc_free(key->receive_hmac_key);
3280 /* Free rekey material */
3282 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3286 if (rekey->send_enc_key) {
3287 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3288 silc_free(rekey->send_enc_key);
3290 silc_free(rekey->hash);
3294 /* Set keys into use */
3296 SilcBool silc_ske_set_keys(SilcSKE ske,
3297 SilcSKEKeyMaterial keymat,
3298 SilcSKESecurityProperties prop,
3299 SilcCipher *ret_send_key,
3300 SilcCipher *ret_receive_key,
3301 SilcHmac *ret_hmac_send,
3302 SilcHmac *ret_hmac_receive,
3305 unsigned char iv[SILC_HASH_MAXLEN];
3306 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3308 /* Allocate ciphers to be used in the communication */
3310 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3314 if (ret_receive_key) {
3315 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3320 /* Allocate HMACs */
3321 if (ret_hmac_send) {
3322 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3326 if (ret_hmac_receive) {
3327 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3334 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3338 /* Set key material */
3339 memset(iv, 0, sizeof(iv));
3340 if (ske->responder) {
3342 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3343 keymat->enc_key_len, TRUE);
3345 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3347 if (!ske->rekeying) {
3349 memcpy(iv, ske->hash, 4);
3351 memcpy(iv + 4, keymat->receive_iv, 8);
3353 /* Rekey, recompute the truncated hash value. */
3354 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3356 memcpy(iv + 4, keymat->receive_iv, 8);
3358 memset(iv + 4, 0, 12);
3361 silc_cipher_set_iv(*ret_send_key, iv);
3364 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3367 if (ret_receive_key) {
3368 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3369 keymat->enc_key_len, FALSE);
3371 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3373 if (!ske->rekeying) {
3375 memcpy(iv, ske->hash, 4);
3377 memcpy(iv + 4, keymat->send_iv, 8);
3379 /* Rekey, recompute the truncated hash value. */
3380 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3382 memcpy(iv + 4, keymat->send_iv, 8);
3384 memset(iv + 4, 0, 12);
3387 silc_cipher_set_iv(*ret_receive_key, iv);
3390 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3394 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3395 keymat->hmac_key_len);
3396 if (ret_hmac_receive)
3397 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3398 keymat->hmac_key_len);
3401 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3402 keymat->enc_key_len, TRUE);
3404 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3406 if (!ske->rekeying) {
3408 memcpy(iv, ske->hash, 4);
3410 memcpy(iv + 4, keymat->send_iv, 8);
3412 /* Rekey, recompute the truncated hash value. */
3413 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3415 memcpy(iv + 4, keymat->send_iv, 8);
3417 memset(iv + 4, 0, 12);
3420 silc_cipher_set_iv(*ret_send_key, iv);
3423 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3426 if (ret_receive_key) {
3427 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3428 keymat->enc_key_len, FALSE);
3430 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3432 if (!ske->rekeying) {
3433 /* Set IV. If IV Included flag was negotiated we only set the
3434 truncated hash value. */
3435 memcpy(iv, ske->hash, 4);
3437 memcpy(iv + 4, keymat->receive_iv, 8);
3439 /* Rekey, recompute the truncated hash value. */
3440 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3442 memcpy(iv + 4, keymat->receive_iv, 8);
3444 memset(iv + 4, 0, 12);
3447 silc_cipher_set_iv(*ret_receive_key, iv);
3450 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3454 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3455 keymat->hmac_key_len);
3456 if (ret_hmac_receive)
3457 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3458 keymat->hmac_key_len);
3464 const char *silc_ske_status_string[] =
3468 "Unexpected error occurred",
3469 "Bad payload in packet",
3470 "Unsupported group",
3471 "Unsupported cipher",
3473 "Unsupported hash function",
3475 "Unsupported public key (or certificate)",
3476 "Incorrect signature",
3477 "Bad or unsupported version",
3481 "Remote did not provide public key",
3482 "Bad reserved field in packet",
3483 "Bad payload length in packet",
3484 "Error computing signature",
3485 "System out of memory",
3486 "Key exchange timeout",
3491 /* Maps status to readable string and returns the string. If string is not
3492 found and empty character string ("") is returned. */
3494 const char *silc_ske_map_status(SilcSKEStatus status)
3498 for (i = 0; silc_ske_status_string[i]; i++)
3500 return silc_ske_status_string[i];
3505 /* Parses remote host's version string. */
3507 SilcBool silc_ske_parse_version(SilcSKE ske,
3508 SilcUInt32 *protocol_version,
3509 char **protocol_version_string,
3510 SilcUInt32 *software_version,
3511 char **software_version_string,
3512 char **vendor_version)
3514 return silc_parse_version_string(ske->remote_version,
3516 protocol_version_string,
3518 software_version_string,
3522 /* Get security properties */
3524 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3529 /* Get key material */
3531 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)