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 and SUCCESS packets synchronously. After SUCCESS packets
114 they keys are taken into use immediately, hence the synchronous
115 processing to get the keys in use as soon as possible. */
116 if (ske->rekeying || packet->type == SILC_PACKET_SUCCESS)
117 silc_fsm_continue_sync(&ske->fsm);
119 silc_fsm_continue(&ske->fsm);
124 /* Packet stream callbacks */
125 static SilcPacketCallbacks silc_ske_stream_cbs =
127 silc_ske_packet_receive, NULL, NULL
130 /* Aborts SKE protocol */
132 static void silc_ske_abort(SilcAsyncOperation op, void *context)
134 SilcSKE ske = context;
138 /* Public key verification completion callback */
140 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
141 void *completion_context)
143 ske->status = status;
144 SILC_FSM_CALL_CONTINUE(&ske->fsm);
147 /* SKR find callback */
149 static void silc_ske_skr_callback(SilcSKR repository,
151 SilcSKRStatus status,
152 SilcDList keys, void *context)
154 SilcSKE ske = context;
156 silc_skr_find_free(find);
158 if (status != SILC_SKR_OK) {
159 if (ske->callbacks->verify_key) {
160 /* Verify from application */
161 ske->callbacks->verify_key(ske, ske->prop->public_key,
162 ske->callbacks->context,
163 silc_ske_pk_verified, NULL);
169 silc_dlist_uninit(keys);
172 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
173 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
174 SILC_FSM_CALL_CONTINUE(&ske->fsm);
177 /* Checks remote and local versions */
179 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
181 SilcUInt32 r_software_version = 0;
183 if (!ske->remote_version || !ske->version)
184 return SILC_SKE_STATUS_BAD_VERSION;
186 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
187 &r_software_version, NULL, NULL))
188 return SILC_SKE_STATUS_BAD_VERSION;
190 /* Backwards compatibility checks */
192 /* Old server versions requires "valid" looking Source ID in the SILC
193 packets during initial key exchange. All version before 1.1.0. */
194 if (r_software_version < 110) {
196 memset(&id, 0, sizeof(id));
198 SILC_LOG_DEBUG(("Remote is old version, add dummy Source ID to packets"));
199 silc_packet_set_ids(ske->stream, SILC_ID_CLIENT, &id, 0, NULL);
202 return SILC_SKE_STATUS_OK;
205 /* Selects the supported security properties from the initiator's Key
206 Exchange Start Payload. A responder function. Saves our reply
207 start payload to ske->start_payload. */
210 silc_ske_select_security_properties(SilcSKE ske,
211 SilcSKEStartPayload remote_payload,
212 SilcSKESecurityProperties *prop)
214 SilcSKEStatus status;
215 SilcSKEStartPayload rp, payload;
219 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
223 /* Check for mandatory fields */
224 if (!rp->ke_grp_len) {
225 SILC_LOG_DEBUG(("KE group not defined in payload"));
226 return SILC_SKE_STATUS_BAD_PAYLOAD;
228 if (!rp->pkcs_alg_len) {
229 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
230 return SILC_SKE_STATUS_BAD_PAYLOAD;
232 if (!rp->enc_alg_len) {
233 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
234 return SILC_SKE_STATUS_BAD_PAYLOAD;
236 if (!rp->hash_alg_len) {
237 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
238 return SILC_SKE_STATUS_BAD_PAYLOAD;
240 if (!rp->hmac_alg_len) {
241 SILC_LOG_DEBUG(("HMAC not defined in payload"));
242 return SILC_SKE_STATUS_BAD_PAYLOAD;
245 /* Allocate security properties */
246 *prop = silc_calloc(1, sizeof(**prop));
248 return SILC_SKE_STATUS_OUT_OF_MEMORY;
250 /* Allocate our reply start payload */
251 payload = silc_calloc(1, sizeof(*payload));
254 return SILC_SKE_STATUS_OUT_OF_MEMORY;
257 /* Check version string */
258 ske->remote_version = silc_memdup(rp->version, rp->version_len);
259 status = silc_ske_check_version(ske);
260 if (status != SILC_SKE_STATUS_OK) {
261 ske->status = status;
265 /* Flags are returned unchanged. */
266 (*prop)->flags = payload->flags = rp->flags;
268 /* Take cookie, we must return it to sender unmodified. */
269 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
270 if (!payload->cookie) {
271 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
274 payload->cookie_len = SILC_SKE_COOKIE_LEN;
275 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
277 /* In case IV included flag and session port is set the first 16-bits of
278 cookie will include our session port. */
279 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
280 /* Take remote port */
281 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
284 SILC_PUT16_MSB(ske->session_port, payload->cookie);
287 /* Put our version to our reply */
288 payload->version = strdup(ske->version);
289 if (!payload->version) {
290 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
293 payload->version_len = strlen(ske->version);
295 /* Get supported Key Exchange groups */
296 cp = rp->ke_grp_list;
297 if (cp && strchr(cp, ',')) {
301 len = strcspn(cp, ",");
302 item = silc_calloc(len + 1, sizeof(char));
304 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
307 memcpy(item, cp, len);
309 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
311 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
312 SILC_LOG_DEBUG(("Found KE group `%s'", item));
314 payload->ke_grp_len = len;
315 payload->ke_grp_list = item;
329 if (!payload->ke_grp_len && !payload->ke_grp_list) {
330 SILC_LOG_DEBUG(("Could not find supported KE group"));
332 return SILC_SKE_STATUS_UNKNOWN_GROUP;
335 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
336 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
338 payload->ke_grp_len = rp->ke_grp_len;
339 payload->ke_grp_list = strdup(rp->ke_grp_list);
342 /* Save group to security properties */
343 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
344 if (status != SILC_SKE_STATUS_OK) {
346 return SILC_SKE_STATUS_UNKNOWN_GROUP;
349 /* Get supported PKCS algorithms */
350 cp = rp->pkcs_alg_list;
351 if (cp && strchr(cp, ',')) {
355 len = strcspn(cp, ",");
356 item = silc_calloc(len + 1, sizeof(char));
358 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
361 memcpy(item, cp, len);
363 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
365 if (silc_pkcs_find_algorithm(item, NULL)) {
366 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
368 payload->pkcs_alg_len = len;
369 payload->pkcs_alg_list = item;
383 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
384 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
385 silc_free(payload->ke_grp_list);
387 return SILC_SKE_STATUS_UNKNOWN_PKCS;
390 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
391 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
393 payload->pkcs_alg_len = rp->pkcs_alg_len;
394 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
397 /* Get supported encryption algorithms */
398 cp = rp->enc_alg_list;
399 if (cp && strchr(cp, ',')) {
403 len = strcspn(cp, ",");
404 item = silc_calloc(len + 1, sizeof(char));
406 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
409 memcpy(item, cp, len);
411 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
413 if (silc_cipher_is_supported(item) == TRUE) {
414 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
416 payload->enc_alg_len = len;
417 payload->enc_alg_list = item;
431 if (!payload->enc_alg_len && !payload->enc_alg_list) {
432 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
433 silc_free(payload->ke_grp_list);
434 silc_free(payload->pkcs_alg_list);
436 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
439 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
442 payload->enc_alg_len = rp->enc_alg_len;
443 payload->enc_alg_list = strdup(rp->enc_alg_list);
446 /* Save selected cipher to security properties */
447 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
448 silc_free(payload->ke_grp_list);
449 silc_free(payload->pkcs_alg_list);
451 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
454 /* Get supported hash algorithms */
455 cp = rp->hash_alg_list;
456 if (cp && strchr(cp, ',')) {
460 len = strcspn(cp, ",");
461 item = silc_calloc(len + 1, sizeof(char));
463 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
466 memcpy(item, cp, len);
468 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
470 if (silc_hash_is_supported(item) == TRUE) {
471 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
473 payload->hash_alg_len = len;
474 payload->hash_alg_list = item;
488 if (!payload->hash_alg_len && !payload->hash_alg_list) {
489 SILC_LOG_DEBUG(("Could not find supported hash alg"));
490 silc_free(payload->ke_grp_list);
491 silc_free(payload->pkcs_alg_list);
492 silc_free(payload->enc_alg_list);
494 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
497 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
500 payload->hash_alg_len = rp->hash_alg_len;
501 payload->hash_alg_list = strdup(rp->hash_alg_list);
504 /* Save selected hash algorithm to security properties */
505 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
506 silc_free(payload->ke_grp_list);
507 silc_free(payload->pkcs_alg_list);
508 silc_free(payload->enc_alg_list);
510 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
513 /* Get supported HMACs */
514 cp = rp->hmac_alg_list;
515 if (cp && strchr(cp, ',')) {
519 len = strcspn(cp, ",");
520 item = silc_calloc(len + 1, sizeof(char));
522 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
525 memcpy(item, cp, len);
527 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
529 if (silc_hmac_is_supported(item) == TRUE) {
530 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
532 payload->hmac_alg_len = len;
533 payload->hmac_alg_list = item;
547 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
548 SILC_LOG_DEBUG(("Could not find supported HMAC"));
549 silc_free(payload->ke_grp_list);
550 silc_free(payload->pkcs_alg_list);
551 silc_free(payload->enc_alg_list);
552 silc_free(payload->hash_alg_list);
554 return SILC_SKE_STATUS_UNKNOWN_HMAC;
557 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
560 payload->hmac_alg_len = rp->hmac_alg_len;
561 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
564 /* Save selected HMACc to security properties */
565 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
566 silc_free(payload->ke_grp_list);
567 silc_free(payload->pkcs_alg_list);
568 silc_free(payload->enc_alg_list);
569 silc_free(payload->hash_alg_list);
571 return SILC_SKE_STATUS_UNKNOWN_HMAC;
574 /* Get supported compression algorithms */
575 cp = rp->comp_alg_list;
576 if (cp && strchr(cp, ',')) {
580 len = strcspn(cp, ",");
581 item = silc_calloc(len + 1, sizeof(char));
583 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
586 memcpy(item, cp, len);
588 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
591 if (!strcmp(item, "none")) {
592 SILC_LOG_DEBUG(("Found Compression `%s'", item));
593 payload->comp_alg_len = len;
594 payload->comp_alg_list = item;
598 if (silc_hmac_is_supported(item) == TRUE) {
599 SILC_LOG_DEBUG(("Found Compression `%s'", item));
600 payload->comp_alg_len = len;
601 payload->comp_alg_list = item;
617 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
618 2 + payload->version_len +
619 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
620 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
621 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
623 /* Save our reply payload */
624 ske->start_payload = payload;
626 return SILC_SKE_STATUS_OK;
629 /* Creates random number such that 1 < rnd < n and at most length
630 of len bits. The rnd sent as argument must be initialized. */
632 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
636 SilcSKEStatus status = SILC_SKE_STATUS_OK;
637 unsigned char *string;
641 return SILC_SKE_STATUS_ERROR;
643 SILC_LOG_DEBUG(("Creating random number"));
647 /* Get the random number as string */
648 string = silc_rng_get_rn_data(ske->rng, l);
650 return SILC_SKE_STATUS_OUT_OF_MEMORY;
652 /* Decode the string into a MP integer */
653 silc_mp_bin2mp(string, l, rnd);
654 silc_mp_mod_2exp(rnd, rnd, len);
657 if (silc_mp_cmp_ui(rnd, 1) < 0)
658 status = SILC_SKE_STATUS_ERROR;
659 if (silc_mp_cmp(rnd, n) >= 0)
660 status = SILC_SKE_STATUS_ERROR;
662 memset(string, 'F', l);
668 /* Creates a hash value HASH as defined in the SKE protocol. If the
669 `initiator' is TRUE then this function is used to create the HASH_i
670 hash value defined in the protocol. If it is FALSE then this is used
671 to create the HASH value defined by the protocol. */
673 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
674 unsigned char *return_hash,
675 SilcUInt32 *return_hash_len,
678 SilcSKEStatus status = SILC_SKE_STATUS_OK;
680 unsigned char *e, *f, *KEY;
681 SilcUInt32 e_len, f_len, KEY_len;
684 SILC_LOG_DEBUG(("Start"));
686 if (initiator == FALSE) {
687 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
688 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
689 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
691 /* Format the buffer used to compute the hash value */
692 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
693 ske->ke2_payload->pk_len +
694 ske->ke1_payload->pk_len +
695 e_len + f_len + KEY_len);
697 return SILC_SKE_STATUS_OUT_OF_MEMORY;
699 /* Initiator is not required to send its public key */
700 if (!ske->ke1_payload->pk_data) {
702 silc_buffer_format(buf,
703 SILC_STR_UI_XNSTRING(
704 ske->start_payload_copy->data,
705 silc_buffer_len(ske->start_payload_copy)),
706 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
707 ske->ke2_payload->pk_len),
708 SILC_STR_UI_XNSTRING(e, e_len),
709 SILC_STR_UI_XNSTRING(f, f_len),
710 SILC_STR_UI_XNSTRING(KEY, KEY_len),
714 silc_buffer_format(buf,
715 SILC_STR_UI_XNSTRING(
716 ske->start_payload_copy->data,
717 silc_buffer_len(ske->start_payload_copy)),
718 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
719 ske->ke2_payload->pk_len),
720 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
721 ske->ke1_payload->pk_len),
722 SILC_STR_UI_XNSTRING(e, e_len),
723 SILC_STR_UI_XNSTRING(f, f_len),
724 SILC_STR_UI_XNSTRING(KEY, KEY_len),
728 silc_buffer_free(buf);
731 memset(KEY, 0, KEY_len);
735 return SILC_SKE_STATUS_ERROR;
740 memset(KEY, 0, KEY_len);
745 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
747 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
748 ske->ke1_payload->pk_len + e_len);
750 return SILC_SKE_STATUS_OUT_OF_MEMORY;
752 /* Format the buffer used to compute the hash value */
754 silc_buffer_format(buf,
755 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
756 silc_buffer_len(ske->start_payload_copy)),
757 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
758 ske->ke1_payload->pk_len),
759 SILC_STR_UI_XNSTRING(e, e_len),
762 silc_buffer_free(buf);
765 return SILC_SKE_STATUS_ERROR;
768 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
775 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
777 *return_hash_len = silc_hash_len(ske->prop->hash);
779 if (initiator == FALSE) {
780 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
782 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
785 silc_buffer_free(buf);
790 /* Generate rekey material */
792 static SilcSKERekeyMaterial
793 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
795 SilcSKERekeyMaterial rekey;
798 /* Create rekey material */
799 rekey = silc_calloc(1, sizeof(*rekey));
804 if (ske->prop->group)
805 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
806 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
807 hash = silc_hash_get_name(ske->prop->hash);
808 rekey->hash = silc_memdup(hash, strlen(hash));
813 if (rekey->pfs == FALSE) {
814 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
815 keymat->enc_key_len / 8);
816 if (!rekey->send_enc_key) {
820 rekey->enc_key_len = keymat->enc_key_len;
826 /* Assembles security properties */
828 static SilcSKEStartPayload
829 silc_ske_assemble_security_properties(SilcSKE ske,
830 SilcSKESecurityPropertyFlag flags,
833 SilcSKEStartPayload rp;
836 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
838 rp = silc_calloc(1, sizeof(*rp));
841 rp->flags = (unsigned char)flags;
843 /* Set random cookie */
844 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
845 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
846 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
847 rp->cookie_len = SILC_SKE_COOKIE_LEN;
849 /* In case IV included flag and session port is set the first 16-bits of
850 cookie will include our session port. */
851 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
852 SILC_PUT16_MSB(ske->session_port, rp->cookie);
855 rp->version = strdup(version);
856 rp->version_len = strlen(version);
858 /* Get supported Key Exhange groups */
859 rp->ke_grp_list = silc_ske_get_supported_groups();
860 rp->ke_grp_len = strlen(rp->ke_grp_list);
862 /* Get supported PKCS algorithms */
863 rp->pkcs_alg_list = silc_pkcs_get_supported();
864 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
866 /* Get supported encryption algorithms */
867 rp->enc_alg_list = silc_cipher_get_supported();
868 rp->enc_alg_len = strlen(rp->enc_alg_list);
870 /* Get supported hash algorithms */
871 rp->hash_alg_list = silc_hash_get_supported();
872 rp->hash_alg_len = strlen(rp->hash_alg_list);
874 /* Get supported HMACs */
875 rp->hmac_alg_list = silc_hmac_get_supported();
876 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
879 /* Get supported compression algorithms */
880 rp->comp_alg_list = strdup("none");
881 rp->comp_alg_len = strlen("none");
883 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
884 2 + rp->version_len +
885 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
886 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
887 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
892 /* Packet retransmission callback. */
894 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
896 SilcSKE ske = context;
898 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
900 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
901 ske->retry_count = 0;
902 ske->retry_timer = SILC_SKE_RETRY_MIN;
903 silc_free(ske->retrans.data);
904 ske->retrans.data = NULL;
905 ske->status = SILC_SKE_STATUS_TIMEOUT;
907 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
909 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
910 silc_fsm_continue_sync(&ske->fsm);
914 SILC_LOG_DEBUG(("Retransmitting packet"));
915 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
916 ske->retrans.data, ske->retrans.data_len);
919 /* Install retransmission timer */
921 static void silc_ske_install_retransmission(SilcSKE ske)
923 if (!silc_packet_stream_is_udp(ske->stream))
926 if (ske->retrans.data) {
927 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
929 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
930 ske, ske->retry_timer, 0);
932 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
933 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
936 /* Sends SILC packet. Handles retransmissions with UDP streams. */
938 static SilcBool silc_ske_packet_send(SilcSKE ske,
940 SilcPacketFlags flags,
941 const unsigned char *data,
946 /* Send the packet */
947 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
949 if (silc_packet_stream_is_udp(ske->stream) &&
950 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
951 silc_free(ske->retrans.data);
952 ske->retrans.type = type;
953 ske->retrans.flags = flags;
954 ske->retrans.data = silc_memdup(data, data_len);
955 ske->retrans.data_len = data_len;
956 silc_ske_install_retransmission(ske);
962 /* Calls completion callback. Completion is called always in this function
963 and must not be called anywhere else. */
965 static void silc_ske_completion(SilcSKE ske)
967 /* Call the completion callback */
968 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
969 if (ske->status != SILC_SKE_STATUS_OK)
970 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
971 ske->callbacks->context);
973 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
974 ske->rekey, ske->callbacks->context);
978 /* SKE FSM destructor. */
980 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
981 void *destructor_context)
983 SilcSKE ske = fsm_context;
984 ske->running = FALSE;
989 /* Key exchange timeout task callback */
991 SILC_TASK_CALLBACK(silc_ske_timeout)
993 SilcSKE ske = context;
995 SILC_LOG_DEBUG(("Timeout"));
998 ske->status = SILC_SKE_STATUS_TIMEOUT;
1000 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1002 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1004 silc_fsm_continue_sync(&ske->fsm);
1007 /******************************* Protocol API *******************************/
1009 /* Allocates new SKE object. */
1011 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1012 SilcSKR repository, SilcPublicKey public_key,
1013 SilcPrivateKey private_key, void *context)
1017 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1019 if (!rng || !schedule)
1023 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1027 ske = silc_calloc(1, sizeof(*ske));
1030 ske->status = SILC_SKE_STATUS_OK;
1032 ske->repository = repository;
1033 ske->user_data = context;
1034 ske->schedule = schedule;
1035 ske->public_key = public_key;
1036 ske->private_key = private_key;
1037 ske->retry_timer = SILC_SKE_RETRY_MIN;
1043 /* Free's SKE object. */
1045 void silc_ske_free(SilcSKE ske)
1047 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1056 /* If already aborted, destroy the session immediately */
1058 ske->status = SILC_SKE_STATUS_ERROR;
1060 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1062 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1063 silc_fsm_continue_sync(&ske->fsm);
1069 if (ske->refcnt > 0)
1072 /* Free start payload */
1073 if (ske->start_payload)
1074 silc_ske_payload_start_free(ske->start_payload);
1076 /* Free KE payload */
1077 if (ske->ke1_payload)
1078 silc_ske_payload_ke_free(ske->ke1_payload);
1079 if (ske->ke2_payload)
1080 silc_ske_payload_ke_free(ske->ke2_payload);
1081 silc_free(ske->remote_version);
1085 if (ske->prop->group)
1086 silc_ske_group_free(ske->prop->group);
1087 if (ske->prop->cipher)
1088 silc_cipher_free(ske->prop->cipher);
1089 if (ske->prop->hash)
1090 silc_hash_free(ske->prop->hash);
1091 if (ske->prop->hmac)
1092 silc_hmac_free(ske->prop->hmac);
1093 if (ske->prop->public_key)
1094 silc_pkcs_public_key_free(ske->prop->public_key);
1095 silc_free(ske->prop);
1098 silc_ske_free_key_material(ske->keymat);
1099 if (ske->start_payload_copy)
1100 silc_buffer_free(ske->start_payload_copy);
1102 silc_mp_uninit(ske->x);
1106 silc_mp_uninit(ske->KEY);
1107 silc_free(ske->KEY);
1109 silc_free(ske->retrans.data);
1110 silc_free(ske->hash);
1111 silc_free(ske->callbacks);
1113 memset(ske, 'F', sizeof(*ske));
1117 /* Return user context */
1119 void *silc_ske_get_context(SilcSKE ske)
1121 return ske->user_data;
1124 /* Sets protocol callbacks */
1126 void silc_ske_set_callbacks(SilcSKE ske,
1127 SilcSKEVerifyCb verify_key,
1128 SilcSKECompletionCb completed,
1132 silc_free(ske->callbacks);
1133 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1134 if (!ske->callbacks)
1136 ske->callbacks->verify_key = verify_key;
1137 ske->callbacks->completed = completed;
1138 ske->callbacks->context = context;
1142 /******************************** Initiator *********************************/
1144 /* Start protocol. Send our proposal */
1146 SILC_FSM_STATE(silc_ske_st_initiator_start)
1148 SilcSKE ske = fsm_context;
1149 SilcBuffer payload_buf;
1152 SILC_LOG_DEBUG(("Start"));
1156 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1157 return SILC_FSM_CONTINUE;
1160 /* Encode the payload */
1161 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1163 if (status != SILC_SKE_STATUS_OK) {
1164 /** Error encoding Start Payload */
1165 ske->status = status;
1166 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1167 return SILC_FSM_CONTINUE;
1170 /* Save the the payload buffer for future use. It is later used to
1171 compute the HASH value. */
1172 ske->start_payload_copy = payload_buf;
1174 /* Send the packet. */
1175 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1176 silc_buffer_data(payload_buf),
1177 silc_buffer_len(payload_buf))) {
1178 /** Error sending packet */
1179 SILC_LOG_DEBUG(("Error sending packet"));
1180 ske->status = SILC_SKE_STATUS_ERROR;
1181 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1182 return SILC_FSM_CONTINUE;
1185 /* Add key exchange timeout */
1186 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1187 ske, ske->timeout, 0);
1189 /** Wait for responder proposal */
1190 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1191 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1192 return SILC_FSM_WAIT;
1195 /* Phase-1. Receives responder's proposal */
1197 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1199 SilcSKE ske = fsm_context;
1200 SilcSKEStatus status;
1201 SilcSKEStartPayload payload;
1202 SilcSKESecurityProperties prop;
1203 SilcSKEDiffieHellmanGroup group = NULL;
1204 SilcBuffer packet_buf = &ske->packet->buffer;
1205 SilcUInt16 remote_port = 0;
1209 SILC_LOG_DEBUG(("Start"));
1211 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1212 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1213 silc_ske_install_retransmission(ske);
1214 silc_packet_free(ske->packet);
1216 return SILC_FSM_WAIT;
1219 /* Decode the payload */
1220 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1221 if (status != SILC_SKE_STATUS_OK) {
1222 /** Error decoding Start Payload */
1223 silc_packet_free(ske->packet);
1225 ske->status = status;
1226 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1227 return SILC_FSM_CONTINUE;
1230 /* Get remote ID and set it to stream */
1231 if (ske->packet->src_id_len) {
1232 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1233 ske->packet->src_id_type,
1234 (ske->packet->src_id_type == SILC_ID_SERVER ?
1235 (void *)&id.u.server_id : (void *)&id.u.client_id),
1236 (ske->packet->src_id_type == SILC_ID_SERVER ?
1237 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1238 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1239 (ske->packet->src_id_type == SILC_ID_SERVER ?
1240 (void *)&id.u.server_id : (void *)&id.u.client_id));
1243 silc_packet_free(ske->packet);
1246 /* Check that the cookie is returned unmodified. In case IV included
1247 flag and session port has been set, the first two bytes of cookie
1248 are the session port and we ignore them in this check. */
1249 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1250 /* Take remote port */
1251 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1254 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1255 SILC_SKE_COOKIE_LEN - coff)) {
1256 /** Invalid cookie */
1257 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1258 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1259 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1260 return SILC_FSM_CONTINUE;
1263 /* Check version string */
1264 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1265 status = silc_ske_check_version(ske);
1266 if (status != SILC_SKE_STATUS_OK) {
1267 /** Version mismatch */
1268 ske->status = status;
1269 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1270 return SILC_FSM_CONTINUE;
1273 /* Free our KE Start Payload context, we don't need it anymore. */
1274 silc_ske_payload_start_free(ske->start_payload);
1275 ske->start_payload = NULL;
1277 /* Take the selected security properties into use while doing
1278 the key exchange. This is used only while doing the key
1280 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1283 prop->flags = payload->flags;
1284 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1285 if (status != SILC_SKE_STATUS_OK)
1288 prop->group = group;
1289 prop->remote_port = remote_port;
1291 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1292 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1295 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1296 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1299 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1300 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1303 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1304 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1308 /* Save remote's KE Start Payload */
1309 ske->start_payload = payload;
1311 /** Send KE Payload */
1312 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1313 return SILC_FSM_CONTINUE;
1317 silc_ske_payload_start_free(payload);
1319 silc_ske_group_free(group);
1321 silc_cipher_free(prop->cipher);
1323 silc_hash_free(prop->hash);
1325 silc_hmac_free(prop->hmac);
1329 if (status == SILC_SKE_STATUS_OK)
1330 status = SILC_SKE_STATUS_ERROR;
1333 ske->status = status;
1334 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1335 return SILC_FSM_CONTINUE;
1338 /* Phase-2. Send KE payload */
1340 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1342 SilcSKE ske = fsm_context;
1343 SilcSKEStatus status;
1344 SilcBuffer payload_buf;
1346 SilcSKEKEPayload payload;
1349 SILC_LOG_DEBUG(("Start"));
1351 /* Create the random number x, 1 < x < q. */
1352 x = silc_calloc(1, sizeof(*x));
1354 /** Out of memory */
1355 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1356 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1357 return SILC_FSM_CONTINUE;
1361 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1362 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1364 if (status != SILC_SKE_STATUS_OK) {
1365 /** Error generating random number */
1368 ske->status = status;
1369 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1370 return SILC_FSM_CONTINUE;
1373 /* Encode the result to Key Exchange Payload. */
1375 payload = silc_calloc(1, sizeof(*payload));
1377 /** Out of memory */
1380 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1381 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1382 return SILC_FSM_CONTINUE;
1384 ske->ke1_payload = payload;
1386 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1388 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1389 silc_mp_init(&payload->x);
1390 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1391 &ske->prop->group->group);
1393 /* Get public key */
1394 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1395 if (!payload->pk_data) {
1396 /** Error encoding public key */
1399 silc_mp_uninit(&payload->x);
1401 ske->ke1_payload = NULL;
1402 ske->status = SILC_SKE_STATUS_ERROR;
1403 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1404 return SILC_FSM_CONTINUE;
1406 payload->pk_len = pk_len;
1407 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1409 /* Compute signature data if we are doing mutual authentication */
1410 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1411 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1412 SilcUInt32 hash_len, sign_len;
1414 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1415 SILC_LOG_DEBUG(("Computing HASH_i value"));
1417 /* Compute the hash value */
1418 memset(hash, 0, sizeof(hash));
1419 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1421 SILC_LOG_DEBUG(("Signing HASH_i value"));
1423 /* Sign the hash value */
1424 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1425 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1426 /** Error computing signature */
1429 silc_mp_uninit(&payload->x);
1430 silc_free(payload->pk_data);
1432 ske->ke1_payload = NULL;
1433 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1434 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1435 return SILC_FSM_CONTINUE;
1437 payload->sign_data = silc_memdup(sign, sign_len);
1438 if (payload->sign_data)
1439 payload->sign_len = sign_len;
1440 memset(sign, 0, sizeof(sign));
1443 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1444 if (status != SILC_SKE_STATUS_OK) {
1445 /** Error encoding KE payload */
1448 silc_mp_uninit(&payload->x);
1449 silc_free(payload->pk_data);
1450 silc_free(payload->sign_data);
1452 ske->ke1_payload = NULL;
1453 ske->status = status;
1454 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1455 return SILC_FSM_CONTINUE;
1460 /* Check for backwards compatibility */
1462 /* Send the packet. */
1463 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1464 silc_buffer_data(payload_buf),
1465 silc_buffer_len(payload_buf))) {
1466 /** Error sending packet */
1467 SILC_LOG_DEBUG(("Error sending packet"));
1468 ske->status = SILC_SKE_STATUS_ERROR;
1469 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1470 return SILC_FSM_CONTINUE;
1473 silc_buffer_free(payload_buf);
1475 /** Waiting responder's KE payload */
1476 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1477 return SILC_FSM_WAIT;
1480 /* Phase-3. Process responder's KE payload */
1482 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1484 SilcSKE ske = fsm_context;
1485 SilcSKEStatus status;
1486 SilcSKEKEPayload payload;
1488 SilcBuffer packet_buf = &ske->packet->buffer;
1490 SILC_LOG_DEBUG(("Start"));
1492 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1493 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1494 silc_ske_install_retransmission(ske);
1495 silc_packet_free(ske->packet);
1497 return SILC_FSM_WAIT;
1500 /* Decode the payload */
1501 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1502 if (status != SILC_SKE_STATUS_OK) {
1503 /** Error decoding KE payload */
1504 silc_packet_free(ske->packet);
1506 ske->status = status;
1507 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1508 return SILC_FSM_CONTINUE;
1510 silc_packet_free(ske->packet);
1512 ske->ke2_payload = payload;
1514 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1515 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1516 "even though we require it"));
1517 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1521 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1523 /* Compute the shared secret key */
1524 KEY = silc_calloc(1, sizeof(*KEY));
1526 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1529 /* Decode the remote's public key */
1530 if (payload->pk_data &&
1531 !silc_pkcs_public_key_alloc(payload->pk_type,
1532 payload->pk_data, payload->pk_len,
1533 &ske->prop->public_key)) {
1534 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1535 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1539 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1541 SILC_LOG_DEBUG(("Verifying public key"));
1543 /** Waiting public key verification */
1544 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1546 /* If repository is provided, verify the key from there. */
1547 if (ske->repository) {
1550 find = silc_skr_find_alloc();
1552 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1555 silc_skr_find_set_pkcs_type(find,
1556 silc_pkcs_get_type(ske->prop->public_key));
1557 silc_skr_find_set_public_key(find, ske->prop->public_key);
1558 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1560 /* Find key from repository */
1561 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1562 silc_ske_skr_callback, ske));
1564 /* Verify from application */
1565 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1566 ske->callbacks->context,
1567 silc_ske_pk_verified, NULL));
1572 /** Process key material */
1573 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1574 return SILC_FSM_CONTINUE;
1577 silc_ske_payload_ke_free(payload);
1578 ske->ke2_payload = NULL;
1580 silc_mp_uninit(ske->KEY);
1581 silc_free(ske->KEY);
1584 if (status == SILC_SKE_STATUS_OK)
1585 return SILC_SKE_STATUS_ERROR;
1588 ske->status = status;
1589 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1590 return SILC_FSM_CONTINUE;
1593 /* Process key material */
1595 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1597 SilcSKE ske = fsm_context;
1598 SilcSKEStatus status;
1599 SilcSKEKEPayload payload;
1600 unsigned char hash[SILC_HASH_MAXLEN];
1601 SilcUInt32 hash_len;
1602 int key_len, block_len;
1606 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1607 return SILC_FSM_CONTINUE;
1610 /* Check result of public key verification */
1611 if (ske->status != SILC_SKE_STATUS_OK) {
1612 /** Public key not verified */
1613 SILC_LOG_DEBUG(("Public key verification failed"));
1614 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1615 return SILC_FSM_CONTINUE;
1618 payload = ske->ke2_payload;
1620 if (ske->prop->public_key) {
1621 SILC_LOG_DEBUG(("Public key is authentic"));
1623 /* Compute the hash value */
1624 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1625 if (status != SILC_SKE_STATUS_OK)
1628 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1630 /* Verify signature */
1631 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1632 payload->sign_len, hash, hash_len, NULL)) {
1633 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1634 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1638 SILC_LOG_DEBUG(("Signature is Ok"));
1640 ske->hash = silc_memdup(hash, hash_len);
1641 ske->hash_len = hash_len;
1642 memset(hash, 'F', hash_len);
1645 ske->status = SILC_SKE_STATUS_OK;
1647 /* In case we are doing rekey move to finish it. */
1650 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1651 return SILC_FSM_CONTINUE;
1654 /* Process key material */
1655 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1656 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1657 hash_len = silc_hash_len(ske->prop->hash);
1658 ske->keymat = silc_ske_process_key_material(ske, block_len,
1662 SILC_LOG_ERROR(("Error processing key material"));
1663 status = SILC_SKE_STATUS_ERROR;
1667 /* Send SUCCESS packet */
1668 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1669 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1670 /** Error sending packet */
1671 SILC_LOG_DEBUG(("Error sending packet"));
1672 ske->status = SILC_SKE_STATUS_ERROR;
1673 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1674 return SILC_FSM_CONTINUE;
1677 /** Waiting completion */
1678 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1679 return SILC_FSM_WAIT;
1682 memset(hash, 'F', sizeof(hash));
1683 silc_ske_payload_ke_free(payload);
1684 ske->ke2_payload = NULL;
1686 silc_mp_uninit(ske->KEY);
1687 silc_free(ske->KEY);
1691 memset(ske->hash, 'F', hash_len);
1692 silc_free(ske->hash);
1696 if (status == SILC_SKE_STATUS_OK)
1697 status = SILC_SKE_STATUS_ERROR;
1700 ske->status = status;
1701 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1702 return SILC_FSM_CONTINUE;
1705 /* Protocol completed */
1707 SILC_FSM_STATE(silc_ske_st_initiator_end)
1709 SilcSKE ske = fsm_context;
1711 SILC_LOG_DEBUG(("Start"));
1713 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1714 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1715 silc_ske_install_retransmission(ske);
1716 silc_packet_free(ske->packet);
1718 return SILC_FSM_WAIT;
1721 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1723 silc_packet_free(ske->packet);
1725 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1726 silc_schedule_task_del_by_context(ske->schedule, ske);
1728 /* Call completion */
1729 silc_ske_completion(ske);
1731 return SILC_FSM_FINISH;
1734 /* Aborted by application */
1736 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1738 SilcSKE ske = fsm_context;
1739 unsigned char data[4];
1741 SILC_LOG_DEBUG(("Aborted by caller"));
1743 /* Send FAILURE packet */
1744 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1745 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1747 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1748 silc_schedule_task_del_by_context(ske->schedule, ske);
1750 /* Call completion */
1751 silc_ske_completion(ske);
1753 return SILC_FSM_FINISH;
1756 /* Error occurred. Send error to remote host */
1758 SILC_FSM_STATE(silc_ske_st_initiator_error)
1760 SilcSKE ske = fsm_context;
1761 SilcSKEStatus status;
1762 unsigned char data[4];
1764 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1765 silc_ske_map_status(ske->status), ske->status));
1767 status = ske->status;
1768 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1769 status = SILC_SKE_STATUS_ERROR;
1771 /* Send FAILURE packet */
1772 SILC_PUT32_MSB((SilcUInt32)status, data);
1773 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1775 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1776 silc_schedule_task_del_by_context(ske->schedule, ske);
1778 /* Call completion */
1779 silc_ske_completion(ske);
1781 return SILC_FSM_FINISH;
1784 /* Failure received from remote */
1786 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1788 SilcSKE ske = fsm_context;
1789 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1791 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1792 silc_ske_map_status(ske->status), ske->status));
1794 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1795 SILC_GET32_MSB(error, ske->packet->buffer.data);
1796 ske->status = error;
1797 silc_packet_free(ske->packet);
1801 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1802 silc_schedule_task_del_by_context(ske->schedule, ske);
1804 /* Call completion */
1805 silc_ske_completion(ske);
1807 return SILC_FSM_FINISH;
1810 /* Starts the protocol as initiator */
1812 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1813 SilcPacketStream stream,
1814 SilcSKEParams params,
1815 SilcSKEStartPayload start_payload)
1817 SILC_LOG_DEBUG(("Start SKE as initiator"));
1819 if (!ske || !stream || !params || !params->version)
1822 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1825 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1828 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1829 ske->session_port = params->session_port;
1831 /* Generate security properties if not provided */
1832 if (!start_payload) {
1833 start_payload = silc_ske_assemble_security_properties(ske,
1840 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1841 ske->start_payload = start_payload;
1842 ske->version = params->version;
1843 ske->running = TRUE;
1845 /* Link to packet stream to get key exchange packets */
1846 ske->stream = stream;
1847 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1848 SILC_PACKET_KEY_EXCHANGE,
1849 SILC_PACKET_KEY_EXCHANGE_2,
1850 SILC_PACKET_SUCCESS,
1851 SILC_PACKET_FAILURE, -1);
1853 /* Start SKE as initiator */
1854 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1859 /******************************** Responder *********************************/
1861 /* Start protocol as responder. Wait initiator's start payload */
1863 SILC_FSM_STATE(silc_ske_st_responder_start)
1865 SilcSKE ske = fsm_context;
1867 SILC_LOG_DEBUG(("Start"));
1871 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1872 return SILC_FSM_CONTINUE;
1875 /* Add key exchange timeout */
1876 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1877 ske, ske->timeout, 0);
1879 /** Wait for initiator */
1880 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1881 return SILC_FSM_WAIT;
1884 /* Decode initiator's start payload. Select the security properties from
1885 the initiator's start payload and send our reply start payload back. */
1887 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1889 SilcSKE ske = fsm_context;
1890 SilcSKEStatus status;
1891 SilcSKEStartPayload remote_payload = NULL;
1892 SilcBuffer packet_buf = &ske->packet->buffer;
1894 SILC_LOG_DEBUG(("Start"));
1896 /* Decode the payload */
1897 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1898 if (status != SILC_SKE_STATUS_OK) {
1899 /** Error decoding Start Payload */
1900 silc_packet_free(ske->packet);
1902 ske->status = status;
1903 silc_fsm_next(fsm, silc_ske_st_responder_error);
1904 return SILC_FSM_CONTINUE;
1907 /* Take a copy of the payload buffer for future use. It is used to
1908 compute the HASH value. */
1909 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1911 silc_packet_free(ske->packet);
1914 /* Force the mutual authentication flag if we want to do it. */
1915 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1916 SILC_LOG_DEBUG(("Force mutual authentication"));
1917 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1920 /* Force PFS flag if we require it */
1921 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1922 SILC_LOG_DEBUG(("Force PFS"));
1923 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1926 /* Disable IV Included flag if requested */
1927 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1928 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1929 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1930 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1933 /* Check and select security properties */
1934 status = silc_ske_select_security_properties(ske, remote_payload,
1936 if (status != SILC_SKE_STATUS_OK) {
1937 /** Error selecting proposal */
1938 silc_ske_payload_start_free(remote_payload);
1939 ske->status = status;
1940 silc_fsm_next(fsm, silc_ske_st_responder_error);
1941 return SILC_FSM_CONTINUE;
1944 silc_ske_payload_start_free(remote_payload);
1946 /* Encode our reply payload to send the selected security properties */
1947 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1949 if (status != SILC_SKE_STATUS_OK)
1952 /* Send the packet. */
1953 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1954 silc_buffer_data(packet_buf),
1955 silc_buffer_len(packet_buf)))
1958 silc_buffer_free(packet_buf);
1960 /** Waiting initiator's KE payload */
1961 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1962 return SILC_FSM_WAIT;
1965 if (ske->prop->group)
1966 silc_ske_group_free(ske->prop->group);
1967 if (ske->prop->cipher)
1968 silc_cipher_free(ske->prop->cipher);
1969 if (ske->prop->hash)
1970 silc_hash_free(ske->prop->hash);
1971 if (ske->prop->hmac)
1972 silc_hmac_free(ske->prop->hmac);
1973 silc_free(ske->prop);
1976 if (status == SILC_SKE_STATUS_OK)
1977 status = SILC_SKE_STATUS_ERROR;
1980 ske->status = status;
1981 silc_fsm_next(fsm, silc_ske_st_responder_error);
1982 return SILC_FSM_CONTINUE;
1985 /* Phase-2. Decode initiator's KE payload */
1987 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1989 SilcSKE ske = fsm_context;
1990 SilcSKEStatus status;
1991 SilcSKEKEPayload recv_payload;
1992 SilcBuffer packet_buf = &ske->packet->buffer;
1994 SILC_LOG_DEBUG(("Start"));
1996 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1997 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1998 silc_ske_install_retransmission(ske);
1999 silc_packet_free(ske->packet);
2001 return SILC_FSM_WAIT;
2004 /* Decode Key Exchange Payload */
2005 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2006 if (status != SILC_SKE_STATUS_OK) {
2007 /** Error decoding KE payload */
2008 silc_packet_free(ske->packet);
2010 ske->status = status;
2011 silc_fsm_next(fsm, silc_ske_st_responder_error);
2012 return SILC_FSM_CONTINUE;
2015 ske->ke1_payload = recv_payload;
2017 silc_packet_free(ske->packet);
2020 /* Verify the received public key and verify the signature if we are
2021 doing mutual authentication. */
2022 if (ske->start_payload &&
2023 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2025 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2027 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2029 /** Public key not provided */
2030 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2031 "certificate), even though we require it"));
2032 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2033 silc_fsm_next(fsm, silc_ske_st_responder_error);
2034 return SILC_FSM_CONTINUE;
2037 /* Decode the remote's public key */
2038 if (recv_payload->pk_data &&
2039 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2040 recv_payload->pk_data,
2041 recv_payload->pk_len,
2042 &ske->prop->public_key)) {
2043 /** Error decoding public key */
2044 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2045 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2046 silc_fsm_next(fsm, silc_ske_st_responder_error);
2047 return SILC_FSM_CONTINUE;
2050 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2052 SILC_LOG_DEBUG(("Verifying public key"));
2054 /** Waiting public key verification */
2055 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2057 /* If repository is provided, verify the key from there. */
2058 if (ske->repository) {
2061 find = silc_skr_find_alloc();
2063 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2064 silc_fsm_next(fsm, silc_ske_st_responder_error);
2065 return SILC_FSM_CONTINUE;
2067 silc_skr_find_set_pkcs_type(find,
2068 silc_pkcs_get_type(ske->prop->public_key));
2069 silc_skr_find_set_public_key(find, ske->prop->public_key);
2070 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2072 /* Find key from repository */
2073 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2074 silc_ske_skr_callback, ske));
2076 /* Verify from application */
2077 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2078 ske->callbacks->context,
2079 silc_ske_pk_verified, NULL));
2085 /** Generate KE2 payload */
2086 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2087 return SILC_FSM_CONTINUE;
2090 /* Phase-4. Generate KE2 payload */
2092 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2094 SilcSKE ske = fsm_context;
2095 SilcSKEStatus status;
2096 SilcSKEKEPayload recv_payload, send_payload;
2101 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2102 return SILC_FSM_CONTINUE;
2105 /* Check result of public key verification */
2106 if (ske->status != SILC_SKE_STATUS_OK) {
2107 /** Public key not verified */
2108 SILC_LOG_DEBUG(("Public key verification failed"));
2109 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2110 return SILC_FSM_CONTINUE;
2113 recv_payload = ske->ke1_payload;
2115 /* The public key verification was performed only if the Mutual
2116 Authentication flag is set. */
2117 if (ske->start_payload &&
2118 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2119 unsigned char hash[SILC_HASH_MAXLEN];
2120 SilcUInt32 hash_len;
2122 SILC_LOG_DEBUG(("Public key is authentic"));
2124 /* Compute the hash value */
2125 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2126 if (status != SILC_SKE_STATUS_OK) {
2127 /** Error computing hash */
2128 ske->status = status;
2129 silc_fsm_next(fsm, silc_ske_st_responder_error);
2130 return SILC_FSM_CONTINUE;
2133 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2135 /* Verify signature */
2136 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2137 recv_payload->sign_len, hash, hash_len, NULL)) {
2138 /** Incorrect signature */
2139 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2140 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2141 silc_fsm_next(fsm, silc_ske_st_responder_error);
2142 return SILC_FSM_CONTINUE;
2145 SILC_LOG_DEBUG(("Signature is Ok"));
2147 memset(hash, 'F', hash_len);
2150 /* Create the random number x, 1 < x < q. */
2151 x = silc_calloc(1, sizeof(*x));
2154 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2155 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2157 if (status != SILC_SKE_STATUS_OK) {
2158 /** Error generating random number */
2161 ske->status = status;
2162 silc_fsm_next(fsm, silc_ske_st_responder_error);
2163 return SILC_FSM_CONTINUE;
2166 /* Save the results for later processing */
2167 send_payload = silc_calloc(1, sizeof(*send_payload));
2169 ske->ke2_payload = send_payload;
2171 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2173 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2174 silc_mp_init(&send_payload->x);
2175 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2176 &ske->prop->group->group);
2178 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2180 /* Compute the shared secret key */
2181 KEY = silc_calloc(1, sizeof(*KEY));
2183 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2184 &ske->prop->group->group);
2187 /** Send KE2 payload */
2188 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2189 return SILC_FSM_CONTINUE;
2192 /* Phase-5. Send KE2 payload */
2194 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2196 SilcSKE ske = fsm_context;
2197 SilcSKEStatus status;
2198 SilcBuffer payload_buf;
2199 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2200 SilcUInt32 hash_len, sign_len, pk_len;
2202 SILC_LOG_DEBUG(("Start"));
2204 if (ske->public_key && ske->private_key) {
2205 SILC_LOG_DEBUG(("Getting public key"));
2207 /* Get the public key */
2208 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2210 /** Error encoding public key */
2211 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2212 silc_fsm_next(fsm, silc_ske_st_responder_error);
2213 return SILC_FSM_CONTINUE;
2215 ske->ke2_payload->pk_data = pk;
2216 ske->ke2_payload->pk_len = pk_len;
2218 SILC_LOG_DEBUG(("Computing HASH value"));
2220 /* Compute the hash value */
2221 memset(hash, 0, sizeof(hash));
2222 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2223 if (status != SILC_SKE_STATUS_OK) {
2224 /** Error computing hash */
2225 ske->status = status;
2226 silc_fsm_next(fsm, silc_ske_st_responder_error);
2227 return SILC_FSM_CONTINUE;
2230 ske->hash = silc_memdup(hash, hash_len);
2231 ske->hash_len = hash_len;
2233 SILC_LOG_DEBUG(("Signing HASH value"));
2235 /* Sign the hash value */
2236 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2237 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2238 /** Error computing signature */
2239 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2240 silc_fsm_next(fsm, silc_ske_st_responder_error);
2241 return SILC_FSM_CONTINUE;
2243 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2244 ske->ke2_payload->sign_len = sign_len;
2245 memset(sign, 0, sizeof(sign));
2247 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2249 /* Encode the Key Exchange Payload */
2250 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2252 if (status != SILC_SKE_STATUS_OK) {
2253 /** Error encoding KE payload */
2254 ske->status = status;
2255 silc_fsm_next(fsm, silc_ske_st_responder_error);
2256 return SILC_FSM_CONTINUE;
2259 /* Send the packet. */
2260 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2261 payload_buf->data, silc_buffer_len(payload_buf))) {
2262 SILC_LOG_DEBUG(("Error sending packet"));
2263 ske->status = SILC_SKE_STATUS_ERROR;
2264 silc_fsm_next(fsm, silc_ske_st_responder_error);
2265 return SILC_FSM_CONTINUE;
2268 silc_buffer_free(payload_buf);
2270 /** Waiting completion */
2271 silc_fsm_next(fsm, silc_ske_st_responder_end);
2272 return SILC_FSM_WAIT;
2275 /* Protocol completed */
2277 SILC_FSM_STATE(silc_ske_st_responder_end)
2279 SilcSKE ske = fsm_context;
2280 unsigned char tmp[4];
2281 SilcUInt32 hash_len, key_len, block_len;
2283 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2284 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2285 silc_ske_install_retransmission(ske);
2286 silc_packet_free(ske->packet);
2288 return SILC_FSM_WAIT;
2290 silc_packet_free(ske->packet);
2293 /* Process key material */
2294 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2295 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2296 hash_len = silc_hash_len(ske->prop->hash);
2297 ske->keymat = silc_ske_process_key_material(ske, block_len,
2301 /** Error processing key material */
2302 ske->status = SILC_SKE_STATUS_ERROR;
2303 silc_fsm_next(fsm, silc_ske_st_responder_error);
2304 return SILC_FSM_CONTINUE;
2307 /* Send SUCCESS packet */
2308 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2309 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2311 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2312 silc_schedule_task_del_by_context(ske->schedule, ske);
2314 /* Call completion */
2315 silc_ske_completion(ske);
2317 return SILC_FSM_FINISH;
2320 /* Aborted by application */
2322 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2324 SilcSKE ske = fsm_context;
2325 unsigned char tmp[4];
2327 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2329 /* Send FAILURE packet */
2330 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2331 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2333 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2334 silc_schedule_task_del_by_context(ske->schedule, ske);
2336 /* Call completion */
2337 silc_ske_completion(ske);
2339 return SILC_FSM_FINISH;
2342 /* Failure received from remote */
2344 SILC_FSM_STATE(silc_ske_st_responder_failure)
2346 SilcSKE ske = fsm_context;
2347 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2349 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2351 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2352 SILC_GET32_MSB(error, ske->packet->buffer.data);
2353 ske->status = error;
2354 silc_packet_free(ske->packet);
2358 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2359 silc_schedule_task_del_by_context(ske->schedule, ske);
2361 /* Call completion */
2362 silc_ske_completion(ske);
2364 return SILC_FSM_FINISH;
2367 /* Error occurred */
2369 SILC_FSM_STATE(silc_ske_st_responder_error)
2371 SilcSKE ske = fsm_context;
2372 unsigned char tmp[4];
2374 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2375 ske->status, silc_ske_map_status(ske->status)));
2377 /* Send FAILURE packet */
2378 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2379 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2380 SILC_PUT32_MSB(ske->status, tmp);
2381 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2383 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2384 silc_schedule_task_del_by_context(ske->schedule, ske);
2386 /* Call completion */
2387 silc_ske_completion(ske);
2389 return SILC_FSM_FINISH;
2392 /* Starts the protocol as responder. */
2394 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2395 SilcPacketStream stream,
2396 SilcSKEParams params)
2398 SILC_LOG_DEBUG(("Start SKE as responder"));
2400 if (!ske || !stream || !params || !params->version)
2403 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2406 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2409 ske->responder = TRUE;
2410 ske->flags = params->flags;
2411 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2412 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2413 ske->session_port = params->session_port;
2414 ske->version = strdup(params->version);
2417 ske->running = TRUE;
2419 /* Link to packet stream to get key exchange packets */
2420 ske->stream = stream;
2421 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2422 SILC_PACKET_KEY_EXCHANGE,
2423 SILC_PACKET_KEY_EXCHANGE_1,
2424 SILC_PACKET_SUCCESS,
2425 SILC_PACKET_FAILURE, -1);
2427 /* Start SKE as responder */
2428 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2433 /***************************** Initiator Rekey ******************************/
2437 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2439 SilcSKE ske = fsm_context;
2442 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2446 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2447 return SILC_FSM_CONTINUE;
2450 /* Add rekey exchange timeout */
2451 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2454 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2457 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2458 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2459 return SILC_FSM_CONTINUE;
2462 /* Send REKEY packet to start rekey protocol */
2463 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2464 /** Error sending packet */
2465 SILC_LOG_DEBUG(("Error sending packet"));
2466 ske->status = SILC_SKE_STATUS_ERROR;
2467 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2468 return SILC_FSM_CONTINUE;
2471 /* If doing rekey without PFS, move directly to the end of the protocol. */
2472 if (!ske->rekey->pfs) {
2473 /** Rekey without PFS */
2474 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2475 return SILC_FSM_CONTINUE;
2478 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2480 if (status != SILC_SKE_STATUS_OK) {
2481 /** Unknown group */
2482 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2483 return SILC_FSM_CONTINUE;
2486 /** Rekey with PFS */
2487 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2488 return SILC_FSM_CONTINUE;
2491 /* Sends REKEY_DONE packet to finish the protocol. */
2493 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2495 SilcSKE ske = fsm_context;
2496 SilcCipher send_key;
2499 SilcUInt32 key_len, block_len, hash_len, x_len;
2500 unsigned char *pfsbuf;
2502 SILC_LOG_DEBUG(("Start"));
2504 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2505 key_len = silc_cipher_get_key_len(send_key);
2506 block_len = silc_cipher_get_block_len(send_key);
2508 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2509 /** Cannot allocate hash */
2510 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2511 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2512 return SILC_FSM_CONTINUE;
2514 hash_len = silc_hash_len(hash);
2516 /* Process key material */
2517 if (ske->rekey->pfs) {
2519 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2521 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2524 memset(pfsbuf, 0, x_len);
2530 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2531 ske->rekey->enc_key_len / 8,
2537 SILC_LOG_ERROR(("Error processing key material"));
2538 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2539 return SILC_FSM_CONTINUE;
2542 ske->prop->cipher = send_key;
2543 ske->prop->hmac = hmac_send;
2544 ske->prop->hash = hash;
2546 /* Get sending keys */
2547 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2548 &hmac_send, NULL, NULL)) {
2549 /** Cannot get keys */
2550 ske->status = SILC_SKE_STATUS_ERROR;
2551 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2552 return SILC_FSM_CONTINUE;
2555 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2556 packet sent after this call will be protected with the new keys. */
2557 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2559 /** Cannot set keys */
2560 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2561 ske->status = SILC_SKE_STATUS_ERROR;
2562 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2563 return SILC_FSM_CONTINUE;
2566 /** Wait for REKEY_DONE */
2567 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2568 return SILC_FSM_WAIT;
2571 /* Rekey protocol end */
2573 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2575 SilcSKE ske = fsm_context;
2576 SilcCipher receive_key;
2577 SilcHmac hmac_receive;
2578 SilcSKERekeyMaterial rekey;
2580 SILC_LOG_DEBUG(("Start"));
2582 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2583 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2584 silc_packet_free(ske->packet);
2586 return SILC_FSM_WAIT;
2589 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2590 ske->prop->cipher = receive_key;
2591 ske->prop->hmac = hmac_receive;
2593 /* Get receiving keys */
2594 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2595 NULL, &hmac_receive, NULL)) {
2596 /** Cannot get keys */
2597 ske->status = SILC_SKE_STATUS_ERROR;
2598 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2599 return SILC_FSM_CONTINUE;
2602 /* Set new receiving keys into use. All packets received after this will
2603 be decrypted with the new keys. */
2604 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2605 hmac_receive, FALSE)) {
2606 /** Cannot set keys */
2607 SILC_LOG_DEBUG(("Cannot set new keys"));
2608 ske->status = SILC_SKE_STATUS_ERROR;
2609 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2610 return SILC_FSM_CONTINUE;
2613 SILC_LOG_DEBUG(("Rekey completed successfully"));
2615 /* Generate new rekey material */
2616 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2619 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2620 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2621 return SILC_FSM_CONTINUE;
2623 rekey->pfs = ske->rekey->pfs;
2626 ske->prop->cipher = NULL;
2627 ske->prop->hmac = NULL;
2628 silc_packet_free(ske->packet);
2630 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2631 silc_schedule_task_del_by_context(ske->schedule, ske);
2633 /* Call completion */
2634 silc_ske_completion(ske);
2636 return SILC_FSM_FINISH;
2639 /* Starts rekey protocol as initiator */
2642 silc_ske_rekey_initiator(SilcSKE ske,
2643 SilcPacketStream stream,
2644 SilcSKERekeyMaterial rekey)
2646 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2648 if (!ske || !stream || !rekey)
2651 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2654 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2658 ske->responder = FALSE;
2659 ske->running = TRUE;
2660 ske->rekeying = TRUE;
2662 /* Link to packet stream to get key exchange packets */
2663 ske->stream = stream;
2664 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2666 SILC_PACKET_REKEY_DONE,
2667 SILC_PACKET_KEY_EXCHANGE_2,
2668 SILC_PACKET_SUCCESS,
2669 SILC_PACKET_FAILURE, -1);
2671 /* Start SKE rekey as initiator */
2672 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2677 /***************************** Responder Rekey ******************************/
2679 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2681 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2683 return SILC_FSM_FINISH;
2686 /* Starts rekey protocol as responder */
2689 silc_ske_rekey_responder(SilcSKE ske,
2690 SilcPacketStream stream,
2691 SilcSKERekeyMaterial rekey)
2693 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2695 if (!ske || !stream || !rekey)
2698 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2701 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2705 ske->responder = TRUE;
2706 ske->running = TRUE;
2707 ske->rekeying = TRUE;
2709 /* Link to packet stream to get key exchange packets */
2710 ske->stream = stream;
2711 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2713 SILC_PACKET_REKEY_DONE,
2714 SILC_PACKET_KEY_EXCHANGE_1,
2715 SILC_PACKET_SUCCESS,
2716 SILC_PACKET_FAILURE, -1);
2718 /* Start SKE rekey as responder */
2719 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2724 /* Processes the provided key material `data' as the SILC protocol
2725 specification defines. */
2728 silc_ske_process_key_material_data(unsigned char *data,
2729 SilcUInt32 data_len,
2730 SilcUInt32 req_iv_len,
2731 SilcUInt32 req_enc_key_len,
2732 SilcUInt32 req_hmac_key_len,
2736 unsigned char hashd[SILC_HASH_MAXLEN];
2737 SilcUInt32 hash_len = req_hmac_key_len;
2738 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2739 SilcSKEKeyMaterial key;
2741 SILC_LOG_DEBUG(("Start"));
2743 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2746 key = silc_calloc(1, sizeof(*key));
2750 buf = silc_buffer_alloc_size(1 + data_len);
2753 silc_buffer_format(buf,
2754 SILC_STR_UI_CHAR(0),
2755 SILC_STR_UI_XNSTRING(data, data_len),
2759 memset(hashd, 0, sizeof(hashd));
2761 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2762 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2763 memcpy(key->send_iv, hashd, req_iv_len);
2764 memset(hashd, 0, sizeof(hashd));
2766 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2767 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2768 memcpy(key->receive_iv, hashd, req_iv_len);
2769 key->iv_len = req_iv_len;
2771 /* Take the encryption keys. If requested key size is more than
2772 the size of hash length we will distribute more key material
2773 as protocol defines. */
2775 if (enc_key_len > hash_len) {
2777 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2778 k3[SILC_HASH_MAXLEN];
2779 unsigned char *dtmp;
2782 if (enc_key_len > (3 * hash_len))
2785 /* Take first round */
2786 memset(k1, 0, sizeof(k1));
2787 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2789 /* Take second round */
2790 dist = silc_buffer_alloc_size(data_len + hash_len);
2793 silc_buffer_format(dist,
2794 SILC_STR_UI_XNSTRING(data, data_len),
2795 SILC_STR_UI_XNSTRING(k1, hash_len),
2797 memset(k2, 0, sizeof(k2));
2798 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2800 /* Take third round */
2801 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2802 silc_buffer_pull_tail(dist, hash_len);
2803 silc_buffer_pull(dist, data_len + hash_len);
2804 silc_buffer_format(dist,
2805 SILC_STR_UI_XNSTRING(k2, hash_len),
2807 silc_buffer_push(dist, data_len + hash_len);
2808 memset(k3, 0, sizeof(k3));
2809 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2811 /* Then, save the keys */
2812 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2813 memcpy(dtmp, k1, hash_len);
2814 memcpy(dtmp + hash_len, k2, hash_len);
2815 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2817 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2818 memcpy(key->send_enc_key, dtmp, enc_key_len);
2819 key->enc_key_len = req_enc_key_len;
2821 memset(dtmp, 0, (3 * hash_len));
2822 memset(k1, 0, sizeof(k1));
2823 memset(k2, 0, sizeof(k2));
2824 memset(k3, 0, sizeof(k3));
2826 silc_buffer_clear(dist);
2827 silc_buffer_free(dist);
2829 /* Take normal hash as key */
2830 memset(hashd, 0, sizeof(hashd));
2831 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2832 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2833 memcpy(key->send_enc_key, hashd, enc_key_len);
2834 key->enc_key_len = req_enc_key_len;
2838 if (enc_key_len > hash_len) {
2840 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2841 k3[SILC_HASH_MAXLEN];
2842 unsigned char *dtmp;
2845 if (enc_key_len > (3 * hash_len))
2848 /* Take first round */
2849 memset(k1, 0, sizeof(k1));
2850 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2852 /* Take second round */
2853 dist = silc_buffer_alloc_size(data_len + hash_len);
2856 silc_buffer_format(dist,
2857 SILC_STR_UI_XNSTRING(data, data_len),
2858 SILC_STR_UI_XNSTRING(k1, hash_len),
2860 memset(k2, 0, sizeof(k2));
2861 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2863 /* Take third round */
2864 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2865 silc_buffer_pull_tail(dist, hash_len);
2866 silc_buffer_pull(dist, data_len + hash_len);
2867 silc_buffer_format(dist,
2868 SILC_STR_UI_XNSTRING(k2, hash_len),
2870 silc_buffer_push(dist, data_len + hash_len);
2871 memset(k3, 0, sizeof(k3));
2872 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2874 /* Then, save the keys */
2875 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2876 memcpy(dtmp, k1, hash_len);
2877 memcpy(dtmp + hash_len, k2, hash_len);
2878 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2880 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2881 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2882 key->enc_key_len = req_enc_key_len;
2884 memset(dtmp, 0, (3 * hash_len));
2885 memset(k1, 0, sizeof(k1));
2886 memset(k2, 0, sizeof(k2));
2887 memset(k3, 0, sizeof(k3));
2889 silc_buffer_clear(dist);
2890 silc_buffer_free(dist);
2892 /* Take normal hash as key */
2893 memset(hashd, 0, sizeof(hashd));
2894 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2895 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2896 memcpy(key->receive_enc_key, hashd, enc_key_len);
2897 key->enc_key_len = req_enc_key_len;
2900 /* Take HMAC keys */
2901 memset(hashd, 0, sizeof(hashd));
2903 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2904 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2905 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2906 memset(hashd, 0, sizeof(hashd));
2908 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2909 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2910 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2911 key->hmac_key_len = req_hmac_key_len;
2912 memset(hashd, 0, sizeof(hashd));
2914 silc_buffer_clear(buf);
2915 silc_buffer_free(buf);
2917 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
2922 /* Processes negotiated key material as protocol specifies. This returns
2923 the actual keys to be used in the SILC. */
2926 silc_ske_process_key_material(SilcSKE ske,
2927 SilcUInt32 req_iv_len,
2928 SilcUInt32 req_enc_key_len,
2929 SilcUInt32 req_hmac_key_len,
2930 SilcSKERekeyMaterial *rekey)
2933 unsigned char *tmpbuf;
2935 SilcSKEKeyMaterial key;
2937 /* Encode KEY to binary data */
2938 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2940 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2943 silc_buffer_format(buf,
2944 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2945 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2948 /* Process the key material */
2949 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2950 req_iv_len, req_enc_key_len,
2954 memset(tmpbuf, 0, klen);
2956 silc_buffer_clear(buf);
2957 silc_buffer_free(buf);
2960 *rekey = silc_ske_make_rekey_material(ske, key);
2968 /* Free key material structure */
2970 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2976 silc_free(key->send_iv);
2977 if (key->receive_iv)
2978 silc_free(key->receive_iv);
2979 if (key->send_enc_key) {
2980 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2981 silc_free(key->send_enc_key);
2983 if (key->receive_enc_key) {
2984 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2985 silc_free(key->receive_enc_key);
2987 if (key->send_hmac_key) {
2988 memset(key->send_hmac_key, 0, key->hmac_key_len);
2989 silc_free(key->send_hmac_key);
2991 if (key->receive_hmac_key) {
2992 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2993 silc_free(key->receive_hmac_key);
2998 /* Free rekey material */
3000 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3004 if (rekey->send_enc_key) {
3005 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3006 silc_free(rekey->send_enc_key);
3008 silc_free(rekey->hash);
3012 /* Set keys into use */
3014 SilcBool silc_ske_set_keys(SilcSKE ske,
3015 SilcSKEKeyMaterial keymat,
3016 SilcSKESecurityProperties prop,
3017 SilcCipher *ret_send_key,
3018 SilcCipher *ret_receive_key,
3019 SilcHmac *ret_hmac_send,
3020 SilcHmac *ret_hmac_receive,
3023 unsigned char iv[32];
3024 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3026 /* Allocate ciphers to be used in the communication */
3028 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3032 if (ret_receive_key) {
3033 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3038 /* Allocate HMACs */
3039 if (ret_hmac_send) {
3040 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3044 if (ret_hmac_receive) {
3045 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3050 /* Set key material */
3051 memset(iv, 0, sizeof(iv));
3052 if (ske->responder) {
3054 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3055 keymat->enc_key_len, TRUE);
3057 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3058 memcpy(iv, ske->hash, 4);
3059 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3060 silc_cipher_set_iv(*ret_send_key, iv);
3062 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3065 if (ret_receive_key) {
3066 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3067 keymat->enc_key_len, FALSE);
3069 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3070 memcpy(iv, ske->hash, 4);
3071 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3072 silc_cipher_set_iv(*ret_receive_key, iv);
3074 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3078 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3079 keymat->hmac_key_len);
3080 if (ret_hmac_receive)
3081 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3082 keymat->hmac_key_len);
3085 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3086 keymat->enc_key_len, TRUE);
3088 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3089 memcpy(iv, ske->hash, 4);
3090 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3091 silc_cipher_set_iv(*ret_send_key, iv);
3093 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3096 if (ret_receive_key) {
3097 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3098 keymat->enc_key_len, FALSE);
3100 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3101 memcpy(iv, ske->hash, 4);
3102 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3103 silc_cipher_set_iv(*ret_receive_key, iv);
3105 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3109 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3110 keymat->hmac_key_len);
3111 if (ret_hmac_receive)
3112 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3113 keymat->hmac_key_len);
3118 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3125 const char *silc_ske_status_string[] =
3129 "Unkown error occurred",
3130 "Bad payload in packet",
3131 "Unsupported group",
3132 "Unsupported cipher",
3134 "Unsupported hash function",
3136 "Unsupported public key (or certificate)",
3137 "Incorrect signature",
3138 "Bad or unsupported version",
3142 "Remote did not provide public key",
3143 "Bad reserved field in packet",
3144 "Bad payload length in packet",
3145 "Error computing signature",
3146 "System out of memory",
3147 "Key exchange timeout",
3152 /* Maps status to readable string and returns the string. If string is not
3153 found and empty character string ("") is returned. */
3155 const char *silc_ske_map_status(SilcSKEStatus status)
3159 for (i = 0; silc_ske_status_string[i]; i++)
3161 return silc_ske_status_string[i];
3166 /* Parses remote host's version string. */
3168 SilcBool silc_ske_parse_version(SilcSKE ske,
3169 SilcUInt32 *protocol_version,
3170 char **protocol_version_string,
3171 SilcUInt32 *software_version,
3172 char **software_version_string,
3173 char **vendor_version)
3175 return silc_parse_version_string(ske->remote_version,
3177 protocol_version_string,
3179 software_version_string,
3183 /* Get security properties */
3185 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3190 /* Get key material */
3192 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)