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 l_protocol_version = 0, r_protocol_version = 0;
180 SilcUInt32 r_software_version = 0;
182 if (!ske->remote_version || !ske->version)
183 return SILC_SKE_STATUS_BAD_VERSION;
185 if (!silc_parse_version_string(ske->remote_version, &r_protocol_version,
186 NULL, &r_software_version, NULL, NULL))
187 return SILC_SKE_STATUS_BAD_VERSION;
189 if (!silc_parse_version_string(ske->version, &l_protocol_version,
190 NULL, NULL, NULL, NULL))
191 return SILC_SKE_STATUS_BAD_VERSION;
193 /* If remote is too new, don't connect */
194 if (l_protocol_version < r_protocol_version)
195 return SILC_SKE_STATUS_BAD_VERSION;
197 /* Backwards compatibility checks */
199 /* Old server versions requires "valid" looking Source ID in the SILC
200 packets during initial key exchange. All version before 1.1.0. */
201 if (r_software_version < 110) {
203 memset(&id, 0, sizeof(id));
205 SILC_LOG_DEBUG(("Remote is old version, add dummy Source ID to packets"));
206 silc_packet_set_ids(ske->stream, SILC_ID_CLIENT, &id, 0, NULL);
209 return SILC_SKE_STATUS_OK;
212 /* Selects the supported security properties from the initiator's Key
213 Exchange Start Payload. A responder function. Saves our reply
214 start payload to ske->start_payload. */
217 silc_ske_select_security_properties(SilcSKE ske,
218 SilcSKEStartPayload remote_payload,
219 SilcSKESecurityProperties *prop)
221 SilcSKEStatus status;
222 SilcSKEStartPayload rp, payload;
226 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
230 /* Check for mandatory fields */
231 if (!rp->ke_grp_len) {
232 SILC_LOG_DEBUG(("KE group not defined in payload"));
233 return SILC_SKE_STATUS_BAD_PAYLOAD;
235 if (!rp->pkcs_alg_len) {
236 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
237 return SILC_SKE_STATUS_BAD_PAYLOAD;
239 if (!rp->enc_alg_len) {
240 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
241 return SILC_SKE_STATUS_BAD_PAYLOAD;
243 if (!rp->hash_alg_len) {
244 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
245 return SILC_SKE_STATUS_BAD_PAYLOAD;
247 if (!rp->hmac_alg_len) {
248 SILC_LOG_DEBUG(("HMAC not defined in payload"));
249 return SILC_SKE_STATUS_BAD_PAYLOAD;
252 /* Allocate security properties */
253 *prop = silc_calloc(1, sizeof(**prop));
255 return SILC_SKE_STATUS_OUT_OF_MEMORY;
257 /* Allocate our reply start payload */
258 payload = silc_calloc(1, sizeof(*payload));
261 return SILC_SKE_STATUS_OUT_OF_MEMORY;
264 /* Check version string */
265 ske->remote_version = silc_memdup(rp->version, rp->version_len);
266 status = silc_ske_check_version(ske);
267 if (status != SILC_SKE_STATUS_OK) {
268 ske->status = status;
272 /* Flags are returned unchanged. */
273 (*prop)->flags = payload->flags = rp->flags;
275 /* Take cookie, we must return it to sender unmodified. */
276 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
277 if (!payload->cookie) {
278 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
281 payload->cookie_len = SILC_SKE_COOKIE_LEN;
282 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
284 /* In case IV included flag and session port is set the first 16-bits of
285 cookie will include our session port. */
286 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
287 /* Take remote port */
288 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
291 SILC_PUT16_MSB(ske->session_port, payload->cookie);
294 /* Put our version to our reply */
295 payload->version = strdup(ske->version);
296 if (!payload->version) {
297 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
300 payload->version_len = strlen(ske->version);
302 /* Get supported Key Exchange groups */
303 cp = rp->ke_grp_list;
304 if (cp && strchr(cp, ',')) {
308 len = strcspn(cp, ",");
309 item = silc_calloc(len + 1, sizeof(char));
311 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
314 memcpy(item, cp, len);
316 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
318 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
319 SILC_LOG_DEBUG(("Found KE group `%s'", item));
321 payload->ke_grp_len = len;
322 payload->ke_grp_list = item;
336 if (!payload->ke_grp_len && !payload->ke_grp_list) {
337 SILC_LOG_DEBUG(("Could not find supported KE group"));
339 return SILC_SKE_STATUS_UNKNOWN_GROUP;
342 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
343 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
345 payload->ke_grp_len = rp->ke_grp_len;
346 payload->ke_grp_list = strdup(rp->ke_grp_list);
349 /* Save group to security properties */
350 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
351 if (status != SILC_SKE_STATUS_OK) {
353 return SILC_SKE_STATUS_UNKNOWN_GROUP;
356 /* Get supported PKCS algorithms */
357 cp = rp->pkcs_alg_list;
358 if (cp && strchr(cp, ',')) {
362 len = strcspn(cp, ",");
363 item = silc_calloc(len + 1, sizeof(char));
365 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
368 memcpy(item, cp, len);
370 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
372 if (silc_pkcs_find_algorithm(item, NULL)) {
373 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
375 payload->pkcs_alg_len = len;
376 payload->pkcs_alg_list = item;
390 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
391 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
392 silc_free(payload->ke_grp_list);
394 return SILC_SKE_STATUS_UNKNOWN_PKCS;
397 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
398 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
400 payload->pkcs_alg_len = rp->pkcs_alg_len;
401 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
404 /* Get supported encryption algorithms */
405 cp = rp->enc_alg_list;
406 if (cp && strchr(cp, ',')) {
410 len = strcspn(cp, ",");
411 item = silc_calloc(len + 1, sizeof(char));
413 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
416 memcpy(item, cp, len);
418 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
420 if (silc_cipher_is_supported(item) == TRUE) {
421 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
423 payload->enc_alg_len = len;
424 payload->enc_alg_list = item;
438 if (!payload->enc_alg_len && !payload->enc_alg_list) {
439 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
440 silc_free(payload->ke_grp_list);
441 silc_free(payload->pkcs_alg_list);
443 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
446 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
449 payload->enc_alg_len = rp->enc_alg_len;
450 payload->enc_alg_list = strdup(rp->enc_alg_list);
453 /* Save selected cipher to security properties */
454 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
455 silc_free(payload->ke_grp_list);
456 silc_free(payload->pkcs_alg_list);
458 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
461 /* Get supported hash algorithms */
462 cp = rp->hash_alg_list;
463 if (cp && strchr(cp, ',')) {
467 len = strcspn(cp, ",");
468 item = silc_calloc(len + 1, sizeof(char));
470 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
473 memcpy(item, cp, len);
475 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
477 if (silc_hash_is_supported(item) == TRUE) {
478 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
480 payload->hash_alg_len = len;
481 payload->hash_alg_list = item;
495 if (!payload->hash_alg_len && !payload->hash_alg_list) {
496 SILC_LOG_DEBUG(("Could not find supported hash alg"));
497 silc_free(payload->ke_grp_list);
498 silc_free(payload->pkcs_alg_list);
499 silc_free(payload->enc_alg_list);
501 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
504 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
507 payload->hash_alg_len = rp->hash_alg_len;
508 payload->hash_alg_list = strdup(rp->hash_alg_list);
511 /* Save selected hash algorithm to security properties */
512 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
513 silc_free(payload->ke_grp_list);
514 silc_free(payload->pkcs_alg_list);
515 silc_free(payload->enc_alg_list);
517 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
520 /* Get supported HMACs */
521 cp = rp->hmac_alg_list;
522 if (cp && strchr(cp, ',')) {
526 len = strcspn(cp, ",");
527 item = silc_calloc(len + 1, sizeof(char));
529 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
532 memcpy(item, cp, len);
534 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
536 if (silc_hmac_is_supported(item) == TRUE) {
537 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
539 payload->hmac_alg_len = len;
540 payload->hmac_alg_list = item;
554 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
555 SILC_LOG_DEBUG(("Could not find supported HMAC"));
556 silc_free(payload->ke_grp_list);
557 silc_free(payload->pkcs_alg_list);
558 silc_free(payload->enc_alg_list);
559 silc_free(payload->hash_alg_list);
561 return SILC_SKE_STATUS_UNKNOWN_HMAC;
564 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
567 payload->hmac_alg_len = rp->hmac_alg_len;
568 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
571 /* Save selected HMACc to security properties */
572 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
573 silc_free(payload->ke_grp_list);
574 silc_free(payload->pkcs_alg_list);
575 silc_free(payload->enc_alg_list);
576 silc_free(payload->hash_alg_list);
578 return SILC_SKE_STATUS_UNKNOWN_HMAC;
581 /* Get supported compression algorithms */
582 cp = rp->comp_alg_list;
583 if (cp && strchr(cp, ',')) {
587 len = strcspn(cp, ",");
588 item = silc_calloc(len + 1, sizeof(char));
590 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
593 memcpy(item, cp, len);
595 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
598 if (!strcmp(item, "none")) {
599 SILC_LOG_DEBUG(("Found Compression `%s'", item));
600 payload->comp_alg_len = len;
601 payload->comp_alg_list = item;
605 if (silc_hmac_is_supported(item) == TRUE) {
606 SILC_LOG_DEBUG(("Found Compression `%s'", item));
607 payload->comp_alg_len = len;
608 payload->comp_alg_list = item;
624 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
625 2 + payload->version_len +
626 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
627 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
628 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
630 /* Save our reply payload */
631 ske->start_payload = payload;
633 return SILC_SKE_STATUS_OK;
636 /* Creates random number such that 1 < rnd < n and at most length
637 of len bits. The rnd sent as argument must be initialized. */
639 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
643 SilcSKEStatus status = SILC_SKE_STATUS_OK;
644 unsigned char *string;
648 return SILC_SKE_STATUS_ERROR;
650 SILC_LOG_DEBUG(("Creating random number"));
654 /* Get the random number as string */
655 string = silc_rng_get_rn_data(ske->rng, l);
657 return SILC_SKE_STATUS_OUT_OF_MEMORY;
659 /* Decode the string into a MP integer */
660 silc_mp_bin2mp(string, l, rnd);
661 silc_mp_mod_2exp(rnd, rnd, len);
664 if (silc_mp_cmp_ui(rnd, 1) < 0)
665 status = SILC_SKE_STATUS_ERROR;
666 if (silc_mp_cmp(rnd, n) >= 0)
667 status = SILC_SKE_STATUS_ERROR;
669 memset(string, 'F', l);
675 /* Creates a hash value HASH as defined in the SKE protocol. If the
676 `initiator' is TRUE then this function is used to create the HASH_i
677 hash value defined in the protocol. If it is FALSE then this is used
678 to create the HASH value defined by the protocol. */
680 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
681 unsigned char *return_hash,
682 SilcUInt32 *return_hash_len,
685 SilcSKEStatus status = SILC_SKE_STATUS_OK;
687 unsigned char *e, *f, *KEY;
688 SilcUInt32 e_len, f_len, KEY_len;
691 SILC_LOG_DEBUG(("Start"));
693 if (initiator == FALSE) {
694 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
695 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
696 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
698 /* Format the buffer used to compute the hash value */
699 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
700 ske->ke2_payload->pk_len +
701 ske->ke1_payload->pk_len +
702 e_len + f_len + KEY_len);
704 return SILC_SKE_STATUS_OUT_OF_MEMORY;
706 /* Initiator is not required to send its public key */
707 if (!ske->ke1_payload->pk_data) {
709 silc_buffer_format(buf,
710 SILC_STR_UI_XNSTRING(
711 ske->start_payload_copy->data,
712 silc_buffer_len(ske->start_payload_copy)),
713 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
714 ske->ke2_payload->pk_len),
715 SILC_STR_UI_XNSTRING(e, e_len),
716 SILC_STR_UI_XNSTRING(f, f_len),
717 SILC_STR_UI_XNSTRING(KEY, KEY_len),
721 silc_buffer_format(buf,
722 SILC_STR_UI_XNSTRING(
723 ske->start_payload_copy->data,
724 silc_buffer_len(ske->start_payload_copy)),
725 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
726 ske->ke2_payload->pk_len),
727 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
728 ske->ke1_payload->pk_len),
729 SILC_STR_UI_XNSTRING(e, e_len),
730 SILC_STR_UI_XNSTRING(f, f_len),
731 SILC_STR_UI_XNSTRING(KEY, KEY_len),
735 silc_buffer_free(buf);
738 memset(KEY, 0, KEY_len);
742 return SILC_SKE_STATUS_ERROR;
747 memset(KEY, 0, KEY_len);
752 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
754 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
755 ske->ke1_payload->pk_len + e_len);
757 return SILC_SKE_STATUS_OUT_OF_MEMORY;
759 /* Format the buffer used to compute the hash value */
761 silc_buffer_format(buf,
762 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
763 silc_buffer_len(ske->start_payload_copy)),
764 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
765 ske->ke1_payload->pk_len),
766 SILC_STR_UI_XNSTRING(e, e_len),
769 silc_buffer_free(buf);
772 return SILC_SKE_STATUS_ERROR;
775 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
782 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
784 *return_hash_len = silc_hash_len(ske->prop->hash);
786 if (initiator == FALSE) {
787 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
789 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
792 silc_buffer_free(buf);
797 /* Generate rekey material */
799 static SilcSKERekeyMaterial
800 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
802 SilcSKERekeyMaterial rekey;
805 /* Create rekey material */
806 rekey = silc_calloc(1, sizeof(*rekey));
811 if (ske->prop->group)
812 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
813 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
814 hash = silc_hash_get_name(ske->prop->hash);
815 rekey->hash = silc_memdup(hash, strlen(hash));
820 if (rekey->pfs == FALSE) {
821 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
822 keymat->enc_key_len / 8);
823 if (!rekey->send_enc_key) {
827 rekey->enc_key_len = keymat->enc_key_len;
833 /* Assembles security properties */
835 static SilcSKEStartPayload
836 silc_ske_assemble_security_properties(SilcSKE ske,
837 SilcSKESecurityPropertyFlag flags,
840 SilcSKEStartPayload rp;
843 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
845 rp = silc_calloc(1, sizeof(*rp));
848 rp->flags = (unsigned char)flags;
850 /* Set random cookie */
851 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
852 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
853 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
854 rp->cookie_len = SILC_SKE_COOKIE_LEN;
856 /* In case IV included flag and session port is set the first 16-bits of
857 cookie will include our session port. */
858 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
859 SILC_PUT16_MSB(ske->session_port, rp->cookie);
862 rp->version = strdup(version);
863 rp->version_len = strlen(version);
865 /* Get supported Key Exhange groups */
866 rp->ke_grp_list = silc_ske_get_supported_groups();
867 rp->ke_grp_len = strlen(rp->ke_grp_list);
869 /* Get supported PKCS algorithms */
870 rp->pkcs_alg_list = silc_pkcs_get_supported();
871 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
873 /* Get supported encryption algorithms */
874 rp->enc_alg_list = silc_cipher_get_supported();
875 rp->enc_alg_len = strlen(rp->enc_alg_list);
877 /* Get supported hash algorithms */
878 rp->hash_alg_list = silc_hash_get_supported();
879 rp->hash_alg_len = strlen(rp->hash_alg_list);
881 /* Get supported HMACs */
882 rp->hmac_alg_list = silc_hmac_get_supported();
883 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
886 /* Get supported compression algorithms */
887 rp->comp_alg_list = strdup("none");
888 rp->comp_alg_len = strlen("none");
890 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
891 2 + rp->version_len +
892 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
893 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
894 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
899 /* Packet retransmission callback. */
901 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
903 SilcSKE ske = context;
905 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
907 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
908 ske->retry_count = 0;
909 ske->retry_timer = SILC_SKE_RETRY_MIN;
910 silc_free(ske->retrans.data);
911 ske->retrans.data = NULL;
912 ske->status = SILC_SKE_STATUS_TIMEOUT;
914 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
916 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
917 silc_fsm_continue_sync(&ske->fsm);
921 SILC_LOG_DEBUG(("Retransmitting packet"));
922 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
923 ske->retrans.data, ske->retrans.data_len);
926 /* Install retransmission timer */
928 static void silc_ske_install_retransmission(SilcSKE ske)
930 if (!silc_packet_stream_is_udp(ske->stream))
933 if (ske->retrans.data) {
934 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
936 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
937 ske, ske->retry_timer, 0);
939 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
940 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
943 /* Sends SILC packet. Handles retransmissions with UDP streams. */
945 static SilcBool silc_ske_packet_send(SilcSKE ske,
947 SilcPacketFlags flags,
948 const unsigned char *data,
953 /* Send the packet */
954 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
956 if (silc_packet_stream_is_udp(ske->stream) &&
957 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
958 silc_free(ske->retrans.data);
959 ske->retrans.type = type;
960 ske->retrans.flags = flags;
961 ske->retrans.data = silc_memdup(data, data_len);
962 ske->retrans.data_len = data_len;
963 silc_ske_install_retransmission(ske);
969 /* SKE FSM destructor. We call completion callback here. All SKE
970 machines go here and call the completion. Completion must not be called
971 from any other place. */
973 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
974 void *destructor_context)
976 SilcSKE ske = fsm_context;
978 /* Call the completion callback */
979 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
980 if (ske->status != SILC_SKE_STATUS_OK)
981 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
982 ske->callbacks->context);
984 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
985 ske->rekey, ske->callbacks->context);
988 ske->running = FALSE;
993 /* Key exchange timeout task callback */
995 SILC_TASK_CALLBACK(silc_ske_timeout)
997 SilcSKE ske = context;
999 SILC_LOG_DEBUG(("Timeout"));
1002 ske->status = SILC_SKE_STATUS_TIMEOUT;
1004 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1006 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1008 silc_fsm_continue_sync(&ske->fsm);
1011 /******************************* Protocol API *******************************/
1013 /* Allocates new SKE object. */
1015 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1016 SilcSKR repository, SilcPublicKey public_key,
1017 SilcPrivateKey private_key, void *context)
1021 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1023 if (!rng || !schedule)
1027 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1031 ske = silc_calloc(1, sizeof(*ske));
1034 ske->status = SILC_SKE_STATUS_OK;
1036 ske->repository = repository;
1037 ske->user_data = context;
1038 ske->schedule = schedule;
1039 ske->public_key = public_key;
1040 ske->private_key = private_key;
1041 ske->retry_timer = SILC_SKE_RETRY_MIN;
1046 /* Free's SKE object. */
1048 void silc_ske_free(SilcSKE ske)
1050 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1059 /* If already aborted, destroy the session immediately */
1061 ske->status = SILC_SKE_STATUS_ERROR;
1063 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1065 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1066 silc_fsm_continue_sync(&ske->fsm);
1071 /* Free start payload */
1072 if (ske->start_payload)
1073 silc_ske_payload_start_free(ske->start_payload);
1075 /* Free KE payload */
1076 if (ske->ke1_payload)
1077 silc_ske_payload_ke_free(ske->ke1_payload);
1078 if (ske->ke2_payload)
1079 silc_ske_payload_ke_free(ske->ke2_payload);
1080 silc_free(ske->remote_version);
1084 if (ske->prop->group)
1085 silc_ske_group_free(ske->prop->group);
1086 if (ske->prop->cipher)
1087 silc_cipher_free(ske->prop->cipher);
1088 if (ske->prop->hash)
1089 silc_hash_free(ske->prop->hash);
1090 if (ske->prop->hmac)
1091 silc_hmac_free(ske->prop->hmac);
1092 silc_free(ske->prop);
1095 silc_ske_free_key_material(ske->keymat);
1096 if (ske->start_payload_copy)
1097 silc_buffer_free(ske->start_payload_copy);
1099 silc_mp_uninit(ske->x);
1103 silc_mp_uninit(ske->KEY);
1104 silc_free(ske->KEY);
1106 silc_free(ske->retrans.data);
1107 silc_free(ske->hash);
1108 silc_free(ske->callbacks);
1110 memset(ske, 'F', sizeof(*ske));
1114 /* Return user context */
1116 void *silc_ske_get_context(SilcSKE ske)
1118 return ske->user_data;
1121 /* Sets protocol callbacks */
1123 void silc_ske_set_callbacks(SilcSKE ske,
1124 SilcSKEVerifyCb verify_key,
1125 SilcSKECompletionCb completed,
1129 silc_free(ske->callbacks);
1130 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1131 if (!ske->callbacks)
1133 ske->callbacks->verify_key = verify_key;
1134 ske->callbacks->completed = completed;
1135 ske->callbacks->context = context;
1139 /******************************** Initiator *********************************/
1141 /* Start protocol. Send our proposal */
1143 SILC_FSM_STATE(silc_ske_st_initiator_start)
1145 SilcSKE ske = fsm_context;
1146 SilcBuffer payload_buf;
1149 SILC_LOG_DEBUG(("Start"));
1153 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1154 return SILC_FSM_CONTINUE;
1157 /* Encode the payload */
1158 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1160 if (status != SILC_SKE_STATUS_OK) {
1161 /** Error encoding Start Payload */
1162 ske->status = status;
1163 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1164 return SILC_FSM_CONTINUE;
1167 /* Save the the payload buffer for future use. It is later used to
1168 compute the HASH value. */
1169 ske->start_payload_copy = payload_buf;
1171 /* Send the packet. */
1172 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1173 silc_buffer_data(payload_buf),
1174 silc_buffer_len(payload_buf))) {
1175 /** Error sending packet */
1176 SILC_LOG_DEBUG(("Error sending packet"));
1177 ske->status = SILC_SKE_STATUS_ERROR;
1178 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1179 return SILC_FSM_CONTINUE;
1182 /* Add key exchange timeout */
1183 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1184 ske, ske->timeout, 0);
1186 /** Wait for responder proposal */
1187 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1188 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1189 return SILC_FSM_WAIT;
1192 /* Phase-1. Receives responder's proposal */
1194 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1196 SilcSKE ske = fsm_context;
1197 SilcSKEStatus status;
1198 SilcSKEStartPayload payload;
1199 SilcSKESecurityProperties prop;
1200 SilcSKEDiffieHellmanGroup group = NULL;
1201 SilcBuffer packet_buf = &ske->packet->buffer;
1202 SilcUInt16 remote_port = 0;
1206 SILC_LOG_DEBUG(("Start"));
1208 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1209 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1210 silc_ske_install_retransmission(ske);
1211 silc_packet_free(ske->packet);
1213 return SILC_FSM_WAIT;
1216 /* Decode the payload */
1217 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1218 if (status != SILC_SKE_STATUS_OK) {
1219 /** Error decoding Start Payload */
1220 silc_packet_free(ske->packet);
1222 ske->status = status;
1223 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1224 return SILC_FSM_CONTINUE;
1227 /* Get remote ID and set it to stream */
1228 if (ske->packet->src_id_len) {
1229 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1230 ske->packet->src_id_type,
1231 (ske->packet->src_id_type == SILC_ID_SERVER ?
1232 (void *)&id.u.server_id : (void *)&id.u.client_id),
1233 (ske->packet->src_id_type == SILC_ID_SERVER ?
1234 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1235 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1236 (ske->packet->src_id_type == SILC_ID_SERVER ?
1237 (void *)&id.u.server_id : (void *)&id.u.client_id));
1240 silc_packet_free(ske->packet);
1243 /* Check that the cookie is returned unmodified. In case IV included
1244 flag and session port has been set, the first two bytes of cookie
1245 are the session port and we ignore them in this check. */
1246 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1247 /* Take remote port */
1248 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1251 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1252 SILC_SKE_COOKIE_LEN - coff)) {
1253 /** Invalid cookie */
1254 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1255 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1256 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1257 return SILC_FSM_CONTINUE;
1260 /* Check version string */
1261 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1262 status = silc_ske_check_version(ske);
1263 if (status != SILC_SKE_STATUS_OK) {
1264 /** Version mismatch */
1265 ske->status = status;
1266 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1267 return SILC_FSM_CONTINUE;
1270 /* Free our KE Start Payload context, we don't need it anymore. */
1271 silc_ske_payload_start_free(ske->start_payload);
1272 ske->start_payload = NULL;
1274 /* Take the selected security properties into use while doing
1275 the key exchange. This is used only while doing the key
1277 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1280 prop->flags = payload->flags;
1281 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1282 if (status != SILC_SKE_STATUS_OK)
1285 prop->group = group;
1286 prop->remote_port = remote_port;
1288 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1289 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1292 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1293 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1296 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1297 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1300 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1301 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1305 /* Save remote's KE Start Payload */
1306 ske->start_payload = payload;
1308 /** Send KE Payload */
1309 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1310 return SILC_FSM_CONTINUE;
1314 silc_ske_payload_start_free(payload);
1316 silc_ske_group_free(group);
1318 silc_cipher_free(prop->cipher);
1320 silc_hash_free(prop->hash);
1322 silc_hmac_free(prop->hmac);
1326 if (status == SILC_SKE_STATUS_OK)
1327 status = SILC_SKE_STATUS_ERROR;
1330 ske->status = status;
1331 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1332 return SILC_FSM_CONTINUE;
1335 /* Phase-2. Send KE payload */
1337 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1339 SilcSKE ske = fsm_context;
1340 SilcSKEStatus status;
1341 SilcBuffer payload_buf;
1343 SilcSKEKEPayload payload;
1346 SILC_LOG_DEBUG(("Start"));
1348 /* Create the random number x, 1 < x < q. */
1349 x = silc_calloc(1, sizeof(*x));
1351 /** Out of memory */
1352 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1353 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1354 return SILC_FSM_CONTINUE;
1358 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1359 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1361 if (status != SILC_SKE_STATUS_OK) {
1362 /** Error generating random number */
1365 ske->status = status;
1366 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1367 return SILC_FSM_CONTINUE;
1370 /* Encode the result to Key Exchange Payload. */
1372 payload = silc_calloc(1, sizeof(*payload));
1374 /** Out of memory */
1377 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1378 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1379 return SILC_FSM_CONTINUE;
1381 ske->ke1_payload = payload;
1383 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1385 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1386 silc_mp_init(&payload->x);
1387 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1388 &ske->prop->group->group);
1390 /* Get public key */
1391 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1392 if (!payload->pk_data) {
1393 /** Error encoding public key */
1396 silc_mp_uninit(&payload->x);
1398 ske->ke1_payload = NULL;
1399 ske->status = SILC_SKE_STATUS_ERROR;
1400 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1401 return SILC_FSM_CONTINUE;
1403 payload->pk_len = pk_len;
1404 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1406 /* Compute signature data if we are doing mutual authentication */
1407 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1408 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1409 SilcUInt32 hash_len, sign_len;
1411 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1412 SILC_LOG_DEBUG(("Computing HASH_i value"));
1414 /* Compute the hash value */
1415 memset(hash, 0, sizeof(hash));
1416 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1418 SILC_LOG_DEBUG(("Signing HASH_i value"));
1420 /* Sign the hash value */
1421 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1422 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1423 /** Error computing signature */
1426 silc_mp_uninit(&payload->x);
1427 silc_free(payload->pk_data);
1429 ske->ke1_payload = NULL;
1430 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1431 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1432 return SILC_FSM_CONTINUE;
1434 payload->sign_data = silc_memdup(sign, sign_len);
1435 if (payload->sign_data)
1436 payload->sign_len = sign_len;
1437 memset(sign, 0, sizeof(sign));
1440 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1441 if (status != SILC_SKE_STATUS_OK) {
1442 /** Error encoding KE payload */
1445 silc_mp_uninit(&payload->x);
1446 silc_free(payload->pk_data);
1447 silc_free(payload->sign_data);
1449 ske->ke1_payload = NULL;
1450 ske->status = status;
1451 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1452 return SILC_FSM_CONTINUE;
1457 /* Check for backwards compatibility */
1459 /* Send the packet. */
1460 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1461 silc_buffer_data(payload_buf),
1462 silc_buffer_len(payload_buf))) {
1463 /** Error sending packet */
1464 SILC_LOG_DEBUG(("Error sending packet"));
1465 ske->status = SILC_SKE_STATUS_ERROR;
1466 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1467 return SILC_FSM_CONTINUE;
1470 silc_buffer_free(payload_buf);
1472 /** Waiting responder's KE payload */
1473 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1474 return SILC_FSM_WAIT;
1477 /* Phase-3. Process responder's KE payload */
1479 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1481 SilcSKE ske = fsm_context;
1482 SilcSKEStatus status;
1483 SilcSKEKEPayload payload;
1485 SilcBuffer packet_buf = &ske->packet->buffer;
1487 SILC_LOG_DEBUG(("Start"));
1489 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1490 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1491 silc_ske_install_retransmission(ske);
1492 silc_packet_free(ske->packet);
1494 return SILC_FSM_WAIT;
1497 /* Decode the payload */
1498 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1499 if (status != SILC_SKE_STATUS_OK) {
1500 /** Error decoding KE payload */
1501 silc_packet_free(ske->packet);
1503 ske->status = status;
1504 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1505 return SILC_FSM_CONTINUE;
1507 silc_packet_free(ske->packet);
1509 ske->ke2_payload = payload;
1511 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1512 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1513 "even though we require it"));
1514 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1518 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1520 /* Compute the shared secret key */
1521 KEY = silc_calloc(1, sizeof(*KEY));
1523 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1526 /* Decode the remote's public key */
1527 if (payload->pk_data &&
1528 !silc_pkcs_public_key_alloc(payload->pk_type,
1529 payload->pk_data, payload->pk_len,
1530 &ske->prop->public_key)) {
1531 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1532 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1536 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1538 SILC_LOG_DEBUG(("Verifying public key"));
1540 /** Waiting public key verification */
1541 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1543 /* If repository is provided, verify the key from there. */
1544 if (ske->repository) {
1547 find = silc_skr_find_alloc();
1549 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1552 silc_skr_find_set_pkcs_type(find,
1553 silc_pkcs_get_type(ske->prop->public_key));
1554 silc_skr_find_set_public_key(find, ske->prop->public_key);
1555 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1557 /* Find key from repository */
1558 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1559 silc_ske_skr_callback, ske));
1561 /* Verify from application */
1562 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1563 ske->callbacks->context,
1564 silc_ske_pk_verified, NULL));
1569 /** Process key material */
1570 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1571 return SILC_FSM_CONTINUE;
1574 silc_ske_payload_ke_free(payload);
1575 ske->ke2_payload = NULL;
1577 silc_mp_uninit(ske->KEY);
1578 silc_free(ske->KEY);
1581 if (status == SILC_SKE_STATUS_OK)
1582 return SILC_SKE_STATUS_ERROR;
1585 ske->status = status;
1586 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1587 return SILC_FSM_CONTINUE;
1590 /* Process key material */
1592 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1594 SilcSKE ske = fsm_context;
1595 SilcSKEStatus status;
1596 SilcSKEKEPayload payload;
1597 unsigned char hash[SILC_HASH_MAXLEN];
1598 SilcUInt32 hash_len;
1599 int key_len, block_len;
1603 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1604 return SILC_FSM_CONTINUE;
1607 /* Check result of public key verification */
1608 if (ske->status != SILC_SKE_STATUS_OK) {
1609 /** Public key not verified */
1610 SILC_LOG_DEBUG(("Public key verification failed"));
1611 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1612 return SILC_FSM_CONTINUE;
1615 payload = ske->ke2_payload;
1617 if (ske->prop->public_key) {
1618 SILC_LOG_DEBUG(("Public key is authentic"));
1620 /* Compute the hash value */
1621 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1622 if (status != SILC_SKE_STATUS_OK)
1625 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1627 /* Verify signature */
1628 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1629 payload->sign_len, hash, hash_len, NULL)) {
1630 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1631 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1635 SILC_LOG_DEBUG(("Signature is Ok"));
1637 ske->hash = silc_memdup(hash, hash_len);
1638 ske->hash_len = hash_len;
1639 memset(hash, 'F', hash_len);
1642 ske->status = SILC_SKE_STATUS_OK;
1644 /* In case we are doing rekey move to finish it. */
1647 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1648 return SILC_FSM_CONTINUE;
1651 /* Process key material */
1652 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1653 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1654 hash_len = silc_hash_len(ske->prop->hash);
1655 ske->keymat = silc_ske_process_key_material(ske, block_len,
1659 SILC_LOG_ERROR(("Error processing key material"));
1660 status = SILC_SKE_STATUS_ERROR;
1664 /* Send SUCCESS packet */
1665 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1666 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1667 /** Error sending packet */
1668 SILC_LOG_DEBUG(("Error sending packet"));
1669 ske->status = SILC_SKE_STATUS_ERROR;
1670 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1671 return SILC_FSM_CONTINUE;
1674 /** Waiting completion */
1675 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1676 return SILC_FSM_WAIT;
1679 memset(hash, 'F', sizeof(hash));
1680 silc_ske_payload_ke_free(payload);
1681 ske->ke2_payload = NULL;
1683 silc_mp_uninit(ske->KEY);
1684 silc_free(ske->KEY);
1688 memset(ske->hash, 'F', hash_len);
1689 silc_free(ske->hash);
1693 if (status == SILC_SKE_STATUS_OK)
1694 status = SILC_SKE_STATUS_ERROR;
1697 ske->status = status;
1698 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1699 return SILC_FSM_CONTINUE;
1702 /* Protocol completed */
1704 SILC_FSM_STATE(silc_ske_st_initiator_end)
1706 SilcSKE ske = fsm_context;
1708 SILC_LOG_DEBUG(("Start"));
1710 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1711 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1712 silc_ske_install_retransmission(ske);
1713 silc_packet_free(ske->packet);
1715 return SILC_FSM_WAIT;
1718 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1720 silc_packet_free(ske->packet);
1722 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1723 silc_schedule_task_del_by_context(ske->schedule, ske);
1725 return SILC_FSM_FINISH;
1728 /* Aborted by application */
1730 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1732 SilcSKE ske = fsm_context;
1733 unsigned char data[4];
1735 SILC_LOG_DEBUG(("Aborted by caller"));
1737 /* Send FAILURE packet */
1738 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1739 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1741 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1742 silc_schedule_task_del_by_context(ske->schedule, ske);
1744 return SILC_FSM_FINISH;
1747 /* Error occurred. Send error to remote host */
1749 SILC_FSM_STATE(silc_ske_st_initiator_error)
1751 SilcSKE ske = fsm_context;
1752 SilcSKEStatus status;
1753 unsigned char data[4];
1755 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1756 silc_ske_map_status(ske->status), ske->status));
1758 status = ske->status;
1759 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1760 status = SILC_SKE_STATUS_ERROR;
1762 /* Send FAILURE packet */
1763 SILC_PUT32_MSB((SilcUInt32)status, data);
1764 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1766 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1767 silc_schedule_task_del_by_context(ske->schedule, ske);
1769 return SILC_FSM_FINISH;
1772 /* Failure received from remote */
1774 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1776 SilcSKE ske = fsm_context;
1777 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1779 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1780 silc_ske_map_status(ske->status), ske->status));
1782 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1783 SILC_GET32_MSB(error, ske->packet->buffer.data);
1784 ske->status = error;
1785 silc_packet_free(ske->packet);
1789 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1790 silc_schedule_task_del_by_context(ske->schedule, ske);
1792 return SILC_FSM_FINISH;
1795 /* Starts the protocol as initiator */
1798 silc_ske_initiator(SilcSKE ske,
1799 SilcPacketStream stream,
1800 SilcSKEParams params,
1801 SilcSKEStartPayload start_payload)
1803 SILC_LOG_DEBUG(("Start SKE as initiator"));
1805 if (!ske || !stream || !params || !params->version)
1808 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1811 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1814 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1815 ske->session_port = params->session_port;
1817 /* Generate security properties if not provided */
1818 if (!start_payload) {
1819 start_payload = silc_ske_assemble_security_properties(ske,
1826 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1827 ske->start_payload = start_payload;
1828 ske->version = params->version;
1829 ske->running = TRUE;
1831 /* Link to packet stream to get key exchange packets */
1832 ske->stream = stream;
1833 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1834 SILC_PACKET_KEY_EXCHANGE,
1835 SILC_PACKET_KEY_EXCHANGE_2,
1836 SILC_PACKET_SUCCESS,
1837 SILC_PACKET_FAILURE, -1);
1839 /* Start SKE as initiator */
1840 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1845 /******************************** Responder *********************************/
1847 /* Start protocol as responder. Wait initiator's start payload */
1849 SILC_FSM_STATE(silc_ske_st_responder_start)
1851 SilcSKE ske = fsm_context;
1853 SILC_LOG_DEBUG(("Start"));
1857 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1858 return SILC_FSM_CONTINUE;
1861 /* Add key exchange timeout */
1862 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1863 ske, ske->timeout, 0);
1865 /** Wait for initiator */
1866 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1867 return SILC_FSM_WAIT;
1870 /* Decode initiator's start payload. Select the security properties from
1871 the initiator's start payload and send our reply start payload back. */
1873 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1875 SilcSKE ske = fsm_context;
1876 SilcSKEStatus status;
1877 SilcSKEStartPayload remote_payload = NULL;
1878 SilcBuffer packet_buf = &ske->packet->buffer;
1880 SILC_LOG_DEBUG(("Start"));
1882 /* Decode the payload */
1883 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1884 if (status != SILC_SKE_STATUS_OK) {
1885 /** Error decoding Start Payload */
1886 silc_packet_free(ske->packet);
1888 ske->status = status;
1889 silc_fsm_next(fsm, silc_ske_st_responder_error);
1890 return SILC_FSM_CONTINUE;
1893 /* Take a copy of the payload buffer for future use. It is used to
1894 compute the HASH value. */
1895 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1897 silc_packet_free(ske->packet);
1900 /* Force the mutual authentication flag if we want to do it. */
1901 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1902 SILC_LOG_DEBUG(("Force mutual authentication"));
1903 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1906 /* Force PFS flag if we require it */
1907 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1908 SILC_LOG_DEBUG(("Force PFS"));
1909 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1912 /* Disable IV Included flag if requested */
1913 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1914 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1915 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1916 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1919 /* Check and select security properties */
1920 status = silc_ske_select_security_properties(ske, remote_payload,
1922 if (status != SILC_SKE_STATUS_OK) {
1923 /** Error selecting proposal */
1924 silc_ske_payload_start_free(remote_payload);
1925 ske->status = status;
1926 silc_fsm_next(fsm, silc_ske_st_responder_error);
1927 return SILC_FSM_CONTINUE;
1930 silc_ske_payload_start_free(remote_payload);
1932 /* Encode our reply payload to send the selected security properties */
1933 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1935 if (status != SILC_SKE_STATUS_OK)
1938 /* Send the packet. */
1939 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1940 silc_buffer_data(packet_buf),
1941 silc_buffer_len(packet_buf)))
1944 silc_buffer_free(packet_buf);
1946 /** Waiting initiator's KE payload */
1947 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1948 return SILC_FSM_WAIT;
1951 if (ske->prop->group)
1952 silc_ske_group_free(ske->prop->group);
1953 if (ske->prop->cipher)
1954 silc_cipher_free(ske->prop->cipher);
1955 if (ske->prop->hash)
1956 silc_hash_free(ske->prop->hash);
1957 if (ske->prop->hmac)
1958 silc_hmac_free(ske->prop->hmac);
1959 silc_free(ske->prop);
1962 if (status == SILC_SKE_STATUS_OK)
1963 status = SILC_SKE_STATUS_ERROR;
1966 ske->status = status;
1967 silc_fsm_next(fsm, silc_ske_st_responder_error);
1968 return SILC_FSM_CONTINUE;
1971 /* Phase-2. Decode initiator's KE payload */
1973 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1975 SilcSKE ske = fsm_context;
1976 SilcSKEStatus status;
1977 SilcSKEKEPayload recv_payload;
1978 SilcBuffer packet_buf = &ske->packet->buffer;
1980 SILC_LOG_DEBUG(("Start"));
1982 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1983 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1984 silc_ske_install_retransmission(ske);
1985 silc_packet_free(ske->packet);
1987 return SILC_FSM_WAIT;
1990 /* Decode Key Exchange Payload */
1991 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1992 if (status != SILC_SKE_STATUS_OK) {
1993 /** Error decoding KE payload */
1994 silc_packet_free(ske->packet);
1996 ske->status = status;
1997 silc_fsm_next(fsm, silc_ske_st_responder_error);
1998 return SILC_FSM_CONTINUE;
2001 ske->ke1_payload = recv_payload;
2003 silc_packet_free(ske->packet);
2006 /* Verify the received public key and verify the signature if we are
2007 doing mutual authentication. */
2008 if (ske->start_payload &&
2009 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2011 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2013 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2015 /** Public key not provided */
2016 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2017 "certificate), even though we require it"));
2018 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2019 silc_fsm_next(fsm, silc_ske_st_responder_error);
2020 return SILC_FSM_CONTINUE;
2023 /* Decode the remote's public key */
2024 if (recv_payload->pk_data &&
2025 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2026 recv_payload->pk_data,
2027 recv_payload->pk_len,
2028 &ske->prop->public_key)) {
2029 /** Error decoding public key */
2030 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2031 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2032 silc_fsm_next(fsm, silc_ske_st_responder_error);
2033 return SILC_FSM_CONTINUE;
2036 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2038 SILC_LOG_DEBUG(("Verifying public key"));
2040 /** Waiting public key verification */
2041 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2043 /* If repository is provided, verify the key from there. */
2044 if (ske->repository) {
2047 find = silc_skr_find_alloc();
2049 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2050 silc_fsm_next(fsm, silc_ske_st_responder_error);
2051 return SILC_FSM_CONTINUE;
2053 silc_skr_find_set_pkcs_type(find,
2054 silc_pkcs_get_type(ske->prop->public_key));
2055 silc_skr_find_set_public_key(find, ske->prop->public_key);
2056 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2058 /* Find key from repository */
2059 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2060 silc_ske_skr_callback, ske));
2062 /* Verify from application */
2063 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2064 ske->callbacks->context,
2065 silc_ske_pk_verified, NULL));
2071 /** Generate KE2 payload */
2072 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2073 return SILC_FSM_CONTINUE;
2076 /* Phase-4. Generate KE2 payload */
2078 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2080 SilcSKE ske = fsm_context;
2081 SilcSKEStatus status;
2082 SilcSKEKEPayload recv_payload, send_payload;
2087 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2088 return SILC_FSM_CONTINUE;
2091 /* Check result of public key verification */
2092 if (ske->status != SILC_SKE_STATUS_OK) {
2093 /** Public key not verified */
2094 SILC_LOG_DEBUG(("Public key verification failed"));
2095 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2096 return SILC_FSM_CONTINUE;
2099 recv_payload = ske->ke1_payload;
2101 /* The public key verification was performed only if the Mutual
2102 Authentication flag is set. */
2103 if (ske->start_payload &&
2104 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2105 unsigned char hash[SILC_HASH_MAXLEN];
2106 SilcUInt32 hash_len;
2108 SILC_LOG_DEBUG(("Public key is authentic"));
2110 /* Compute the hash value */
2111 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2112 if (status != SILC_SKE_STATUS_OK) {
2113 /** Error computing hash */
2114 ske->status = status;
2115 silc_fsm_next(fsm, silc_ske_st_responder_error);
2116 return SILC_FSM_CONTINUE;
2119 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2121 /* Verify signature */
2122 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2123 recv_payload->sign_len, hash, hash_len, NULL)) {
2124 /** Incorrect signature */
2125 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2126 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2127 silc_fsm_next(fsm, silc_ske_st_responder_error);
2128 return SILC_FSM_CONTINUE;
2131 SILC_LOG_DEBUG(("Signature is Ok"));
2133 memset(hash, 'F', hash_len);
2136 /* Create the random number x, 1 < x < q. */
2137 x = silc_calloc(1, sizeof(*x));
2140 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2141 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2143 if (status != SILC_SKE_STATUS_OK) {
2144 /** Error generating random number */
2147 ske->status = status;
2148 silc_fsm_next(fsm, silc_ske_st_responder_error);
2149 return SILC_FSM_CONTINUE;
2152 /* Save the results for later processing */
2153 send_payload = silc_calloc(1, sizeof(*send_payload));
2155 ske->ke2_payload = send_payload;
2157 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2159 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2160 silc_mp_init(&send_payload->x);
2161 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2162 &ske->prop->group->group);
2164 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2166 /* Compute the shared secret key */
2167 KEY = silc_calloc(1, sizeof(*KEY));
2169 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2170 &ske->prop->group->group);
2173 /** Send KE2 payload */
2174 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2175 return SILC_FSM_CONTINUE;
2178 /* Phase-5. Send KE2 payload */
2180 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2182 SilcSKE ske = fsm_context;
2183 SilcSKEStatus status;
2184 SilcBuffer payload_buf;
2185 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2186 SilcUInt32 hash_len, sign_len, pk_len;
2188 SILC_LOG_DEBUG(("Start"));
2190 if (ske->public_key && ske->private_key) {
2191 SILC_LOG_DEBUG(("Getting public key"));
2193 /* Get the public key */
2194 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2196 /** Error encoding public key */
2197 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2198 silc_fsm_next(fsm, silc_ske_st_responder_error);
2199 return SILC_FSM_CONTINUE;
2201 ske->ke2_payload->pk_data = pk;
2202 ske->ke2_payload->pk_len = pk_len;
2204 SILC_LOG_DEBUG(("Computing HASH value"));
2206 /* Compute the hash value */
2207 memset(hash, 0, sizeof(hash));
2208 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2209 if (status != SILC_SKE_STATUS_OK) {
2210 /** Error computing hash */
2211 ske->status = status;
2212 silc_fsm_next(fsm, silc_ske_st_responder_error);
2213 return SILC_FSM_CONTINUE;
2216 ske->hash = silc_memdup(hash, hash_len);
2217 ske->hash_len = hash_len;
2219 SILC_LOG_DEBUG(("Signing HASH value"));
2221 /* Sign the hash value */
2222 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2223 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2224 /** Error computing signature */
2225 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2226 silc_fsm_next(fsm, silc_ske_st_responder_error);
2227 return SILC_FSM_CONTINUE;
2229 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2230 ske->ke2_payload->sign_len = sign_len;
2231 memset(sign, 0, sizeof(sign));
2233 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2235 /* Encode the Key Exchange Payload */
2236 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2238 if (status != SILC_SKE_STATUS_OK) {
2239 /** Error encoding KE payload */
2240 ske->status = status;
2241 silc_fsm_next(fsm, silc_ske_st_responder_error);
2242 return SILC_FSM_CONTINUE;
2245 /* Send the packet. */
2246 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2247 payload_buf->data, silc_buffer_len(payload_buf))) {
2248 SILC_LOG_DEBUG(("Error sending packet"));
2249 ske->status = SILC_SKE_STATUS_ERROR;
2250 silc_fsm_next(fsm, silc_ske_st_responder_error);
2251 return SILC_FSM_CONTINUE;
2254 silc_buffer_free(payload_buf);
2256 /** Waiting completion */
2257 silc_fsm_next(fsm, silc_ske_st_responder_end);
2258 return SILC_FSM_WAIT;
2261 /* Protocol completed */
2263 SILC_FSM_STATE(silc_ske_st_responder_end)
2265 SilcSKE ske = fsm_context;
2266 unsigned char tmp[4];
2267 SilcUInt32 hash_len, key_len, block_len;
2269 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2270 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2271 silc_ske_install_retransmission(ske);
2272 silc_packet_free(ske->packet);
2274 return SILC_FSM_WAIT;
2276 silc_packet_free(ske->packet);
2279 /* Process key material */
2280 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2281 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2282 hash_len = silc_hash_len(ske->prop->hash);
2283 ske->keymat = silc_ske_process_key_material(ske, block_len,
2287 /** Error processing key material */
2288 ske->status = SILC_SKE_STATUS_ERROR;
2289 silc_fsm_next(fsm, silc_ske_st_responder_error);
2290 return SILC_FSM_CONTINUE;
2293 /* Send SUCCESS packet */
2294 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2295 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2297 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2298 silc_schedule_task_del_by_context(ske->schedule, ske);
2300 return SILC_FSM_FINISH;
2303 /* Aborted by application */
2305 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2307 SilcSKE ske = fsm_context;
2308 unsigned char tmp[4];
2310 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2312 /* Send FAILURE packet */
2313 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2314 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2316 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2317 silc_schedule_task_del_by_context(ske->schedule, ske);
2319 return SILC_FSM_FINISH;
2322 /* Failure received from remote */
2324 SILC_FSM_STATE(silc_ske_st_responder_failure)
2326 SilcSKE ske = fsm_context;
2327 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2329 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2331 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2332 SILC_GET32_MSB(error, ske->packet->buffer.data);
2333 ske->status = error;
2334 silc_packet_free(ske->packet);
2338 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2339 silc_schedule_task_del_by_context(ske->schedule, ske);
2341 return SILC_FSM_FINISH;
2344 /* Error occurred */
2346 SILC_FSM_STATE(silc_ske_st_responder_error)
2348 SilcSKE ske = fsm_context;
2349 unsigned char tmp[4];
2351 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2352 ske->status, silc_ske_map_status(ske->status)));
2354 /* Send FAILURE packet */
2355 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2356 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2357 SILC_PUT32_MSB(ske->status, tmp);
2358 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2360 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2361 silc_schedule_task_del_by_context(ske->schedule, ske);
2363 return SILC_FSM_FINISH;
2366 /* Starts the protocol as responder. */
2369 silc_ske_responder(SilcSKE ske,
2370 SilcPacketStream stream,
2371 SilcSKEParams params)
2373 SILC_LOG_DEBUG(("Start SKE as responder"));
2375 if (!ske || !stream || !params || !params->version)
2378 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2381 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2384 ske->responder = TRUE;
2385 ske->flags = params->flags;
2386 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2387 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2388 ske->session_port = params->session_port;
2389 ske->version = strdup(params->version);
2392 ske->running = TRUE;
2394 /* Link to packet stream to get key exchange packets */
2395 ske->stream = stream;
2396 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2397 SILC_PACKET_KEY_EXCHANGE,
2398 SILC_PACKET_KEY_EXCHANGE_1,
2399 SILC_PACKET_SUCCESS,
2400 SILC_PACKET_FAILURE, -1);
2402 /* Start SKE as responder */
2403 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2408 /***************************** Initiator Rekey ******************************/
2412 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2414 SilcSKE ske = fsm_context;
2417 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2421 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2422 return SILC_FSM_CONTINUE;
2425 /* Add rekey exchange timeout */
2426 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2429 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2432 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2433 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2434 return SILC_FSM_CONTINUE;
2437 /* Send REKEY packet to start rekey protocol */
2438 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2439 /** Error sending packet */
2440 SILC_LOG_DEBUG(("Error sending packet"));
2441 ske->status = SILC_SKE_STATUS_ERROR;
2442 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2443 return SILC_FSM_CONTINUE;
2446 /* If doing rekey without PFS, move directly to the end of the protocol. */
2447 if (!ske->rekey->pfs) {
2448 /** Rekey without PFS */
2449 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2450 return SILC_FSM_CONTINUE;
2453 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2455 if (status != SILC_SKE_STATUS_OK) {
2456 /** Unknown group */
2457 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2458 return SILC_FSM_CONTINUE;
2461 /** Rekey with PFS */
2462 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2463 return SILC_FSM_CONTINUE;
2466 /* Sends REKEY_DONE packet to finish the protocol. */
2468 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2470 SilcSKE ske = fsm_context;
2471 SilcCipher send_key;
2474 SilcUInt32 key_len, block_len, hash_len, x_len;
2475 unsigned char *pfsbuf;
2477 SILC_LOG_DEBUG(("Start"));
2479 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2480 key_len = silc_cipher_get_key_len(send_key);
2481 block_len = silc_cipher_get_block_len(send_key);
2483 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2484 /** Cannot allocate hash */
2485 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2486 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2487 return SILC_FSM_CONTINUE;
2489 hash_len = silc_hash_len(hash);
2491 /* Process key material */
2492 if (ske->rekey->pfs) {
2494 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2496 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2499 memset(pfsbuf, 0, x_len);
2505 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2506 ske->rekey->enc_key_len / 8,
2512 SILC_LOG_ERROR(("Error processing key material"));
2513 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2514 return SILC_FSM_CONTINUE;
2517 ske->prop->cipher = send_key;
2518 ske->prop->hmac = hmac_send;
2519 ske->prop->hash = hash;
2521 /* Get sending keys */
2522 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2523 &hmac_send, NULL, NULL)) {
2524 /** Cannot get keys */
2525 ske->status = SILC_SKE_STATUS_ERROR;
2526 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2527 return SILC_FSM_CONTINUE;
2530 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2531 packet sent after this call will be protected with the new keys. */
2532 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2534 /** Cannot set keys */
2535 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2536 ske->status = SILC_SKE_STATUS_ERROR;
2537 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2538 return SILC_FSM_CONTINUE;
2541 /** Wait for REKEY_DONE */
2542 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2543 return SILC_FSM_WAIT;
2546 /* Rekey protocol end */
2548 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2550 SilcSKE ske = fsm_context;
2551 SilcCipher receive_key;
2552 SilcHmac hmac_receive;
2553 SilcSKERekeyMaterial rekey;
2555 SILC_LOG_DEBUG(("Start"));
2557 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2558 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2559 silc_packet_free(ske->packet);
2561 return SILC_FSM_WAIT;
2564 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2565 ske->prop->cipher = receive_key;
2566 ske->prop->hmac = hmac_receive;
2568 /* Get receiving keys */
2569 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2570 NULL, &hmac_receive, NULL)) {
2571 /** Cannot get keys */
2572 ske->status = SILC_SKE_STATUS_ERROR;
2573 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2574 return SILC_FSM_CONTINUE;
2577 /* Set new receiving keys into use. All packets received after this will
2578 be decrypted with the new keys. */
2579 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2580 hmac_receive, FALSE)) {
2581 /** Cannot set keys */
2582 SILC_LOG_DEBUG(("Cannot set new keys"));
2583 ske->status = SILC_SKE_STATUS_ERROR;
2584 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2585 return SILC_FSM_CONTINUE;
2588 SILC_LOG_DEBUG(("Rekey completed successfully"));
2590 /* Generate new rekey material */
2591 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2594 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2595 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2596 return SILC_FSM_CONTINUE;
2598 rekey->pfs = ske->rekey->pfs;
2601 ske->prop->cipher = NULL;
2602 ske->prop->hmac = NULL;
2603 silc_packet_free(ske->packet);
2605 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2606 silc_schedule_task_del_by_context(ske->schedule, ske);
2608 return SILC_FSM_FINISH;
2611 /* Starts rekey protocol as initiator */
2614 silc_ske_rekey_initiator(SilcSKE ske,
2615 SilcPacketStream stream,
2616 SilcSKERekeyMaterial rekey)
2618 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2620 if (!ske || !stream || !rekey)
2623 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2626 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2630 ske->responder = FALSE;
2631 ske->running = TRUE;
2632 ske->rekeying = TRUE;
2634 /* Link to packet stream to get key exchange packets */
2635 ske->stream = stream;
2636 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2638 SILC_PACKET_REKEY_DONE,
2639 SILC_PACKET_KEY_EXCHANGE_2,
2640 SILC_PACKET_SUCCESS,
2641 SILC_PACKET_FAILURE, -1);
2643 /* Start SKE rekey as initiator */
2644 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2649 /***************************** Responder Rekey ******************************/
2651 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2653 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2655 return SILC_FSM_FINISH;
2658 /* Starts rekey protocol as responder */
2661 silc_ske_rekey_responder(SilcSKE ske,
2662 SilcPacketStream stream,
2663 SilcSKERekeyMaterial rekey)
2665 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2667 if (!ske || !stream || !rekey)
2670 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2673 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2677 ske->responder = TRUE;
2678 ske->running = TRUE;
2679 ske->rekeying = TRUE;
2681 /* Link to packet stream to get key exchange packets */
2682 ske->stream = stream;
2683 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2685 SILC_PACKET_REKEY_DONE,
2686 SILC_PACKET_KEY_EXCHANGE_1,
2687 SILC_PACKET_SUCCESS,
2688 SILC_PACKET_FAILURE, -1);
2690 /* Start SKE rekey as responder */
2691 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2696 /* Processes the provided key material `data' as the SILC protocol
2697 specification defines. */
2700 silc_ske_process_key_material_data(unsigned char *data,
2701 SilcUInt32 data_len,
2702 SilcUInt32 req_iv_len,
2703 SilcUInt32 req_enc_key_len,
2704 SilcUInt32 req_hmac_key_len,
2708 unsigned char hashd[SILC_HASH_MAXLEN];
2709 SilcUInt32 hash_len = req_hmac_key_len;
2710 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2711 SilcSKEKeyMaterial key;
2713 SILC_LOG_DEBUG(("Start"));
2715 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2718 key = silc_calloc(1, sizeof(*key));
2722 buf = silc_buffer_alloc_size(1 + data_len);
2725 silc_buffer_format(buf,
2726 SILC_STR_UI_CHAR(0),
2727 SILC_STR_UI_XNSTRING(data, data_len),
2731 memset(hashd, 0, sizeof(hashd));
2733 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2734 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2735 memcpy(key->send_iv, hashd, req_iv_len);
2736 memset(hashd, 0, sizeof(hashd));
2738 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2739 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2740 memcpy(key->receive_iv, hashd, req_iv_len);
2741 key->iv_len = req_iv_len;
2743 /* Take the encryption keys. If requested key size is more than
2744 the size of hash length we will distribute more key material
2745 as protocol defines. */
2747 if (enc_key_len > hash_len) {
2749 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2750 k3[SILC_HASH_MAXLEN];
2751 unsigned char *dtmp;
2754 if (enc_key_len > (3 * hash_len))
2757 /* Take first round */
2758 memset(k1, 0, sizeof(k1));
2759 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2761 /* Take second round */
2762 dist = silc_buffer_alloc_size(data_len + hash_len);
2765 silc_buffer_format(dist,
2766 SILC_STR_UI_XNSTRING(data, data_len),
2767 SILC_STR_UI_XNSTRING(k1, hash_len),
2769 memset(k2, 0, sizeof(k2));
2770 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2772 /* Take third round */
2773 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2774 silc_buffer_pull_tail(dist, hash_len);
2775 silc_buffer_pull(dist, data_len + hash_len);
2776 silc_buffer_format(dist,
2777 SILC_STR_UI_XNSTRING(k2, hash_len),
2779 silc_buffer_push(dist, data_len + hash_len);
2780 memset(k3, 0, sizeof(k3));
2781 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2783 /* Then, save the keys */
2784 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2785 memcpy(dtmp, k1, hash_len);
2786 memcpy(dtmp + hash_len, k2, hash_len);
2787 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2789 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2790 memcpy(key->send_enc_key, dtmp, enc_key_len);
2791 key->enc_key_len = req_enc_key_len;
2793 memset(dtmp, 0, (3 * hash_len));
2794 memset(k1, 0, sizeof(k1));
2795 memset(k2, 0, sizeof(k2));
2796 memset(k3, 0, sizeof(k3));
2798 silc_buffer_clear(dist);
2799 silc_buffer_free(dist);
2801 /* Take normal hash as key */
2802 memset(hashd, 0, sizeof(hashd));
2803 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2804 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2805 memcpy(key->send_enc_key, hashd, enc_key_len);
2806 key->enc_key_len = req_enc_key_len;
2810 if (enc_key_len > hash_len) {
2812 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2813 k3[SILC_HASH_MAXLEN];
2814 unsigned char *dtmp;
2817 if (enc_key_len > (3 * hash_len))
2820 /* Take first round */
2821 memset(k1, 0, sizeof(k1));
2822 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2824 /* Take second round */
2825 dist = silc_buffer_alloc_size(data_len + hash_len);
2828 silc_buffer_format(dist,
2829 SILC_STR_UI_XNSTRING(data, data_len),
2830 SILC_STR_UI_XNSTRING(k1, hash_len),
2832 memset(k2, 0, sizeof(k2));
2833 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2835 /* Take third round */
2836 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2837 silc_buffer_pull_tail(dist, hash_len);
2838 silc_buffer_pull(dist, data_len + hash_len);
2839 silc_buffer_format(dist,
2840 SILC_STR_UI_XNSTRING(k2, hash_len),
2842 silc_buffer_push(dist, data_len + hash_len);
2843 memset(k3, 0, sizeof(k3));
2844 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2846 /* Then, save the keys */
2847 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2848 memcpy(dtmp, k1, hash_len);
2849 memcpy(dtmp + hash_len, k2, hash_len);
2850 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2852 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2853 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2854 key->enc_key_len = req_enc_key_len;
2856 memset(dtmp, 0, (3 * hash_len));
2857 memset(k1, 0, sizeof(k1));
2858 memset(k2, 0, sizeof(k2));
2859 memset(k3, 0, sizeof(k3));
2861 silc_buffer_clear(dist);
2862 silc_buffer_free(dist);
2864 /* Take normal hash as key */
2865 memset(hashd, 0, sizeof(hashd));
2866 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2867 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2868 memcpy(key->receive_enc_key, hashd, enc_key_len);
2869 key->enc_key_len = req_enc_key_len;
2872 /* Take HMAC keys */
2873 memset(hashd, 0, sizeof(hashd));
2875 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2876 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2877 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2878 memset(hashd, 0, sizeof(hashd));
2880 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2881 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2882 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2883 key->hmac_key_len = req_hmac_key_len;
2884 memset(hashd, 0, sizeof(hashd));
2886 silc_buffer_clear(buf);
2887 silc_buffer_free(buf);
2889 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
2894 /* Processes negotiated key material as protocol specifies. This returns
2895 the actual keys to be used in the SILC. */
2898 silc_ske_process_key_material(SilcSKE ske,
2899 SilcUInt32 req_iv_len,
2900 SilcUInt32 req_enc_key_len,
2901 SilcUInt32 req_hmac_key_len,
2902 SilcSKERekeyMaterial *rekey)
2905 unsigned char *tmpbuf;
2907 SilcSKEKeyMaterial key;
2909 /* Encode KEY to binary data */
2910 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2912 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2915 silc_buffer_format(buf,
2916 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2917 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2920 /* Process the key material */
2921 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2922 req_iv_len, req_enc_key_len,
2926 memset(tmpbuf, 0, klen);
2928 silc_buffer_clear(buf);
2929 silc_buffer_free(buf);
2932 *rekey = silc_ske_make_rekey_material(ske, key);
2940 /* Free key material structure */
2942 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2948 silc_free(key->send_iv);
2949 if (key->receive_iv)
2950 silc_free(key->receive_iv);
2951 if (key->send_enc_key) {
2952 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2953 silc_free(key->send_enc_key);
2955 if (key->receive_enc_key) {
2956 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2957 silc_free(key->receive_enc_key);
2959 if (key->send_hmac_key) {
2960 memset(key->send_hmac_key, 0, key->hmac_key_len);
2961 silc_free(key->send_hmac_key);
2963 if (key->receive_hmac_key) {
2964 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2965 silc_free(key->receive_hmac_key);
2970 /* Free rekey material */
2972 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
2976 if (rekey->send_enc_key) {
2977 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
2978 silc_free(rekey->send_enc_key);
2980 silc_free(rekey->hash);
2984 /* Set keys into use */
2986 SilcBool silc_ske_set_keys(SilcSKE ske,
2987 SilcSKEKeyMaterial keymat,
2988 SilcSKESecurityProperties prop,
2989 SilcCipher *ret_send_key,
2990 SilcCipher *ret_receive_key,
2991 SilcHmac *ret_hmac_send,
2992 SilcHmac *ret_hmac_receive,
2995 unsigned char iv[32];
2997 /* Allocate ciphers to be used in the communication */
2999 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3003 if (ret_receive_key) {
3004 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3009 /* Allocate HMACs */
3010 if (ret_hmac_send) {
3011 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3015 if (ret_hmac_receive) {
3016 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3021 /* Set key material */
3022 memset(iv, 0, sizeof(iv));
3023 if (ske->responder) {
3025 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3026 keymat->enc_key_len, TRUE);
3028 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3029 memcpy(iv, ske->hash, 4);
3030 memcpy(iv + 4, keymat->receive_iv, 4);
3031 silc_cipher_set_iv(*ret_send_key, iv);
3033 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3036 if (ret_receive_key) {
3037 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3038 keymat->enc_key_len, FALSE);
3040 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3041 memcpy(iv, ske->hash, 4);
3042 memcpy(iv + 4, keymat->send_iv, 4);
3043 silc_cipher_set_iv(*ret_receive_key, iv);
3045 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3049 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3050 keymat->hmac_key_len);
3051 if (ret_hmac_receive)
3052 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3053 keymat->hmac_key_len);
3056 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3057 keymat->enc_key_len, TRUE);
3059 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3060 memcpy(iv, ske->hash, 4);
3061 memcpy(iv + 4, keymat->send_iv, 4);
3062 silc_cipher_set_iv(*ret_send_key, iv);
3064 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3067 if (ret_receive_key) {
3068 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3069 keymat->enc_key_len, FALSE);
3071 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3072 memcpy(iv, ske->hash, 4);
3073 memcpy(iv + 4, keymat->receive_iv, 4);
3074 silc_cipher_set_iv(*ret_receive_key, iv);
3076 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3080 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3081 keymat->hmac_key_len);
3082 if (ret_hmac_receive)
3083 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3084 keymat->hmac_key_len);
3089 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3096 const char *silc_ske_status_string[] =
3100 "Unkown error occurred",
3101 "Bad payload in packet",
3102 "Unsupported group",
3103 "Unsupported cipher",
3105 "Unsupported hash function",
3107 "Unsupported public key (or certificate)",
3108 "Incorrect signature",
3109 "Bad or unsupported version",
3113 "Remote did not provide public key",
3114 "Bad reserved field in packet",
3115 "Bad payload length in packet",
3116 "Error computing signature",
3117 "System out of memory",
3118 "Key exchange timeout",
3123 /* Maps status to readable string and returns the string. If string is not
3124 found and empty character string ("") is returned. */
3126 const char *silc_ske_map_status(SilcSKEStatus status)
3130 for (i = 0; silc_ske_status_string[i]; i++)
3132 return silc_ske_status_string[i];
3137 /* Parses remote host's version string. */
3139 SilcBool silc_ske_parse_version(SilcSKE ske,
3140 SilcUInt32 *protocol_version,
3141 char **protocol_version_string,
3142 SilcUInt32 *software_version,
3143 char **software_version_string,
3144 char **vendor_version)
3146 return silc_parse_version_string(ske->remote_version,
3148 protocol_version_string,
3150 software_version_string,
3154 /* Get security properties */
3156 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3161 /* Get key material */
3163 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)