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 */
1789 silc_ske_initiator(SilcSKE ske,
1790 SilcPacketStream stream,
1791 SilcSKEParams params,
1792 SilcSKEStartPayload start_payload)
1794 SILC_LOG_DEBUG(("Start SKE as initiator"));
1796 if (!ske || !stream || !params || !params->version)
1799 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1802 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1805 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1806 ske->session_port = params->session_port;
1808 /* Generate security properties if not provided */
1809 if (!start_payload) {
1810 start_payload = silc_ske_assemble_security_properties(ske,
1817 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1818 ske->start_payload = start_payload;
1819 ske->version = params->version;
1820 ske->running = TRUE;
1822 /* Link to packet stream to get key exchange packets */
1823 ske->stream = stream;
1824 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1825 SILC_PACKET_KEY_EXCHANGE,
1826 SILC_PACKET_KEY_EXCHANGE_2,
1827 SILC_PACKET_SUCCESS,
1828 SILC_PACKET_FAILURE, -1);
1830 /* Start SKE as initiator */
1831 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1836 /******************************** Responder *********************************/
1838 /* Start protocol as responder. Wait initiator's start payload */
1840 SILC_FSM_STATE(silc_ske_st_responder_start)
1842 SilcSKE ske = fsm_context;
1844 SILC_LOG_DEBUG(("Start"));
1848 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1849 return SILC_FSM_CONTINUE;
1852 /* Add key exchange timeout */
1853 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1854 ske, ske->timeout, 0);
1856 /** Wait for initiator */
1857 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1858 return SILC_FSM_WAIT;
1861 /* Decode initiator's start payload. Select the security properties from
1862 the initiator's start payload and send our reply start payload back. */
1864 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1866 SilcSKE ske = fsm_context;
1867 SilcSKEStatus status;
1868 SilcSKEStartPayload remote_payload = NULL;
1869 SilcBuffer packet_buf = &ske->packet->buffer;
1871 SILC_LOG_DEBUG(("Start"));
1873 /* Decode the payload */
1874 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1875 if (status != SILC_SKE_STATUS_OK) {
1876 /** Error decoding Start Payload */
1877 silc_packet_free(ske->packet);
1879 ske->status = status;
1880 silc_fsm_next(fsm, silc_ske_st_responder_error);
1881 return SILC_FSM_CONTINUE;
1884 /* Take a copy of the payload buffer for future use. It is used to
1885 compute the HASH value. */
1886 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1888 silc_packet_free(ske->packet);
1891 /* Force the mutual authentication flag if we want to do it. */
1892 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1893 SILC_LOG_DEBUG(("Force mutual authentication"));
1894 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1897 /* Force PFS flag if we require it */
1898 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1899 SILC_LOG_DEBUG(("Force PFS"));
1900 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1903 /* Disable IV Included flag if requested */
1904 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1905 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1906 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1907 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1910 /* Check and select security properties */
1911 status = silc_ske_select_security_properties(ske, remote_payload,
1913 if (status != SILC_SKE_STATUS_OK) {
1914 /** Error selecting proposal */
1915 silc_ske_payload_start_free(remote_payload);
1916 ske->status = status;
1917 silc_fsm_next(fsm, silc_ske_st_responder_error);
1918 return SILC_FSM_CONTINUE;
1921 silc_ske_payload_start_free(remote_payload);
1923 /* Encode our reply payload to send the selected security properties */
1924 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1926 if (status != SILC_SKE_STATUS_OK)
1929 /* Send the packet. */
1930 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1931 silc_buffer_data(packet_buf),
1932 silc_buffer_len(packet_buf)))
1935 silc_buffer_free(packet_buf);
1937 /** Waiting initiator's KE payload */
1938 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1939 return SILC_FSM_WAIT;
1942 if (ske->prop->group)
1943 silc_ske_group_free(ske->prop->group);
1944 if (ske->prop->cipher)
1945 silc_cipher_free(ske->prop->cipher);
1946 if (ske->prop->hash)
1947 silc_hash_free(ske->prop->hash);
1948 if (ske->prop->hmac)
1949 silc_hmac_free(ske->prop->hmac);
1950 silc_free(ske->prop);
1953 if (status == SILC_SKE_STATUS_OK)
1954 status = SILC_SKE_STATUS_ERROR;
1957 ske->status = status;
1958 silc_fsm_next(fsm, silc_ske_st_responder_error);
1959 return SILC_FSM_CONTINUE;
1962 /* Phase-2. Decode initiator's KE payload */
1964 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1966 SilcSKE ske = fsm_context;
1967 SilcSKEStatus status;
1968 SilcSKEKEPayload recv_payload;
1969 SilcBuffer packet_buf = &ske->packet->buffer;
1971 SILC_LOG_DEBUG(("Start"));
1973 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1974 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1975 silc_ske_install_retransmission(ske);
1976 silc_packet_free(ske->packet);
1978 return SILC_FSM_WAIT;
1981 /* Decode Key Exchange Payload */
1982 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1983 if (status != SILC_SKE_STATUS_OK) {
1984 /** Error decoding KE payload */
1985 silc_packet_free(ske->packet);
1987 ske->status = status;
1988 silc_fsm_next(fsm, silc_ske_st_responder_error);
1989 return SILC_FSM_CONTINUE;
1992 ske->ke1_payload = recv_payload;
1994 silc_packet_free(ske->packet);
1997 /* Verify the received public key and verify the signature if we are
1998 doing mutual authentication. */
1999 if (ske->start_payload &&
2000 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2002 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2004 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2006 /** Public key not provided */
2007 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2008 "certificate), even though we require it"));
2009 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2010 silc_fsm_next(fsm, silc_ske_st_responder_error);
2011 return SILC_FSM_CONTINUE;
2014 /* Decode the remote's public key */
2015 if (recv_payload->pk_data &&
2016 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2017 recv_payload->pk_data,
2018 recv_payload->pk_len,
2019 &ske->prop->public_key)) {
2020 /** Error decoding public key */
2021 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2022 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2023 silc_fsm_next(fsm, silc_ske_st_responder_error);
2024 return SILC_FSM_CONTINUE;
2027 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2029 SILC_LOG_DEBUG(("Verifying public key"));
2031 /** Waiting public key verification */
2032 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2034 /* If repository is provided, verify the key from there. */
2035 if (ske->repository) {
2038 find = silc_skr_find_alloc();
2040 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2041 silc_fsm_next(fsm, silc_ske_st_responder_error);
2042 return SILC_FSM_CONTINUE;
2044 silc_skr_find_set_pkcs_type(find,
2045 silc_pkcs_get_type(ske->prop->public_key));
2046 silc_skr_find_set_public_key(find, ske->prop->public_key);
2047 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2049 /* Find key from repository */
2050 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2051 silc_ske_skr_callback, ske));
2053 /* Verify from application */
2054 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2055 ske->callbacks->context,
2056 silc_ske_pk_verified, NULL));
2062 /** Generate KE2 payload */
2063 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2064 return SILC_FSM_CONTINUE;
2067 /* Phase-4. Generate KE2 payload */
2069 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2071 SilcSKE ske = fsm_context;
2072 SilcSKEStatus status;
2073 SilcSKEKEPayload recv_payload, send_payload;
2078 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2079 return SILC_FSM_CONTINUE;
2082 /* Check result of public key verification */
2083 if (ske->status != SILC_SKE_STATUS_OK) {
2084 /** Public key not verified */
2085 SILC_LOG_DEBUG(("Public key verification failed"));
2086 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2087 return SILC_FSM_CONTINUE;
2090 recv_payload = ske->ke1_payload;
2092 /* The public key verification was performed only if the Mutual
2093 Authentication flag is set. */
2094 if (ske->start_payload &&
2095 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2096 unsigned char hash[SILC_HASH_MAXLEN];
2097 SilcUInt32 hash_len;
2099 SILC_LOG_DEBUG(("Public key is authentic"));
2101 /* Compute the hash value */
2102 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2103 if (status != SILC_SKE_STATUS_OK) {
2104 /** Error computing hash */
2105 ske->status = status;
2106 silc_fsm_next(fsm, silc_ske_st_responder_error);
2107 return SILC_FSM_CONTINUE;
2110 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2112 /* Verify signature */
2113 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2114 recv_payload->sign_len, hash, hash_len, NULL)) {
2115 /** Incorrect signature */
2116 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2117 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2118 silc_fsm_next(fsm, silc_ske_st_responder_error);
2119 return SILC_FSM_CONTINUE;
2122 SILC_LOG_DEBUG(("Signature is Ok"));
2124 memset(hash, 'F', hash_len);
2127 /* Create the random number x, 1 < x < q. */
2128 x = silc_calloc(1, sizeof(*x));
2131 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2132 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2134 if (status != SILC_SKE_STATUS_OK) {
2135 /** Error generating random number */
2138 ske->status = status;
2139 silc_fsm_next(fsm, silc_ske_st_responder_error);
2140 return SILC_FSM_CONTINUE;
2143 /* Save the results for later processing */
2144 send_payload = silc_calloc(1, sizeof(*send_payload));
2146 ske->ke2_payload = send_payload;
2148 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2150 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2151 silc_mp_init(&send_payload->x);
2152 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2153 &ske->prop->group->group);
2155 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2157 /* Compute the shared secret key */
2158 KEY = silc_calloc(1, sizeof(*KEY));
2160 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2161 &ske->prop->group->group);
2164 /** Send KE2 payload */
2165 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2166 return SILC_FSM_CONTINUE;
2169 /* Phase-5. Send KE2 payload */
2171 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2173 SilcSKE ske = fsm_context;
2174 SilcSKEStatus status;
2175 SilcBuffer payload_buf;
2176 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2177 SilcUInt32 hash_len, sign_len, pk_len;
2179 SILC_LOG_DEBUG(("Start"));
2181 if (ske->public_key && ske->private_key) {
2182 SILC_LOG_DEBUG(("Getting public key"));
2184 /* Get the public key */
2185 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2187 /** Error encoding public key */
2188 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2189 silc_fsm_next(fsm, silc_ske_st_responder_error);
2190 return SILC_FSM_CONTINUE;
2192 ske->ke2_payload->pk_data = pk;
2193 ske->ke2_payload->pk_len = pk_len;
2195 SILC_LOG_DEBUG(("Computing HASH value"));
2197 /* Compute the hash value */
2198 memset(hash, 0, sizeof(hash));
2199 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2200 if (status != SILC_SKE_STATUS_OK) {
2201 /** Error computing hash */
2202 ske->status = status;
2203 silc_fsm_next(fsm, silc_ske_st_responder_error);
2204 return SILC_FSM_CONTINUE;
2207 ske->hash = silc_memdup(hash, hash_len);
2208 ske->hash_len = hash_len;
2210 SILC_LOG_DEBUG(("Signing HASH value"));
2212 /* Sign the hash value */
2213 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2214 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2215 /** Error computing signature */
2216 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2217 silc_fsm_next(fsm, silc_ske_st_responder_error);
2218 return SILC_FSM_CONTINUE;
2220 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2221 ske->ke2_payload->sign_len = sign_len;
2222 memset(sign, 0, sizeof(sign));
2224 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2226 /* Encode the Key Exchange Payload */
2227 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2229 if (status != SILC_SKE_STATUS_OK) {
2230 /** Error encoding KE payload */
2231 ske->status = status;
2232 silc_fsm_next(fsm, silc_ske_st_responder_error);
2233 return SILC_FSM_CONTINUE;
2236 /* Send the packet. */
2237 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2238 payload_buf->data, silc_buffer_len(payload_buf))) {
2239 SILC_LOG_DEBUG(("Error sending packet"));
2240 ske->status = SILC_SKE_STATUS_ERROR;
2241 silc_fsm_next(fsm, silc_ske_st_responder_error);
2242 return SILC_FSM_CONTINUE;
2245 silc_buffer_free(payload_buf);
2247 /** Waiting completion */
2248 silc_fsm_next(fsm, silc_ske_st_responder_end);
2249 return SILC_FSM_WAIT;
2252 /* Protocol completed */
2254 SILC_FSM_STATE(silc_ske_st_responder_end)
2256 SilcSKE ske = fsm_context;
2257 unsigned char tmp[4];
2258 SilcUInt32 hash_len, key_len, block_len;
2260 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2261 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2262 silc_ske_install_retransmission(ske);
2263 silc_packet_free(ske->packet);
2265 return SILC_FSM_WAIT;
2267 silc_packet_free(ske->packet);
2270 /* Process key material */
2271 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2272 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2273 hash_len = silc_hash_len(ske->prop->hash);
2274 ske->keymat = silc_ske_process_key_material(ske, block_len,
2278 /** Error processing key material */
2279 ske->status = SILC_SKE_STATUS_ERROR;
2280 silc_fsm_next(fsm, silc_ske_st_responder_error);
2281 return SILC_FSM_CONTINUE;
2284 /* Send SUCCESS packet */
2285 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2286 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2288 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2289 silc_schedule_task_del_by_context(ske->schedule, ske);
2291 return SILC_FSM_FINISH;
2294 /* Aborted by application */
2296 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2298 SilcSKE ske = fsm_context;
2299 unsigned char tmp[4];
2301 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2303 /* Send FAILURE packet */
2304 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2305 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2307 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2308 silc_schedule_task_del_by_context(ske->schedule, ske);
2310 return SILC_FSM_FINISH;
2313 /* Failure received from remote */
2315 SILC_FSM_STATE(silc_ske_st_responder_failure)
2317 SilcSKE ske = fsm_context;
2318 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2320 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2322 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2323 SILC_GET32_MSB(error, ske->packet->buffer.data);
2324 ske->status = error;
2325 silc_packet_free(ske->packet);
2329 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2330 silc_schedule_task_del_by_context(ske->schedule, ske);
2332 return SILC_FSM_FINISH;
2335 /* Error occurred */
2337 SILC_FSM_STATE(silc_ske_st_responder_error)
2339 SilcSKE ske = fsm_context;
2340 unsigned char tmp[4];
2342 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2343 ske->status, silc_ske_map_status(ske->status)));
2345 /* Send FAILURE packet */
2346 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2347 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2348 SILC_PUT32_MSB(ske->status, tmp);
2349 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2351 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2352 silc_schedule_task_del_by_context(ske->schedule, ske);
2354 return SILC_FSM_FINISH;
2357 /* Starts the protocol as responder. */
2360 silc_ske_responder(SilcSKE ske,
2361 SilcPacketStream stream,
2362 SilcSKEParams params)
2364 SILC_LOG_DEBUG(("Start SKE as responder"));
2366 if (!ske || !stream || !params || !params->version)
2369 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2372 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2375 ske->responder = TRUE;
2376 ske->flags = params->flags;
2377 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2378 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2379 ske->session_port = params->session_port;
2380 ske->version = strdup(params->version);
2383 ske->running = TRUE;
2385 /* Link to packet stream to get key exchange packets */
2386 ske->stream = stream;
2387 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2388 SILC_PACKET_KEY_EXCHANGE,
2389 SILC_PACKET_KEY_EXCHANGE_1,
2390 SILC_PACKET_SUCCESS,
2391 SILC_PACKET_FAILURE, -1);
2393 /* Start SKE as responder */
2394 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2399 /***************************** Initiator Rekey ******************************/
2403 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2405 SilcSKE ske = fsm_context;
2408 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2412 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2413 return SILC_FSM_CONTINUE;
2416 /* Add rekey exchange timeout */
2417 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2420 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2423 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2424 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2425 return SILC_FSM_CONTINUE;
2428 /* Send REKEY packet to start rekey protocol */
2429 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2430 /** Error sending packet */
2431 SILC_LOG_DEBUG(("Error sending packet"));
2432 ske->status = SILC_SKE_STATUS_ERROR;
2433 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2434 return SILC_FSM_CONTINUE;
2437 /* If doing rekey without PFS, move directly to the end of the protocol. */
2438 if (!ske->rekey->pfs) {
2439 /** Rekey without PFS */
2440 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2441 return SILC_FSM_CONTINUE;
2444 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2446 if (status != SILC_SKE_STATUS_OK) {
2447 /** Unknown group */
2448 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2449 return SILC_FSM_CONTINUE;
2452 /** Rekey with PFS */
2453 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2454 return SILC_FSM_CONTINUE;
2457 /* Sends REKEY_DONE packet to finish the protocol. */
2459 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2461 SilcSKE ske = fsm_context;
2462 SilcCipher send_key;
2465 SilcUInt32 key_len, block_len, hash_len, x_len;
2466 unsigned char *pfsbuf;
2468 SILC_LOG_DEBUG(("Start"));
2470 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2471 key_len = silc_cipher_get_key_len(send_key);
2472 block_len = silc_cipher_get_block_len(send_key);
2474 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2475 /** Cannot allocate hash */
2476 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2477 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2478 return SILC_FSM_CONTINUE;
2480 hash_len = silc_hash_len(hash);
2482 /* Process key material */
2483 if (ske->rekey->pfs) {
2485 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2487 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2490 memset(pfsbuf, 0, x_len);
2496 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2497 ske->rekey->enc_key_len / 8,
2503 SILC_LOG_ERROR(("Error processing key material"));
2504 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2505 return SILC_FSM_CONTINUE;
2508 ske->prop->cipher = send_key;
2509 ske->prop->hmac = hmac_send;
2510 ske->prop->hash = hash;
2512 /* Get sending keys */
2513 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2514 &hmac_send, NULL, NULL)) {
2515 /** Cannot get keys */
2516 ske->status = SILC_SKE_STATUS_ERROR;
2517 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2518 return SILC_FSM_CONTINUE;
2521 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2522 packet sent after this call will be protected with the new keys. */
2523 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2525 /** Cannot set keys */
2526 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2527 ske->status = SILC_SKE_STATUS_ERROR;
2528 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2529 return SILC_FSM_CONTINUE;
2532 /** Wait for REKEY_DONE */
2533 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2534 return SILC_FSM_WAIT;
2537 /* Rekey protocol end */
2539 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2541 SilcSKE ske = fsm_context;
2542 SilcCipher receive_key;
2543 SilcHmac hmac_receive;
2544 SilcSKERekeyMaterial rekey;
2546 SILC_LOG_DEBUG(("Start"));
2548 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2549 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2550 silc_packet_free(ske->packet);
2552 return SILC_FSM_WAIT;
2555 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2556 ske->prop->cipher = receive_key;
2557 ske->prop->hmac = hmac_receive;
2559 /* Get receiving keys */
2560 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2561 NULL, &hmac_receive, NULL)) {
2562 /** Cannot get keys */
2563 ske->status = SILC_SKE_STATUS_ERROR;
2564 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2565 return SILC_FSM_CONTINUE;
2568 /* Set new receiving keys into use. All packets received after this will
2569 be decrypted with the new keys. */
2570 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2571 hmac_receive, FALSE)) {
2572 /** Cannot set keys */
2573 SILC_LOG_DEBUG(("Cannot set new keys"));
2574 ske->status = SILC_SKE_STATUS_ERROR;
2575 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2576 return SILC_FSM_CONTINUE;
2579 SILC_LOG_DEBUG(("Rekey completed successfully"));
2581 /* Generate new rekey material */
2582 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2585 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2586 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2587 return SILC_FSM_CONTINUE;
2589 rekey->pfs = ske->rekey->pfs;
2592 ske->prop->cipher = NULL;
2593 ske->prop->hmac = NULL;
2594 silc_packet_free(ske->packet);
2596 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2597 silc_schedule_task_del_by_context(ske->schedule, ske);
2599 return SILC_FSM_FINISH;
2602 /* Starts rekey protocol as initiator */
2605 silc_ske_rekey_initiator(SilcSKE ske,
2606 SilcPacketStream stream,
2607 SilcSKERekeyMaterial rekey)
2609 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2611 if (!ske || !stream || !rekey)
2614 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2617 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2621 ske->responder = FALSE;
2622 ske->running = TRUE;
2623 ske->rekeying = TRUE;
2625 /* Link to packet stream to get key exchange packets */
2626 ske->stream = stream;
2627 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2629 SILC_PACKET_REKEY_DONE,
2630 SILC_PACKET_KEY_EXCHANGE_2,
2631 SILC_PACKET_SUCCESS,
2632 SILC_PACKET_FAILURE, -1);
2634 /* Start SKE rekey as initiator */
2635 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2640 /***************************** Responder Rekey ******************************/
2642 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2644 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2646 return SILC_FSM_FINISH;
2649 /* Starts rekey protocol as responder */
2652 silc_ske_rekey_responder(SilcSKE ske,
2653 SilcPacketStream stream,
2654 SilcSKERekeyMaterial rekey)
2656 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2658 if (!ske || !stream || !rekey)
2661 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2664 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2668 ske->responder = TRUE;
2669 ske->running = TRUE;
2670 ske->rekeying = TRUE;
2672 /* Link to packet stream to get key exchange packets */
2673 ske->stream = stream;
2674 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2676 SILC_PACKET_REKEY_DONE,
2677 SILC_PACKET_KEY_EXCHANGE_1,
2678 SILC_PACKET_SUCCESS,
2679 SILC_PACKET_FAILURE, -1);
2681 /* Start SKE rekey as responder */
2682 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2687 /* Processes the provided key material `data' as the SILC protocol
2688 specification defines. */
2691 silc_ske_process_key_material_data(unsigned char *data,
2692 SilcUInt32 data_len,
2693 SilcUInt32 req_iv_len,
2694 SilcUInt32 req_enc_key_len,
2695 SilcUInt32 req_hmac_key_len,
2699 unsigned char hashd[SILC_HASH_MAXLEN];
2700 SilcUInt32 hash_len = req_hmac_key_len;
2701 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2702 SilcSKEKeyMaterial key;
2704 SILC_LOG_DEBUG(("Start"));
2706 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2709 key = silc_calloc(1, sizeof(*key));
2713 buf = silc_buffer_alloc_size(1 + data_len);
2716 silc_buffer_format(buf,
2717 SILC_STR_UI_CHAR(0),
2718 SILC_STR_UI_XNSTRING(data, data_len),
2722 memset(hashd, 0, sizeof(hashd));
2724 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2725 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2726 memcpy(key->send_iv, hashd, req_iv_len);
2727 memset(hashd, 0, sizeof(hashd));
2729 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2730 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2731 memcpy(key->receive_iv, hashd, req_iv_len);
2732 key->iv_len = req_iv_len;
2734 /* Take the encryption keys. If requested key size is more than
2735 the size of hash length we will distribute more key material
2736 as protocol defines. */
2738 if (enc_key_len > hash_len) {
2740 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2741 k3[SILC_HASH_MAXLEN];
2742 unsigned char *dtmp;
2745 if (enc_key_len > (3 * hash_len))
2748 /* Take first round */
2749 memset(k1, 0, sizeof(k1));
2750 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2752 /* Take second round */
2753 dist = silc_buffer_alloc_size(data_len + hash_len);
2756 silc_buffer_format(dist,
2757 SILC_STR_UI_XNSTRING(data, data_len),
2758 SILC_STR_UI_XNSTRING(k1, hash_len),
2760 memset(k2, 0, sizeof(k2));
2761 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2763 /* Take third round */
2764 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2765 silc_buffer_pull_tail(dist, hash_len);
2766 silc_buffer_pull(dist, data_len + hash_len);
2767 silc_buffer_format(dist,
2768 SILC_STR_UI_XNSTRING(k2, hash_len),
2770 silc_buffer_push(dist, data_len + hash_len);
2771 memset(k3, 0, sizeof(k3));
2772 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2774 /* Then, save the keys */
2775 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2776 memcpy(dtmp, k1, hash_len);
2777 memcpy(dtmp + hash_len, k2, hash_len);
2778 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2780 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2781 memcpy(key->send_enc_key, dtmp, enc_key_len);
2782 key->enc_key_len = req_enc_key_len;
2784 memset(dtmp, 0, (3 * hash_len));
2785 memset(k1, 0, sizeof(k1));
2786 memset(k2, 0, sizeof(k2));
2787 memset(k3, 0, sizeof(k3));
2789 silc_buffer_clear(dist);
2790 silc_buffer_free(dist);
2792 /* Take normal hash as key */
2793 memset(hashd, 0, sizeof(hashd));
2794 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2795 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2796 memcpy(key->send_enc_key, hashd, enc_key_len);
2797 key->enc_key_len = req_enc_key_len;
2801 if (enc_key_len > hash_len) {
2803 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2804 k3[SILC_HASH_MAXLEN];
2805 unsigned char *dtmp;
2808 if (enc_key_len > (3 * hash_len))
2811 /* Take first round */
2812 memset(k1, 0, sizeof(k1));
2813 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2815 /* Take second round */
2816 dist = silc_buffer_alloc_size(data_len + hash_len);
2819 silc_buffer_format(dist,
2820 SILC_STR_UI_XNSTRING(data, data_len),
2821 SILC_STR_UI_XNSTRING(k1, hash_len),
2823 memset(k2, 0, sizeof(k2));
2824 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2826 /* Take third round */
2827 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2828 silc_buffer_pull_tail(dist, hash_len);
2829 silc_buffer_pull(dist, data_len + hash_len);
2830 silc_buffer_format(dist,
2831 SILC_STR_UI_XNSTRING(k2, hash_len),
2833 silc_buffer_push(dist, data_len + hash_len);
2834 memset(k3, 0, sizeof(k3));
2835 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2837 /* Then, save the keys */
2838 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2839 memcpy(dtmp, k1, hash_len);
2840 memcpy(dtmp + hash_len, k2, hash_len);
2841 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2843 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2844 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2845 key->enc_key_len = req_enc_key_len;
2847 memset(dtmp, 0, (3 * hash_len));
2848 memset(k1, 0, sizeof(k1));
2849 memset(k2, 0, sizeof(k2));
2850 memset(k3, 0, sizeof(k3));
2852 silc_buffer_clear(dist);
2853 silc_buffer_free(dist);
2855 /* Take normal hash as key */
2856 memset(hashd, 0, sizeof(hashd));
2857 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2858 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2859 memcpy(key->receive_enc_key, hashd, enc_key_len);
2860 key->enc_key_len = req_enc_key_len;
2863 /* Take HMAC keys */
2864 memset(hashd, 0, sizeof(hashd));
2866 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2867 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2868 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2869 memset(hashd, 0, sizeof(hashd));
2871 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2872 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2873 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2874 key->hmac_key_len = req_hmac_key_len;
2875 memset(hashd, 0, sizeof(hashd));
2877 silc_buffer_clear(buf);
2878 silc_buffer_free(buf);
2880 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
2885 /* Processes negotiated key material as protocol specifies. This returns
2886 the actual keys to be used in the SILC. */
2889 silc_ske_process_key_material(SilcSKE ske,
2890 SilcUInt32 req_iv_len,
2891 SilcUInt32 req_enc_key_len,
2892 SilcUInt32 req_hmac_key_len,
2893 SilcSKERekeyMaterial *rekey)
2896 unsigned char *tmpbuf;
2898 SilcSKEKeyMaterial key;
2900 /* Encode KEY to binary data */
2901 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2903 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2906 silc_buffer_format(buf,
2907 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2908 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2911 /* Process the key material */
2912 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2913 req_iv_len, req_enc_key_len,
2917 memset(tmpbuf, 0, klen);
2919 silc_buffer_clear(buf);
2920 silc_buffer_free(buf);
2923 *rekey = silc_ske_make_rekey_material(ske, key);
2931 /* Free key material structure */
2933 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2939 silc_free(key->send_iv);
2940 if (key->receive_iv)
2941 silc_free(key->receive_iv);
2942 if (key->send_enc_key) {
2943 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2944 silc_free(key->send_enc_key);
2946 if (key->receive_enc_key) {
2947 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2948 silc_free(key->receive_enc_key);
2950 if (key->send_hmac_key) {
2951 memset(key->send_hmac_key, 0, key->hmac_key_len);
2952 silc_free(key->send_hmac_key);
2954 if (key->receive_hmac_key) {
2955 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2956 silc_free(key->receive_hmac_key);
2961 /* Free rekey material */
2963 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
2967 if (rekey->send_enc_key) {
2968 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
2969 silc_free(rekey->send_enc_key);
2971 silc_free(rekey->hash);
2975 /* Set keys into use */
2977 SilcBool silc_ske_set_keys(SilcSKE ske,
2978 SilcSKEKeyMaterial keymat,
2979 SilcSKESecurityProperties prop,
2980 SilcCipher *ret_send_key,
2981 SilcCipher *ret_receive_key,
2982 SilcHmac *ret_hmac_send,
2983 SilcHmac *ret_hmac_receive,
2986 unsigned char iv[32];
2988 /* Allocate ciphers to be used in the communication */
2990 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2994 if (ret_receive_key) {
2995 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3000 /* Allocate HMACs */
3001 if (ret_hmac_send) {
3002 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3006 if (ret_hmac_receive) {
3007 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3012 /* Set key material */
3013 memset(iv, 0, sizeof(iv));
3014 if (ske->responder) {
3016 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3017 keymat->enc_key_len, TRUE);
3019 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3020 memcpy(iv, ske->hash, 4);
3021 memcpy(iv + 4, keymat->receive_iv, 4);
3022 silc_cipher_set_iv(*ret_send_key, iv);
3024 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3027 if (ret_receive_key) {
3028 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3029 keymat->enc_key_len, FALSE);
3031 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3032 memcpy(iv, ske->hash, 4);
3033 memcpy(iv + 4, keymat->send_iv, 4);
3034 silc_cipher_set_iv(*ret_receive_key, iv);
3036 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3040 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3041 keymat->hmac_key_len);
3042 if (ret_hmac_receive)
3043 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3044 keymat->hmac_key_len);
3047 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3048 keymat->enc_key_len, TRUE);
3050 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3051 memcpy(iv, ske->hash, 4);
3052 memcpy(iv + 4, keymat->send_iv, 4);
3053 silc_cipher_set_iv(*ret_send_key, iv);
3055 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3058 if (ret_receive_key) {
3059 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3060 keymat->enc_key_len, FALSE);
3062 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3063 memcpy(iv, ske->hash, 4);
3064 memcpy(iv + 4, keymat->receive_iv, 4);
3065 silc_cipher_set_iv(*ret_receive_key, iv);
3067 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3071 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3072 keymat->hmac_key_len);
3073 if (ret_hmac_receive)
3074 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3075 keymat->hmac_key_len);
3080 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3087 const char *silc_ske_status_string[] =
3091 "Unkown error occurred",
3092 "Bad payload in packet",
3093 "Unsupported group",
3094 "Unsupported cipher",
3096 "Unsupported hash function",
3098 "Unsupported public key (or certificate)",
3099 "Incorrect signature",
3100 "Bad or unsupported version",
3104 "Remote did not provide public key",
3105 "Bad reserved field in packet",
3106 "Bad payload length in packet",
3107 "Error computing signature",
3108 "System out of memory",
3109 "Key exchange timeout",
3114 /* Maps status to readable string and returns the string. If string is not
3115 found and empty character string ("") is returned. */
3117 const char *silc_ske_map_status(SilcSKEStatus status)
3121 for (i = 0; silc_ske_status_string[i]; i++)
3123 return silc_ske_status_string[i];
3128 /* Parses remote host's version string. */
3130 SilcBool silc_ske_parse_version(SilcSKE ske,
3131 SilcUInt32 *protocol_version,
3132 char **protocol_version_string,
3133 SilcUInt32 *software_version,
3134 char **software_version_string,
3135 char **vendor_version)
3137 return silc_parse_version_string(ske->remote_version,
3139 protocol_version_string,
3141 software_version_string,
3145 /* Get security properties */
3147 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3152 /* Get key material */
3154 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)