5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
23 #include "groups_internal.h"
25 /************************** Types and definitions ***************************/
27 /* Structure to hold all SKE callbacks. */
28 struct SilcSKECallbacksStruct {
29 SilcSKEVerifyCb verify_key;
30 SilcSKECompletionCb completed;
34 /************************ Static utility functions **************************/
37 SILC_FSM_STATE(silc_ske_st_initiator_start);
38 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
39 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
40 SILC_FSM_STATE(silc_ske_st_initiator_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_TASK_CALLBACK(silc_ske_packet_send_retry);
61 silc_ske_process_key_material(SilcSKE ske,
62 SilcUInt32 req_iv_len,
63 SilcUInt32 req_enc_key_len,
64 SilcUInt32 req_hmac_key_len,
65 SilcSKERekeyMaterial *rekey);
66 static SilcBool silc_ske_packet_send(SilcSKE ske,
68 SilcPacketFlags flags,
69 const unsigned char *data,
74 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
75 SilcPacketStream stream,
77 void *callback_context,
80 SilcSKE ske = callback_context;
82 /* Clear retransmission */
83 ske->retry_timer = SILC_SKE_RETRY_MIN;
85 silc_schedule_task_del_by_callback(ske->schedule,
86 silc_ske_packet_send_retry);
88 /* Signal for new packet */
91 /* Check if we were aborted */
93 silc_packet_free(packet);
97 silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
99 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
101 silc_fsm_continue_sync(&ske->fsm);
105 /* See if received failure from remote */
106 if (packet->type == SILC_PACKET_FAILURE) {
108 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
110 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
113 /* Handle rekey synchronously */
115 silc_fsm_continue_sync(&ske->fsm);
117 silc_fsm_continue(&ske->fsm);
122 /* Packet stream callbacks */
123 static SilcPacketCallbacks silc_ske_stream_cbs =
125 silc_ske_packet_receive, NULL, NULL
128 /* Aborts SKE protocol */
130 static void silc_ske_abort(SilcAsyncOperation op, void *context)
132 SilcSKE ske = context;
136 /* Public key verification completion callback */
138 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
139 void *completion_context)
141 ske->status = status;
142 SILC_FSM_CALL_CONTINUE(&ske->fsm);
145 /* SKR find callback */
147 static void silc_ske_skr_callback(SilcSKR repository,
149 SilcSKRStatus status,
150 SilcDList keys, void *context)
152 SilcSKE ske = context;
154 silc_skr_find_free(find);
156 if (status != SILC_SKR_OK) {
157 if (ske->callbacks->verify_key) {
158 /* Verify from application */
159 ske->callbacks->verify_key(ske, ske->prop->public_key,
160 ske->callbacks->context,
161 silc_ske_pk_verified, NULL);
167 silc_dlist_uninit(keys);
170 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
171 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
172 SILC_FSM_CALL_CONTINUE(&ske->fsm);
175 /* Checks remote and local versions */
177 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
179 SilcUInt32 r_software_version = 0;
181 if (!ske->remote_version || !ske->version)
182 return SILC_SKE_STATUS_BAD_VERSION;
184 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
185 &r_software_version, NULL, NULL))
186 return SILC_SKE_STATUS_BAD_VERSION;
188 /* Backwards compatibility checks */
190 /* Old server versions requires "valid" looking Source ID in the SILC
191 packets during initial key exchange. All version before 1.1.0. */
192 if (r_software_version < 110) {
194 memset(&id, 0, sizeof(id));
196 SILC_LOG_DEBUG(("Remote is old version, add dummy Source ID to packets"));
197 silc_packet_set_ids(ske->stream, SILC_ID_CLIENT, &id, 0, NULL);
200 return SILC_SKE_STATUS_OK;
203 /* Selects the supported security properties from the initiator's Key
204 Exchange Start Payload. A responder function. Saves our reply
205 start payload to ske->start_payload. */
208 silc_ske_select_security_properties(SilcSKE ske,
209 SilcSKEStartPayload remote_payload,
210 SilcSKESecurityProperties *prop)
212 SilcSKEStatus status;
213 SilcSKEStartPayload rp, payload;
217 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
221 /* Check for mandatory fields */
222 if (!rp->ke_grp_len) {
223 SILC_LOG_DEBUG(("KE group not defined in payload"));
224 return SILC_SKE_STATUS_BAD_PAYLOAD;
226 if (!rp->pkcs_alg_len) {
227 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
228 return SILC_SKE_STATUS_BAD_PAYLOAD;
230 if (!rp->enc_alg_len) {
231 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
232 return SILC_SKE_STATUS_BAD_PAYLOAD;
234 if (!rp->hash_alg_len) {
235 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
236 return SILC_SKE_STATUS_BAD_PAYLOAD;
238 if (!rp->hmac_alg_len) {
239 SILC_LOG_DEBUG(("HMAC not defined in payload"));
240 return SILC_SKE_STATUS_BAD_PAYLOAD;
243 /* Allocate security properties */
244 *prop = silc_calloc(1, sizeof(**prop));
246 return SILC_SKE_STATUS_OUT_OF_MEMORY;
248 /* Allocate our reply start payload */
249 payload = silc_calloc(1, sizeof(*payload));
252 return SILC_SKE_STATUS_OUT_OF_MEMORY;
255 /* Check version string */
256 ske->remote_version = silc_memdup(rp->version, rp->version_len);
257 status = silc_ske_check_version(ske);
258 if (status != SILC_SKE_STATUS_OK) {
259 ske->status = status;
263 /* Flags are returned unchanged. */
264 (*prop)->flags = payload->flags = rp->flags;
266 /* Take cookie, we must return it to sender unmodified. */
267 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
268 if (!payload->cookie) {
269 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
272 payload->cookie_len = SILC_SKE_COOKIE_LEN;
273 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
275 /* In case IV included flag and session port is set the first 16-bits of
276 cookie will include our session port. */
277 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
278 /* Take remote port */
279 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
282 SILC_PUT16_MSB(ske->session_port, payload->cookie);
285 /* Put our version to our reply */
286 payload->version = strdup(ske->version);
287 if (!payload->version) {
288 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
291 payload->version_len = strlen(ske->version);
293 /* Get supported Key Exchange groups */
294 cp = rp->ke_grp_list;
295 if (cp && strchr(cp, ',')) {
299 len = strcspn(cp, ",");
300 item = silc_calloc(len + 1, sizeof(char));
302 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
305 memcpy(item, cp, len);
307 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
309 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
310 SILC_LOG_DEBUG(("Found KE group `%s'", item));
312 payload->ke_grp_len = len;
313 payload->ke_grp_list = item;
327 if (!payload->ke_grp_len && !payload->ke_grp_list) {
328 SILC_LOG_DEBUG(("Could not find supported KE group"));
330 return SILC_SKE_STATUS_UNKNOWN_GROUP;
333 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
334 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
336 payload->ke_grp_len = rp->ke_grp_len;
337 payload->ke_grp_list = strdup(rp->ke_grp_list);
340 /* Save group to security properties */
341 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
342 if (status != SILC_SKE_STATUS_OK) {
344 return SILC_SKE_STATUS_UNKNOWN_GROUP;
347 /* Get supported PKCS algorithms */
348 cp = rp->pkcs_alg_list;
349 if (cp && strchr(cp, ',')) {
353 len = strcspn(cp, ",");
354 item = silc_calloc(len + 1, sizeof(char));
356 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
359 memcpy(item, cp, len);
361 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
363 if (silc_pkcs_find_algorithm(item, NULL)) {
364 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
366 payload->pkcs_alg_len = len;
367 payload->pkcs_alg_list = item;
381 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
382 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
383 silc_free(payload->ke_grp_list);
385 return SILC_SKE_STATUS_UNKNOWN_PKCS;
388 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
389 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
391 payload->pkcs_alg_len = rp->pkcs_alg_len;
392 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
395 /* Get supported encryption algorithms */
396 cp = rp->enc_alg_list;
397 if (cp && strchr(cp, ',')) {
401 len = strcspn(cp, ",");
402 item = silc_calloc(len + 1, sizeof(char));
404 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
407 memcpy(item, cp, len);
409 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
411 if (silc_cipher_is_supported(item) == TRUE) {
412 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
414 payload->enc_alg_len = len;
415 payload->enc_alg_list = item;
429 if (!payload->enc_alg_len && !payload->enc_alg_list) {
430 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
431 silc_free(payload->ke_grp_list);
432 silc_free(payload->pkcs_alg_list);
434 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
437 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
440 payload->enc_alg_len = rp->enc_alg_len;
441 payload->enc_alg_list = strdup(rp->enc_alg_list);
444 /* Save selected cipher to security properties */
445 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
446 silc_free(payload->ke_grp_list);
447 silc_free(payload->pkcs_alg_list);
449 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
452 /* Get supported hash algorithms */
453 cp = rp->hash_alg_list;
454 if (cp && strchr(cp, ',')) {
458 len = strcspn(cp, ",");
459 item = silc_calloc(len + 1, sizeof(char));
461 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
464 memcpy(item, cp, len);
466 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
468 if (silc_hash_is_supported(item) == TRUE) {
469 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
471 payload->hash_alg_len = len;
472 payload->hash_alg_list = item;
486 if (!payload->hash_alg_len && !payload->hash_alg_list) {
487 SILC_LOG_DEBUG(("Could not find supported hash alg"));
488 silc_free(payload->ke_grp_list);
489 silc_free(payload->pkcs_alg_list);
490 silc_free(payload->enc_alg_list);
492 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
495 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
498 payload->hash_alg_len = rp->hash_alg_len;
499 payload->hash_alg_list = strdup(rp->hash_alg_list);
502 /* Save selected hash algorithm to security properties */
503 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
504 silc_free(payload->ke_grp_list);
505 silc_free(payload->pkcs_alg_list);
506 silc_free(payload->enc_alg_list);
508 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
511 /* Get supported HMACs */
512 cp = rp->hmac_alg_list;
513 if (cp && strchr(cp, ',')) {
517 len = strcspn(cp, ",");
518 item = silc_calloc(len + 1, sizeof(char));
520 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
523 memcpy(item, cp, len);
525 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
527 if (silc_hmac_is_supported(item) == TRUE) {
528 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
530 payload->hmac_alg_len = len;
531 payload->hmac_alg_list = item;
545 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
546 SILC_LOG_DEBUG(("Could not find supported HMAC"));
547 silc_free(payload->ke_grp_list);
548 silc_free(payload->pkcs_alg_list);
549 silc_free(payload->enc_alg_list);
550 silc_free(payload->hash_alg_list);
552 return SILC_SKE_STATUS_UNKNOWN_HMAC;
555 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
558 payload->hmac_alg_len = rp->hmac_alg_len;
559 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
562 /* Save selected HMACc to security properties */
563 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
564 silc_free(payload->ke_grp_list);
565 silc_free(payload->pkcs_alg_list);
566 silc_free(payload->enc_alg_list);
567 silc_free(payload->hash_alg_list);
569 return SILC_SKE_STATUS_UNKNOWN_HMAC;
572 /* Get supported compression algorithms */
573 cp = rp->comp_alg_list;
574 if (cp && strchr(cp, ',')) {
578 len = strcspn(cp, ",");
579 item = silc_calloc(len + 1, sizeof(char));
581 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
584 memcpy(item, cp, len);
586 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
589 if (!strcmp(item, "none")) {
590 SILC_LOG_DEBUG(("Found Compression `%s'", item));
591 payload->comp_alg_len = len;
592 payload->comp_alg_list = item;
596 if (silc_hmac_is_supported(item) == TRUE) {
597 SILC_LOG_DEBUG(("Found Compression `%s'", item));
598 payload->comp_alg_len = len;
599 payload->comp_alg_list = item;
615 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
616 2 + payload->version_len +
617 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
618 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
619 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
621 /* Save our reply payload */
622 ske->start_payload = payload;
624 return SILC_SKE_STATUS_OK;
627 /* Creates random number such that 1 < rnd < n and at most length
628 of len bits. The rnd sent as argument must be initialized. */
630 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
634 SilcSKEStatus status = SILC_SKE_STATUS_OK;
635 unsigned char *string;
639 return SILC_SKE_STATUS_ERROR;
641 SILC_LOG_DEBUG(("Creating random number"));
645 /* Get the random number as string */
646 string = silc_rng_get_rn_data(ske->rng, l);
648 return SILC_SKE_STATUS_OUT_OF_MEMORY;
650 /* Decode the string into a MP integer */
651 silc_mp_bin2mp(string, l, rnd);
652 silc_mp_mod_2exp(rnd, rnd, len);
655 if (silc_mp_cmp_ui(rnd, 1) < 0)
656 status = SILC_SKE_STATUS_ERROR;
657 if (silc_mp_cmp(rnd, n) >= 0)
658 status = SILC_SKE_STATUS_ERROR;
660 memset(string, 'F', l);
666 /* Creates a hash value HASH as defined in the SKE protocol. If the
667 `initiator' is TRUE then this function is used to create the HASH_i
668 hash value defined in the protocol. If it is FALSE then this is used
669 to create the HASH value defined by the protocol. */
671 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
672 unsigned char *return_hash,
673 SilcUInt32 *return_hash_len,
676 SilcSKEStatus status = SILC_SKE_STATUS_OK;
678 unsigned char *e, *f, *KEY;
679 SilcUInt32 e_len, f_len, KEY_len;
682 SILC_LOG_DEBUG(("Start"));
684 if (initiator == FALSE) {
685 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
686 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
687 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
689 /* Format the buffer used to compute the hash value */
690 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
691 ske->ke2_payload->pk_len +
692 ske->ke1_payload->pk_len +
693 e_len + f_len + KEY_len);
695 return SILC_SKE_STATUS_OUT_OF_MEMORY;
697 /* Initiator is not required to send its public key */
698 if (!ske->ke1_payload->pk_data) {
700 silc_buffer_format(buf,
701 SILC_STR_UI_XNSTRING(
702 ske->start_payload_copy->data,
703 silc_buffer_len(ske->start_payload_copy)),
704 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
705 ske->ke2_payload->pk_len),
706 SILC_STR_UI_XNSTRING(e, e_len),
707 SILC_STR_UI_XNSTRING(f, f_len),
708 SILC_STR_UI_XNSTRING(KEY, KEY_len),
712 silc_buffer_format(buf,
713 SILC_STR_UI_XNSTRING(
714 ske->start_payload_copy->data,
715 silc_buffer_len(ske->start_payload_copy)),
716 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
717 ske->ke2_payload->pk_len),
718 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
719 ske->ke1_payload->pk_len),
720 SILC_STR_UI_XNSTRING(e, e_len),
721 SILC_STR_UI_XNSTRING(f, f_len),
722 SILC_STR_UI_XNSTRING(KEY, KEY_len),
726 silc_buffer_free(buf);
729 memset(KEY, 0, KEY_len);
733 return SILC_SKE_STATUS_ERROR;
738 memset(KEY, 0, KEY_len);
743 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
745 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
746 ske->ke1_payload->pk_len + e_len);
748 return SILC_SKE_STATUS_OUT_OF_MEMORY;
750 /* Format the buffer used to compute the hash value */
752 silc_buffer_format(buf,
753 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
754 silc_buffer_len(ske->start_payload_copy)),
755 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
756 ske->ke1_payload->pk_len),
757 SILC_STR_UI_XNSTRING(e, e_len),
760 silc_buffer_free(buf);
763 return SILC_SKE_STATUS_ERROR;
766 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
773 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
775 *return_hash_len = silc_hash_len(ske->prop->hash);
777 if (initiator == FALSE) {
778 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
780 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
783 silc_buffer_free(buf);
788 /* Generate rekey material */
790 static SilcSKERekeyMaterial
791 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
793 SilcSKERekeyMaterial rekey;
796 /* Create rekey material */
797 rekey = silc_calloc(1, sizeof(*rekey));
802 if (ske->prop->group)
803 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
804 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
805 hash = silc_hash_get_name(ske->prop->hash);
806 rekey->hash = silc_memdup(hash, strlen(hash));
811 if (rekey->pfs == FALSE) {
812 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
813 keymat->enc_key_len / 8);
814 if (!rekey->send_enc_key) {
818 rekey->enc_key_len = keymat->enc_key_len;
824 /* Assembles security properties */
826 static SilcSKEStartPayload
827 silc_ske_assemble_security_properties(SilcSKE ske,
828 SilcSKESecurityPropertyFlag flags,
831 SilcSKEStartPayload rp;
834 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
836 rp = silc_calloc(1, sizeof(*rp));
839 rp->flags = (unsigned char)flags;
841 /* Set random cookie */
842 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
843 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
844 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
845 rp->cookie_len = SILC_SKE_COOKIE_LEN;
847 /* In case IV included flag and session port is set the first 16-bits of
848 cookie will include our session port. */
849 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
850 SILC_PUT16_MSB(ske->session_port, rp->cookie);
853 rp->version = strdup(version);
854 rp->version_len = strlen(version);
856 /* Get supported Key Exhange groups */
857 rp->ke_grp_list = silc_ske_get_supported_groups();
858 rp->ke_grp_len = strlen(rp->ke_grp_list);
860 /* Get supported PKCS algorithms */
861 rp->pkcs_alg_list = silc_pkcs_get_supported();
862 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
864 /* Get supported encryption algorithms */
865 rp->enc_alg_list = silc_cipher_get_supported();
866 rp->enc_alg_len = strlen(rp->enc_alg_list);
868 /* Get supported hash algorithms */
869 rp->hash_alg_list = silc_hash_get_supported();
870 rp->hash_alg_len = strlen(rp->hash_alg_list);
872 /* Get supported HMACs */
873 rp->hmac_alg_list = silc_hmac_get_supported();
874 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
877 /* Get supported compression algorithms */
878 rp->comp_alg_list = strdup("none");
879 rp->comp_alg_len = strlen("none");
881 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
882 2 + rp->version_len +
883 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
884 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
885 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
890 /* Packet retransmission callback. */
892 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
894 SilcSKE ske = context;
896 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
898 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
899 ske->retry_count = 0;
900 ske->retry_timer = SILC_SKE_RETRY_MIN;
901 silc_free(ske->retrans.data);
902 ske->retrans.data = NULL;
903 ske->status = SILC_SKE_STATUS_TIMEOUT;
905 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
907 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
908 silc_fsm_continue_sync(&ske->fsm);
912 SILC_LOG_DEBUG(("Retransmitting packet"));
913 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
914 ske->retrans.data, ske->retrans.data_len);
917 /* Install retransmission timer */
919 static void silc_ske_install_retransmission(SilcSKE ske)
921 if (!silc_packet_stream_is_udp(ske->stream))
924 if (ske->retrans.data) {
925 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
927 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
928 ske, ske->retry_timer, 0);
930 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
931 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
934 /* Sends SILC packet. Handles retransmissions with UDP streams. */
936 static SilcBool silc_ske_packet_send(SilcSKE ske,
938 SilcPacketFlags flags,
939 const unsigned char *data,
944 /* Send the packet */
945 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
947 if (silc_packet_stream_is_udp(ske->stream) &&
948 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
949 silc_free(ske->retrans.data);
950 ske->retrans.type = type;
951 ske->retrans.flags = flags;
952 ske->retrans.data = silc_memdup(data, data_len);
953 ske->retrans.data_len = data_len;
954 silc_ske_install_retransmission(ske);
960 /* SKE FSM destructor. We call completion callback here. All SKE
961 machines go here and call the completion. Completion must not be called
962 from any other place. */
964 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
965 void *destructor_context)
967 SilcSKE ske = fsm_context;
969 /* Call the completion callback */
970 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
971 if (ske->status != SILC_SKE_STATUS_OK)
972 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
973 ske->callbacks->context);
975 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
976 ske->rekey, ske->callbacks->context);
979 ske->running = FALSE;
984 /* Key exchange timeout task callback */
986 SILC_TASK_CALLBACK(silc_ske_timeout)
988 SilcSKE ske = context;
990 SILC_LOG_DEBUG(("Timeout"));
993 ske->status = SILC_SKE_STATUS_TIMEOUT;
995 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
997 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
999 silc_fsm_continue_sync(&ske->fsm);
1002 /******************************* Protocol API *******************************/
1004 /* Allocates new SKE object. */
1006 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1007 SilcSKR repository, SilcPublicKey public_key,
1008 SilcPrivateKey private_key, void *context)
1012 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1014 if (!rng || !schedule)
1018 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1022 ske = silc_calloc(1, sizeof(*ske));
1025 ske->status = SILC_SKE_STATUS_OK;
1027 ske->repository = repository;
1028 ske->user_data = context;
1029 ske->schedule = schedule;
1030 ske->public_key = public_key;
1031 ske->private_key = private_key;
1032 ske->retry_timer = SILC_SKE_RETRY_MIN;
1037 /* Free's SKE object. */
1039 void silc_ske_free(SilcSKE ske)
1041 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1050 /* If already aborted, destroy the session immediately */
1052 ske->status = SILC_SKE_STATUS_ERROR;
1054 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1056 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1057 silc_fsm_continue_sync(&ske->fsm);
1062 /* Free start payload */
1063 if (ske->start_payload)
1064 silc_ske_payload_start_free(ske->start_payload);
1066 /* Free KE payload */
1067 if (ske->ke1_payload)
1068 silc_ske_payload_ke_free(ske->ke1_payload);
1069 if (ske->ke2_payload)
1070 silc_ske_payload_ke_free(ske->ke2_payload);
1071 silc_free(ske->remote_version);
1075 if (ske->prop->group)
1076 silc_ske_group_free(ske->prop->group);
1077 if (ske->prop->cipher)
1078 silc_cipher_free(ske->prop->cipher);
1079 if (ske->prop->hash)
1080 silc_hash_free(ske->prop->hash);
1081 if (ske->prop->hmac)
1082 silc_hmac_free(ske->prop->hmac);
1083 silc_free(ske->prop);
1086 silc_ske_free_key_material(ske->keymat);
1087 if (ske->start_payload_copy)
1088 silc_buffer_free(ske->start_payload_copy);
1090 silc_mp_uninit(ske->x);
1094 silc_mp_uninit(ske->KEY);
1095 silc_free(ske->KEY);
1097 silc_free(ske->retrans.data);
1098 silc_free(ske->hash);
1099 silc_free(ske->callbacks);
1101 memset(ske, 'F', sizeof(*ske));
1105 /* Return user context */
1107 void *silc_ske_get_context(SilcSKE ske)
1109 return ske->user_data;
1112 /* Sets protocol callbacks */
1114 void silc_ske_set_callbacks(SilcSKE ske,
1115 SilcSKEVerifyCb verify_key,
1116 SilcSKECompletionCb completed,
1120 silc_free(ske->callbacks);
1121 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1122 if (!ske->callbacks)
1124 ske->callbacks->verify_key = verify_key;
1125 ske->callbacks->completed = completed;
1126 ske->callbacks->context = context;
1130 /******************************** Initiator *********************************/
1132 /* Start protocol. Send our proposal */
1134 SILC_FSM_STATE(silc_ske_st_initiator_start)
1136 SilcSKE ske = fsm_context;
1137 SilcBuffer payload_buf;
1140 SILC_LOG_DEBUG(("Start"));
1144 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1145 return SILC_FSM_CONTINUE;
1148 /* Encode the payload */
1149 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1151 if (status != SILC_SKE_STATUS_OK) {
1152 /** Error encoding Start Payload */
1153 ske->status = status;
1154 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1155 return SILC_FSM_CONTINUE;
1158 /* Save the the payload buffer for future use. It is later used to
1159 compute the HASH value. */
1160 ske->start_payload_copy = payload_buf;
1162 /* Send the packet. */
1163 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1164 silc_buffer_data(payload_buf),
1165 silc_buffer_len(payload_buf))) {
1166 /** Error sending packet */
1167 SILC_LOG_DEBUG(("Error sending packet"));
1168 ske->status = SILC_SKE_STATUS_ERROR;
1169 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1170 return SILC_FSM_CONTINUE;
1173 /* Add key exchange timeout */
1174 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1175 ske, ske->timeout, 0);
1177 /** Wait for responder proposal */
1178 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1179 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1180 return SILC_FSM_WAIT;
1183 /* Phase-1. Receives responder's proposal */
1185 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1187 SilcSKE ske = fsm_context;
1188 SilcSKEStatus status;
1189 SilcSKEStartPayload payload;
1190 SilcSKESecurityProperties prop;
1191 SilcSKEDiffieHellmanGroup group = NULL;
1192 SilcBuffer packet_buf = &ske->packet->buffer;
1193 SilcUInt16 remote_port = 0;
1197 SILC_LOG_DEBUG(("Start"));
1199 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1200 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1201 silc_ske_install_retransmission(ske);
1202 silc_packet_free(ske->packet);
1204 return SILC_FSM_WAIT;
1207 /* Decode the payload */
1208 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1209 if (status != SILC_SKE_STATUS_OK) {
1210 /** Error decoding Start Payload */
1211 silc_packet_free(ske->packet);
1213 ske->status = status;
1214 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1215 return SILC_FSM_CONTINUE;
1218 /* Get remote ID and set it to stream */
1219 if (ske->packet->src_id_len) {
1220 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1221 ske->packet->src_id_type,
1222 (ske->packet->src_id_type == SILC_ID_SERVER ?
1223 (void *)&id.u.server_id : (void *)&id.u.client_id),
1224 (ske->packet->src_id_type == SILC_ID_SERVER ?
1225 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1226 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1227 (ske->packet->src_id_type == SILC_ID_SERVER ?
1228 (void *)&id.u.server_id : (void *)&id.u.client_id));
1231 silc_packet_free(ske->packet);
1234 /* Check that the cookie is returned unmodified. In case IV included
1235 flag and session port has been set, the first two bytes of cookie
1236 are the session port and we ignore them in this check. */
1237 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1238 /* Take remote port */
1239 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1242 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1243 SILC_SKE_COOKIE_LEN - coff)) {
1244 /** Invalid cookie */
1245 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1246 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1247 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1248 return SILC_FSM_CONTINUE;
1251 /* Check version string */
1252 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1253 status = silc_ske_check_version(ske);
1254 if (status != SILC_SKE_STATUS_OK) {
1255 /** Version mismatch */
1256 ske->status = status;
1257 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1258 return SILC_FSM_CONTINUE;
1261 /* Free our KE Start Payload context, we don't need it anymore. */
1262 silc_ske_payload_start_free(ske->start_payload);
1263 ske->start_payload = NULL;
1265 /* Take the selected security properties into use while doing
1266 the key exchange. This is used only while doing the key
1268 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1271 prop->flags = payload->flags;
1272 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1273 if (status != SILC_SKE_STATUS_OK)
1276 prop->group = group;
1277 prop->remote_port = remote_port;
1279 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1280 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1283 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1284 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1287 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1288 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1291 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1292 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1296 /* Save remote's KE Start Payload */
1297 ske->start_payload = payload;
1299 /** Send KE Payload */
1300 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1301 return SILC_FSM_CONTINUE;
1305 silc_ske_payload_start_free(payload);
1307 silc_ske_group_free(group);
1309 silc_cipher_free(prop->cipher);
1311 silc_hash_free(prop->hash);
1313 silc_hmac_free(prop->hmac);
1317 if (status == SILC_SKE_STATUS_OK)
1318 status = SILC_SKE_STATUS_ERROR;
1321 ske->status = status;
1322 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1323 return SILC_FSM_CONTINUE;
1326 /* Phase-2. Send KE payload */
1328 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1330 SilcSKE ske = fsm_context;
1331 SilcSKEStatus status;
1332 SilcBuffer payload_buf;
1334 SilcSKEKEPayload payload;
1337 SILC_LOG_DEBUG(("Start"));
1339 /* Create the random number x, 1 < x < q. */
1340 x = silc_calloc(1, sizeof(*x));
1342 /** Out of memory */
1343 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1344 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1345 return SILC_FSM_CONTINUE;
1349 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1350 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1352 if (status != SILC_SKE_STATUS_OK) {
1353 /** Error generating random number */
1356 ske->status = status;
1357 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1358 return SILC_FSM_CONTINUE;
1361 /* Encode the result to Key Exchange Payload. */
1363 payload = silc_calloc(1, sizeof(*payload));
1365 /** Out of memory */
1368 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1369 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1370 return SILC_FSM_CONTINUE;
1372 ske->ke1_payload = payload;
1374 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1376 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1377 silc_mp_init(&payload->x);
1378 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1379 &ske->prop->group->group);
1381 /* Get public key */
1382 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1383 if (!payload->pk_data) {
1384 /** Error encoding public key */
1387 silc_mp_uninit(&payload->x);
1389 ske->ke1_payload = NULL;
1390 ske->status = SILC_SKE_STATUS_ERROR;
1391 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1392 return SILC_FSM_CONTINUE;
1394 payload->pk_len = pk_len;
1395 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1397 /* Compute signature data if we are doing mutual authentication */
1398 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1399 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1400 SilcUInt32 hash_len, sign_len;
1402 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1403 SILC_LOG_DEBUG(("Computing HASH_i value"));
1405 /* Compute the hash value */
1406 memset(hash, 0, sizeof(hash));
1407 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1409 SILC_LOG_DEBUG(("Signing HASH_i value"));
1411 /* Sign the hash value */
1412 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1413 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1414 /** Error computing signature */
1417 silc_mp_uninit(&payload->x);
1418 silc_free(payload->pk_data);
1420 ske->ke1_payload = NULL;
1421 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1422 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1423 return SILC_FSM_CONTINUE;
1425 payload->sign_data = silc_memdup(sign, sign_len);
1426 if (payload->sign_data)
1427 payload->sign_len = sign_len;
1428 memset(sign, 0, sizeof(sign));
1431 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1432 if (status != SILC_SKE_STATUS_OK) {
1433 /** Error encoding KE payload */
1436 silc_mp_uninit(&payload->x);
1437 silc_free(payload->pk_data);
1438 silc_free(payload->sign_data);
1440 ske->ke1_payload = NULL;
1441 ske->status = status;
1442 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1443 return SILC_FSM_CONTINUE;
1448 /* Check for backwards compatibility */
1450 /* Send the packet. */
1451 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1452 silc_buffer_data(payload_buf),
1453 silc_buffer_len(payload_buf))) {
1454 /** Error sending packet */
1455 SILC_LOG_DEBUG(("Error sending packet"));
1456 ske->status = SILC_SKE_STATUS_ERROR;
1457 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1458 return SILC_FSM_CONTINUE;
1461 silc_buffer_free(payload_buf);
1463 /** Waiting responder's KE payload */
1464 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1465 return SILC_FSM_WAIT;
1468 /* Phase-3. Process responder's KE payload */
1470 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1472 SilcSKE ske = fsm_context;
1473 SilcSKEStatus status;
1474 SilcSKEKEPayload payload;
1476 SilcBuffer packet_buf = &ske->packet->buffer;
1478 SILC_LOG_DEBUG(("Start"));
1480 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1481 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1482 silc_ske_install_retransmission(ske);
1483 silc_packet_free(ske->packet);
1485 return SILC_FSM_WAIT;
1488 /* Decode the payload */
1489 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1490 if (status != SILC_SKE_STATUS_OK) {
1491 /** Error decoding KE payload */
1492 silc_packet_free(ske->packet);
1494 ske->status = status;
1495 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1496 return SILC_FSM_CONTINUE;
1498 silc_packet_free(ske->packet);
1500 ske->ke2_payload = payload;
1502 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1503 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1504 "even though we require it"));
1505 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1509 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1511 /* Compute the shared secret key */
1512 KEY = silc_calloc(1, sizeof(*KEY));
1514 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1517 /* Decode the remote's public key */
1518 if (payload->pk_data &&
1519 !silc_pkcs_public_key_alloc(payload->pk_type,
1520 payload->pk_data, payload->pk_len,
1521 &ske->prop->public_key)) {
1522 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1523 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1527 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1529 SILC_LOG_DEBUG(("Verifying public key"));
1531 /** Waiting public key verification */
1532 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1534 /* If repository is provided, verify the key from there. */
1535 if (ske->repository) {
1538 find = silc_skr_find_alloc();
1540 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1543 silc_skr_find_set_pkcs_type(find,
1544 silc_pkcs_get_type(ske->prop->public_key));
1545 silc_skr_find_set_public_key(find, ske->prop->public_key);
1546 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1548 /* Find key from repository */
1549 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1550 silc_ske_skr_callback, ske));
1552 /* Verify from application */
1553 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1554 ske->callbacks->context,
1555 silc_ske_pk_verified, NULL));
1560 /** Process key material */
1561 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1562 return SILC_FSM_CONTINUE;
1565 silc_ske_payload_ke_free(payload);
1566 ske->ke2_payload = NULL;
1568 silc_mp_uninit(ske->KEY);
1569 silc_free(ske->KEY);
1572 if (status == SILC_SKE_STATUS_OK)
1573 return SILC_SKE_STATUS_ERROR;
1576 ske->status = status;
1577 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1578 return SILC_FSM_CONTINUE;
1581 /* Process key material */
1583 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1585 SilcSKE ske = fsm_context;
1586 SilcSKEStatus status;
1587 SilcSKEKEPayload payload;
1588 unsigned char hash[SILC_HASH_MAXLEN];
1589 SilcUInt32 hash_len;
1590 int key_len, block_len;
1594 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1595 return SILC_FSM_CONTINUE;
1598 /* Check result of public key verification */
1599 if (ske->status != SILC_SKE_STATUS_OK) {
1600 /** Public key not verified */
1601 SILC_LOG_DEBUG(("Public key verification failed"));
1602 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1603 return SILC_FSM_CONTINUE;
1606 payload = ske->ke2_payload;
1608 if (ske->prop->public_key) {
1609 SILC_LOG_DEBUG(("Public key is authentic"));
1611 /* Compute the hash value */
1612 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1613 if (status != SILC_SKE_STATUS_OK)
1616 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1618 /* Verify signature */
1619 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1620 payload->sign_len, hash, hash_len, NULL)) {
1621 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1622 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1626 SILC_LOG_DEBUG(("Signature is Ok"));
1628 ske->hash = silc_memdup(hash, hash_len);
1629 ske->hash_len = hash_len;
1630 memset(hash, 'F', hash_len);
1633 ske->status = SILC_SKE_STATUS_OK;
1635 /* In case we are doing rekey move to finish it. */
1638 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1639 return SILC_FSM_CONTINUE;
1642 /* Process key material */
1643 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1644 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1645 hash_len = silc_hash_len(ske->prop->hash);
1646 ske->keymat = silc_ske_process_key_material(ske, block_len,
1650 SILC_LOG_ERROR(("Error processing key material"));
1651 status = SILC_SKE_STATUS_ERROR;
1655 /* Send SUCCESS packet */
1656 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1657 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1658 /** Error sending packet */
1659 SILC_LOG_DEBUG(("Error sending packet"));
1660 ske->status = SILC_SKE_STATUS_ERROR;
1661 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1662 return SILC_FSM_CONTINUE;
1665 /** Waiting completion */
1666 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1667 return SILC_FSM_WAIT;
1670 memset(hash, 'F', sizeof(hash));
1671 silc_ske_payload_ke_free(payload);
1672 ske->ke2_payload = NULL;
1674 silc_mp_uninit(ske->KEY);
1675 silc_free(ske->KEY);
1679 memset(ske->hash, 'F', hash_len);
1680 silc_free(ske->hash);
1684 if (status == SILC_SKE_STATUS_OK)
1685 status = SILC_SKE_STATUS_ERROR;
1688 ske->status = status;
1689 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1690 return SILC_FSM_CONTINUE;
1693 /* Protocol completed */
1695 SILC_FSM_STATE(silc_ske_st_initiator_end)
1697 SilcSKE ske = fsm_context;
1699 SILC_LOG_DEBUG(("Start"));
1701 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1702 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1703 silc_ske_install_retransmission(ske);
1704 silc_packet_free(ske->packet);
1706 return SILC_FSM_WAIT;
1709 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1711 silc_packet_free(ske->packet);
1713 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1714 silc_schedule_task_del_by_context(ske->schedule, ske);
1716 return SILC_FSM_FINISH;
1719 /* Aborted by application */
1721 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1723 SilcSKE ske = fsm_context;
1724 unsigned char data[4];
1726 SILC_LOG_DEBUG(("Aborted by caller"));
1728 /* Send FAILURE packet */
1729 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1730 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1732 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1733 silc_schedule_task_del_by_context(ske->schedule, ske);
1735 return SILC_FSM_FINISH;
1738 /* Error occurred. Send error to remote host */
1740 SILC_FSM_STATE(silc_ske_st_initiator_error)
1742 SilcSKE ske = fsm_context;
1743 SilcSKEStatus status;
1744 unsigned char data[4];
1746 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1747 silc_ske_map_status(ske->status), ske->status));
1749 status = ske->status;
1750 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1751 status = SILC_SKE_STATUS_ERROR;
1753 /* Send FAILURE packet */
1754 SILC_PUT32_MSB((SilcUInt32)status, data);
1755 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1757 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1758 silc_schedule_task_del_by_context(ske->schedule, ske);
1760 return SILC_FSM_FINISH;
1763 /* Failure received from remote */
1765 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1767 SilcSKE ske = fsm_context;
1768 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1770 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1771 silc_ske_map_status(ske->status), ske->status));
1773 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1774 SILC_GET32_MSB(error, ske->packet->buffer.data);
1775 ske->status = error;
1776 silc_packet_free(ske->packet);
1780 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1781 silc_schedule_task_del_by_context(ske->schedule, ske);
1783 return SILC_FSM_FINISH;
1786 /* Starts the protocol as initiator */
1788 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1789 SilcPacketStream stream,
1790 SilcSKEParams params,
1791 SilcSKEStartPayload start_payload)
1793 SILC_LOG_DEBUG(("Start SKE as initiator"));
1795 if (!ske || !stream || !params || !params->version)
1798 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1801 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1804 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1805 ske->session_port = params->session_port;
1807 /* Generate security properties if not provided */
1808 if (!start_payload) {
1809 start_payload = silc_ske_assemble_security_properties(ske,
1816 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1817 ske->start_payload = start_payload;
1818 ske->version = params->version;
1819 ske->running = TRUE;
1821 /* Link to packet stream to get key exchange packets */
1822 ske->stream = stream;
1823 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1824 SILC_PACKET_KEY_EXCHANGE,
1825 SILC_PACKET_KEY_EXCHANGE_2,
1826 SILC_PACKET_SUCCESS,
1827 SILC_PACKET_FAILURE, -1);
1829 /* Start SKE as initiator */
1830 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1835 /******************************** Responder *********************************/
1837 /* Start protocol as responder. Wait initiator's start payload */
1839 SILC_FSM_STATE(silc_ske_st_responder_start)
1841 SilcSKE ske = fsm_context;
1843 SILC_LOG_DEBUG(("Start"));
1847 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1848 return SILC_FSM_CONTINUE;
1851 /* Add key exchange timeout */
1852 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1853 ske, ske->timeout, 0);
1855 /** Wait for initiator */
1856 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1857 return SILC_FSM_WAIT;
1860 /* Decode initiator's start payload. Select the security properties from
1861 the initiator's start payload and send our reply start payload back. */
1863 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1865 SilcSKE ske = fsm_context;
1866 SilcSKEStatus status;
1867 SilcSKEStartPayload remote_payload = NULL;
1868 SilcBuffer packet_buf = &ske->packet->buffer;
1870 SILC_LOG_DEBUG(("Start"));
1872 /* Decode the payload */
1873 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1874 if (status != SILC_SKE_STATUS_OK) {
1875 /** Error decoding Start Payload */
1876 silc_packet_free(ske->packet);
1878 ske->status = status;
1879 silc_fsm_next(fsm, silc_ske_st_responder_error);
1880 return SILC_FSM_CONTINUE;
1883 /* Take a copy of the payload buffer for future use. It is used to
1884 compute the HASH value. */
1885 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1887 silc_packet_free(ske->packet);
1890 /* Force the mutual authentication flag if we want to do it. */
1891 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1892 SILC_LOG_DEBUG(("Force mutual authentication"));
1893 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1896 /* Force PFS flag if we require it */
1897 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1898 SILC_LOG_DEBUG(("Force PFS"));
1899 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1902 /* Disable IV Included flag if requested */
1903 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1904 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1905 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1906 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1909 /* Check and select security properties */
1910 status = silc_ske_select_security_properties(ske, remote_payload,
1912 if (status != SILC_SKE_STATUS_OK) {
1913 /** Error selecting proposal */
1914 silc_ske_payload_start_free(remote_payload);
1915 ske->status = status;
1916 silc_fsm_next(fsm, silc_ske_st_responder_error);
1917 return SILC_FSM_CONTINUE;
1920 silc_ske_payload_start_free(remote_payload);
1922 /* Encode our reply payload to send the selected security properties */
1923 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1925 if (status != SILC_SKE_STATUS_OK)
1928 /* Send the packet. */
1929 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1930 silc_buffer_data(packet_buf),
1931 silc_buffer_len(packet_buf)))
1934 silc_buffer_free(packet_buf);
1936 /** Waiting initiator's KE payload */
1937 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1938 return SILC_FSM_WAIT;
1941 if (ske->prop->group)
1942 silc_ske_group_free(ske->prop->group);
1943 if (ske->prop->cipher)
1944 silc_cipher_free(ske->prop->cipher);
1945 if (ske->prop->hash)
1946 silc_hash_free(ske->prop->hash);
1947 if (ske->prop->hmac)
1948 silc_hmac_free(ske->prop->hmac);
1949 silc_free(ske->prop);
1952 if (status == SILC_SKE_STATUS_OK)
1953 status = SILC_SKE_STATUS_ERROR;
1956 ske->status = status;
1957 silc_fsm_next(fsm, silc_ske_st_responder_error);
1958 return SILC_FSM_CONTINUE;
1961 /* Phase-2. Decode initiator's KE payload */
1963 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1965 SilcSKE ske = fsm_context;
1966 SilcSKEStatus status;
1967 SilcSKEKEPayload recv_payload;
1968 SilcBuffer packet_buf = &ske->packet->buffer;
1970 SILC_LOG_DEBUG(("Start"));
1972 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1973 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1974 silc_ske_install_retransmission(ske);
1975 silc_packet_free(ske->packet);
1977 return SILC_FSM_WAIT;
1980 /* Decode Key Exchange Payload */
1981 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1982 if (status != SILC_SKE_STATUS_OK) {
1983 /** Error decoding KE payload */
1984 silc_packet_free(ske->packet);
1986 ske->status = status;
1987 silc_fsm_next(fsm, silc_ske_st_responder_error);
1988 return SILC_FSM_CONTINUE;
1991 ske->ke1_payload = recv_payload;
1993 silc_packet_free(ske->packet);
1996 /* Verify the received public key and verify the signature if we are
1997 doing mutual authentication. */
1998 if (ske->start_payload &&
1999 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2001 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2003 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2005 /** Public key not provided */
2006 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2007 "certificate), even though we require it"));
2008 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2009 silc_fsm_next(fsm, silc_ske_st_responder_error);
2010 return SILC_FSM_CONTINUE;
2013 /* Decode the remote's public key */
2014 if (recv_payload->pk_data &&
2015 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2016 recv_payload->pk_data,
2017 recv_payload->pk_len,
2018 &ske->prop->public_key)) {
2019 /** Error decoding public key */
2020 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2021 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2022 silc_fsm_next(fsm, silc_ske_st_responder_error);
2023 return SILC_FSM_CONTINUE;
2026 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2028 SILC_LOG_DEBUG(("Verifying public key"));
2030 /** Waiting public key verification */
2031 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2033 /* If repository is provided, verify the key from there. */
2034 if (ske->repository) {
2037 find = silc_skr_find_alloc();
2039 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2040 silc_fsm_next(fsm, silc_ske_st_responder_error);
2041 return SILC_FSM_CONTINUE;
2043 silc_skr_find_set_pkcs_type(find,
2044 silc_pkcs_get_type(ske->prop->public_key));
2045 silc_skr_find_set_public_key(find, ske->prop->public_key);
2046 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2048 /* Find key from repository */
2049 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2050 silc_ske_skr_callback, ske));
2052 /* Verify from application */
2053 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2054 ske->callbacks->context,
2055 silc_ske_pk_verified, NULL));
2061 /** Generate KE2 payload */
2062 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2063 return SILC_FSM_CONTINUE;
2066 /* Phase-4. Generate KE2 payload */
2068 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2070 SilcSKE ske = fsm_context;
2071 SilcSKEStatus status;
2072 SilcSKEKEPayload recv_payload, send_payload;
2077 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2078 return SILC_FSM_CONTINUE;
2081 /* Check result of public key verification */
2082 if (ske->status != SILC_SKE_STATUS_OK) {
2083 /** Public key not verified */
2084 SILC_LOG_DEBUG(("Public key verification failed"));
2085 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2086 return SILC_FSM_CONTINUE;
2089 recv_payload = ske->ke1_payload;
2091 /* The public key verification was performed only if the Mutual
2092 Authentication flag is set. */
2093 if (ske->start_payload &&
2094 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2095 unsigned char hash[SILC_HASH_MAXLEN];
2096 SilcUInt32 hash_len;
2098 SILC_LOG_DEBUG(("Public key is authentic"));
2100 /* Compute the hash value */
2101 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2102 if (status != SILC_SKE_STATUS_OK) {
2103 /** Error computing hash */
2104 ske->status = status;
2105 silc_fsm_next(fsm, silc_ske_st_responder_error);
2106 return SILC_FSM_CONTINUE;
2109 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2111 /* Verify signature */
2112 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2113 recv_payload->sign_len, hash, hash_len, NULL)) {
2114 /** Incorrect signature */
2115 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2116 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2117 silc_fsm_next(fsm, silc_ske_st_responder_error);
2118 return SILC_FSM_CONTINUE;
2121 SILC_LOG_DEBUG(("Signature is Ok"));
2123 memset(hash, 'F', hash_len);
2126 /* Create the random number x, 1 < x < q. */
2127 x = silc_calloc(1, sizeof(*x));
2130 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2131 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2133 if (status != SILC_SKE_STATUS_OK) {
2134 /** Error generating random number */
2137 ske->status = status;
2138 silc_fsm_next(fsm, silc_ske_st_responder_error);
2139 return SILC_FSM_CONTINUE;
2142 /* Save the results for later processing */
2143 send_payload = silc_calloc(1, sizeof(*send_payload));
2145 ske->ke2_payload = send_payload;
2147 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2149 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2150 silc_mp_init(&send_payload->x);
2151 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2152 &ske->prop->group->group);
2154 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2156 /* Compute the shared secret key */
2157 KEY = silc_calloc(1, sizeof(*KEY));
2159 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2160 &ske->prop->group->group);
2163 /** Send KE2 payload */
2164 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2165 return SILC_FSM_CONTINUE;
2168 /* Phase-5. Send KE2 payload */
2170 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2172 SilcSKE ske = fsm_context;
2173 SilcSKEStatus status;
2174 SilcBuffer payload_buf;
2175 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2176 SilcUInt32 hash_len, sign_len, pk_len;
2178 SILC_LOG_DEBUG(("Start"));
2180 if (ske->public_key && ske->private_key) {
2181 SILC_LOG_DEBUG(("Getting public key"));
2183 /* Get the public key */
2184 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2186 /** Error encoding public key */
2187 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2188 silc_fsm_next(fsm, silc_ske_st_responder_error);
2189 return SILC_FSM_CONTINUE;
2191 ske->ke2_payload->pk_data = pk;
2192 ske->ke2_payload->pk_len = pk_len;
2194 SILC_LOG_DEBUG(("Computing HASH value"));
2196 /* Compute the hash value */
2197 memset(hash, 0, sizeof(hash));
2198 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2199 if (status != SILC_SKE_STATUS_OK) {
2200 /** Error computing hash */
2201 ske->status = status;
2202 silc_fsm_next(fsm, silc_ske_st_responder_error);
2203 return SILC_FSM_CONTINUE;
2206 ske->hash = silc_memdup(hash, hash_len);
2207 ske->hash_len = hash_len;
2209 SILC_LOG_DEBUG(("Signing HASH value"));
2211 /* Sign the hash value */
2212 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2213 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2214 /** Error computing signature */
2215 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2216 silc_fsm_next(fsm, silc_ske_st_responder_error);
2217 return SILC_FSM_CONTINUE;
2219 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2220 ske->ke2_payload->sign_len = sign_len;
2221 memset(sign, 0, sizeof(sign));
2223 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2225 /* Encode the Key Exchange Payload */
2226 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2228 if (status != SILC_SKE_STATUS_OK) {
2229 /** Error encoding KE payload */
2230 ske->status = status;
2231 silc_fsm_next(fsm, silc_ske_st_responder_error);
2232 return SILC_FSM_CONTINUE;
2235 /* Send the packet. */
2236 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2237 payload_buf->data, silc_buffer_len(payload_buf))) {
2238 SILC_LOG_DEBUG(("Error sending packet"));
2239 ske->status = SILC_SKE_STATUS_ERROR;
2240 silc_fsm_next(fsm, silc_ske_st_responder_error);
2241 return SILC_FSM_CONTINUE;
2244 silc_buffer_free(payload_buf);
2246 /** Waiting completion */
2247 silc_fsm_next(fsm, silc_ske_st_responder_end);
2248 return SILC_FSM_WAIT;
2251 /* Protocol completed */
2253 SILC_FSM_STATE(silc_ske_st_responder_end)
2255 SilcSKE ske = fsm_context;
2256 unsigned char tmp[4];
2257 SilcUInt32 hash_len, key_len, block_len;
2259 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2260 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2261 silc_ske_install_retransmission(ske);
2262 silc_packet_free(ske->packet);
2264 return SILC_FSM_WAIT;
2266 silc_packet_free(ske->packet);
2269 /* Process key material */
2270 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2271 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2272 hash_len = silc_hash_len(ske->prop->hash);
2273 ske->keymat = silc_ske_process_key_material(ske, block_len,
2277 /** Error processing key material */
2278 ske->status = SILC_SKE_STATUS_ERROR;
2279 silc_fsm_next(fsm, silc_ske_st_responder_error);
2280 return SILC_FSM_CONTINUE;
2283 /* Send SUCCESS packet */
2284 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2285 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2287 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2288 silc_schedule_task_del_by_context(ske->schedule, ske);
2290 return SILC_FSM_FINISH;
2293 /* Aborted by application */
2295 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2297 SilcSKE ske = fsm_context;
2298 unsigned char tmp[4];
2300 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2302 /* Send FAILURE packet */
2303 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2304 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2306 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2307 silc_schedule_task_del_by_context(ske->schedule, ske);
2309 return SILC_FSM_FINISH;
2312 /* Failure received from remote */
2314 SILC_FSM_STATE(silc_ske_st_responder_failure)
2316 SilcSKE ske = fsm_context;
2317 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2319 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2321 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2322 SILC_GET32_MSB(error, ske->packet->buffer.data);
2323 ske->status = error;
2324 silc_packet_free(ske->packet);
2328 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2329 silc_schedule_task_del_by_context(ske->schedule, ske);
2331 return SILC_FSM_FINISH;
2334 /* Error occurred */
2336 SILC_FSM_STATE(silc_ske_st_responder_error)
2338 SilcSKE ske = fsm_context;
2339 unsigned char tmp[4];
2341 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2342 ske->status, silc_ske_map_status(ske->status)));
2344 /* Send FAILURE packet */
2345 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2346 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2347 SILC_PUT32_MSB(ske->status, tmp);
2348 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2350 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2351 silc_schedule_task_del_by_context(ske->schedule, ske);
2353 return SILC_FSM_FINISH;
2356 /* Starts the protocol as responder. */
2358 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2359 SilcPacketStream stream,
2360 SilcSKEParams params)
2362 SILC_LOG_DEBUG(("Start SKE as responder"));
2364 if (!ske || !stream || !params || !params->version)
2367 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2370 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2373 ske->responder = TRUE;
2374 ske->flags = params->flags;
2375 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2376 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2377 ske->session_port = params->session_port;
2378 ske->version = strdup(params->version);
2381 ske->running = TRUE;
2383 /* Link to packet stream to get key exchange packets */
2384 ske->stream = stream;
2385 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2386 SILC_PACKET_KEY_EXCHANGE,
2387 SILC_PACKET_KEY_EXCHANGE_1,
2388 SILC_PACKET_SUCCESS,
2389 SILC_PACKET_FAILURE, -1);
2391 /* Start SKE as responder */
2392 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2397 /***************************** Initiator Rekey ******************************/
2401 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2403 SilcSKE ske = fsm_context;
2406 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2410 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2411 return SILC_FSM_CONTINUE;
2414 /* Add rekey exchange timeout */
2415 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2418 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2421 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2422 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2423 return SILC_FSM_CONTINUE;
2426 /* Send REKEY packet to start rekey protocol */
2427 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2428 /** Error sending packet */
2429 SILC_LOG_DEBUG(("Error sending packet"));
2430 ske->status = SILC_SKE_STATUS_ERROR;
2431 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2432 return SILC_FSM_CONTINUE;
2435 /* If doing rekey without PFS, move directly to the end of the protocol. */
2436 if (!ske->rekey->pfs) {
2437 /** Rekey without PFS */
2438 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2439 return SILC_FSM_CONTINUE;
2442 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2444 if (status != SILC_SKE_STATUS_OK) {
2445 /** Unknown group */
2446 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2447 return SILC_FSM_CONTINUE;
2450 /** Rekey with PFS */
2451 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2452 return SILC_FSM_CONTINUE;
2455 /* Sends REKEY_DONE packet to finish the protocol. */
2457 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2459 SilcSKE ske = fsm_context;
2460 SilcCipher send_key;
2463 SilcUInt32 key_len, block_len, hash_len, x_len;
2464 unsigned char *pfsbuf;
2466 SILC_LOG_DEBUG(("Start"));
2468 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2469 key_len = silc_cipher_get_key_len(send_key);
2470 block_len = silc_cipher_get_block_len(send_key);
2472 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2473 /** Cannot allocate hash */
2474 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2475 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2476 return SILC_FSM_CONTINUE;
2478 hash_len = silc_hash_len(hash);
2480 /* Process key material */
2481 if (ske->rekey->pfs) {
2483 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2485 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2488 memset(pfsbuf, 0, x_len);
2494 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2495 ske->rekey->enc_key_len / 8,
2501 SILC_LOG_ERROR(("Error processing key material"));
2502 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2503 return SILC_FSM_CONTINUE;
2506 ske->prop->cipher = send_key;
2507 ske->prop->hmac = hmac_send;
2508 ske->prop->hash = hash;
2510 /* Get sending keys */
2511 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2512 &hmac_send, NULL, NULL)) {
2513 /** Cannot get keys */
2514 ske->status = SILC_SKE_STATUS_ERROR;
2515 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2516 return SILC_FSM_CONTINUE;
2519 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2520 packet sent after this call will be protected with the new keys. */
2521 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2523 /** Cannot set keys */
2524 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2525 ske->status = SILC_SKE_STATUS_ERROR;
2526 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2527 return SILC_FSM_CONTINUE;
2530 /** Wait for REKEY_DONE */
2531 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2532 return SILC_FSM_WAIT;
2535 /* Rekey protocol end */
2537 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2539 SilcSKE ske = fsm_context;
2540 SilcCipher receive_key;
2541 SilcHmac hmac_receive;
2542 SilcSKERekeyMaterial rekey;
2544 SILC_LOG_DEBUG(("Start"));
2546 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2547 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2548 silc_packet_free(ske->packet);
2550 return SILC_FSM_WAIT;
2553 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2554 ske->prop->cipher = receive_key;
2555 ske->prop->hmac = hmac_receive;
2557 /* Get receiving keys */
2558 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2559 NULL, &hmac_receive, NULL)) {
2560 /** Cannot get keys */
2561 ske->status = SILC_SKE_STATUS_ERROR;
2562 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2563 return SILC_FSM_CONTINUE;
2566 /* Set new receiving keys into use. All packets received after this will
2567 be decrypted with the new keys. */
2568 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2569 hmac_receive, FALSE)) {
2570 /** Cannot set keys */
2571 SILC_LOG_DEBUG(("Cannot set new keys"));
2572 ske->status = SILC_SKE_STATUS_ERROR;
2573 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2574 return SILC_FSM_CONTINUE;
2577 SILC_LOG_DEBUG(("Rekey completed successfully"));
2579 /* Generate new rekey material */
2580 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2583 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2584 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2585 return SILC_FSM_CONTINUE;
2587 rekey->pfs = ske->rekey->pfs;
2590 ske->prop->cipher = NULL;
2591 ske->prop->hmac = NULL;
2592 silc_packet_free(ske->packet);
2594 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2595 silc_schedule_task_del_by_context(ske->schedule, ske);
2597 return SILC_FSM_FINISH;
2600 /* Starts rekey protocol as initiator */
2603 silc_ske_rekey_initiator(SilcSKE ske,
2604 SilcPacketStream stream,
2605 SilcSKERekeyMaterial rekey)
2607 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2609 if (!ske || !stream || !rekey)
2612 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2615 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2619 ske->responder = FALSE;
2620 ske->running = TRUE;
2621 ske->rekeying = TRUE;
2623 /* Link to packet stream to get key exchange packets */
2624 ske->stream = stream;
2625 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2627 SILC_PACKET_REKEY_DONE,
2628 SILC_PACKET_KEY_EXCHANGE_2,
2629 SILC_PACKET_SUCCESS,
2630 SILC_PACKET_FAILURE, -1);
2632 /* Start SKE rekey as initiator */
2633 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2638 /***************************** Responder Rekey ******************************/
2640 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2642 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2644 return SILC_FSM_FINISH;
2647 /* Starts rekey protocol as responder */
2650 silc_ske_rekey_responder(SilcSKE ske,
2651 SilcPacketStream stream,
2652 SilcSKERekeyMaterial rekey)
2654 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2656 if (!ske || !stream || !rekey)
2659 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2662 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2666 ske->responder = TRUE;
2667 ske->running = TRUE;
2668 ske->rekeying = TRUE;
2670 /* Link to packet stream to get key exchange packets */
2671 ske->stream = stream;
2672 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2674 SILC_PACKET_REKEY_DONE,
2675 SILC_PACKET_KEY_EXCHANGE_1,
2676 SILC_PACKET_SUCCESS,
2677 SILC_PACKET_FAILURE, -1);
2679 /* Start SKE rekey as responder */
2680 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2685 /* Processes the provided key material `data' as the SILC protocol
2686 specification defines. */
2689 silc_ske_process_key_material_data(unsigned char *data,
2690 SilcUInt32 data_len,
2691 SilcUInt32 req_iv_len,
2692 SilcUInt32 req_enc_key_len,
2693 SilcUInt32 req_hmac_key_len,
2697 unsigned char hashd[SILC_HASH_MAXLEN];
2698 SilcUInt32 hash_len = req_hmac_key_len;
2699 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2700 SilcSKEKeyMaterial key;
2702 SILC_LOG_DEBUG(("Start"));
2704 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2707 key = silc_calloc(1, sizeof(*key));
2711 buf = silc_buffer_alloc_size(1 + data_len);
2714 silc_buffer_format(buf,
2715 SILC_STR_UI_CHAR(0),
2716 SILC_STR_UI_XNSTRING(data, data_len),
2720 memset(hashd, 0, sizeof(hashd));
2722 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2723 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2724 memcpy(key->send_iv, hashd, req_iv_len);
2725 memset(hashd, 0, sizeof(hashd));
2727 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2728 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2729 memcpy(key->receive_iv, hashd, req_iv_len);
2730 key->iv_len = req_iv_len;
2732 /* Take the encryption keys. If requested key size is more than
2733 the size of hash length we will distribute more key material
2734 as protocol defines. */
2736 if (enc_key_len > hash_len) {
2738 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2739 k3[SILC_HASH_MAXLEN];
2740 unsigned char *dtmp;
2743 if (enc_key_len > (3 * hash_len))
2746 /* Take first round */
2747 memset(k1, 0, sizeof(k1));
2748 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2750 /* Take second round */
2751 dist = silc_buffer_alloc_size(data_len + hash_len);
2754 silc_buffer_format(dist,
2755 SILC_STR_UI_XNSTRING(data, data_len),
2756 SILC_STR_UI_XNSTRING(k1, hash_len),
2758 memset(k2, 0, sizeof(k2));
2759 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2761 /* Take third round */
2762 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2763 silc_buffer_pull_tail(dist, hash_len);
2764 silc_buffer_pull(dist, data_len + hash_len);
2765 silc_buffer_format(dist,
2766 SILC_STR_UI_XNSTRING(k2, hash_len),
2768 silc_buffer_push(dist, data_len + hash_len);
2769 memset(k3, 0, sizeof(k3));
2770 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2772 /* Then, save the keys */
2773 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2774 memcpy(dtmp, k1, hash_len);
2775 memcpy(dtmp + hash_len, k2, hash_len);
2776 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2778 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2779 memcpy(key->send_enc_key, dtmp, enc_key_len);
2780 key->enc_key_len = req_enc_key_len;
2782 memset(dtmp, 0, (3 * hash_len));
2783 memset(k1, 0, sizeof(k1));
2784 memset(k2, 0, sizeof(k2));
2785 memset(k3, 0, sizeof(k3));
2787 silc_buffer_clear(dist);
2788 silc_buffer_free(dist);
2790 /* Take normal hash as key */
2791 memset(hashd, 0, sizeof(hashd));
2792 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2793 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2794 memcpy(key->send_enc_key, hashd, enc_key_len);
2795 key->enc_key_len = req_enc_key_len;
2799 if (enc_key_len > hash_len) {
2801 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2802 k3[SILC_HASH_MAXLEN];
2803 unsigned char *dtmp;
2806 if (enc_key_len > (3 * hash_len))
2809 /* Take first round */
2810 memset(k1, 0, sizeof(k1));
2811 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2813 /* Take second round */
2814 dist = silc_buffer_alloc_size(data_len + hash_len);
2817 silc_buffer_format(dist,
2818 SILC_STR_UI_XNSTRING(data, data_len),
2819 SILC_STR_UI_XNSTRING(k1, hash_len),
2821 memset(k2, 0, sizeof(k2));
2822 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2824 /* Take third round */
2825 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2826 silc_buffer_pull_tail(dist, hash_len);
2827 silc_buffer_pull(dist, data_len + hash_len);
2828 silc_buffer_format(dist,
2829 SILC_STR_UI_XNSTRING(k2, hash_len),
2831 silc_buffer_push(dist, data_len + hash_len);
2832 memset(k3, 0, sizeof(k3));
2833 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2835 /* Then, save the keys */
2836 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2837 memcpy(dtmp, k1, hash_len);
2838 memcpy(dtmp + hash_len, k2, hash_len);
2839 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2841 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2842 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2843 key->enc_key_len = req_enc_key_len;
2845 memset(dtmp, 0, (3 * hash_len));
2846 memset(k1, 0, sizeof(k1));
2847 memset(k2, 0, sizeof(k2));
2848 memset(k3, 0, sizeof(k3));
2850 silc_buffer_clear(dist);
2851 silc_buffer_free(dist);
2853 /* Take normal hash as key */
2854 memset(hashd, 0, sizeof(hashd));
2855 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2856 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2857 memcpy(key->receive_enc_key, hashd, enc_key_len);
2858 key->enc_key_len = req_enc_key_len;
2861 /* Take HMAC keys */
2862 memset(hashd, 0, sizeof(hashd));
2864 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2865 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2866 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2867 memset(hashd, 0, sizeof(hashd));
2869 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2870 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2871 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2872 key->hmac_key_len = req_hmac_key_len;
2873 memset(hashd, 0, sizeof(hashd));
2875 silc_buffer_clear(buf);
2876 silc_buffer_free(buf);
2878 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
2883 /* Processes negotiated key material as protocol specifies. This returns
2884 the actual keys to be used in the SILC. */
2887 silc_ske_process_key_material(SilcSKE ske,
2888 SilcUInt32 req_iv_len,
2889 SilcUInt32 req_enc_key_len,
2890 SilcUInt32 req_hmac_key_len,
2891 SilcSKERekeyMaterial *rekey)
2894 unsigned char *tmpbuf;
2896 SilcSKEKeyMaterial key;
2898 /* Encode KEY to binary data */
2899 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2901 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2904 silc_buffer_format(buf,
2905 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2906 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2909 /* Process the key material */
2910 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2911 req_iv_len, req_enc_key_len,
2915 memset(tmpbuf, 0, klen);
2917 silc_buffer_clear(buf);
2918 silc_buffer_free(buf);
2921 *rekey = silc_ske_make_rekey_material(ske, key);
2929 /* Free key material structure */
2931 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2937 silc_free(key->send_iv);
2938 if (key->receive_iv)
2939 silc_free(key->receive_iv);
2940 if (key->send_enc_key) {
2941 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2942 silc_free(key->send_enc_key);
2944 if (key->receive_enc_key) {
2945 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2946 silc_free(key->receive_enc_key);
2948 if (key->send_hmac_key) {
2949 memset(key->send_hmac_key, 0, key->hmac_key_len);
2950 silc_free(key->send_hmac_key);
2952 if (key->receive_hmac_key) {
2953 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2954 silc_free(key->receive_hmac_key);
2959 /* Free rekey material */
2961 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
2965 if (rekey->send_enc_key) {
2966 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
2967 silc_free(rekey->send_enc_key);
2969 silc_free(rekey->hash);
2973 /* Set keys into use */
2975 SilcBool silc_ske_set_keys(SilcSKE ske,
2976 SilcSKEKeyMaterial keymat,
2977 SilcSKESecurityProperties prop,
2978 SilcCipher *ret_send_key,
2979 SilcCipher *ret_receive_key,
2980 SilcHmac *ret_hmac_send,
2981 SilcHmac *ret_hmac_receive,
2984 unsigned char iv[32];
2986 /* Allocate ciphers to be used in the communication */
2988 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2992 if (ret_receive_key) {
2993 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2998 /* Allocate HMACs */
2999 if (ret_hmac_send) {
3000 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3004 if (ret_hmac_receive) {
3005 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3010 /* Set key material */
3011 memset(iv, 0, sizeof(iv));
3012 if (ske->responder) {
3014 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3015 keymat->enc_key_len, TRUE);
3017 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3018 memcpy(iv, ske->hash, 4);
3019 memcpy(iv + 4, keymat->receive_iv, 4);
3020 silc_cipher_set_iv(*ret_send_key, iv);
3022 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3025 if (ret_receive_key) {
3026 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3027 keymat->enc_key_len, FALSE);
3029 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3030 memcpy(iv, ske->hash, 4);
3031 memcpy(iv + 4, keymat->send_iv, 4);
3032 silc_cipher_set_iv(*ret_receive_key, iv);
3034 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3038 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3039 keymat->hmac_key_len);
3040 if (ret_hmac_receive)
3041 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3042 keymat->hmac_key_len);
3045 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3046 keymat->enc_key_len, TRUE);
3048 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3049 memcpy(iv, ske->hash, 4);
3050 memcpy(iv + 4, keymat->send_iv, 4);
3051 silc_cipher_set_iv(*ret_send_key, iv);
3053 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3056 if (ret_receive_key) {
3057 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3058 keymat->enc_key_len, FALSE);
3060 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3061 memcpy(iv, ske->hash, 4);
3062 memcpy(iv + 4, keymat->receive_iv, 4);
3063 silc_cipher_set_iv(*ret_receive_key, iv);
3065 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3069 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3070 keymat->hmac_key_len);
3071 if (ret_hmac_receive)
3072 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3073 keymat->hmac_key_len);
3078 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3085 const char *silc_ske_status_string[] =
3089 "Unkown error occurred",
3090 "Bad payload in packet",
3091 "Unsupported group",
3092 "Unsupported cipher",
3094 "Unsupported hash function",
3096 "Unsupported public key (or certificate)",
3097 "Incorrect signature",
3098 "Bad or unsupported version",
3102 "Remote did not provide public key",
3103 "Bad reserved field in packet",
3104 "Bad payload length in packet",
3105 "Error computing signature",
3106 "System out of memory",
3107 "Key exchange timeout",
3112 /* Maps status to readable string and returns the string. If string is not
3113 found and empty character string ("") is returned. */
3115 const char *silc_ske_map_status(SilcSKEStatus status)
3119 for (i = 0; silc_ske_status_string[i]; i++)
3121 return silc_ske_status_string[i];
3126 /* Parses remote host's version string. */
3128 SilcBool silc_ske_parse_version(SilcSKE ske,
3129 SilcUInt32 *protocol_version,
3130 char **protocol_version_string,
3131 SilcUInt32 *software_version,
3132 char **software_version_string,
3133 char **vendor_version)
3135 return silc_parse_version_string(ske->remote_version,
3137 protocol_version_string,
3139 software_version_string,
3143 /* Get security properties */
3145 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3150 /* Get key material */
3152 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)