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;
1042 /* Free's SKE object. */
1044 void silc_ske_free(SilcSKE ske)
1046 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1055 /* If already aborted, destroy the session immediately */
1057 ske->status = SILC_SKE_STATUS_ERROR;
1059 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1061 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1062 silc_fsm_continue_sync(&ske->fsm);
1067 /* Free start payload */
1068 if (ske->start_payload)
1069 silc_ske_payload_start_free(ske->start_payload);
1071 /* Free KE payload */
1072 if (ske->ke1_payload)
1073 silc_ske_payload_ke_free(ske->ke1_payload);
1074 if (ske->ke2_payload)
1075 silc_ske_payload_ke_free(ske->ke2_payload);
1076 silc_free(ske->remote_version);
1080 if (ske->prop->group)
1081 silc_ske_group_free(ske->prop->group);
1082 if (ske->prop->cipher)
1083 silc_cipher_free(ske->prop->cipher);
1084 if (ske->prop->hash)
1085 silc_hash_free(ske->prop->hash);
1086 if (ske->prop->hmac)
1087 silc_hmac_free(ske->prop->hmac);
1088 silc_free(ske->prop);
1091 silc_ske_free_key_material(ske->keymat);
1092 if (ske->start_payload_copy)
1093 silc_buffer_free(ske->start_payload_copy);
1095 silc_mp_uninit(ske->x);
1099 silc_mp_uninit(ske->KEY);
1100 silc_free(ske->KEY);
1102 silc_free(ske->retrans.data);
1103 silc_free(ske->hash);
1104 silc_free(ske->callbacks);
1106 memset(ske, 'F', sizeof(*ske));
1110 /* Return user context */
1112 void *silc_ske_get_context(SilcSKE ske)
1114 return ske->user_data;
1117 /* Sets protocol callbacks */
1119 void silc_ske_set_callbacks(SilcSKE ske,
1120 SilcSKEVerifyCb verify_key,
1121 SilcSKECompletionCb completed,
1125 silc_free(ske->callbacks);
1126 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1127 if (!ske->callbacks)
1129 ske->callbacks->verify_key = verify_key;
1130 ske->callbacks->completed = completed;
1131 ske->callbacks->context = context;
1135 /******************************** Initiator *********************************/
1137 /* Start protocol. Send our proposal */
1139 SILC_FSM_STATE(silc_ske_st_initiator_start)
1141 SilcSKE ske = fsm_context;
1142 SilcBuffer payload_buf;
1145 SILC_LOG_DEBUG(("Start"));
1149 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1150 return SILC_FSM_CONTINUE;
1153 /* Encode the payload */
1154 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1156 if (status != SILC_SKE_STATUS_OK) {
1157 /** Error encoding Start Payload */
1158 ske->status = status;
1159 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1160 return SILC_FSM_CONTINUE;
1163 /* Save the the payload buffer for future use. It is later used to
1164 compute the HASH value. */
1165 ske->start_payload_copy = payload_buf;
1167 /* Send the packet. */
1168 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1169 silc_buffer_data(payload_buf),
1170 silc_buffer_len(payload_buf))) {
1171 /** Error sending packet */
1172 SILC_LOG_DEBUG(("Error sending packet"));
1173 ske->status = SILC_SKE_STATUS_ERROR;
1174 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1175 return SILC_FSM_CONTINUE;
1178 /* Add key exchange timeout */
1179 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1180 ske, ske->timeout, 0);
1182 /** Wait for responder proposal */
1183 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1184 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1185 return SILC_FSM_WAIT;
1188 /* Phase-1. Receives responder's proposal */
1190 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1192 SilcSKE ske = fsm_context;
1193 SilcSKEStatus status;
1194 SilcSKEStartPayload payload;
1195 SilcSKESecurityProperties prop;
1196 SilcSKEDiffieHellmanGroup group = NULL;
1197 SilcBuffer packet_buf = &ske->packet->buffer;
1198 SilcUInt16 remote_port = 0;
1202 SILC_LOG_DEBUG(("Start"));
1204 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1205 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1206 silc_ske_install_retransmission(ske);
1207 silc_packet_free(ske->packet);
1209 return SILC_FSM_WAIT;
1212 /* Decode the payload */
1213 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1214 if (status != SILC_SKE_STATUS_OK) {
1215 /** Error decoding Start Payload */
1216 silc_packet_free(ske->packet);
1218 ske->status = status;
1219 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1220 return SILC_FSM_CONTINUE;
1223 /* Get remote ID and set it to stream */
1224 if (ske->packet->src_id_len) {
1225 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1226 ske->packet->src_id_type,
1227 (ske->packet->src_id_type == SILC_ID_SERVER ?
1228 (void *)&id.u.server_id : (void *)&id.u.client_id),
1229 (ske->packet->src_id_type == SILC_ID_SERVER ?
1230 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1231 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1232 (ske->packet->src_id_type == SILC_ID_SERVER ?
1233 (void *)&id.u.server_id : (void *)&id.u.client_id));
1236 silc_packet_free(ske->packet);
1239 /* Check that the cookie is returned unmodified. In case IV included
1240 flag and session port has been set, the first two bytes of cookie
1241 are the session port and we ignore them in this check. */
1242 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1243 /* Take remote port */
1244 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1247 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1248 SILC_SKE_COOKIE_LEN - coff)) {
1249 /** Invalid cookie */
1250 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1251 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1252 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1253 return SILC_FSM_CONTINUE;
1256 /* Check version string */
1257 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1258 status = silc_ske_check_version(ske);
1259 if (status != SILC_SKE_STATUS_OK) {
1260 /** Version mismatch */
1261 ske->status = status;
1262 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1263 return SILC_FSM_CONTINUE;
1266 /* Free our KE Start Payload context, we don't need it anymore. */
1267 silc_ske_payload_start_free(ske->start_payload);
1268 ske->start_payload = NULL;
1270 /* Take the selected security properties into use while doing
1271 the key exchange. This is used only while doing the key
1273 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1276 prop->flags = payload->flags;
1277 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1278 if (status != SILC_SKE_STATUS_OK)
1281 prop->group = group;
1282 prop->remote_port = remote_port;
1284 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1285 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1288 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1289 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1292 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1293 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1296 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1297 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1301 /* Save remote's KE Start Payload */
1302 ske->start_payload = payload;
1304 /** Send KE Payload */
1305 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1306 return SILC_FSM_CONTINUE;
1310 silc_ske_payload_start_free(payload);
1312 silc_ske_group_free(group);
1314 silc_cipher_free(prop->cipher);
1316 silc_hash_free(prop->hash);
1318 silc_hmac_free(prop->hmac);
1322 if (status == SILC_SKE_STATUS_OK)
1323 status = SILC_SKE_STATUS_ERROR;
1326 ske->status = status;
1327 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1328 return SILC_FSM_CONTINUE;
1331 /* Phase-2. Send KE payload */
1333 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1335 SilcSKE ske = fsm_context;
1336 SilcSKEStatus status;
1337 SilcBuffer payload_buf;
1339 SilcSKEKEPayload payload;
1342 SILC_LOG_DEBUG(("Start"));
1344 /* Create the random number x, 1 < x < q. */
1345 x = silc_calloc(1, sizeof(*x));
1347 /** Out of memory */
1348 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1349 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1350 return SILC_FSM_CONTINUE;
1354 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1355 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1357 if (status != SILC_SKE_STATUS_OK) {
1358 /** Error generating random number */
1361 ske->status = status;
1362 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1363 return SILC_FSM_CONTINUE;
1366 /* Encode the result to Key Exchange Payload. */
1368 payload = silc_calloc(1, sizeof(*payload));
1370 /** Out of memory */
1373 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1374 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1375 return SILC_FSM_CONTINUE;
1377 ske->ke1_payload = payload;
1379 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1381 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1382 silc_mp_init(&payload->x);
1383 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1384 &ske->prop->group->group);
1386 /* Get public key */
1387 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1388 if (!payload->pk_data) {
1389 /** Error encoding public key */
1392 silc_mp_uninit(&payload->x);
1394 ske->ke1_payload = NULL;
1395 ske->status = SILC_SKE_STATUS_ERROR;
1396 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1397 return SILC_FSM_CONTINUE;
1399 payload->pk_len = pk_len;
1400 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1402 /* Compute signature data if we are doing mutual authentication */
1403 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1404 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1405 SilcUInt32 hash_len, sign_len;
1407 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1408 SILC_LOG_DEBUG(("Computing HASH_i value"));
1410 /* Compute the hash value */
1411 memset(hash, 0, sizeof(hash));
1412 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1414 SILC_LOG_DEBUG(("Signing HASH_i value"));
1416 /* Sign the hash value */
1417 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1418 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1419 /** Error computing signature */
1422 silc_mp_uninit(&payload->x);
1423 silc_free(payload->pk_data);
1425 ske->ke1_payload = NULL;
1426 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1427 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1428 return SILC_FSM_CONTINUE;
1430 payload->sign_data = silc_memdup(sign, sign_len);
1431 if (payload->sign_data)
1432 payload->sign_len = sign_len;
1433 memset(sign, 0, sizeof(sign));
1436 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1437 if (status != SILC_SKE_STATUS_OK) {
1438 /** Error encoding KE payload */
1441 silc_mp_uninit(&payload->x);
1442 silc_free(payload->pk_data);
1443 silc_free(payload->sign_data);
1445 ske->ke1_payload = NULL;
1446 ske->status = status;
1447 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1448 return SILC_FSM_CONTINUE;
1453 /* Check for backwards compatibility */
1455 /* Send the packet. */
1456 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1457 silc_buffer_data(payload_buf),
1458 silc_buffer_len(payload_buf))) {
1459 /** Error sending packet */
1460 SILC_LOG_DEBUG(("Error sending packet"));
1461 ske->status = SILC_SKE_STATUS_ERROR;
1462 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1463 return SILC_FSM_CONTINUE;
1466 silc_buffer_free(payload_buf);
1468 /** Waiting responder's KE payload */
1469 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1470 return SILC_FSM_WAIT;
1473 /* Phase-3. Process responder's KE payload */
1475 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1477 SilcSKE ske = fsm_context;
1478 SilcSKEStatus status;
1479 SilcSKEKEPayload payload;
1481 SilcBuffer packet_buf = &ske->packet->buffer;
1483 SILC_LOG_DEBUG(("Start"));
1485 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1486 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1487 silc_ske_install_retransmission(ske);
1488 silc_packet_free(ske->packet);
1490 return SILC_FSM_WAIT;
1493 /* Decode the payload */
1494 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1495 if (status != SILC_SKE_STATUS_OK) {
1496 /** Error decoding KE payload */
1497 silc_packet_free(ske->packet);
1499 ske->status = status;
1500 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1501 return SILC_FSM_CONTINUE;
1503 silc_packet_free(ske->packet);
1505 ske->ke2_payload = payload;
1507 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1508 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1509 "even though we require it"));
1510 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1514 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1516 /* Compute the shared secret key */
1517 KEY = silc_calloc(1, sizeof(*KEY));
1519 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1522 /* Decode the remote's public key */
1523 if (payload->pk_data &&
1524 !silc_pkcs_public_key_alloc(payload->pk_type,
1525 payload->pk_data, payload->pk_len,
1526 &ske->prop->public_key)) {
1527 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1528 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1532 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1534 SILC_LOG_DEBUG(("Verifying public key"));
1536 /** Waiting public key verification */
1537 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1539 /* If repository is provided, verify the key from there. */
1540 if (ske->repository) {
1543 find = silc_skr_find_alloc();
1545 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1548 silc_skr_find_set_pkcs_type(find,
1549 silc_pkcs_get_type(ske->prop->public_key));
1550 silc_skr_find_set_public_key(find, ske->prop->public_key);
1551 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1553 /* Find key from repository */
1554 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1555 silc_ske_skr_callback, ske));
1557 /* Verify from application */
1558 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1559 ske->callbacks->context,
1560 silc_ske_pk_verified, NULL));
1565 /** Process key material */
1566 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1567 return SILC_FSM_CONTINUE;
1570 silc_ske_payload_ke_free(payload);
1571 ske->ke2_payload = NULL;
1573 silc_mp_uninit(ske->KEY);
1574 silc_free(ske->KEY);
1577 if (status == SILC_SKE_STATUS_OK)
1578 return SILC_SKE_STATUS_ERROR;
1581 ske->status = status;
1582 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1583 return SILC_FSM_CONTINUE;
1586 /* Process key material */
1588 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1590 SilcSKE ske = fsm_context;
1591 SilcSKEStatus status;
1592 SilcSKEKEPayload payload;
1593 unsigned char hash[SILC_HASH_MAXLEN];
1594 SilcUInt32 hash_len;
1595 int key_len, block_len;
1599 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1600 return SILC_FSM_CONTINUE;
1603 /* Check result of public key verification */
1604 if (ske->status != SILC_SKE_STATUS_OK) {
1605 /** Public key not verified */
1606 SILC_LOG_DEBUG(("Public key verification failed"));
1607 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1608 return SILC_FSM_CONTINUE;
1611 payload = ske->ke2_payload;
1613 if (ske->prop->public_key) {
1614 SILC_LOG_DEBUG(("Public key is authentic"));
1616 /* Compute the hash value */
1617 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1618 if (status != SILC_SKE_STATUS_OK)
1621 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1623 /* Verify signature */
1624 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1625 payload->sign_len, hash, hash_len, NULL)) {
1626 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1627 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1631 SILC_LOG_DEBUG(("Signature is Ok"));
1633 ske->hash = silc_memdup(hash, hash_len);
1634 ske->hash_len = hash_len;
1635 memset(hash, 'F', hash_len);
1638 ske->status = SILC_SKE_STATUS_OK;
1640 /* In case we are doing rekey move to finish it. */
1643 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1644 return SILC_FSM_CONTINUE;
1647 /* Process key material */
1648 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1649 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1650 hash_len = silc_hash_len(ske->prop->hash);
1651 ske->keymat = silc_ske_process_key_material(ske, block_len,
1655 SILC_LOG_ERROR(("Error processing key material"));
1656 status = SILC_SKE_STATUS_ERROR;
1660 /* Send SUCCESS packet */
1661 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1662 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1663 /** Error sending packet */
1664 SILC_LOG_DEBUG(("Error sending packet"));
1665 ske->status = SILC_SKE_STATUS_ERROR;
1666 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1667 return SILC_FSM_CONTINUE;
1670 /** Waiting completion */
1671 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1672 return SILC_FSM_WAIT;
1675 memset(hash, 'F', sizeof(hash));
1676 silc_ske_payload_ke_free(payload);
1677 ske->ke2_payload = NULL;
1679 silc_mp_uninit(ske->KEY);
1680 silc_free(ske->KEY);
1684 memset(ske->hash, 'F', hash_len);
1685 silc_free(ske->hash);
1689 if (status == SILC_SKE_STATUS_OK)
1690 status = SILC_SKE_STATUS_ERROR;
1693 ske->status = status;
1694 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1695 return SILC_FSM_CONTINUE;
1698 /* Protocol completed */
1700 SILC_FSM_STATE(silc_ske_st_initiator_end)
1702 SilcSKE ske = fsm_context;
1704 SILC_LOG_DEBUG(("Start"));
1706 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1707 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1708 silc_ske_install_retransmission(ske);
1709 silc_packet_free(ske->packet);
1711 return SILC_FSM_WAIT;
1714 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1716 silc_packet_free(ske->packet);
1718 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1719 silc_schedule_task_del_by_context(ske->schedule, ske);
1721 /* Call completion */
1722 silc_ske_completion(ske);
1724 return SILC_FSM_FINISH;
1727 /* Aborted by application */
1729 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1731 SilcSKE ske = fsm_context;
1732 unsigned char data[4];
1734 SILC_LOG_DEBUG(("Aborted by caller"));
1736 /* Send FAILURE packet */
1737 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1738 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1740 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1741 silc_schedule_task_del_by_context(ske->schedule, ske);
1743 /* Call completion */
1744 silc_ske_completion(ske);
1746 return SILC_FSM_FINISH;
1749 /* Error occurred. Send error to remote host */
1751 SILC_FSM_STATE(silc_ske_st_initiator_error)
1753 SilcSKE ske = fsm_context;
1754 SilcSKEStatus status;
1755 unsigned char data[4];
1757 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1758 silc_ske_map_status(ske->status), ske->status));
1760 status = ske->status;
1761 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1762 status = SILC_SKE_STATUS_ERROR;
1764 /* Send FAILURE packet */
1765 SILC_PUT32_MSB((SilcUInt32)status, data);
1766 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1768 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1769 silc_schedule_task_del_by_context(ske->schedule, ske);
1771 /* Call completion */
1772 silc_ske_completion(ske);
1774 return SILC_FSM_FINISH;
1777 /* Failure received from remote */
1779 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1781 SilcSKE ske = fsm_context;
1782 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1784 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1785 silc_ske_map_status(ske->status), ske->status));
1787 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1788 SILC_GET32_MSB(error, ske->packet->buffer.data);
1789 ske->status = error;
1790 silc_packet_free(ske->packet);
1794 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1795 silc_schedule_task_del_by_context(ske->schedule, ske);
1797 /* Call completion */
1798 silc_ske_completion(ske);
1800 return SILC_FSM_FINISH;
1803 /* Starts the protocol as initiator */
1805 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1806 SilcPacketStream stream,
1807 SilcSKEParams params,
1808 SilcSKEStartPayload start_payload)
1810 SILC_LOG_DEBUG(("Start SKE as initiator"));
1812 if (!ske || !stream || !params || !params->version)
1815 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1818 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1821 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1822 ske->session_port = params->session_port;
1824 /* Generate security properties if not provided */
1825 if (!start_payload) {
1826 start_payload = silc_ske_assemble_security_properties(ske,
1833 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1834 ske->start_payload = start_payload;
1835 ske->version = params->version;
1836 ske->running = TRUE;
1838 /* Link to packet stream to get key exchange packets */
1839 ske->stream = stream;
1840 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1841 SILC_PACKET_KEY_EXCHANGE,
1842 SILC_PACKET_KEY_EXCHANGE_2,
1843 SILC_PACKET_SUCCESS,
1844 SILC_PACKET_FAILURE, -1);
1846 /* Start SKE as initiator */
1847 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1852 /******************************** Responder *********************************/
1854 /* Start protocol as responder. Wait initiator's start payload */
1856 SILC_FSM_STATE(silc_ske_st_responder_start)
1858 SilcSKE ske = fsm_context;
1860 SILC_LOG_DEBUG(("Start"));
1864 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1865 return SILC_FSM_CONTINUE;
1868 /* Add key exchange timeout */
1869 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1870 ske, ske->timeout, 0);
1872 /** Wait for initiator */
1873 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1874 return SILC_FSM_WAIT;
1877 /* Decode initiator's start payload. Select the security properties from
1878 the initiator's start payload and send our reply start payload back. */
1880 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1882 SilcSKE ske = fsm_context;
1883 SilcSKEStatus status;
1884 SilcSKEStartPayload remote_payload = NULL;
1885 SilcBuffer packet_buf = &ske->packet->buffer;
1887 SILC_LOG_DEBUG(("Start"));
1889 /* Decode the payload */
1890 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1891 if (status != SILC_SKE_STATUS_OK) {
1892 /** Error decoding Start Payload */
1893 silc_packet_free(ske->packet);
1895 ske->status = status;
1896 silc_fsm_next(fsm, silc_ske_st_responder_error);
1897 return SILC_FSM_CONTINUE;
1900 /* Take a copy of the payload buffer for future use. It is used to
1901 compute the HASH value. */
1902 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1904 silc_packet_free(ske->packet);
1907 /* Force the mutual authentication flag if we want to do it. */
1908 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1909 SILC_LOG_DEBUG(("Force mutual authentication"));
1910 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1913 /* Force PFS flag if we require it */
1914 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1915 SILC_LOG_DEBUG(("Force PFS"));
1916 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1919 /* Disable IV Included flag if requested */
1920 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1921 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1922 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1923 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1926 /* Check and select security properties */
1927 status = silc_ske_select_security_properties(ske, remote_payload,
1929 if (status != SILC_SKE_STATUS_OK) {
1930 /** Error selecting proposal */
1931 silc_ske_payload_start_free(remote_payload);
1932 ske->status = status;
1933 silc_fsm_next(fsm, silc_ske_st_responder_error);
1934 return SILC_FSM_CONTINUE;
1937 silc_ske_payload_start_free(remote_payload);
1939 /* Encode our reply payload to send the selected security properties */
1940 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1942 if (status != SILC_SKE_STATUS_OK)
1945 /* Send the packet. */
1946 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1947 silc_buffer_data(packet_buf),
1948 silc_buffer_len(packet_buf)))
1951 silc_buffer_free(packet_buf);
1953 /** Waiting initiator's KE payload */
1954 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1955 return SILC_FSM_WAIT;
1958 if (ske->prop->group)
1959 silc_ske_group_free(ske->prop->group);
1960 if (ske->prop->cipher)
1961 silc_cipher_free(ske->prop->cipher);
1962 if (ske->prop->hash)
1963 silc_hash_free(ske->prop->hash);
1964 if (ske->prop->hmac)
1965 silc_hmac_free(ske->prop->hmac);
1966 silc_free(ske->prop);
1969 if (status == SILC_SKE_STATUS_OK)
1970 status = SILC_SKE_STATUS_ERROR;
1973 ske->status = status;
1974 silc_fsm_next(fsm, silc_ske_st_responder_error);
1975 return SILC_FSM_CONTINUE;
1978 /* Phase-2. Decode initiator's KE payload */
1980 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1982 SilcSKE ske = fsm_context;
1983 SilcSKEStatus status;
1984 SilcSKEKEPayload recv_payload;
1985 SilcBuffer packet_buf = &ske->packet->buffer;
1987 SILC_LOG_DEBUG(("Start"));
1989 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1990 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1991 silc_ske_install_retransmission(ske);
1992 silc_packet_free(ske->packet);
1994 return SILC_FSM_WAIT;
1997 /* Decode Key Exchange Payload */
1998 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1999 if (status != SILC_SKE_STATUS_OK) {
2000 /** Error decoding KE payload */
2001 silc_packet_free(ske->packet);
2003 ske->status = status;
2004 silc_fsm_next(fsm, silc_ske_st_responder_error);
2005 return SILC_FSM_CONTINUE;
2008 ske->ke1_payload = recv_payload;
2010 silc_packet_free(ske->packet);
2013 /* Verify the received public key and verify the signature if we are
2014 doing mutual authentication. */
2015 if (ske->start_payload &&
2016 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2018 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2020 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2022 /** Public key not provided */
2023 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2024 "certificate), even though we require it"));
2025 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2026 silc_fsm_next(fsm, silc_ske_st_responder_error);
2027 return SILC_FSM_CONTINUE;
2030 /* Decode the remote's public key */
2031 if (recv_payload->pk_data &&
2032 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2033 recv_payload->pk_data,
2034 recv_payload->pk_len,
2035 &ske->prop->public_key)) {
2036 /** Error decoding public key */
2037 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2038 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2039 silc_fsm_next(fsm, silc_ske_st_responder_error);
2040 return SILC_FSM_CONTINUE;
2043 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2045 SILC_LOG_DEBUG(("Verifying public key"));
2047 /** Waiting public key verification */
2048 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2050 /* If repository is provided, verify the key from there. */
2051 if (ske->repository) {
2054 find = silc_skr_find_alloc();
2056 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2057 silc_fsm_next(fsm, silc_ske_st_responder_error);
2058 return SILC_FSM_CONTINUE;
2060 silc_skr_find_set_pkcs_type(find,
2061 silc_pkcs_get_type(ske->prop->public_key));
2062 silc_skr_find_set_public_key(find, ske->prop->public_key);
2063 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2065 /* Find key from repository */
2066 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2067 silc_ske_skr_callback, ske));
2069 /* Verify from application */
2070 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2071 ske->callbacks->context,
2072 silc_ske_pk_verified, NULL));
2078 /** Generate KE2 payload */
2079 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2080 return SILC_FSM_CONTINUE;
2083 /* Phase-4. Generate KE2 payload */
2085 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2087 SilcSKE ske = fsm_context;
2088 SilcSKEStatus status;
2089 SilcSKEKEPayload recv_payload, send_payload;
2094 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2095 return SILC_FSM_CONTINUE;
2098 /* Check result of public key verification */
2099 if (ske->status != SILC_SKE_STATUS_OK) {
2100 /** Public key not verified */
2101 SILC_LOG_DEBUG(("Public key verification failed"));
2102 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2103 return SILC_FSM_CONTINUE;
2106 recv_payload = ske->ke1_payload;
2108 /* The public key verification was performed only if the Mutual
2109 Authentication flag is set. */
2110 if (ske->start_payload &&
2111 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2112 unsigned char hash[SILC_HASH_MAXLEN];
2113 SilcUInt32 hash_len;
2115 SILC_LOG_DEBUG(("Public key is authentic"));
2117 /* Compute the hash value */
2118 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2119 if (status != SILC_SKE_STATUS_OK) {
2120 /** Error computing hash */
2121 ske->status = status;
2122 silc_fsm_next(fsm, silc_ske_st_responder_error);
2123 return SILC_FSM_CONTINUE;
2126 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2128 /* Verify signature */
2129 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2130 recv_payload->sign_len, hash, hash_len, NULL)) {
2131 /** Incorrect signature */
2132 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2133 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2134 silc_fsm_next(fsm, silc_ske_st_responder_error);
2135 return SILC_FSM_CONTINUE;
2138 SILC_LOG_DEBUG(("Signature is Ok"));
2140 memset(hash, 'F', hash_len);
2143 /* Create the random number x, 1 < x < q. */
2144 x = silc_calloc(1, sizeof(*x));
2147 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2148 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2150 if (status != SILC_SKE_STATUS_OK) {
2151 /** Error generating random number */
2154 ske->status = status;
2155 silc_fsm_next(fsm, silc_ske_st_responder_error);
2156 return SILC_FSM_CONTINUE;
2159 /* Save the results for later processing */
2160 send_payload = silc_calloc(1, sizeof(*send_payload));
2162 ske->ke2_payload = send_payload;
2164 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2166 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2167 silc_mp_init(&send_payload->x);
2168 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2169 &ske->prop->group->group);
2171 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2173 /* Compute the shared secret key */
2174 KEY = silc_calloc(1, sizeof(*KEY));
2176 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2177 &ske->prop->group->group);
2180 /** Send KE2 payload */
2181 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2182 return SILC_FSM_CONTINUE;
2185 /* Phase-5. Send KE2 payload */
2187 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2189 SilcSKE ske = fsm_context;
2190 SilcSKEStatus status;
2191 SilcBuffer payload_buf;
2192 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2193 SilcUInt32 hash_len, sign_len, pk_len;
2195 SILC_LOG_DEBUG(("Start"));
2197 if (ske->public_key && ske->private_key) {
2198 SILC_LOG_DEBUG(("Getting public key"));
2200 /* Get the public key */
2201 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2203 /** Error encoding public key */
2204 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2205 silc_fsm_next(fsm, silc_ske_st_responder_error);
2206 return SILC_FSM_CONTINUE;
2208 ske->ke2_payload->pk_data = pk;
2209 ske->ke2_payload->pk_len = pk_len;
2211 SILC_LOG_DEBUG(("Computing HASH value"));
2213 /* Compute the hash value */
2214 memset(hash, 0, sizeof(hash));
2215 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2216 if (status != SILC_SKE_STATUS_OK) {
2217 /** Error computing hash */
2218 ske->status = status;
2219 silc_fsm_next(fsm, silc_ske_st_responder_error);
2220 return SILC_FSM_CONTINUE;
2223 ske->hash = silc_memdup(hash, hash_len);
2224 ske->hash_len = hash_len;
2226 SILC_LOG_DEBUG(("Signing HASH value"));
2228 /* Sign the hash value */
2229 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2230 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2231 /** Error computing signature */
2232 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2233 silc_fsm_next(fsm, silc_ske_st_responder_error);
2234 return SILC_FSM_CONTINUE;
2236 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2237 ske->ke2_payload->sign_len = sign_len;
2238 memset(sign, 0, sizeof(sign));
2240 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2242 /* Encode the Key Exchange Payload */
2243 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2245 if (status != SILC_SKE_STATUS_OK) {
2246 /** Error encoding KE payload */
2247 ske->status = status;
2248 silc_fsm_next(fsm, silc_ske_st_responder_error);
2249 return SILC_FSM_CONTINUE;
2252 /* Send the packet. */
2253 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2254 payload_buf->data, silc_buffer_len(payload_buf))) {
2255 SILC_LOG_DEBUG(("Error sending packet"));
2256 ske->status = SILC_SKE_STATUS_ERROR;
2257 silc_fsm_next(fsm, silc_ske_st_responder_error);
2258 return SILC_FSM_CONTINUE;
2261 silc_buffer_free(payload_buf);
2263 /** Waiting completion */
2264 silc_fsm_next(fsm, silc_ske_st_responder_end);
2265 return SILC_FSM_WAIT;
2268 /* Protocol completed */
2270 SILC_FSM_STATE(silc_ske_st_responder_end)
2272 SilcSKE ske = fsm_context;
2273 unsigned char tmp[4];
2274 SilcUInt32 hash_len, key_len, block_len;
2276 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2277 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2278 silc_ske_install_retransmission(ske);
2279 silc_packet_free(ske->packet);
2281 return SILC_FSM_WAIT;
2283 silc_packet_free(ske->packet);
2286 /* Process key material */
2287 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2288 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2289 hash_len = silc_hash_len(ske->prop->hash);
2290 ske->keymat = silc_ske_process_key_material(ske, block_len,
2294 /** Error processing key material */
2295 ske->status = SILC_SKE_STATUS_ERROR;
2296 silc_fsm_next(fsm, silc_ske_st_responder_error);
2297 return SILC_FSM_CONTINUE;
2300 /* Send SUCCESS packet */
2301 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2302 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2304 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2305 silc_schedule_task_del_by_context(ske->schedule, ske);
2307 /* Call completion */
2308 silc_ske_completion(ske);
2310 return SILC_FSM_FINISH;
2313 /* Aborted by application */
2315 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2317 SilcSKE ske = fsm_context;
2318 unsigned char tmp[4];
2320 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2322 /* Send FAILURE packet */
2323 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2324 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2326 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2327 silc_schedule_task_del_by_context(ske->schedule, ske);
2329 /* Call completion */
2330 silc_ske_completion(ske);
2332 return SILC_FSM_FINISH;
2335 /* Failure received from remote */
2337 SILC_FSM_STATE(silc_ske_st_responder_failure)
2339 SilcSKE ske = fsm_context;
2340 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2342 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2344 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2345 SILC_GET32_MSB(error, ske->packet->buffer.data);
2346 ske->status = error;
2347 silc_packet_free(ske->packet);
2351 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2352 silc_schedule_task_del_by_context(ske->schedule, ske);
2354 /* Call completion */
2355 silc_ske_completion(ske);
2357 return SILC_FSM_FINISH;
2360 /* Error occurred */
2362 SILC_FSM_STATE(silc_ske_st_responder_error)
2364 SilcSKE ske = fsm_context;
2365 unsigned char tmp[4];
2367 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2368 ske->status, silc_ske_map_status(ske->status)));
2370 /* Send FAILURE packet */
2371 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2372 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2373 SILC_PUT32_MSB(ske->status, tmp);
2374 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2376 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2377 silc_schedule_task_del_by_context(ske->schedule, ske);
2379 /* Call completion */
2380 silc_ske_completion(ske);
2382 return SILC_FSM_FINISH;
2385 /* Starts the protocol as responder. */
2387 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2388 SilcPacketStream stream,
2389 SilcSKEParams params)
2391 SILC_LOG_DEBUG(("Start SKE as responder"));
2393 if (!ske || !stream || !params || !params->version)
2396 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2399 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2402 ske->responder = TRUE;
2403 ske->flags = params->flags;
2404 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2405 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2406 ske->session_port = params->session_port;
2407 ske->version = strdup(params->version);
2410 ske->running = TRUE;
2412 /* Link to packet stream to get key exchange packets */
2413 ske->stream = stream;
2414 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2415 SILC_PACKET_KEY_EXCHANGE,
2416 SILC_PACKET_KEY_EXCHANGE_1,
2417 SILC_PACKET_SUCCESS,
2418 SILC_PACKET_FAILURE, -1);
2420 /* Start SKE as responder */
2421 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2426 /***************************** Initiator Rekey ******************************/
2430 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2432 SilcSKE ske = fsm_context;
2435 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2439 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2440 return SILC_FSM_CONTINUE;
2443 /* Add rekey exchange timeout */
2444 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2447 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2450 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2451 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2452 return SILC_FSM_CONTINUE;
2455 /* Send REKEY packet to start rekey protocol */
2456 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2457 /** Error sending packet */
2458 SILC_LOG_DEBUG(("Error sending packet"));
2459 ske->status = SILC_SKE_STATUS_ERROR;
2460 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2461 return SILC_FSM_CONTINUE;
2464 /* If doing rekey without PFS, move directly to the end of the protocol. */
2465 if (!ske->rekey->pfs) {
2466 /** Rekey without PFS */
2467 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2468 return SILC_FSM_CONTINUE;
2471 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2473 if (status != SILC_SKE_STATUS_OK) {
2474 /** Unknown group */
2475 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2476 return SILC_FSM_CONTINUE;
2479 /** Rekey with PFS */
2480 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2481 return SILC_FSM_CONTINUE;
2484 /* Sends REKEY_DONE packet to finish the protocol. */
2486 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2488 SilcSKE ske = fsm_context;
2489 SilcCipher send_key;
2492 SilcUInt32 key_len, block_len, hash_len, x_len;
2493 unsigned char *pfsbuf;
2495 SILC_LOG_DEBUG(("Start"));
2497 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2498 key_len = silc_cipher_get_key_len(send_key);
2499 block_len = silc_cipher_get_block_len(send_key);
2501 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2502 /** Cannot allocate hash */
2503 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2504 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2505 return SILC_FSM_CONTINUE;
2507 hash_len = silc_hash_len(hash);
2509 /* Process key material */
2510 if (ske->rekey->pfs) {
2512 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2514 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2517 memset(pfsbuf, 0, x_len);
2523 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2524 ske->rekey->enc_key_len / 8,
2530 SILC_LOG_ERROR(("Error processing key material"));
2531 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2532 return SILC_FSM_CONTINUE;
2535 ske->prop->cipher = send_key;
2536 ske->prop->hmac = hmac_send;
2537 ske->prop->hash = hash;
2539 /* Get sending keys */
2540 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2541 &hmac_send, NULL, NULL)) {
2542 /** Cannot get keys */
2543 ske->status = SILC_SKE_STATUS_ERROR;
2544 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2545 return SILC_FSM_CONTINUE;
2548 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2549 packet sent after this call will be protected with the new keys. */
2550 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2552 /** Cannot set keys */
2553 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2554 ske->status = SILC_SKE_STATUS_ERROR;
2555 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2556 return SILC_FSM_CONTINUE;
2559 /** Wait for REKEY_DONE */
2560 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2561 return SILC_FSM_WAIT;
2564 /* Rekey protocol end */
2566 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2568 SilcSKE ske = fsm_context;
2569 SilcCipher receive_key;
2570 SilcHmac hmac_receive;
2571 SilcSKERekeyMaterial rekey;
2573 SILC_LOG_DEBUG(("Start"));
2575 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2576 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2577 silc_packet_free(ske->packet);
2579 return SILC_FSM_WAIT;
2582 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2583 ske->prop->cipher = receive_key;
2584 ske->prop->hmac = hmac_receive;
2586 /* Get receiving keys */
2587 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2588 NULL, &hmac_receive, NULL)) {
2589 /** Cannot get keys */
2590 ske->status = SILC_SKE_STATUS_ERROR;
2591 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2592 return SILC_FSM_CONTINUE;
2595 /* Set new receiving keys into use. All packets received after this will
2596 be decrypted with the new keys. */
2597 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2598 hmac_receive, FALSE)) {
2599 /** Cannot set keys */
2600 SILC_LOG_DEBUG(("Cannot set new keys"));
2601 ske->status = SILC_SKE_STATUS_ERROR;
2602 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2603 return SILC_FSM_CONTINUE;
2606 SILC_LOG_DEBUG(("Rekey completed successfully"));
2608 /* Generate new rekey material */
2609 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2612 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2613 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2614 return SILC_FSM_CONTINUE;
2616 rekey->pfs = ske->rekey->pfs;
2619 ske->prop->cipher = NULL;
2620 ske->prop->hmac = NULL;
2621 silc_packet_free(ske->packet);
2623 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2624 silc_schedule_task_del_by_context(ske->schedule, ske);
2626 /* Call completion */
2627 silc_ske_completion(ske);
2629 return SILC_FSM_FINISH;
2632 /* Starts rekey protocol as initiator */
2635 silc_ske_rekey_initiator(SilcSKE ske,
2636 SilcPacketStream stream,
2637 SilcSKERekeyMaterial rekey)
2639 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2641 if (!ske || !stream || !rekey)
2644 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2647 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2651 ske->responder = FALSE;
2652 ske->running = TRUE;
2653 ske->rekeying = TRUE;
2655 /* Link to packet stream to get key exchange packets */
2656 ske->stream = stream;
2657 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2659 SILC_PACKET_REKEY_DONE,
2660 SILC_PACKET_KEY_EXCHANGE_2,
2661 SILC_PACKET_SUCCESS,
2662 SILC_PACKET_FAILURE, -1);
2664 /* Start SKE rekey as initiator */
2665 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2670 /***************************** Responder Rekey ******************************/
2672 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2674 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2676 return SILC_FSM_FINISH;
2679 /* Starts rekey protocol as responder */
2682 silc_ske_rekey_responder(SilcSKE ske,
2683 SilcPacketStream stream,
2684 SilcSKERekeyMaterial rekey)
2686 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2688 if (!ske || !stream || !rekey)
2691 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2694 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2698 ske->responder = TRUE;
2699 ske->running = TRUE;
2700 ske->rekeying = TRUE;
2702 /* Link to packet stream to get key exchange packets */
2703 ske->stream = stream;
2704 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2706 SILC_PACKET_REKEY_DONE,
2707 SILC_PACKET_KEY_EXCHANGE_1,
2708 SILC_PACKET_SUCCESS,
2709 SILC_PACKET_FAILURE, -1);
2711 /* Start SKE rekey as responder */
2712 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2717 /* Processes the provided key material `data' as the SILC protocol
2718 specification defines. */
2721 silc_ske_process_key_material_data(unsigned char *data,
2722 SilcUInt32 data_len,
2723 SilcUInt32 req_iv_len,
2724 SilcUInt32 req_enc_key_len,
2725 SilcUInt32 req_hmac_key_len,
2729 unsigned char hashd[SILC_HASH_MAXLEN];
2730 SilcUInt32 hash_len = req_hmac_key_len;
2731 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2732 SilcSKEKeyMaterial key;
2734 SILC_LOG_DEBUG(("Start"));
2736 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2739 key = silc_calloc(1, sizeof(*key));
2743 buf = silc_buffer_alloc_size(1 + data_len);
2746 silc_buffer_format(buf,
2747 SILC_STR_UI_CHAR(0),
2748 SILC_STR_UI_XNSTRING(data, data_len),
2752 memset(hashd, 0, sizeof(hashd));
2754 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2755 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2756 memcpy(key->send_iv, hashd, req_iv_len);
2757 memset(hashd, 0, sizeof(hashd));
2759 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2760 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2761 memcpy(key->receive_iv, hashd, req_iv_len);
2762 key->iv_len = req_iv_len;
2764 /* Take the encryption keys. If requested key size is more than
2765 the size of hash length we will distribute more key material
2766 as protocol defines. */
2768 if (enc_key_len > hash_len) {
2770 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2771 k3[SILC_HASH_MAXLEN];
2772 unsigned char *dtmp;
2775 if (enc_key_len > (3 * hash_len))
2778 /* Take first round */
2779 memset(k1, 0, sizeof(k1));
2780 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2782 /* Take second round */
2783 dist = silc_buffer_alloc_size(data_len + hash_len);
2786 silc_buffer_format(dist,
2787 SILC_STR_UI_XNSTRING(data, data_len),
2788 SILC_STR_UI_XNSTRING(k1, hash_len),
2790 memset(k2, 0, sizeof(k2));
2791 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2793 /* Take third round */
2794 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2795 silc_buffer_pull_tail(dist, hash_len);
2796 silc_buffer_pull(dist, data_len + hash_len);
2797 silc_buffer_format(dist,
2798 SILC_STR_UI_XNSTRING(k2, hash_len),
2800 silc_buffer_push(dist, data_len + hash_len);
2801 memset(k3, 0, sizeof(k3));
2802 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2804 /* Then, save the keys */
2805 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2806 memcpy(dtmp, k1, hash_len);
2807 memcpy(dtmp + hash_len, k2, hash_len);
2808 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2810 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2811 memcpy(key->send_enc_key, dtmp, enc_key_len);
2812 key->enc_key_len = req_enc_key_len;
2814 memset(dtmp, 0, (3 * hash_len));
2815 memset(k1, 0, sizeof(k1));
2816 memset(k2, 0, sizeof(k2));
2817 memset(k3, 0, sizeof(k3));
2819 silc_buffer_clear(dist);
2820 silc_buffer_free(dist);
2822 /* Take normal hash as key */
2823 memset(hashd, 0, sizeof(hashd));
2824 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2825 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2826 memcpy(key->send_enc_key, hashd, enc_key_len);
2827 key->enc_key_len = req_enc_key_len;
2831 if (enc_key_len > hash_len) {
2833 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2834 k3[SILC_HASH_MAXLEN];
2835 unsigned char *dtmp;
2838 if (enc_key_len > (3 * hash_len))
2841 /* Take first round */
2842 memset(k1, 0, sizeof(k1));
2843 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2845 /* Take second round */
2846 dist = silc_buffer_alloc_size(data_len + hash_len);
2849 silc_buffer_format(dist,
2850 SILC_STR_UI_XNSTRING(data, data_len),
2851 SILC_STR_UI_XNSTRING(k1, hash_len),
2853 memset(k2, 0, sizeof(k2));
2854 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2856 /* Take third round */
2857 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2858 silc_buffer_pull_tail(dist, hash_len);
2859 silc_buffer_pull(dist, data_len + hash_len);
2860 silc_buffer_format(dist,
2861 SILC_STR_UI_XNSTRING(k2, hash_len),
2863 silc_buffer_push(dist, data_len + hash_len);
2864 memset(k3, 0, sizeof(k3));
2865 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2867 /* Then, save the keys */
2868 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2869 memcpy(dtmp, k1, hash_len);
2870 memcpy(dtmp + hash_len, k2, hash_len);
2871 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2873 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2874 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2875 key->enc_key_len = req_enc_key_len;
2877 memset(dtmp, 0, (3 * hash_len));
2878 memset(k1, 0, sizeof(k1));
2879 memset(k2, 0, sizeof(k2));
2880 memset(k3, 0, sizeof(k3));
2882 silc_buffer_clear(dist);
2883 silc_buffer_free(dist);
2885 /* Take normal hash as key */
2886 memset(hashd, 0, sizeof(hashd));
2887 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2888 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2889 memcpy(key->receive_enc_key, hashd, enc_key_len);
2890 key->enc_key_len = req_enc_key_len;
2893 /* Take HMAC keys */
2894 memset(hashd, 0, sizeof(hashd));
2896 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2897 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2898 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2899 memset(hashd, 0, sizeof(hashd));
2901 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2902 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2903 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2904 key->hmac_key_len = req_hmac_key_len;
2905 memset(hashd, 0, sizeof(hashd));
2907 silc_buffer_clear(buf);
2908 silc_buffer_free(buf);
2910 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
2915 /* Processes negotiated key material as protocol specifies. This returns
2916 the actual keys to be used in the SILC. */
2919 silc_ske_process_key_material(SilcSKE ske,
2920 SilcUInt32 req_iv_len,
2921 SilcUInt32 req_enc_key_len,
2922 SilcUInt32 req_hmac_key_len,
2923 SilcSKERekeyMaterial *rekey)
2926 unsigned char *tmpbuf;
2928 SilcSKEKeyMaterial key;
2930 /* Encode KEY to binary data */
2931 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2933 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2936 silc_buffer_format(buf,
2937 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2938 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2941 /* Process the key material */
2942 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2943 req_iv_len, req_enc_key_len,
2947 memset(tmpbuf, 0, klen);
2949 silc_buffer_clear(buf);
2950 silc_buffer_free(buf);
2953 *rekey = silc_ske_make_rekey_material(ske, key);
2961 /* Free key material structure */
2963 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2969 silc_free(key->send_iv);
2970 if (key->receive_iv)
2971 silc_free(key->receive_iv);
2972 if (key->send_enc_key) {
2973 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2974 silc_free(key->send_enc_key);
2976 if (key->receive_enc_key) {
2977 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2978 silc_free(key->receive_enc_key);
2980 if (key->send_hmac_key) {
2981 memset(key->send_hmac_key, 0, key->hmac_key_len);
2982 silc_free(key->send_hmac_key);
2984 if (key->receive_hmac_key) {
2985 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2986 silc_free(key->receive_hmac_key);
2991 /* Free rekey material */
2993 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
2997 if (rekey->send_enc_key) {
2998 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
2999 silc_free(rekey->send_enc_key);
3001 silc_free(rekey->hash);
3005 /* Set keys into use */
3007 SilcBool silc_ske_set_keys(SilcSKE ske,
3008 SilcSKEKeyMaterial keymat,
3009 SilcSKESecurityProperties prop,
3010 SilcCipher *ret_send_key,
3011 SilcCipher *ret_receive_key,
3012 SilcHmac *ret_hmac_send,
3013 SilcHmac *ret_hmac_receive,
3016 unsigned char iv[32];
3018 /* Allocate ciphers to be used in the communication */
3020 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3024 if (ret_receive_key) {
3025 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3030 /* Allocate HMACs */
3031 if (ret_hmac_send) {
3032 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3036 if (ret_hmac_receive) {
3037 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3042 /* Set key material */
3043 memset(iv, 0, sizeof(iv));
3044 if (ske->responder) {
3046 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3047 keymat->enc_key_len, TRUE);
3049 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3050 memcpy(iv, ske->hash, 4);
3051 memcpy(iv + 4, keymat->receive_iv, 4);
3052 silc_cipher_set_iv(*ret_send_key, iv);
3054 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3057 if (ret_receive_key) {
3058 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3059 keymat->enc_key_len, FALSE);
3061 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3062 memcpy(iv, ske->hash, 4);
3063 memcpy(iv + 4, keymat->send_iv, 4);
3064 silc_cipher_set_iv(*ret_receive_key, iv);
3066 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3070 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3071 keymat->hmac_key_len);
3072 if (ret_hmac_receive)
3073 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3074 keymat->hmac_key_len);
3077 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3078 keymat->enc_key_len, TRUE);
3080 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3081 memcpy(iv, ske->hash, 4);
3082 memcpy(iv + 4, keymat->send_iv, 4);
3083 silc_cipher_set_iv(*ret_send_key, iv);
3085 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3088 if (ret_receive_key) {
3089 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3090 keymat->enc_key_len, FALSE);
3092 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3093 memcpy(iv, ske->hash, 4);
3094 memcpy(iv + 4, keymat->receive_iv, 4);
3095 silc_cipher_set_iv(*ret_receive_key, iv);
3097 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3101 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3102 keymat->hmac_key_len);
3103 if (ret_hmac_receive)
3104 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3105 keymat->hmac_key_len);
3110 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3117 const char *silc_ske_status_string[] =
3121 "Unkown error occurred",
3122 "Bad payload in packet",
3123 "Unsupported group",
3124 "Unsupported cipher",
3126 "Unsupported hash function",
3128 "Unsupported public key (or certificate)",
3129 "Incorrect signature",
3130 "Bad or unsupported version",
3134 "Remote did not provide public key",
3135 "Bad reserved field in packet",
3136 "Bad payload length in packet",
3137 "Error computing signature",
3138 "System out of memory",
3139 "Key exchange timeout",
3144 /* Maps status to readable string and returns the string. If string is not
3145 found and empty character string ("") is returned. */
3147 const char *silc_ske_map_status(SilcSKEStatus status)
3151 for (i = 0; silc_ske_status_string[i]; i++)
3153 return silc_ske_status_string[i];
3158 /* Parses remote host's version string. */
3160 SilcBool silc_ske_parse_version(SilcSKE ske,
3161 SilcUInt32 *protocol_version,
3162 char **protocol_version_string,
3163 SilcUInt32 *software_version,
3164 char **software_version_string,
3165 char **vendor_version)
3167 return silc_parse_version_string(ske->remote_version,
3169 protocol_version_string,
3171 software_version_string,
3175 /* Get security properties */
3177 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3182 /* Get key material */
3184 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)