5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2014 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 return SILC_SKE_STATUS_BAD_VERSION;
246 /* Check for mandatory fields */
247 if (!rp->ke_grp_len) {
248 SILC_LOG_DEBUG(("KE group not defined in payload"));
249 return SILC_SKE_STATUS_BAD_PAYLOAD;
251 if (!rp->pkcs_alg_len) {
252 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
253 return SILC_SKE_STATUS_BAD_PAYLOAD;
255 if (!rp->enc_alg_len) {
256 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
257 return SILC_SKE_STATUS_BAD_PAYLOAD;
259 if (!rp->hash_alg_len) {
260 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
261 return SILC_SKE_STATUS_BAD_PAYLOAD;
263 if (!rp->hmac_alg_len) {
264 SILC_LOG_DEBUG(("HMAC not defined in payload"));
265 return SILC_SKE_STATUS_BAD_PAYLOAD;
268 /* Allocate security properties */
269 *prop = silc_calloc(1, sizeof(**prop));
271 return SILC_SKE_STATUS_OUT_OF_MEMORY;
273 /* Allocate our reply start payload */
274 payload = silc_calloc(1, sizeof(*payload));
277 return SILC_SKE_STATUS_OUT_OF_MEMORY;
280 /* Check version string */
281 ske->remote_version = silc_memdup(rp->version, rp->version_len);
282 status = silc_ske_check_version(ske);
283 if (status != SILC_SKE_STATUS_OK) {
284 ske->status = status;
288 /* Flags are returned unchanged. */
289 (*prop)->flags = payload->flags = rp->flags;
291 /* Take cookie, we must return it to sender unmodified. */
292 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
293 if (!payload->cookie) {
294 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
297 payload->cookie_len = SILC_SKE_COOKIE_LEN;
298 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
300 /* In case IV included flag and session port is set the first 16-bits of
301 cookie will include our session port. */
302 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
303 /* Take remote port */
304 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
307 SILC_PUT16_MSB(ske->session_port, payload->cookie);
310 /* Put our version to our reply */
311 payload->version = strdup(ske->version);
312 if (!payload->version) {
313 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
316 payload->version_len = strlen(ske->version);
318 /* Get supported Key Exchange groups */
319 cp = rp->ke_grp_list;
320 if (cp && strchr(cp, ',')) {
324 len = strcspn(cp, ",");
325 item = silc_calloc(len + 1, sizeof(char));
327 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
330 memcpy(item, cp, len);
332 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
334 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
335 SILC_LOG_DEBUG(("Found KE group `%s'", item));
337 payload->ke_grp_len = len;
338 payload->ke_grp_list = item;
352 if (!payload->ke_grp_len && !payload->ke_grp_list) {
353 SILC_LOG_DEBUG(("Could not find supported KE group"));
355 return SILC_SKE_STATUS_UNKNOWN_GROUP;
358 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
359 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
361 payload->ke_grp_len = rp->ke_grp_len;
362 payload->ke_grp_list = strdup(rp->ke_grp_list);
365 /* Save group to security properties */
366 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
367 if (status != SILC_SKE_STATUS_OK) {
369 return SILC_SKE_STATUS_UNKNOWN_GROUP;
372 /* Get supported PKCS algorithms */
373 cp = rp->pkcs_alg_list;
374 if (cp && strchr(cp, ',')) {
378 len = strcspn(cp, ",");
379 item = silc_calloc(len + 1, sizeof(char));
381 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
384 memcpy(item, cp, len);
386 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
388 if (silc_pkcs_find_algorithm(item, NULL)) {
389 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
391 payload->pkcs_alg_len = len;
392 payload->pkcs_alg_list = item;
406 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
407 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
408 silc_free(payload->ke_grp_list);
410 return SILC_SKE_STATUS_UNKNOWN_PKCS;
413 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
414 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
416 payload->pkcs_alg_len = rp->pkcs_alg_len;
417 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
420 /* Get supported encryption algorithms */
421 cp = rp->enc_alg_list;
422 if (cp && strchr(cp, ',')) {
426 len = strcspn(cp, ",");
427 item = silc_calloc(len + 1, sizeof(char));
429 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
432 memcpy(item, cp, len);
434 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
436 if (silc_cipher_is_supported(item) == TRUE) {
437 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
439 payload->enc_alg_len = len;
440 payload->enc_alg_list = item;
454 if (!payload->enc_alg_len && !payload->enc_alg_list) {
455 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
456 silc_free(payload->ke_grp_list);
457 silc_free(payload->pkcs_alg_list);
459 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
462 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
465 payload->enc_alg_len = rp->enc_alg_len;
466 payload->enc_alg_list = strdup(rp->enc_alg_list);
469 /* Save selected cipher to security properties */
470 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
471 silc_free(payload->ke_grp_list);
472 silc_free(payload->pkcs_alg_list);
474 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
477 /* Get supported hash algorithms */
478 cp = rp->hash_alg_list;
479 if (cp && strchr(cp, ',')) {
483 len = strcspn(cp, ",");
484 item = silc_calloc(len + 1, sizeof(char));
486 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
489 memcpy(item, cp, len);
491 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
493 if (silc_hash_is_supported(item) == TRUE) {
494 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
496 payload->hash_alg_len = len;
497 payload->hash_alg_list = item;
511 if (!payload->hash_alg_len && !payload->hash_alg_list) {
512 SILC_LOG_DEBUG(("Could not find supported hash alg"));
513 silc_free(payload->ke_grp_list);
514 silc_free(payload->pkcs_alg_list);
515 silc_free(payload->enc_alg_list);
517 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
520 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
523 payload->hash_alg_len = rp->hash_alg_len;
524 payload->hash_alg_list = strdup(rp->hash_alg_list);
527 /* Save selected hash algorithm to security properties */
528 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
529 silc_free(payload->ke_grp_list);
530 silc_free(payload->pkcs_alg_list);
531 silc_free(payload->enc_alg_list);
533 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
536 /* Get supported HMACs */
537 cp = rp->hmac_alg_list;
538 if (cp && strchr(cp, ',')) {
542 len = strcspn(cp, ",");
543 item = silc_calloc(len + 1, sizeof(char));
545 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
548 memcpy(item, cp, len);
550 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
552 if (silc_hmac_is_supported(item) == TRUE) {
553 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
555 payload->hmac_alg_len = len;
556 payload->hmac_alg_list = item;
570 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
571 SILC_LOG_DEBUG(("Could not find supported HMAC"));
572 silc_free(payload->ke_grp_list);
573 silc_free(payload->pkcs_alg_list);
574 silc_free(payload->enc_alg_list);
575 silc_free(payload->hash_alg_list);
577 return SILC_SKE_STATUS_UNKNOWN_HMAC;
580 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
583 payload->hmac_alg_len = rp->hmac_alg_len;
584 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
587 /* Save selected HMACc to security properties */
588 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
589 silc_free(payload->ke_grp_list);
590 silc_free(payload->pkcs_alg_list);
591 silc_free(payload->enc_alg_list);
592 silc_free(payload->hash_alg_list);
594 return SILC_SKE_STATUS_UNKNOWN_HMAC;
597 /* Get supported compression algorithms */
598 cp = rp->comp_alg_list;
599 if (cp && strchr(cp, ',')) {
603 len = strcspn(cp, ",");
604 item = silc_calloc(len + 1, sizeof(char));
606 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
609 memcpy(item, cp, len);
611 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
614 if (!strcmp(item, "none")) {
615 SILC_LOG_DEBUG(("Found Compression `%s'", item));
616 payload->comp_alg_len = len;
617 payload->comp_alg_list = item;
621 if (silc_hmac_is_supported(item) == TRUE) {
622 SILC_LOG_DEBUG(("Found Compression `%s'", item));
623 payload->comp_alg_len = len;
624 payload->comp_alg_list = item;
640 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
641 2 + payload->version_len +
642 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
643 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
644 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
646 /* Save our reply payload */
647 ske->start_payload = payload;
649 return SILC_SKE_STATUS_OK;
652 /* Creates random number such that 1 < rnd < n and at most length
653 of len bits. The rnd sent as argument must be initialized. */
655 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
659 SilcSKEStatus status = SILC_SKE_STATUS_OK;
660 unsigned char *string;
664 return SILC_SKE_STATUS_ERROR;
666 SILC_LOG_DEBUG(("Creating random number"));
670 /* Get the random number as string */
671 string = silc_rng_get_rn_data(ske->rng, l);
673 return SILC_SKE_STATUS_OUT_OF_MEMORY;
675 /* Decode the string into a MP integer */
676 silc_mp_bin2mp(string, l, rnd);
677 silc_mp_mod_2exp(rnd, rnd, len);
680 if (silc_mp_cmp_ui(rnd, 1) < 0)
681 status = SILC_SKE_STATUS_ERROR;
682 if (silc_mp_cmp(rnd, n) >= 0)
683 status = SILC_SKE_STATUS_ERROR;
685 memset(string, 'F', l);
691 /* Creates a hash value HASH as defined in the SKE protocol. If the
692 `initiator' is TRUE then this function is used to create the HASH_i
693 hash value defined in the protocol. If it is FALSE then this is used
694 to create the HASH value defined by the protocol. */
696 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
697 unsigned char *return_hash,
698 SilcUInt32 *return_hash_len,
701 SilcSKEStatus status = SILC_SKE_STATUS_OK;
703 unsigned char *e, *f, *KEY, *s_data;
704 SilcUInt32 e_len, f_len, KEY_len, s_len;
707 SILC_LOG_DEBUG(("Start"));
709 if (initiator == FALSE) {
710 s_data = (ske->start_payload_copy ?
711 silc_buffer_data(ske->start_payload_copy) : NULL);
712 s_len = (ske->start_payload_copy ?
713 silc_buffer_len(ske->start_payload_copy) : 0);
714 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
716 return SILC_SKE_STATUS_OUT_OF_MEMORY;
717 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
719 return SILC_SKE_STATUS_OUT_OF_MEMORY;
720 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
722 return SILC_SKE_STATUS_OUT_OF_MEMORY;
724 /* Format the buffer used to compute the hash value */
725 buf = silc_buffer_alloc_size(s_len +
726 ske->ke2_payload->pk_len +
727 ske->ke1_payload->pk_len +
728 e_len + f_len + KEY_len);
730 return SILC_SKE_STATUS_OUT_OF_MEMORY;
732 /* Initiator is not required to send its public key */
733 if (!ske->ke1_payload->pk_data) {
735 silc_buffer_format(buf,
736 SILC_STR_DATA(s_data, s_len),
737 SILC_STR_DATA(ske->ke2_payload->pk_data,
738 ske->ke2_payload->pk_len),
739 SILC_STR_DATA(e, e_len),
740 SILC_STR_DATA(f, f_len),
741 SILC_STR_DATA(KEY, KEY_len),
745 silc_buffer_format(buf,
746 SILC_STR_DATA(s_data, s_len),
747 SILC_STR_DATA(ske->ke2_payload->pk_data,
748 ske->ke2_payload->pk_len),
749 SILC_STR_DATA(ske->ke1_payload->pk_data,
750 ske->ke1_payload->pk_len),
751 SILC_STR_DATA(e, e_len),
752 SILC_STR_DATA(f, f_len),
753 SILC_STR_DATA(KEY, KEY_len),
757 silc_buffer_free(buf);
760 memset(KEY, 0, KEY_len);
764 return SILC_SKE_STATUS_ERROR;
769 memset(KEY, 0, KEY_len);
774 s_data = (ske->start_payload_copy ?
775 silc_buffer_data(ske->start_payload_copy) : NULL);
776 s_len = (ske->start_payload_copy ?
777 silc_buffer_len(ske->start_payload_copy) : 0);
778 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
780 return SILC_SKE_STATUS_OUT_OF_MEMORY;
782 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
784 return SILC_SKE_STATUS_OUT_OF_MEMORY;
786 /* Format the buffer used to compute the hash value */
788 silc_buffer_format(buf,
789 SILC_STR_DATA(s_data, s_len),
790 SILC_STR_DATA(ske->ke1_payload->pk_data,
791 ske->ke1_payload->pk_len),
792 SILC_STR_DATA(e, e_len),
795 silc_buffer_free(buf);
798 return SILC_SKE_STATUS_ERROR;
801 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
808 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
810 *return_hash_len = silc_hash_len(ske->prop->hash);
812 if (initiator == FALSE) {
813 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
815 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
818 silc_buffer_free(buf);
823 /* Generate rekey material */
825 static SilcSKERekeyMaterial
826 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
828 SilcSKERekeyMaterial rekey;
834 /* Create rekey material */
835 rekey = silc_calloc(1, sizeof(*rekey));
840 if (ske->prop->group)
841 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
842 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
843 hash = silc_hash_get_name(ske->prop->hash);
844 rekey->hash = silc_memdup(hash, strlen(hash));
849 if (rekey->pfs == FALSE) {
850 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
851 keymat->enc_key_len / 8);
852 if (!rekey->send_enc_key) {
856 rekey->enc_key_len = keymat->enc_key_len;
862 /* Assembles security properties */
864 static SilcSKEStartPayload
865 silc_ske_assemble_security_properties(SilcSKE ske,
866 SilcSKESecurityPropertyFlag flags,
869 SilcSKEStartPayload rp;
872 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
874 rp = silc_calloc(1, sizeof(*rp));
879 rp->flags = (unsigned char)flags;
881 /* Set random cookie */
882 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
887 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
888 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
889 rp->cookie_len = SILC_SKE_COOKIE_LEN;
891 /* In case IV included flag and session port is set the first 16-bits of
892 cookie will include our session port. */
893 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
894 SILC_PUT16_MSB(ske->session_port, rp->cookie);
897 rp->version = strdup(version);
899 rp->version_len = strlen(version);
901 /* Get supported Key Exhange groups */
902 rp->ke_grp_list = silc_ske_get_supported_groups();
904 rp->ke_grp_len = strlen(rp->ke_grp_list);
906 /* Get supported PKCS algorithms */
907 rp->pkcs_alg_list = silc_pkcs_get_supported();
908 if (rp->pkcs_alg_list)
909 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
911 /* Get supported encryption algorithms */
912 rp->enc_alg_list = silc_cipher_get_supported();
913 if (rp->enc_alg_list)
914 rp->enc_alg_len = strlen(rp->enc_alg_list);
916 /* Get supported hash algorithms */
917 rp->hash_alg_list = silc_hash_get_supported();
918 if (rp->hash_alg_list)
919 rp->hash_alg_len = strlen(rp->hash_alg_list);
921 /* Get supported HMACs */
922 rp->hmac_alg_list = silc_hmac_get_supported();
923 if (rp->hmac_alg_list)
924 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
927 /* Get supported compression algorithms */
928 rp->comp_alg_list = strdup("none");
929 rp->comp_alg_len = strlen("none");
931 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
932 2 + rp->version_len +
933 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
934 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
935 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
940 /* Packet retransmission callback. */
942 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
944 SilcSKE ske = context;
946 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
948 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
949 ske->retry_count = 0;
950 ske->retry_timer = SILC_SKE_RETRY_MIN;
951 silc_free(ske->retrans.data);
952 ske->retrans.data = NULL;
953 ske->status = SILC_SKE_STATUS_TIMEOUT;
954 silc_ske_notify_failure(ske);
955 silc_fsm_continue_sync(&ske->fsm);
959 SILC_LOG_DEBUG(("Retransmitting packet"));
960 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
961 ske->retrans.data, ske->retrans.data_len);
964 /* Install retransmission timer */
966 static void silc_ske_install_retransmission(SilcSKE ske)
968 if (!silc_packet_stream_is_udp(ske->stream))
971 if (ske->retrans.data) {
972 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
974 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
975 ske, ske->retry_timer, 0);
977 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
978 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
981 /* Sends SILC packet. Handles retransmissions with UDP streams. */
983 static SilcBool silc_ske_packet_send(SilcSKE ske,
985 SilcPacketFlags flags,
986 const unsigned char *data,
991 /* Send the packet */
992 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
994 if (silc_packet_stream_is_udp(ske->stream) &&
995 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
996 silc_free(ske->retrans.data);
997 ske->retrans.type = type;
998 ske->retrans.flags = flags;
999 ske->retrans.data = silc_memdup(data, data_len);
1000 if (ske->retrans.data) {
1001 ske->retrans.data_len = data_len;
1002 silc_ske_install_retransmission(ske);
1009 /* Calls completion callback. Completion is called always in this function
1010 and must not be called anywhere else. */
1012 static void silc_ske_completion(SilcSKE ske)
1014 /* Call the completion callback */
1015 if (!ske->aborted && ske->callbacks->completed) {
1016 if (ske->status != SILC_SKE_STATUS_OK)
1017 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1018 ske->callbacks->context);
1020 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1021 ske->rekey, ske->callbacks->context);
1025 /* SKE FSM destructor. */
1027 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
1028 void *destructor_context)
1030 SilcSKE ske = fsm_context;
1034 /* Key exchange timeout task callback */
1036 SILC_TASK_CALLBACK(silc_ske_timeout)
1038 SilcSKE ske = context;
1040 SILC_LOG_DEBUG(("Timeout"));
1043 ske->status = SILC_SKE_STATUS_TIMEOUT;
1044 silc_ske_notify_failure(ske);
1046 silc_fsm_continue_sync(&ske->fsm);
1049 /******************************* Protocol API *******************************/
1051 /* Allocates new SKE object. */
1053 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1054 SilcSKR repository, SilcPublicKey public_key,
1055 SilcPrivateKey private_key, void *context)
1059 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1061 if (!rng || !schedule)
1065 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1069 ske = silc_calloc(1, sizeof(*ske));
1072 ske->status = SILC_SKE_STATUS_OK;
1074 ske->repository = repository;
1075 ske->user_data = context;
1076 ske->schedule = schedule;
1077 ske->public_key = public_key;
1078 ske->private_key = private_key;
1079 ske->retry_timer = SILC_SKE_RETRY_MIN;
1085 /* Free's SKE object. */
1087 void silc_ske_free(SilcSKE ske)
1092 SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu",
1093 ske, ske->aborted, ske->refcnt));
1097 * If already aborted, destroy the session immediately. Only do the
1098 * notification work if we have not already though, as doing so twice
1099 * results in memory corruption. We may have silc_ske_free called
1100 * twice, once when the abort is requested, and then again when the
1101 * FSM finish routine is called. We have to be prepared to handle
1105 ske->status = SILC_SKE_STATUS_ERROR;
1107 silc_ske_notify_failure(ske);
1109 if (silc_fsm_is_started(&ske->fsm))
1110 silc_fsm_continue_sync(&ske->fsm);
1112 SILC_LOG_DEBUG(("Not continuing FSM as it's finished for SKE %p", ske));
1116 if (ske->refcnt > 0)
1119 /* Free start payload */
1120 if (ske->start_payload)
1121 silc_ske_payload_start_free(ske->start_payload);
1123 /* Free KE payload */
1124 if (ske->ke1_payload)
1125 silc_ske_payload_ke_free(ske->ke1_payload);
1126 if (ske->ke2_payload)
1127 silc_ske_payload_ke_free(ske->ke2_payload);
1128 silc_free(ske->remote_version);
1132 if (ske->prop->group)
1133 silc_ske_group_free(ske->prop->group);
1134 if (ske->prop->cipher)
1135 silc_cipher_free(ske->prop->cipher);
1136 if (ske->prop->hash)
1137 silc_hash_free(ske->prop->hash);
1138 if (ske->prop->hmac)
1139 silc_hmac_free(ske->prop->hmac);
1140 if (ske->prop->public_key)
1141 silc_pkcs_public_key_free(ske->prop->public_key);
1142 silc_free(ske->prop);
1145 silc_ske_free_key_material(ske->keymat);
1146 if (ske->start_payload_copy)
1147 silc_buffer_free(ske->start_payload_copy);
1149 silc_mp_uninit(ske->x);
1153 silc_mp_uninit(ske->KEY);
1154 silc_free(ske->KEY);
1156 silc_free(ske->retrans.data);
1157 silc_free(ske->hash);
1158 silc_free(ske->callbacks);
1160 memset(ske, 0xdd, sizeof(*ske));
1164 /* Return user context */
1166 void *silc_ske_get_context(SilcSKE ske)
1168 return ske->user_data;
1171 /* Sets protocol callbacks */
1173 void silc_ske_set_callbacks(SilcSKE ske,
1174 SilcSKEVerifyCb verify_key,
1175 SilcSKECompletionCb completed,
1179 silc_free(ske->callbacks);
1180 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1181 if (!ske->callbacks)
1183 ske->callbacks->verify_key = verify_key;
1184 ske->callbacks->completed = completed;
1185 ske->callbacks->context = context;
1189 /******************************** Initiator *********************************/
1191 /* Start protocol. Send our proposal */
1193 SILC_FSM_STATE(silc_ske_st_initiator_start)
1195 SilcSKE ske = fsm_context;
1196 SilcBuffer payload_buf;
1199 SILC_LOG_DEBUG(("Start"));
1203 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1204 return SILC_FSM_CONTINUE;
1207 /* Encode the payload */
1208 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1210 if (status != SILC_SKE_STATUS_OK) {
1211 /** Error encoding Start Payload */
1212 ske->status = status;
1213 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1214 return SILC_FSM_CONTINUE;
1217 /* Save the the payload buffer for future use. It is later used to
1218 compute the HASH value. */
1219 ske->start_payload_copy = payload_buf;
1221 /* Send the packet. */
1222 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1223 silc_buffer_data(payload_buf),
1224 silc_buffer_len(payload_buf))) {
1225 /** Error sending packet */
1226 SILC_LOG_DEBUG(("Error sending packet"));
1227 ske->status = SILC_SKE_STATUS_ERROR;
1228 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1229 return SILC_FSM_CONTINUE;
1232 /* Add key exchange timeout */
1233 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1234 ske, ske->timeout, 0);
1236 /** Wait for responder proposal */
1237 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1238 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1239 return SILC_FSM_WAIT;
1242 /* Phase-1. Receives responder's proposal */
1244 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1246 SilcSKE ske = fsm_context;
1247 SilcSKEStatus status;
1248 SilcSKEStartPayload payload;
1249 SilcSKESecurityProperties prop;
1250 SilcSKEDiffieHellmanGroup group = NULL;
1251 SilcBuffer packet_buf = &ske->packet->buffer;
1252 SilcUInt16 remote_port = 0;
1256 SILC_LOG_DEBUG(("Start"));
1258 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1259 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1260 silc_ske_install_retransmission(ske);
1261 silc_packet_free(ske->packet);
1263 return SILC_FSM_WAIT;
1266 /* Decode the payload */
1267 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1268 if (status != SILC_SKE_STATUS_OK) {
1269 /** Error decoding Start Payload */
1270 silc_packet_free(ske->packet);
1272 ske->status = status;
1273 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1274 return SILC_FSM_CONTINUE;
1277 /* Get remote ID and set it to stream */
1278 if (ske->packet->src_id_len) {
1279 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1280 ske->packet->src_id_type,
1281 (ske->packet->src_id_type == SILC_ID_SERVER ?
1282 (void *)&id.u.server_id : (void *)&id.u.client_id),
1283 (ske->packet->src_id_type == SILC_ID_SERVER ?
1284 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1285 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1286 (ske->packet->src_id_type == SILC_ID_SERVER ?
1287 (void *)&id.u.server_id : (void *)&id.u.client_id));
1290 silc_packet_free(ske->packet);
1293 /* Check that the cookie is returned unmodified. In case IV included
1294 flag and session port has been set, the first two bytes of cookie
1295 are the session port and we ignore them in this check. */
1296 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1297 /* Take remote port */
1298 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1301 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1302 SILC_SKE_COOKIE_LEN - coff)) {
1303 /** Invalid cookie */
1304 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1305 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1306 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1307 return SILC_FSM_CONTINUE;
1310 /* Check version string */
1311 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1312 status = silc_ske_check_version(ske);
1313 if (status != SILC_SKE_STATUS_OK) {
1314 /** Version mismatch */
1315 ske->status = status;
1316 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1317 return SILC_FSM_CONTINUE;
1320 /* Free our KE Start Payload context, we don't need it anymore. */
1321 silc_ske_payload_start_free(ske->start_payload);
1322 ske->start_payload = NULL;
1324 /* Take the selected security properties into use while doing
1325 the key exchange. This is used only while doing the key
1327 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1330 prop->flags = payload->flags;
1331 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1332 if (status != SILC_SKE_STATUS_OK)
1335 prop->group = group;
1336 prop->remote_port = remote_port;
1338 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1339 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1342 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1343 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1346 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1347 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1350 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1351 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1355 /* Save remote's KE Start Payload */
1356 ske->start_payload = payload;
1358 /** Send KE Payload */
1359 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1360 return SILC_FSM_CONTINUE;
1364 silc_ske_payload_start_free(payload);
1366 silc_ske_group_free(group);
1369 silc_cipher_free(prop->cipher);
1371 silc_hash_free(prop->hash);
1373 silc_hmac_free(prop->hmac);
1378 if (status == SILC_SKE_STATUS_OK)
1379 status = SILC_SKE_STATUS_ERROR;
1382 ske->status = status;
1383 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1384 return SILC_FSM_CONTINUE;
1387 /* Phase-2. Send KE payload */
1389 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1391 SilcSKE ske = fsm_context;
1392 SilcSKEStatus status;
1393 SilcBuffer payload_buf;
1395 SilcSKEKEPayload payload;
1398 SILC_LOG_DEBUG(("Start"));
1400 /* Create the random number x, 1 < x < q. */
1401 x = silc_calloc(1, sizeof(*x));
1403 /** Out of memory */
1404 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1405 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1406 return SILC_FSM_CONTINUE;
1410 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1411 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1413 if (status != SILC_SKE_STATUS_OK) {
1414 /** Error generating random number */
1417 ske->status = status;
1418 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1419 return SILC_FSM_CONTINUE;
1422 /* Encode the result to Key Exchange Payload. */
1424 payload = silc_calloc(1, sizeof(*payload));
1426 /** Out of memory */
1429 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1430 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1431 return SILC_FSM_CONTINUE;
1433 ske->ke1_payload = payload;
1435 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1437 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1438 silc_mp_init(&payload->x);
1439 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1440 &ske->prop->group->group);
1442 /* Get public key */
1443 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1444 if (!payload->pk_data) {
1445 /** Error encoding public key */
1448 silc_mp_uninit(&payload->x);
1450 ske->ke1_payload = NULL;
1451 ske->status = SILC_SKE_STATUS_ERROR;
1452 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1453 return SILC_FSM_CONTINUE;
1455 payload->pk_len = pk_len;
1456 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1458 /* Compute signature data if we are doing mutual authentication */
1459 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1460 unsigned char hash[SILC_HASH_MAXLEN], sign[65536 + 1];
1461 SilcUInt32 hash_len, sign_len;
1463 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1464 SILC_LOG_DEBUG(("Computing HASH_i value"));
1466 /* Compute the hash value */
1467 memset(hash, 0, sizeof(hash));
1468 if (silc_ske_make_hash(ske, hash, &hash_len, TRUE) != SILC_SKE_STATUS_OK)
1470 /** Error computing hash */
1473 silc_mp_uninit(&payload->x);
1474 silc_free(payload->pk_data);
1476 ske->ke1_payload = NULL;
1477 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1478 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1479 return SILC_FSM_CONTINUE;
1482 SILC_LOG_DEBUG(("Signing HASH_i value"));
1484 /* Sign the hash value */
1485 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1486 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1487 /** Error computing signature */
1490 silc_mp_uninit(&payload->x);
1491 silc_free(payload->pk_data);
1493 ske->ke1_payload = NULL;
1494 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1495 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1496 return SILC_FSM_CONTINUE;
1498 payload->sign_data = silc_memdup(sign, sign_len);
1499 if (payload->sign_data)
1500 payload->sign_len = sign_len;
1501 memset(sign, 0, sizeof(sign));
1504 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1505 if (status != SILC_SKE_STATUS_OK) {
1506 /** Error encoding KE payload */
1509 silc_mp_uninit(&payload->x);
1510 silc_free(payload->pk_data);
1511 silc_free(payload->sign_data);
1513 ske->ke1_payload = NULL;
1514 ske->status = status;
1515 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1516 return SILC_FSM_CONTINUE;
1521 /* Check for backwards compatibility */
1523 /* Send the packet. */
1524 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1525 silc_buffer_data(payload_buf),
1526 silc_buffer_len(payload_buf))) {
1527 /** Error sending packet */
1528 SILC_LOG_DEBUG(("Error sending packet"));
1529 ske->status = SILC_SKE_STATUS_ERROR;
1530 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1531 return SILC_FSM_CONTINUE;
1534 silc_buffer_free(payload_buf);
1536 /** Waiting responder's KE payload */
1537 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1538 return SILC_FSM_WAIT;
1541 /* Phase-3. Process responder's KE payload */
1543 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1545 SilcSKE ske = fsm_context;
1546 SilcSKEStatus status;
1547 SilcSKEKEPayload payload;
1549 SilcBuffer packet_buf = &ske->packet->buffer;
1551 SILC_LOG_DEBUG(("Start"));
1553 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1554 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1555 silc_ske_install_retransmission(ske);
1556 silc_packet_free(ske->packet);
1558 return SILC_FSM_WAIT;
1561 /* Decode the payload */
1562 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1563 if (status != SILC_SKE_STATUS_OK) {
1564 /** Error decoding KE payload */
1565 silc_packet_free(ske->packet);
1567 ske->status = status;
1568 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1569 return SILC_FSM_CONTINUE;
1571 silc_packet_free(ske->packet);
1573 ske->ke2_payload = payload;
1575 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1576 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1577 "even though we require it"));
1578 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1582 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1584 /* Compute the shared secret key */
1585 KEY = silc_calloc(1, sizeof(*KEY));
1587 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1591 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1594 /* Decode the remote's public key */
1595 if (payload->pk_data &&
1596 !silc_pkcs_public_key_alloc(payload->pk_type,
1597 payload->pk_data, payload->pk_len,
1598 &ske->prop->public_key)) {
1599 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1600 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1604 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1606 SILC_LOG_DEBUG(("Verifying public key"));
1608 /** Waiting public key verification */
1609 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1611 /* If repository is provided, verify the key from there. */
1612 if (ske->repository) {
1615 find = silc_skr_find_alloc();
1617 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1620 silc_skr_find_set_pkcs_type(find,
1621 silc_pkcs_get_type(ske->prop->public_key));
1622 silc_skr_find_set_public_key(find, ske->prop->public_key);
1623 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1625 /* Find key from repository */
1626 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1627 find, silc_ske_skr_callback, ske));
1629 /* Verify from application */
1630 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1631 ske->callbacks->context,
1632 silc_ske_pk_verified, NULL));
1637 /** Process key material */
1638 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1639 return SILC_FSM_CONTINUE;
1642 silc_ske_payload_ke_free(payload);
1643 ske->ke2_payload = NULL;
1645 silc_mp_uninit(ske->KEY);
1646 silc_free(ske->KEY);
1649 if (status == SILC_SKE_STATUS_OK)
1650 return SILC_SKE_STATUS_ERROR;
1653 ske->status = status;
1654 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1655 return SILC_FSM_CONTINUE;
1658 /* Process key material */
1660 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1662 SilcSKE ske = fsm_context;
1663 SilcSKEStatus status;
1664 SilcSKEKEPayload payload;
1665 unsigned char hash[SILC_HASH_MAXLEN];
1666 SilcUInt32 hash_len;
1667 int key_len, block_len;
1671 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1672 return SILC_FSM_CONTINUE;
1675 /* Check result of public key verification */
1676 if (ske->status != SILC_SKE_STATUS_OK) {
1677 /** Public key not verified */
1678 SILC_LOG_DEBUG(("Public key verification failed"));
1679 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1680 return SILC_FSM_CONTINUE;
1683 payload = ske->ke2_payload;
1685 /* Compute the HASH value */
1686 SILC_LOG_DEBUG(("Computing HASH value"));
1687 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1688 if (status != SILC_SKE_STATUS_OK)
1690 ske->hash = silc_memdup(hash, hash_len);
1692 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1695 ske->hash_len = hash_len;
1697 if (ske->prop->public_key) {
1698 SILC_LOG_DEBUG(("Public key is authentic"));
1699 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1701 /* Verify signature */
1702 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1703 payload->sign_len, hash, hash_len, NULL)) {
1704 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1705 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1709 SILC_LOG_DEBUG(("Signature is Ok"));
1710 memset(hash, 'F', hash_len);
1713 ske->status = SILC_SKE_STATUS_OK;
1715 /* In case we are doing rekey move to finish it. */
1718 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1719 return SILC_FSM_CONTINUE;
1722 /* Process key material */
1723 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1724 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1725 hash_len = silc_hash_len(ske->prop->hash);
1726 ske->keymat = silc_ske_process_key_material(ske, block_len,
1730 SILC_LOG_ERROR(("Error processing key material"));
1731 status = SILC_SKE_STATUS_ERROR;
1735 /* Send SUCCESS packet */
1736 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1737 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1738 /** Error sending packet */
1739 SILC_LOG_DEBUG(("Error sending packet"));
1740 ske->status = SILC_SKE_STATUS_ERROR;
1741 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1742 return SILC_FSM_CONTINUE;
1745 /** Waiting completion */
1746 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1747 return SILC_FSM_WAIT;
1750 memset(hash, 'F', sizeof(hash));
1751 silc_ske_payload_ke_free(payload);
1752 ske->ke2_payload = NULL;
1754 silc_mp_uninit(ske->KEY);
1755 silc_free(ske->KEY);
1759 memset(ske->hash, 'F', hash_len);
1760 silc_free(ske->hash);
1764 if (status == SILC_SKE_STATUS_OK)
1765 status = SILC_SKE_STATUS_ERROR;
1768 ske->status = status;
1769 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1770 return SILC_FSM_CONTINUE;
1773 /* Protocol completed */
1775 SILC_FSM_STATE(silc_ske_st_initiator_end)
1777 SilcSKE ske = fsm_context;
1779 SILC_LOG_DEBUG(("Start"));
1781 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1782 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1783 silc_ske_install_retransmission(ske);
1784 silc_packet_free(ske->packet);
1786 return SILC_FSM_WAIT;
1789 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1791 silc_packet_free(ske->packet);
1793 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1794 silc_schedule_task_del_by_context(ske->schedule, ske);
1796 /* Call completion */
1797 silc_ske_completion(ske);
1799 return SILC_FSM_FINISH;
1802 /* Aborted by application */
1804 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1806 SilcSKE ske = fsm_context;
1807 unsigned char data[4];
1809 SILC_LOG_DEBUG(("Aborted by caller"));
1811 /* Send FAILURE packet */
1812 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1813 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1815 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1816 silc_schedule_task_del_by_context(ske->schedule, ske);
1818 /* Call completion */
1819 silc_ske_completion(ske);
1821 return SILC_FSM_FINISH;
1824 /* Error occurred. Send error to remote host */
1826 SILC_FSM_STATE(silc_ske_st_initiator_error)
1828 SilcSKE ske = fsm_context;
1829 SilcSKEStatus status;
1830 unsigned char data[4];
1832 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1833 silc_ske_map_status(ske->status), ske->status));
1835 status = ske->status;
1836 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1837 status = SILC_SKE_STATUS_ERROR;
1839 /* Send FAILURE packet */
1840 SILC_PUT32_MSB((SilcUInt32)status, data);
1841 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1843 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1844 silc_schedule_task_del_by_context(ske->schedule, ske);
1846 /* Call completion */
1847 silc_ske_completion(ske);
1849 return SILC_FSM_FINISH;
1852 /* Failure received from remote */
1854 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1856 SilcSKE ske = fsm_context;
1857 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1859 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1860 SILC_GET32_MSB(error, ske->packet->buffer.data);
1861 silc_packet_free(ske->packet);
1864 ske->status = error;
1866 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1867 silc_ske_map_status(ske->status), ske->status));
1869 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1870 silc_schedule_task_del_by_context(ske->schedule, ske);
1872 /* Call completion */
1873 silc_ske_completion(ske);
1875 return SILC_FSM_FINISH;
1878 /* Starts the protocol as initiator */
1880 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1881 SilcPacketStream stream,
1882 SilcSKEParams params,
1883 SilcSKEStartPayload start_payload)
1885 SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; "
1886 "start_payload=%p", ske, stream, params, start_payload));
1888 if (!ske || !stream || !params || !params->version)
1891 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1894 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1897 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1898 ske->session_port = params->session_port;
1900 /* Generate security properties if not provided */
1901 if (!start_payload) {
1902 start_payload = silc_ske_assemble_security_properties(ske,
1909 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1910 ske->start_payload = start_payload;
1911 ske->version = params->version;
1914 /* Link to packet stream to get key exchange packets */
1915 ske->stream = stream;
1916 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1917 SILC_PACKET_KEY_EXCHANGE,
1918 SILC_PACKET_KEY_EXCHANGE_2,
1919 SILC_PACKET_SUCCESS,
1920 SILC_PACKET_FAILURE, -1);
1922 /* Start SKE as initiator */
1923 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1928 /******************************** Responder *********************************/
1930 /* Start protocol as responder. Wait initiator's start payload */
1932 SILC_FSM_STATE(silc_ske_st_responder_start)
1934 SilcSKE ske = fsm_context;
1936 SILC_LOG_DEBUG(("Start"));
1940 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1941 return SILC_FSM_CONTINUE;
1944 /* Add key exchange timeout */
1945 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1946 ske, ske->timeout, 0);
1948 /** Wait for initiator */
1949 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1950 return SILC_FSM_WAIT;
1953 /* Decode initiator's start payload. Select the security properties from
1954 the initiator's start payload and send our reply start payload back. */
1956 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1958 SilcSKE ske = fsm_context;
1959 SilcSKEStatus status;
1960 SilcSKEStartPayload remote_payload = NULL;
1961 SilcBuffer packet_buf = &ske->packet->buffer;
1964 SILC_LOG_DEBUG(("Start"));
1966 /* Decode the payload */
1967 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1968 if (status != SILC_SKE_STATUS_OK) {
1969 /** Error decoding Start Payload */
1970 silc_packet_free(ske->packet);
1972 ske->status = status;
1973 silc_fsm_next(fsm, silc_ske_st_responder_error);
1974 return SILC_FSM_CONTINUE;
1977 /* Get remote ID and set it to stream */
1978 if (ske->packet->src_id_len) {
1979 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1980 ske->packet->src_id_type,
1981 (ske->packet->src_id_type == SILC_ID_SERVER ?
1982 (void *)&id.u.server_id : (void *)&id.u.client_id),
1983 (ske->packet->src_id_type == SILC_ID_SERVER ?
1984 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1985 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1986 (ske->packet->src_id_type == SILC_ID_SERVER ?
1987 (void *)&id.u.server_id : (void *)&id.u.client_id));
1990 /* Take a copy of the payload buffer for future use. It is used to
1991 compute the HASH value. */
1992 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1993 if (!ske->start_payload_copy) {
1994 silc_packet_free(ske->packet);
1996 ske->status = status;
1997 silc_fsm_next(fsm, silc_ske_st_responder_error);
1998 return SILC_FSM_CONTINUE;
2001 silc_packet_free(ske->packet);
2004 /* Force the mutual authentication flag if we want to do it. */
2005 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2006 SILC_LOG_DEBUG(("Force mutual authentication"));
2007 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
2010 /* Force PFS flag if we require it */
2011 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
2012 SILC_LOG_DEBUG(("Force PFS"));
2013 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
2016 /* Disable IV Included flag if requested */
2017 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
2018 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
2019 SILC_LOG_DEBUG(("We do not support IV Included flag"));
2020 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
2023 /* Check and select security properties */
2024 status = silc_ske_select_security_properties(ske, remote_payload,
2026 if (status != SILC_SKE_STATUS_OK) {
2027 /** Error selecting proposal */
2028 silc_ske_payload_start_free(remote_payload);
2029 ske->status = status;
2030 silc_fsm_next(fsm, silc_ske_st_responder_error);
2031 return SILC_FSM_CONTINUE;
2034 silc_ske_payload_start_free(remote_payload);
2036 /* Encode our reply payload to send the selected security properties */
2037 status = silc_ske_payload_start_encode(ske, ske->start_payload,
2039 if (status != SILC_SKE_STATUS_OK)
2042 /* Send the packet. */
2043 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
2044 silc_buffer_data(packet_buf),
2045 silc_buffer_len(packet_buf)))
2048 silc_buffer_free(packet_buf);
2050 /** Waiting initiator's KE payload */
2051 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2052 return SILC_FSM_WAIT;
2055 if (ske->prop->group)
2056 silc_ske_group_free(ske->prop->group);
2057 if (ske->prop->cipher)
2058 silc_cipher_free(ske->prop->cipher);
2059 if (ske->prop->hash)
2060 silc_hash_free(ske->prop->hash);
2061 if (ske->prop->hmac)
2062 silc_hmac_free(ske->prop->hmac);
2063 silc_free(ske->prop);
2066 if (status == SILC_SKE_STATUS_OK)
2067 status = SILC_SKE_STATUS_ERROR;
2070 ske->status = status;
2071 silc_fsm_next(fsm, silc_ske_st_responder_error);
2072 return SILC_FSM_CONTINUE;
2075 /* Phase-2. Decode initiator's KE payload */
2077 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2079 SilcSKE ske = fsm_context;
2080 SilcSKEStatus status;
2081 SilcSKEKEPayload recv_payload;
2082 SilcBuffer packet_buf = &ske->packet->buffer;
2084 SILC_LOG_DEBUG(("Start"));
2086 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2087 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2088 silc_ske_install_retransmission(ske);
2089 silc_packet_free(ske->packet);
2091 return SILC_FSM_WAIT;
2094 /* Decode Key Exchange Payload */
2095 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2096 if (status != SILC_SKE_STATUS_OK) {
2097 /** Error decoding KE payload */
2098 silc_packet_free(ske->packet);
2100 ske->status = status;
2101 silc_fsm_next(fsm, silc_ske_st_responder_error);
2102 return SILC_FSM_CONTINUE;
2105 ske->ke1_payload = recv_payload;
2107 silc_packet_free(ske->packet);
2110 /* Verify public key, except in rekey, when it is not sent */
2112 if (!recv_payload->pk_data) {
2113 /** Public key not provided */
2114 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2115 "certificate), even though we require it"));
2116 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2117 silc_fsm_next(fsm, silc_ske_st_responder_error);
2118 return SILC_FSM_CONTINUE;
2121 /* Decode the remote's public key */
2122 if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2123 recv_payload->pk_data,
2124 recv_payload->pk_len,
2125 &ske->prop->public_key)) {
2126 /** Error decoding public key */
2127 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2128 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2129 silc_fsm_next(fsm, silc_ske_st_responder_error);
2130 return SILC_FSM_CONTINUE;
2133 SILC_LOG_DEBUG(("Verifying public key"));
2135 /** Waiting public key verification */
2136 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2138 /* If repository is provided, verify the key from there. */
2139 if (ske->repository) {
2142 find = silc_skr_find_alloc();
2144 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2145 silc_fsm_next(fsm, silc_ske_st_responder_error);
2146 return SILC_FSM_CONTINUE;
2148 silc_skr_find_set_pkcs_type(find,
2149 silc_pkcs_get_type(ske->prop->public_key));
2150 silc_skr_find_set_public_key(find, ske->prop->public_key);
2151 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2153 /* Find key from repository */
2154 SILC_FSM_CALL(silc_skr_find(ske->repository,
2155 silc_fsm_get_schedule(fsm), find,
2156 silc_ske_skr_callback, ske));
2158 /* Verify from application */
2159 if (ske->callbacks->verify_key)
2160 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2161 ske->callbacks->context,
2162 silc_ske_pk_verified, NULL));
2166 /** Generate KE2 payload */
2167 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2168 return SILC_FSM_CONTINUE;
2171 /* Phase-4. Generate KE2 payload */
2173 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2175 SilcSKE ske = fsm_context;
2176 SilcSKEStatus status;
2177 SilcSKEKEPayload recv_payload, send_payload = NULL;
2178 SilcMPInt *x = NULL, *KEY;
2182 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2183 return SILC_FSM_CONTINUE;
2186 /* Check result of public key verification */
2187 if (ske->status != SILC_SKE_STATUS_OK) {
2188 /** Public key not verified */
2189 SILC_LOG_DEBUG(("Public key verification failed"));
2193 recv_payload = ske->ke1_payload;
2195 /* The public key verification was performed only if the Mutual
2196 Authentication flag is set. */
2197 if (ske->start_payload &&
2198 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2199 unsigned char hash[SILC_HASH_MAXLEN];
2200 SilcUInt32 hash_len;
2202 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2204 /* Compute the hash value */
2205 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2206 if (status != SILC_SKE_STATUS_OK) {
2207 /** Error computing hash */
2208 SILC_LOG_DEBUG(("Error computing hash"));
2209 ske->status = status;
2213 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2215 /* Verify signature */
2216 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2217 recv_payload->sign_len, hash, hash_len, NULL)) {
2218 /** Incorrect signature */
2219 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2220 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2224 SILC_LOG_DEBUG(("Signature is Ok"));
2226 memset(hash, 'F', hash_len);
2229 /* Create the random number x, 1 < x < q. */
2230 x = silc_calloc(1, sizeof(*x));
2232 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2237 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2238 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2240 if (status != SILC_SKE_STATUS_OK) {
2241 /** Error generating random number */
2242 ske->status = status;
2246 /* Save the results for later processing */
2247 send_payload = silc_calloc(1, sizeof(*send_payload));
2248 if (!send_payload) {
2249 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2253 ske->ke2_payload = send_payload;
2255 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2257 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2258 silc_mp_init(&send_payload->x);
2259 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2260 &ske->prop->group->group);
2262 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2264 /* Compute the shared secret key */
2265 KEY = silc_calloc(1, sizeof(*KEY));
2267 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2271 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2272 &ske->prop->group->group);
2275 /** Send KE2 payload */
2276 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2277 return SILC_FSM_CONTINUE;
2283 silc_free(send_payload);
2284 ske->ke2_payload = NULL;
2286 silc_fsm_next(fsm, silc_ske_st_responder_error);
2287 return SILC_FSM_CONTINUE;
2290 /* Phase-5. Send KE2 payload */
2292 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2294 SilcSKE ske = fsm_context;
2295 SilcSKEStatus status;
2296 SilcBuffer payload_buf;
2297 unsigned char hash[SILC_HASH_MAXLEN], sign[65536 + 1], *pk;
2298 SilcUInt32 hash_len, sign_len, pk_len;
2300 SILC_LOG_DEBUG(("Start"));
2302 if (ske->public_key && ske->private_key) {
2303 SILC_LOG_DEBUG(("Getting public key"));
2305 /* Get the public key */
2306 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2308 /** Error encoding public key */
2309 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2310 silc_fsm_next(fsm, silc_ske_st_responder_error);
2311 return SILC_FSM_CONTINUE;
2313 ske->ke2_payload->pk_data = pk;
2314 ske->ke2_payload->pk_len = pk_len;
2317 SILC_LOG_DEBUG(("Computing HASH value"));
2319 /* Compute the hash value */
2320 memset(hash, 0, sizeof(hash));
2321 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2322 if (status != SILC_SKE_STATUS_OK) {
2323 /** Error computing hash */
2324 ske->status = status;
2325 silc_fsm_next(fsm, silc_ske_st_responder_error);
2326 return SILC_FSM_CONTINUE;
2328 ske->hash = silc_memdup(hash, hash_len);
2330 /** Error computing hash */
2331 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2332 silc_fsm_next(fsm, silc_ske_st_responder_error);
2333 return SILC_FSM_CONTINUE;
2335 ske->hash_len = hash_len;
2337 if (ske->public_key && ske->private_key) {
2338 SILC_LOG_DEBUG(("Signing HASH value"));
2340 /* Sign the hash value */
2341 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2342 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2343 /** Error computing signature */
2344 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2345 silc_fsm_next(fsm, silc_ske_st_responder_error);
2346 return SILC_FSM_CONTINUE;
2348 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2349 if (!ske->ke2_payload->sign_data) {
2350 /** Error computing hash */
2351 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2352 silc_fsm_next(fsm, silc_ske_st_responder_error);
2353 return SILC_FSM_CONTINUE;
2355 ske->ke2_payload->sign_len = sign_len;
2356 memset(sign, 0, sizeof(sign));
2358 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2360 /* Encode the Key Exchange Payload */
2361 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2363 if (status != SILC_SKE_STATUS_OK) {
2364 /** Error encoding KE payload */
2365 ske->status = status;
2366 silc_fsm_next(fsm, silc_ske_st_responder_error);
2367 return SILC_FSM_CONTINUE;
2370 /* Send the packet. */
2371 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2372 payload_buf->data, silc_buffer_len(payload_buf))) {
2373 SILC_LOG_DEBUG(("Error sending packet"));
2374 ske->status = SILC_SKE_STATUS_ERROR;
2375 silc_fsm_next(fsm, silc_ske_st_responder_error);
2376 return SILC_FSM_CONTINUE;
2379 silc_buffer_free(payload_buf);
2381 /* In case we are doing rekey move to finish it. */
2384 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2385 return SILC_FSM_CONTINUE;
2388 /** Waiting completion */
2389 silc_fsm_next(fsm, silc_ske_st_responder_end);
2390 return SILC_FSM_WAIT;
2393 /* Protocol completed */
2395 SILC_FSM_STATE(silc_ske_st_responder_end)
2397 SilcSKE ske = fsm_context;
2398 unsigned char tmp[4];
2399 SilcUInt32 hash_len, key_len, block_len;
2401 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2402 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2403 silc_ske_install_retransmission(ske);
2404 silc_packet_free(ske->packet);
2406 return SILC_FSM_WAIT;
2408 silc_packet_free(ske->packet);
2411 /* Process key material */
2412 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2413 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2414 hash_len = silc_hash_len(ske->prop->hash);
2415 ske->keymat = silc_ske_process_key_material(ske, block_len,
2419 /** Error processing key material */
2420 ske->status = SILC_SKE_STATUS_ERROR;
2421 silc_fsm_next(fsm, silc_ske_st_responder_error);
2422 return SILC_FSM_CONTINUE;
2425 /* Send SUCCESS packet */
2426 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2427 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2429 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2430 silc_schedule_task_del_by_context(ske->schedule, ske);
2432 /* Call completion */
2433 silc_ske_completion(ske);
2435 return SILC_FSM_FINISH;
2438 /* Aborted by application */
2440 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2442 SilcSKE ske = fsm_context;
2443 unsigned char tmp[4];
2445 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2447 /* Send FAILURE packet */
2448 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2449 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2451 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2452 silc_schedule_task_del_by_context(ske->schedule, ske);
2454 /* Call completion */
2455 silc_ske_completion(ske);
2457 return SILC_FSM_FINISH;
2460 /* Failure received from remote */
2462 SILC_FSM_STATE(silc_ske_st_responder_failure)
2464 SilcSKE ske = fsm_context;
2465 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2467 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2469 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2470 SILC_GET32_MSB(error, ske->packet->buffer.data);
2471 silc_packet_free(ske->packet);
2474 ske->status = error;
2475 if (ske->status == SILC_SKE_STATUS_OK)
2476 ske->status = SILC_SKE_STATUS_ERROR;
2478 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2479 silc_schedule_task_del_by_context(ske->schedule, ske);
2481 /* Call completion */
2482 silc_ske_completion(ske);
2484 return SILC_FSM_FINISH;
2487 /* Error occurred */
2489 SILC_FSM_STATE(silc_ske_st_responder_error)
2491 SilcSKE ske = fsm_context;
2492 unsigned char tmp[4];
2494 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2495 ske->status, silc_ske_map_status(ske->status)));
2497 /* Send FAILURE packet */
2498 if (ske->status == SILC_SKE_STATUS_OUT_OF_MEMORY)
2499 ske->status = SILC_SKE_STATUS_ERROR;
2500 else if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2501 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2502 SILC_PUT32_MSB(ske->status, tmp);
2503 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2505 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2506 silc_schedule_task_del_by_context(ske->schedule, ske);
2508 /* Call completion */
2509 silc_ske_completion(ske);
2511 return SILC_FSM_FINISH;
2514 /* Starts the protocol as responder. */
2516 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2517 SilcPacketStream stream,
2518 SilcSKEParams params)
2520 SILC_LOG_DEBUG(("Start SKE as responder"));
2522 if (!ske || !stream || !params || !params->version)
2525 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2528 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2531 ske->responder = TRUE;
2532 ske->flags = params->flags;
2533 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2534 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2535 ske->session_port = params->session_port;
2536 ske->version = params->version;
2541 /* Link to packet stream to get key exchange packets */
2542 ske->stream = stream;
2543 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2544 SILC_PACKET_KEY_EXCHANGE,
2545 SILC_PACKET_KEY_EXCHANGE_1,
2546 SILC_PACKET_SUCCESS,
2547 SILC_PACKET_FAILURE, -1);
2549 /* Start SKE as responder */
2550 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2555 /***************************** Initiator Rekey ******************************/
2559 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2561 SilcSKE ske = fsm_context;
2564 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2568 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2569 return SILC_FSM_CONTINUE;
2572 /* Add rekey exchange timeout */
2573 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2576 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2579 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2580 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2581 return SILC_FSM_CONTINUE;
2584 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2585 /** Cannot allocate hash */
2586 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2587 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2588 return SILC_FSM_CONTINUE;
2591 /* Send REKEY packet to start rekey protocol */
2592 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2593 /** Error sending packet */
2594 SILC_LOG_DEBUG(("Error sending packet"));
2595 ske->status = SILC_SKE_STATUS_ERROR;
2596 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2597 return SILC_FSM_CONTINUE;
2600 /* If doing rekey without PFS, move directly to the end of the protocol. */
2601 if (!ske->rekey->pfs) {
2602 /** Rekey without PFS */
2603 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2604 return SILC_FSM_CONTINUE;
2607 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2609 if (status != SILC_SKE_STATUS_OK) {
2610 /** Unknown group */
2611 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2612 return SILC_FSM_CONTINUE;
2615 /** Rekey with PFS */
2616 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2617 return SILC_FSM_CONTINUE;
2620 /* Sends REKEY_DONE packet to finish the protocol. */
2622 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2624 SilcSKE ske = fsm_context;
2625 SilcCipher send_key;
2628 SilcUInt32 key_len, block_len, hash_len, x_len;
2629 unsigned char *pfsbuf;
2631 SILC_LOG_DEBUG(("Start"));
2633 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2634 key_len = silc_cipher_get_key_len(send_key);
2635 block_len = silc_cipher_get_block_len(send_key);
2636 hash = ske->prop->hash;
2637 hash_len = silc_hash_len(hash);
2639 /* Process key material */
2640 if (ske->rekey->pfs) {
2642 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2644 SILC_LOG_ERROR(("Error processing key material"));
2645 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2646 return SILC_FSM_CONTINUE;
2648 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2651 memset(pfsbuf, 0, x_len);
2656 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2657 ske->rekey->enc_key_len / 8,
2663 SILC_LOG_ERROR(("Error processing key material"));
2664 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2665 return SILC_FSM_CONTINUE;
2668 ske->prop->cipher = send_key;
2669 ske->prop->hmac = hmac_send;
2671 /* Get sending keys */
2672 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2673 &hmac_send, NULL, NULL)) {
2674 /** Cannot get keys */
2675 ske->status = SILC_SKE_STATUS_ERROR;
2676 ske->prop->cipher = NULL;
2677 ske->prop->hmac = NULL;
2678 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2679 return SILC_FSM_CONTINUE;
2682 ske->prop->cipher = NULL;
2683 ske->prop->hmac = NULL;
2685 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2686 packet sent after this call will be protected with the new keys. */
2687 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2689 /** Cannot set keys */
2690 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2691 ske->status = SILC_SKE_STATUS_ERROR;
2692 silc_cipher_free(send_key);
2693 silc_hmac_free(hmac_send);
2694 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2695 return SILC_FSM_CONTINUE;
2698 /** Wait for REKEY_DONE */
2699 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2700 return SILC_FSM_WAIT;
2703 /* Rekey protocol end */
2705 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2707 SilcSKE ske = fsm_context;
2708 SilcCipher receive_key;
2709 SilcHmac hmac_receive;
2710 SilcSKERekeyMaterial rekey;
2712 SILC_LOG_DEBUG(("Start"));
2714 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2715 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2716 silc_packet_free(ske->packet);
2718 return SILC_FSM_WAIT;
2721 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2722 ske->prop->cipher = receive_key;
2723 ske->prop->hmac = hmac_receive;
2725 /* Get receiving keys */
2726 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2727 NULL, &hmac_receive, NULL)) {
2728 /** Cannot get keys */
2729 ske->status = SILC_SKE_STATUS_ERROR;
2730 ske->prop->cipher = NULL;
2731 ske->prop->hmac = NULL;
2732 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2733 return SILC_FSM_CONTINUE;
2736 /* Set new receiving keys into use. All packets received after this will
2737 be decrypted with the new keys. */
2738 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2739 hmac_receive, FALSE)) {
2740 /** Cannot set keys */
2741 SILC_LOG_DEBUG(("Cannot set new keys"));
2742 ske->status = SILC_SKE_STATUS_ERROR;
2743 silc_cipher_free(receive_key);
2744 silc_hmac_free(hmac_receive);
2745 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2746 return SILC_FSM_CONTINUE;
2749 SILC_LOG_DEBUG(("Rekey completed successfully"));
2751 /* Generate new rekey material */
2752 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2755 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2756 ske->prop->cipher = NULL;
2757 ske->prop->hmac = NULL;
2758 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2759 return SILC_FSM_CONTINUE;
2761 rekey->pfs = ske->rekey->pfs;
2764 ske->prop->cipher = NULL;
2765 ske->prop->hmac = NULL;
2766 silc_packet_free(ske->packet);
2768 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2769 silc_schedule_task_del_by_context(ske->schedule, ske);
2771 /* Call completion */
2772 silc_ske_completion(ske);
2774 return SILC_FSM_FINISH;
2777 /* Starts rekey protocol as initiator */
2780 silc_ske_rekey_initiator(SilcSKE ske,
2781 SilcPacketStream stream,
2782 SilcSKERekeyMaterial rekey)
2784 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2786 if (!ske || !stream || !rekey) {
2787 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2792 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2795 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2799 ske->responder = FALSE;
2800 ske->rekeying = TRUE;
2803 /* Link to packet stream to get key exchange packets */
2804 ske->stream = stream;
2805 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2807 SILC_PACKET_REKEY_DONE,
2808 SILC_PACKET_KEY_EXCHANGE_2,
2809 SILC_PACKET_SUCCESS,
2810 SILC_PACKET_FAILURE, -1);
2812 /* Start SKE rekey as initiator */
2813 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2818 /***************************** Responder Rekey ******************************/
2820 /* Wait for initiator's packet */
2822 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2824 SilcSKE ske = fsm_context;
2826 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2830 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2831 return SILC_FSM_CONTINUE;
2834 /* Add rekey exchange timeout */
2835 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2838 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2840 /* If REKEY packet already received process it directly */
2841 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2842 return SILC_FSM_CONTINUE;
2844 /* Wait for REKEY */
2845 return SILC_FSM_WAIT;
2848 /* Process initiator's REKEY packet */
2850 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2852 SilcSKE ske = fsm_context;
2853 SilcSKEStatus status;
2855 SILC_LOG_DEBUG(("Start"));
2857 if (ske->packet->type != SILC_PACKET_REKEY) {
2858 ske->status = SILC_SKE_STATUS_ERROR;
2859 silc_packet_free(ske->packet);
2861 silc_fsm_next(fsm, silc_ske_st_responder_error);
2862 return SILC_FSM_CONTINUE;
2865 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2868 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2869 silc_fsm_next(fsm, silc_ske_st_responder_error);
2870 return SILC_FSM_CONTINUE;
2873 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2874 /** Cannot allocate hash */
2875 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2876 silc_fsm_next(fsm, silc_ske_st_responder_error);
2877 return SILC_FSM_CONTINUE;
2880 /* If doing rekey without PFS, move directly to the end of the protocol. */
2881 if (!ske->rekey->pfs) {
2882 /** Rekey without PFS */
2883 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2884 return SILC_FSM_CONTINUE;
2887 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2889 if (status != SILC_SKE_STATUS_OK) {
2890 /** Unknown group */
2891 silc_fsm_next(fsm, silc_ske_st_responder_error);
2892 return SILC_FSM_CONTINUE;
2895 /** Rekey with PFS */
2896 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2897 return SILC_FSM_WAIT;
2900 /* Sends REKEY_DONE packet to finish the protocol. */
2902 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2904 SilcSKE ske = fsm_context;
2905 SilcCipher send_key;
2908 SilcUInt32 key_len, block_len, hash_len, x_len;
2909 unsigned char *pfsbuf;
2911 SILC_LOG_DEBUG(("Start"));
2913 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2914 key_len = silc_cipher_get_key_len(send_key);
2915 block_len = silc_cipher_get_block_len(send_key);
2916 hash = ske->prop->hash;
2917 hash_len = silc_hash_len(hash);
2919 /* Process key material */
2920 if (ske->rekey->pfs) {
2922 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2924 SILC_LOG_ERROR(("Error processing key material"));
2925 silc_fsm_next(fsm, silc_ske_st_responder_error);
2926 return SILC_FSM_CONTINUE;
2928 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2931 memset(pfsbuf, 0, x_len);
2936 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2937 ske->rekey->enc_key_len / 8,
2943 SILC_LOG_ERROR(("Error processing key material"));
2944 silc_fsm_next(fsm, silc_ske_st_responder_error);
2945 return SILC_FSM_CONTINUE;
2948 ske->prop->cipher = send_key;
2949 ske->prop->hmac = hmac_send;
2951 /* Get sending keys */
2952 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2953 &hmac_send, NULL, NULL)) {
2954 /** Cannot get keys */
2955 ske->status = SILC_SKE_STATUS_ERROR;
2956 ske->prop->cipher = NULL;
2957 ske->prop->hmac = NULL;
2958 silc_fsm_next(fsm, silc_ske_st_responder_error);
2959 return SILC_FSM_CONTINUE;
2962 ske->prop->cipher = NULL;
2963 ske->prop->hmac = NULL;
2965 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2966 packet sent after this call will be protected with the new keys. */
2967 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2969 /** Cannot set keys */
2970 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2971 ske->status = SILC_SKE_STATUS_ERROR;
2972 silc_cipher_free(send_key);
2973 silc_hmac_free(hmac_send);
2974 silc_fsm_next(fsm, silc_ske_st_responder_error);
2975 return SILC_FSM_CONTINUE;
2978 /** Wait for REKEY_DONE */
2979 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2980 return SILC_FSM_WAIT;
2983 /* Rekey protocol end */
2985 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2987 SilcSKE ske = fsm_context;
2988 SilcCipher receive_key;
2989 SilcHmac hmac_receive;
2990 SilcSKERekeyMaterial rekey;
2992 SILC_LOG_DEBUG(("Start"));
2994 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2995 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2996 silc_packet_free(ske->packet);
2998 return SILC_FSM_WAIT;
3001 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
3002 ske->prop->cipher = receive_key;
3003 ske->prop->hmac = hmac_receive;
3005 /* Get receiving keys */
3006 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
3007 NULL, &hmac_receive, NULL)) {
3008 /** Cannot get keys */
3009 ske->status = SILC_SKE_STATUS_ERROR;
3010 ske->prop->cipher = NULL;
3011 ske->prop->hmac = NULL;
3012 silc_fsm_next(fsm, silc_ske_st_responder_error);
3013 return SILC_FSM_CONTINUE;
3016 /* Set new receiving keys into use. All packets received after this will
3017 be decrypted with the new keys. */
3018 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3019 hmac_receive, FALSE)) {
3020 /** Cannot set keys */
3021 SILC_LOG_DEBUG(("Cannot set new keys"));
3022 ske->status = SILC_SKE_STATUS_ERROR;
3023 ske->prop->cipher = NULL;
3024 ske->prop->hmac = NULL;
3025 silc_cipher_free(receive_key);
3026 silc_hmac_free(hmac_receive);
3027 silc_fsm_next(fsm, silc_ske_st_responder_error);
3028 return SILC_FSM_CONTINUE;
3031 SILC_LOG_DEBUG(("Rekey completed successfully"));
3033 /* Generate new rekey material */
3034 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3037 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3038 ske->prop->cipher = NULL;
3039 ske->prop->hmac = NULL;
3040 silc_fsm_next(fsm, silc_ske_st_responder_error);
3041 return SILC_FSM_CONTINUE;
3043 rekey->pfs = ske->rekey->pfs;
3046 ske->prop->cipher = NULL;
3047 ske->prop->hmac = NULL;
3048 silc_packet_free(ske->packet);
3050 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3051 silc_schedule_task_del_by_context(ske->schedule, ske);
3053 /* Call completion */
3054 silc_ske_completion(ske);
3056 return SILC_FSM_FINISH;
3059 /* Starts rekey protocol as responder */
3062 silc_ske_rekey_responder(SilcSKE ske,
3063 SilcPacketStream stream,
3064 SilcSKERekeyMaterial rekey,
3067 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3069 if (!ske || !stream || !rekey)
3072 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3075 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3079 ske->responder = TRUE;
3080 ske->rekeying = TRUE;
3081 ske->packet = packet;
3084 /* Link to packet stream to get key exchange packets */
3085 ske->stream = stream;
3086 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3088 SILC_PACKET_REKEY_DONE,
3089 SILC_PACKET_KEY_EXCHANGE_1,
3090 SILC_PACKET_SUCCESS,
3091 SILC_PACKET_FAILURE, -1);
3093 /* Start SKE rekey as responder */
3094 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3099 /* Processes the provided key material `data' as the SILC protocol
3100 specification defines. */
3103 silc_ske_process_key_material_data(unsigned char *data,
3104 SilcUInt32 data_len,
3105 SilcUInt32 req_iv_len,
3106 SilcUInt32 req_enc_key_len,
3107 SilcUInt32 req_hmac_key_len,
3111 unsigned char hashd[SILC_HASH_MAXLEN];
3112 SilcUInt32 hash_len = req_hmac_key_len;
3113 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3114 SilcSKEKeyMaterial key;
3116 SILC_LOG_DEBUG(("Start"));
3118 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3121 key = silc_calloc(1, sizeof(*key));
3125 buf = silc_buffer_alloc_size(1 + data_len);
3128 silc_buffer_format(buf,
3129 SILC_STR_UI_CHAR(0),
3130 SILC_STR_DATA(data, data_len),
3134 memset(hashd, 0, sizeof(hashd));
3136 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3137 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3138 if (!key->send_iv) {
3139 silc_buffer_clear(buf);
3140 silc_buffer_free(buf);
3144 memcpy(key->send_iv, hashd, req_iv_len);
3145 memset(hashd, 0, sizeof(hashd));
3147 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3148 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3149 if (!key->receive_iv) {
3150 silc_buffer_clear(buf);
3151 silc_buffer_free(buf);
3155 memcpy(key->receive_iv, hashd, req_iv_len);
3156 key->iv_len = req_iv_len;
3158 /* Take the encryption keys. If requested key size is more than
3159 the size of hash length we will distribute more key material
3160 as protocol defines. */
3162 if (enc_key_len > hash_len) {
3164 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3165 k3[SILC_HASH_MAXLEN];
3166 unsigned char *dtmp;
3169 if (enc_key_len > (3 * hash_len))
3172 /* Take first round */
3173 memset(k1, 0, sizeof(k1));
3174 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3176 /* Take second round */
3177 dist = silc_buffer_alloc_size(data_len + hash_len);
3180 silc_buffer_format(dist,
3181 SILC_STR_DATA(data, data_len),
3182 SILC_STR_DATA(k1, hash_len),
3184 memset(k2, 0, sizeof(k2));
3185 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3187 /* Take third round */
3188 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3189 silc_buffer_pull_tail(dist, hash_len);
3190 silc_buffer_pull(dist, data_len + hash_len);
3191 silc_buffer_format(dist,
3192 SILC_STR_DATA(k2, hash_len),
3194 silc_buffer_push(dist, data_len + hash_len);
3195 memset(k3, 0, sizeof(k3));
3196 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3198 /* Then, save the keys */
3199 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3201 silc_buffer_clear(buf);
3202 silc_buffer_free(buf);
3206 memcpy(dtmp, k1, hash_len);
3207 memcpy(dtmp + hash_len, k2, hash_len);
3208 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3210 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3211 if (!key->send_enc_key) {
3212 silc_buffer_clear(buf);
3213 silc_buffer_free(buf);
3218 memcpy(key->send_enc_key, dtmp, enc_key_len);
3219 key->enc_key_len = req_enc_key_len;
3221 memset(dtmp, 0, (3 * hash_len));
3222 memset(k1, 0, sizeof(k1));
3223 memset(k2, 0, sizeof(k2));
3224 memset(k3, 0, sizeof(k3));
3226 silc_buffer_clear(dist);
3227 silc_buffer_free(dist);
3229 /* Take normal hash as key */
3230 memset(hashd, 0, sizeof(hashd));
3231 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3232 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3233 if (!key->send_enc_key) {
3234 silc_buffer_clear(buf);
3235 silc_buffer_free(buf);
3239 memcpy(key->send_enc_key, hashd, enc_key_len);
3240 key->enc_key_len = req_enc_key_len;
3244 if (enc_key_len > hash_len) {
3246 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3247 k3[SILC_HASH_MAXLEN];
3248 unsigned char *dtmp;
3251 if (enc_key_len > (3 * hash_len))
3254 /* Take first round */
3255 memset(k1, 0, sizeof(k1));
3256 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3258 /* Take second round */
3259 dist = silc_buffer_alloc_size(data_len + hash_len);
3262 silc_buffer_format(dist,
3263 SILC_STR_DATA(data, data_len),
3264 SILC_STR_DATA(k1, hash_len),
3266 memset(k2, 0, sizeof(k2));
3267 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3269 /* Take third round */
3270 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3271 silc_buffer_pull_tail(dist, hash_len);
3272 silc_buffer_pull(dist, data_len + hash_len);
3273 silc_buffer_format(dist,
3274 SILC_STR_DATA(k2, hash_len),
3276 silc_buffer_push(dist, data_len + hash_len);
3277 memset(k3, 0, sizeof(k3));
3278 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3280 /* Then, save the keys */
3281 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3283 silc_buffer_clear(buf);
3284 silc_buffer_free(buf);
3288 memcpy(dtmp, k1, hash_len);
3289 memcpy(dtmp + hash_len, k2, hash_len);
3290 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3292 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3293 if (!key->receive_enc_key) {
3294 silc_buffer_clear(buf);
3295 silc_buffer_free(buf);
3300 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3301 key->enc_key_len = req_enc_key_len;
3303 memset(dtmp, 0, (3 * hash_len));
3304 memset(k1, 0, sizeof(k1));
3305 memset(k2, 0, sizeof(k2));
3306 memset(k3, 0, sizeof(k3));
3308 silc_buffer_clear(dist);
3309 silc_buffer_free(dist);
3311 /* Take normal hash as key */
3312 memset(hashd, 0, sizeof(hashd));
3313 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3314 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3315 if (!key->receive_enc_key) {
3316 silc_buffer_clear(buf);
3317 silc_buffer_free(buf);
3321 memcpy(key->receive_enc_key, hashd, enc_key_len);
3322 key->enc_key_len = req_enc_key_len;
3325 /* Take HMAC keys */
3326 memset(hashd, 0, sizeof(hashd));
3328 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3329 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3330 if (!key->send_hmac_key) {
3331 silc_buffer_clear(buf);
3332 silc_buffer_free(buf);
3336 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3337 memset(hashd, 0, sizeof(hashd));
3339 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3340 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3341 if (!key->receive_hmac_key) {
3342 silc_buffer_clear(buf);
3343 silc_buffer_free(buf);
3347 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3348 key->hmac_key_len = req_hmac_key_len;
3349 memset(hashd, 0, sizeof(hashd));
3351 silc_buffer_clear(buf);
3352 silc_buffer_free(buf);
3354 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3359 /* Processes negotiated key material as protocol specifies. This returns
3360 the actual keys to be used in the SILC. */
3363 silc_ske_process_key_material(SilcSKE ske,
3364 SilcUInt32 req_iv_len,
3365 SilcUInt32 req_enc_key_len,
3366 SilcUInt32 req_hmac_key_len,
3367 SilcSKERekeyMaterial *rekey)
3370 unsigned char *tmpbuf;
3372 SilcSKEKeyMaterial key;
3374 /* Encode KEY to binary data */
3375 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3377 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3380 silc_buffer_format(buf,
3381 SILC_STR_DATA(tmpbuf, klen),
3382 SILC_STR_DATA(ske->hash, ske->hash_len),
3385 /* Process the key material */
3386 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3387 req_iv_len, req_enc_key_len,
3391 memset(tmpbuf, 0, klen);
3393 silc_buffer_clear(buf);
3394 silc_buffer_free(buf);
3397 *rekey = silc_ske_make_rekey_material(ske, key);
3405 /* Free key material structure */
3407 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3413 silc_free(key->send_iv);
3414 if (key->receive_iv)
3415 silc_free(key->receive_iv);
3416 if (key->send_enc_key) {
3417 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3418 silc_free(key->send_enc_key);
3420 if (key->receive_enc_key) {
3421 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3422 silc_free(key->receive_enc_key);
3424 if (key->send_hmac_key) {
3425 memset(key->send_hmac_key, 0, key->hmac_key_len);
3426 silc_free(key->send_hmac_key);
3428 if (key->receive_hmac_key) {
3429 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3430 silc_free(key->receive_hmac_key);
3435 /* Free rekey material */
3437 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3441 if (rekey->send_enc_key) {
3442 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3443 silc_free(rekey->send_enc_key);
3445 silc_free(rekey->hash);
3449 /* Set keys into use */
3451 SilcBool silc_ske_set_keys(SilcSKE ske,
3452 SilcSKEKeyMaterial keymat,
3453 SilcSKESecurityProperties prop,
3454 SilcCipher *ret_send_key,
3455 SilcCipher *ret_receive_key,
3456 SilcHmac *ret_hmac_send,
3457 SilcHmac *ret_hmac_receive,
3460 unsigned char iv[SILC_HASH_MAXLEN];
3461 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3463 /* Allocate ciphers to be used in the communication */
3465 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3469 if (ret_receive_key) {
3470 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3475 /* Allocate HMACs */
3476 if (ret_hmac_send) {
3477 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3481 if (ret_hmac_receive) {
3482 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3489 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3493 /* Set key material */
3494 memset(iv, 0, sizeof(iv));
3495 if (ske->responder) {
3497 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3498 keymat->enc_key_len, TRUE);
3500 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3502 if (!ske->rekeying) {
3504 memcpy(iv, ske->hash, 4);
3506 memcpy(iv + 4, keymat->receive_iv, 8);
3508 /* Rekey, recompute the truncated hash value. */
3509 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3511 memcpy(iv + 4, keymat->receive_iv, 8);
3513 memset(iv + 4, 0, 12);
3516 silc_cipher_set_iv(*ret_send_key, iv);
3519 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3522 if (ret_receive_key) {
3523 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3524 keymat->enc_key_len, FALSE);
3526 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3528 if (!ske->rekeying) {
3530 memcpy(iv, ske->hash, 4);
3532 memcpy(iv + 4, keymat->send_iv, 8);
3534 /* Rekey, recompute the truncated hash value. */
3535 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3537 memcpy(iv + 4, keymat->send_iv, 8);
3539 memset(iv + 4, 0, 12);
3542 silc_cipher_set_iv(*ret_receive_key, iv);
3545 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3549 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3550 keymat->hmac_key_len);
3551 if (ret_hmac_receive)
3552 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3553 keymat->hmac_key_len);
3556 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3557 keymat->enc_key_len, TRUE);
3559 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3561 if (!ske->rekeying) {
3563 memcpy(iv, ske->hash, 4);
3565 memcpy(iv + 4, keymat->send_iv, 8);
3567 /* Rekey, recompute the truncated hash value. */
3568 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3570 memcpy(iv + 4, keymat->send_iv, 8);
3572 memset(iv + 4, 0, 12);
3575 silc_cipher_set_iv(*ret_send_key, iv);
3578 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3581 if (ret_receive_key) {
3582 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3583 keymat->enc_key_len, FALSE);
3585 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3587 if (!ske->rekeying) {
3588 /* Set IV. If IV Included flag was negotiated we only set the
3589 truncated hash value. */
3590 memcpy(iv, ske->hash, 4);
3592 memcpy(iv + 4, keymat->receive_iv, 8);
3594 /* Rekey, recompute the truncated hash value. */
3595 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3597 memcpy(iv + 4, keymat->receive_iv, 8);
3599 memset(iv + 4, 0, 12);
3602 silc_cipher_set_iv(*ret_receive_key, iv);
3605 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3609 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3610 keymat->hmac_key_len);
3611 if (ret_hmac_receive)
3612 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3613 keymat->hmac_key_len);
3619 const char *silc_ske_status_string[] =
3623 "Unexpected error occurred",
3624 "Bad payload in packet",
3625 "Unsupported group",
3626 "Unsupported cipher",
3628 "Unsupported hash function",
3630 "Unsupported public key (or certificate)",
3631 "Incorrect signature",
3632 "Bad or unsupported version",
3636 "Remote did not provide public key",
3637 "Bad reserved field in packet",
3638 "Bad payload length in packet",
3639 "Error computing signature",
3640 "System out of memory",
3641 "Key exchange timeout",
3646 /* Maps status to readable string and returns the string. If string is not
3647 found and empty character string ("") is returned. */
3649 const char *silc_ske_map_status(SilcSKEStatus status)
3653 for (i = 0; silc_ske_status_string[i]; i++)
3655 return silc_ske_status_string[i];
3660 /* Parses remote host's version string. */
3662 SilcBool silc_ske_parse_version(SilcSKE ske,
3663 SilcUInt32 *protocol_version,
3664 char **protocol_version_string,
3665 SilcUInt32 *software_version,
3666 char **software_version_string,
3667 char **vendor_version)
3669 return silc_parse_version_string(ske->remote_version,
3671 protocol_version_string,
3673 software_version_string,
3677 /* Get security properties */
3679 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3684 /* Get key material */
3686 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)