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 if (ske->prop->public_key)
1089 silc_pkcs_public_key_free(ske->prop->public_key);
1090 silc_free(ske->prop);
1093 silc_ske_free_key_material(ske->keymat);
1094 if (ske->start_payload_copy)
1095 silc_buffer_free(ske->start_payload_copy);
1097 silc_mp_uninit(ske->x);
1101 silc_mp_uninit(ske->KEY);
1102 silc_free(ske->KEY);
1104 silc_free(ske->retrans.data);
1105 silc_free(ske->hash);
1106 silc_free(ske->callbacks);
1108 memset(ske, 'F', sizeof(*ske));
1112 /* Return user context */
1114 void *silc_ske_get_context(SilcSKE ske)
1116 return ske->user_data;
1119 /* Sets protocol callbacks */
1121 void silc_ske_set_callbacks(SilcSKE ske,
1122 SilcSKEVerifyCb verify_key,
1123 SilcSKECompletionCb completed,
1127 silc_free(ske->callbacks);
1128 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1129 if (!ske->callbacks)
1131 ske->callbacks->verify_key = verify_key;
1132 ske->callbacks->completed = completed;
1133 ske->callbacks->context = context;
1137 /******************************** Initiator *********************************/
1139 /* Start protocol. Send our proposal */
1141 SILC_FSM_STATE(silc_ske_st_initiator_start)
1143 SilcSKE ske = fsm_context;
1144 SilcBuffer payload_buf;
1147 SILC_LOG_DEBUG(("Start"));
1151 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1152 return SILC_FSM_CONTINUE;
1155 /* Encode the payload */
1156 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1158 if (status != SILC_SKE_STATUS_OK) {
1159 /** Error encoding Start Payload */
1160 ske->status = status;
1161 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1162 return SILC_FSM_CONTINUE;
1165 /* Save the the payload buffer for future use. It is later used to
1166 compute the HASH value. */
1167 ske->start_payload_copy = payload_buf;
1169 /* Send the packet. */
1170 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1171 silc_buffer_data(payload_buf),
1172 silc_buffer_len(payload_buf))) {
1173 /** Error sending packet */
1174 SILC_LOG_DEBUG(("Error sending packet"));
1175 ske->status = SILC_SKE_STATUS_ERROR;
1176 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1177 return SILC_FSM_CONTINUE;
1180 /* Add key exchange timeout */
1181 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1182 ske, ske->timeout, 0);
1184 /** Wait for responder proposal */
1185 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1186 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1187 return SILC_FSM_WAIT;
1190 /* Phase-1. Receives responder's proposal */
1192 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1194 SilcSKE ske = fsm_context;
1195 SilcSKEStatus status;
1196 SilcSKEStartPayload payload;
1197 SilcSKESecurityProperties prop;
1198 SilcSKEDiffieHellmanGroup group = NULL;
1199 SilcBuffer packet_buf = &ske->packet->buffer;
1200 SilcUInt16 remote_port = 0;
1204 SILC_LOG_DEBUG(("Start"));
1206 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1207 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1208 silc_ske_install_retransmission(ske);
1209 silc_packet_free(ske->packet);
1211 return SILC_FSM_WAIT;
1214 /* Decode the payload */
1215 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1216 if (status != SILC_SKE_STATUS_OK) {
1217 /** Error decoding Start Payload */
1218 silc_packet_free(ske->packet);
1220 ske->status = status;
1221 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1222 return SILC_FSM_CONTINUE;
1225 /* Get remote ID and set it to stream */
1226 if (ske->packet->src_id_len) {
1227 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1228 ske->packet->src_id_type,
1229 (ske->packet->src_id_type == SILC_ID_SERVER ?
1230 (void *)&id.u.server_id : (void *)&id.u.client_id),
1231 (ske->packet->src_id_type == SILC_ID_SERVER ?
1232 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1233 silc_packet_set_ids(ske->stream, 0, NULL, 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));
1238 silc_packet_free(ske->packet);
1241 /* Check that the cookie is returned unmodified. In case IV included
1242 flag and session port has been set, the first two bytes of cookie
1243 are the session port and we ignore them in this check. */
1244 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1245 /* Take remote port */
1246 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1249 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1250 SILC_SKE_COOKIE_LEN - coff)) {
1251 /** Invalid cookie */
1252 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1253 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1254 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1255 return SILC_FSM_CONTINUE;
1258 /* Check version string */
1259 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1260 status = silc_ske_check_version(ske);
1261 if (status != SILC_SKE_STATUS_OK) {
1262 /** Version mismatch */
1263 ske->status = status;
1264 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1265 return SILC_FSM_CONTINUE;
1268 /* Free our KE Start Payload context, we don't need it anymore. */
1269 silc_ske_payload_start_free(ske->start_payload);
1270 ske->start_payload = NULL;
1272 /* Take the selected security properties into use while doing
1273 the key exchange. This is used only while doing the key
1275 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1278 prop->flags = payload->flags;
1279 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1280 if (status != SILC_SKE_STATUS_OK)
1283 prop->group = group;
1284 prop->remote_port = remote_port;
1286 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1287 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1290 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1291 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1294 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1295 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1298 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1299 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1303 /* Save remote's KE Start Payload */
1304 ske->start_payload = payload;
1306 /** Send KE Payload */
1307 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1308 return SILC_FSM_CONTINUE;
1312 silc_ske_payload_start_free(payload);
1314 silc_ske_group_free(group);
1316 silc_cipher_free(prop->cipher);
1318 silc_hash_free(prop->hash);
1320 silc_hmac_free(prop->hmac);
1324 if (status == SILC_SKE_STATUS_OK)
1325 status = SILC_SKE_STATUS_ERROR;
1328 ske->status = status;
1329 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1330 return SILC_FSM_CONTINUE;
1333 /* Phase-2. Send KE payload */
1335 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1337 SilcSKE ske = fsm_context;
1338 SilcSKEStatus status;
1339 SilcBuffer payload_buf;
1341 SilcSKEKEPayload payload;
1344 SILC_LOG_DEBUG(("Start"));
1346 /* Create the random number x, 1 < x < q. */
1347 x = silc_calloc(1, sizeof(*x));
1349 /** Out of memory */
1350 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1351 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1352 return SILC_FSM_CONTINUE;
1356 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1357 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1359 if (status != SILC_SKE_STATUS_OK) {
1360 /** Error generating random number */
1363 ske->status = status;
1364 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1365 return SILC_FSM_CONTINUE;
1368 /* Encode the result to Key Exchange Payload. */
1370 payload = silc_calloc(1, sizeof(*payload));
1372 /** Out of memory */
1375 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1376 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1377 return SILC_FSM_CONTINUE;
1379 ske->ke1_payload = payload;
1381 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1383 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1384 silc_mp_init(&payload->x);
1385 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1386 &ske->prop->group->group);
1388 /* Get public key */
1389 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1390 if (!payload->pk_data) {
1391 /** Error encoding public key */
1394 silc_mp_uninit(&payload->x);
1396 ske->ke1_payload = NULL;
1397 ske->status = SILC_SKE_STATUS_ERROR;
1398 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1399 return SILC_FSM_CONTINUE;
1401 payload->pk_len = pk_len;
1402 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1404 /* Compute signature data if we are doing mutual authentication */
1405 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1406 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1407 SilcUInt32 hash_len, sign_len;
1409 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1410 SILC_LOG_DEBUG(("Computing HASH_i value"));
1412 /* Compute the hash value */
1413 memset(hash, 0, sizeof(hash));
1414 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1416 SILC_LOG_DEBUG(("Signing HASH_i value"));
1418 /* Sign the hash value */
1419 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1420 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1421 /** Error computing signature */
1424 silc_mp_uninit(&payload->x);
1425 silc_free(payload->pk_data);
1427 ske->ke1_payload = NULL;
1428 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1429 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1430 return SILC_FSM_CONTINUE;
1432 payload->sign_data = silc_memdup(sign, sign_len);
1433 if (payload->sign_data)
1434 payload->sign_len = sign_len;
1435 memset(sign, 0, sizeof(sign));
1438 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1439 if (status != SILC_SKE_STATUS_OK) {
1440 /** Error encoding KE payload */
1443 silc_mp_uninit(&payload->x);
1444 silc_free(payload->pk_data);
1445 silc_free(payload->sign_data);
1447 ske->ke1_payload = NULL;
1448 ske->status = status;
1449 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1450 return SILC_FSM_CONTINUE;
1455 /* Check for backwards compatibility */
1457 /* Send the packet. */
1458 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1459 silc_buffer_data(payload_buf),
1460 silc_buffer_len(payload_buf))) {
1461 /** Error sending packet */
1462 SILC_LOG_DEBUG(("Error sending packet"));
1463 ske->status = SILC_SKE_STATUS_ERROR;
1464 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1465 return SILC_FSM_CONTINUE;
1468 silc_buffer_free(payload_buf);
1470 /** Waiting responder's KE payload */
1471 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1472 return SILC_FSM_WAIT;
1475 /* Phase-3. Process responder's KE payload */
1477 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1479 SilcSKE ske = fsm_context;
1480 SilcSKEStatus status;
1481 SilcSKEKEPayload payload;
1483 SilcBuffer packet_buf = &ske->packet->buffer;
1485 SILC_LOG_DEBUG(("Start"));
1487 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1488 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1489 silc_ske_install_retransmission(ske);
1490 silc_packet_free(ske->packet);
1492 return SILC_FSM_WAIT;
1495 /* Decode the payload */
1496 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1497 if (status != SILC_SKE_STATUS_OK) {
1498 /** Error decoding KE payload */
1499 silc_packet_free(ske->packet);
1501 ske->status = status;
1502 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1503 return SILC_FSM_CONTINUE;
1505 silc_packet_free(ske->packet);
1507 ske->ke2_payload = payload;
1509 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1510 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1511 "even though we require it"));
1512 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1516 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1518 /* Compute the shared secret key */
1519 KEY = silc_calloc(1, sizeof(*KEY));
1521 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1524 /* Decode the remote's public key */
1525 if (payload->pk_data &&
1526 !silc_pkcs_public_key_alloc(payload->pk_type,
1527 payload->pk_data, payload->pk_len,
1528 &ske->prop->public_key)) {
1529 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1530 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1534 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1536 SILC_LOG_DEBUG(("Verifying public key"));
1538 /** Waiting public key verification */
1539 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1541 /* If repository is provided, verify the key from there. */
1542 if (ske->repository) {
1545 find = silc_skr_find_alloc();
1547 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1550 silc_skr_find_set_pkcs_type(find,
1551 silc_pkcs_get_type(ske->prop->public_key));
1552 silc_skr_find_set_public_key(find, ske->prop->public_key);
1553 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1555 /* Find key from repository */
1556 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1557 silc_ske_skr_callback, ske));
1559 /* Verify from application */
1560 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1561 ske->callbacks->context,
1562 silc_ske_pk_verified, NULL));
1567 /** Process key material */
1568 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1569 return SILC_FSM_CONTINUE;
1572 silc_ske_payload_ke_free(payload);
1573 ske->ke2_payload = NULL;
1575 silc_mp_uninit(ske->KEY);
1576 silc_free(ske->KEY);
1579 if (status == SILC_SKE_STATUS_OK)
1580 return SILC_SKE_STATUS_ERROR;
1583 ske->status = status;
1584 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1585 return SILC_FSM_CONTINUE;
1588 /* Process key material */
1590 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1592 SilcSKE ske = fsm_context;
1593 SilcSKEStatus status;
1594 SilcSKEKEPayload payload;
1595 unsigned char hash[SILC_HASH_MAXLEN];
1596 SilcUInt32 hash_len;
1597 int key_len, block_len;
1601 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1602 return SILC_FSM_CONTINUE;
1605 /* Check result of public key verification */
1606 if (ske->status != SILC_SKE_STATUS_OK) {
1607 /** Public key not verified */
1608 SILC_LOG_DEBUG(("Public key verification failed"));
1609 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1610 return SILC_FSM_CONTINUE;
1613 payload = ske->ke2_payload;
1615 if (ske->prop->public_key) {
1616 SILC_LOG_DEBUG(("Public key is authentic"));
1618 /* Compute the hash value */
1619 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1620 if (status != SILC_SKE_STATUS_OK)
1623 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1625 /* Verify signature */
1626 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1627 payload->sign_len, hash, hash_len, NULL)) {
1628 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1629 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1633 SILC_LOG_DEBUG(("Signature is Ok"));
1635 ske->hash = silc_memdup(hash, hash_len);
1636 ske->hash_len = hash_len;
1637 memset(hash, 'F', hash_len);
1640 ske->status = SILC_SKE_STATUS_OK;
1642 /* In case we are doing rekey move to finish it. */
1645 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1646 return SILC_FSM_CONTINUE;
1649 /* Process key material */
1650 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1651 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1652 hash_len = silc_hash_len(ske->prop->hash);
1653 ske->keymat = silc_ske_process_key_material(ske, block_len,
1657 SILC_LOG_ERROR(("Error processing key material"));
1658 status = SILC_SKE_STATUS_ERROR;
1662 /* Send SUCCESS packet */
1663 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1664 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1665 /** Error sending packet */
1666 SILC_LOG_DEBUG(("Error sending packet"));
1667 ske->status = SILC_SKE_STATUS_ERROR;
1668 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1669 return SILC_FSM_CONTINUE;
1672 /** Waiting completion */
1673 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1674 return SILC_FSM_WAIT;
1677 memset(hash, 'F', sizeof(hash));
1678 silc_ske_payload_ke_free(payload);
1679 ske->ke2_payload = NULL;
1681 silc_mp_uninit(ske->KEY);
1682 silc_free(ske->KEY);
1686 memset(ske->hash, 'F', hash_len);
1687 silc_free(ske->hash);
1691 if (status == SILC_SKE_STATUS_OK)
1692 status = SILC_SKE_STATUS_ERROR;
1695 ske->status = status;
1696 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1697 return SILC_FSM_CONTINUE;
1700 /* Protocol completed */
1702 SILC_FSM_STATE(silc_ske_st_initiator_end)
1704 SilcSKE ske = fsm_context;
1706 SILC_LOG_DEBUG(("Start"));
1708 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1709 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1710 silc_ske_install_retransmission(ske);
1711 silc_packet_free(ske->packet);
1713 return SILC_FSM_WAIT;
1716 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1718 silc_packet_free(ske->packet);
1720 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1721 silc_schedule_task_del_by_context(ske->schedule, ske);
1723 /* Call completion */
1724 silc_ske_completion(ske);
1726 return SILC_FSM_FINISH;
1729 /* Aborted by application */
1731 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1733 SilcSKE ske = fsm_context;
1734 unsigned char data[4];
1736 SILC_LOG_DEBUG(("Aborted by caller"));
1738 /* Send FAILURE packet */
1739 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1740 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1742 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1743 silc_schedule_task_del_by_context(ske->schedule, ske);
1745 /* Call completion */
1746 silc_ske_completion(ske);
1748 return SILC_FSM_FINISH;
1751 /* Error occurred. Send error to remote host */
1753 SILC_FSM_STATE(silc_ske_st_initiator_error)
1755 SilcSKE ske = fsm_context;
1756 SilcSKEStatus status;
1757 unsigned char data[4];
1759 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1760 silc_ske_map_status(ske->status), ske->status));
1762 status = ske->status;
1763 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1764 status = SILC_SKE_STATUS_ERROR;
1766 /* Send FAILURE packet */
1767 SILC_PUT32_MSB((SilcUInt32)status, data);
1768 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1770 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1771 silc_schedule_task_del_by_context(ske->schedule, ske);
1773 /* Call completion */
1774 silc_ske_completion(ske);
1776 return SILC_FSM_FINISH;
1779 /* Failure received from remote */
1781 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1783 SilcSKE ske = fsm_context;
1784 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1786 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1787 silc_ske_map_status(ske->status), ske->status));
1789 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1790 SILC_GET32_MSB(error, ske->packet->buffer.data);
1791 ske->status = error;
1792 silc_packet_free(ske->packet);
1796 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1797 silc_schedule_task_del_by_context(ske->schedule, ske);
1799 /* Call completion */
1800 silc_ske_completion(ske);
1802 return SILC_FSM_FINISH;
1805 /* Starts the protocol as initiator */
1807 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1808 SilcPacketStream stream,
1809 SilcSKEParams params,
1810 SilcSKEStartPayload start_payload)
1812 SILC_LOG_DEBUG(("Start SKE as initiator"));
1814 if (!ske || !stream || !params || !params->version)
1817 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1820 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1823 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1824 ske->session_port = params->session_port;
1826 /* Generate security properties if not provided */
1827 if (!start_payload) {
1828 start_payload = silc_ske_assemble_security_properties(ske,
1835 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1836 ske->start_payload = start_payload;
1837 ske->version = params->version;
1838 ske->running = TRUE;
1840 /* Link to packet stream to get key exchange packets */
1841 ske->stream = stream;
1842 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1843 SILC_PACKET_KEY_EXCHANGE,
1844 SILC_PACKET_KEY_EXCHANGE_2,
1845 SILC_PACKET_SUCCESS,
1846 SILC_PACKET_FAILURE, -1);
1848 /* Start SKE as initiator */
1849 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1854 /******************************** Responder *********************************/
1856 /* Start protocol as responder. Wait initiator's start payload */
1858 SILC_FSM_STATE(silc_ske_st_responder_start)
1860 SilcSKE ske = fsm_context;
1862 SILC_LOG_DEBUG(("Start"));
1866 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1867 return SILC_FSM_CONTINUE;
1870 /* Add key exchange timeout */
1871 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1872 ske, ske->timeout, 0);
1874 /** Wait for initiator */
1875 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1876 return SILC_FSM_WAIT;
1879 /* Decode initiator's start payload. Select the security properties from
1880 the initiator's start payload and send our reply start payload back. */
1882 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1884 SilcSKE ske = fsm_context;
1885 SilcSKEStatus status;
1886 SilcSKEStartPayload remote_payload = NULL;
1887 SilcBuffer packet_buf = &ske->packet->buffer;
1889 SILC_LOG_DEBUG(("Start"));
1891 /* Decode the payload */
1892 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1893 if (status != SILC_SKE_STATUS_OK) {
1894 /** Error decoding Start Payload */
1895 silc_packet_free(ske->packet);
1897 ske->status = status;
1898 silc_fsm_next(fsm, silc_ske_st_responder_error);
1899 return SILC_FSM_CONTINUE;
1902 /* Take a copy of the payload buffer for future use. It is used to
1903 compute the HASH value. */
1904 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1906 silc_packet_free(ske->packet);
1909 /* Force the mutual authentication flag if we want to do it. */
1910 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1911 SILC_LOG_DEBUG(("Force mutual authentication"));
1912 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1915 /* Force PFS flag if we require it */
1916 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1917 SILC_LOG_DEBUG(("Force PFS"));
1918 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1921 /* Disable IV Included flag if requested */
1922 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1923 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1924 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1925 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1928 /* Check and select security properties */
1929 status = silc_ske_select_security_properties(ske, remote_payload,
1931 if (status != SILC_SKE_STATUS_OK) {
1932 /** Error selecting proposal */
1933 silc_ske_payload_start_free(remote_payload);
1934 ske->status = status;
1935 silc_fsm_next(fsm, silc_ske_st_responder_error);
1936 return SILC_FSM_CONTINUE;
1939 silc_ske_payload_start_free(remote_payload);
1941 /* Encode our reply payload to send the selected security properties */
1942 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1944 if (status != SILC_SKE_STATUS_OK)
1947 /* Send the packet. */
1948 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1949 silc_buffer_data(packet_buf),
1950 silc_buffer_len(packet_buf)))
1953 silc_buffer_free(packet_buf);
1955 /** Waiting initiator's KE payload */
1956 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1957 return SILC_FSM_WAIT;
1960 if (ske->prop->group)
1961 silc_ske_group_free(ske->prop->group);
1962 if (ske->prop->cipher)
1963 silc_cipher_free(ske->prop->cipher);
1964 if (ske->prop->hash)
1965 silc_hash_free(ske->prop->hash);
1966 if (ske->prop->hmac)
1967 silc_hmac_free(ske->prop->hmac);
1968 silc_free(ske->prop);
1971 if (status == SILC_SKE_STATUS_OK)
1972 status = SILC_SKE_STATUS_ERROR;
1975 ske->status = status;
1976 silc_fsm_next(fsm, silc_ske_st_responder_error);
1977 return SILC_FSM_CONTINUE;
1980 /* Phase-2. Decode initiator's KE payload */
1982 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1984 SilcSKE ske = fsm_context;
1985 SilcSKEStatus status;
1986 SilcSKEKEPayload recv_payload;
1987 SilcBuffer packet_buf = &ske->packet->buffer;
1989 SILC_LOG_DEBUG(("Start"));
1991 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1992 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1993 silc_ske_install_retransmission(ske);
1994 silc_packet_free(ske->packet);
1996 return SILC_FSM_WAIT;
1999 /* Decode Key Exchange Payload */
2000 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2001 if (status != SILC_SKE_STATUS_OK) {
2002 /** Error decoding KE payload */
2003 silc_packet_free(ske->packet);
2005 ske->status = status;
2006 silc_fsm_next(fsm, silc_ske_st_responder_error);
2007 return SILC_FSM_CONTINUE;
2010 ske->ke1_payload = recv_payload;
2012 silc_packet_free(ske->packet);
2015 /* Verify the received public key and verify the signature if we are
2016 doing mutual authentication. */
2017 if (ske->start_payload &&
2018 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2020 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2022 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2024 /** Public key not provided */
2025 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2026 "certificate), even though we require it"));
2027 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2028 silc_fsm_next(fsm, silc_ske_st_responder_error);
2029 return SILC_FSM_CONTINUE;
2032 /* Decode the remote's public key */
2033 if (recv_payload->pk_data &&
2034 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2035 recv_payload->pk_data,
2036 recv_payload->pk_len,
2037 &ske->prop->public_key)) {
2038 /** Error decoding public key */
2039 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2040 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2041 silc_fsm_next(fsm, silc_ske_st_responder_error);
2042 return SILC_FSM_CONTINUE;
2045 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2047 SILC_LOG_DEBUG(("Verifying public key"));
2049 /** Waiting public key verification */
2050 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2052 /* If repository is provided, verify the key from there. */
2053 if (ske->repository) {
2056 find = silc_skr_find_alloc();
2058 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2059 silc_fsm_next(fsm, silc_ske_st_responder_error);
2060 return SILC_FSM_CONTINUE;
2062 silc_skr_find_set_pkcs_type(find,
2063 silc_pkcs_get_type(ske->prop->public_key));
2064 silc_skr_find_set_public_key(find, ske->prop->public_key);
2065 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2067 /* Find key from repository */
2068 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2069 silc_ske_skr_callback, ske));
2071 /* Verify from application */
2072 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2073 ske->callbacks->context,
2074 silc_ske_pk_verified, NULL));
2080 /** Generate KE2 payload */
2081 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2082 return SILC_FSM_CONTINUE;
2085 /* Phase-4. Generate KE2 payload */
2087 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2089 SilcSKE ske = fsm_context;
2090 SilcSKEStatus status;
2091 SilcSKEKEPayload recv_payload, send_payload;
2096 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2097 return SILC_FSM_CONTINUE;
2100 /* Check result of public key verification */
2101 if (ske->status != SILC_SKE_STATUS_OK) {
2102 /** Public key not verified */
2103 SILC_LOG_DEBUG(("Public key verification failed"));
2104 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2105 return SILC_FSM_CONTINUE;
2108 recv_payload = ske->ke1_payload;
2110 /* The public key verification was performed only if the Mutual
2111 Authentication flag is set. */
2112 if (ske->start_payload &&
2113 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2114 unsigned char hash[SILC_HASH_MAXLEN];
2115 SilcUInt32 hash_len;
2117 SILC_LOG_DEBUG(("Public key is authentic"));
2119 /* Compute the hash value */
2120 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2121 if (status != SILC_SKE_STATUS_OK) {
2122 /** Error computing hash */
2123 ske->status = status;
2124 silc_fsm_next(fsm, silc_ske_st_responder_error);
2125 return SILC_FSM_CONTINUE;
2128 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2130 /* Verify signature */
2131 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2132 recv_payload->sign_len, hash, hash_len, NULL)) {
2133 /** Incorrect signature */
2134 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2135 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2136 silc_fsm_next(fsm, silc_ske_st_responder_error);
2137 return SILC_FSM_CONTINUE;
2140 SILC_LOG_DEBUG(("Signature is Ok"));
2142 memset(hash, 'F', hash_len);
2145 /* Create the random number x, 1 < x < q. */
2146 x = silc_calloc(1, sizeof(*x));
2149 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2150 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2152 if (status != SILC_SKE_STATUS_OK) {
2153 /** Error generating random number */
2156 ske->status = status;
2157 silc_fsm_next(fsm, silc_ske_st_responder_error);
2158 return SILC_FSM_CONTINUE;
2161 /* Save the results for later processing */
2162 send_payload = silc_calloc(1, sizeof(*send_payload));
2164 ske->ke2_payload = send_payload;
2166 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2168 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2169 silc_mp_init(&send_payload->x);
2170 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2171 &ske->prop->group->group);
2173 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2175 /* Compute the shared secret key */
2176 KEY = silc_calloc(1, sizeof(*KEY));
2178 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2179 &ske->prop->group->group);
2182 /** Send KE2 payload */
2183 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2184 return SILC_FSM_CONTINUE;
2187 /* Phase-5. Send KE2 payload */
2189 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2191 SilcSKE ske = fsm_context;
2192 SilcSKEStatus status;
2193 SilcBuffer payload_buf;
2194 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2195 SilcUInt32 hash_len, sign_len, pk_len;
2197 SILC_LOG_DEBUG(("Start"));
2199 if (ske->public_key && ske->private_key) {
2200 SILC_LOG_DEBUG(("Getting public key"));
2202 /* Get the public key */
2203 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2205 /** Error encoding public key */
2206 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2207 silc_fsm_next(fsm, silc_ske_st_responder_error);
2208 return SILC_FSM_CONTINUE;
2210 ske->ke2_payload->pk_data = pk;
2211 ske->ke2_payload->pk_len = pk_len;
2213 SILC_LOG_DEBUG(("Computing HASH value"));
2215 /* Compute the hash value */
2216 memset(hash, 0, sizeof(hash));
2217 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2218 if (status != SILC_SKE_STATUS_OK) {
2219 /** Error computing hash */
2220 ske->status = status;
2221 silc_fsm_next(fsm, silc_ske_st_responder_error);
2222 return SILC_FSM_CONTINUE;
2225 ske->hash = silc_memdup(hash, hash_len);
2226 ske->hash_len = hash_len;
2228 SILC_LOG_DEBUG(("Signing HASH value"));
2230 /* Sign the hash value */
2231 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2232 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2233 /** Error computing signature */
2234 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2235 silc_fsm_next(fsm, silc_ske_st_responder_error);
2236 return SILC_FSM_CONTINUE;
2238 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2239 ske->ke2_payload->sign_len = sign_len;
2240 memset(sign, 0, sizeof(sign));
2242 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2244 /* Encode the Key Exchange Payload */
2245 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2247 if (status != SILC_SKE_STATUS_OK) {
2248 /** Error encoding KE payload */
2249 ske->status = status;
2250 silc_fsm_next(fsm, silc_ske_st_responder_error);
2251 return SILC_FSM_CONTINUE;
2254 /* Send the packet. */
2255 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2256 payload_buf->data, silc_buffer_len(payload_buf))) {
2257 SILC_LOG_DEBUG(("Error sending packet"));
2258 ske->status = SILC_SKE_STATUS_ERROR;
2259 silc_fsm_next(fsm, silc_ske_st_responder_error);
2260 return SILC_FSM_CONTINUE;
2263 silc_buffer_free(payload_buf);
2265 /** Waiting completion */
2266 silc_fsm_next(fsm, silc_ske_st_responder_end);
2267 return SILC_FSM_WAIT;
2270 /* Protocol completed */
2272 SILC_FSM_STATE(silc_ske_st_responder_end)
2274 SilcSKE ske = fsm_context;
2275 unsigned char tmp[4];
2276 SilcUInt32 hash_len, key_len, block_len;
2278 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2279 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2280 silc_ske_install_retransmission(ske);
2281 silc_packet_free(ske->packet);
2283 return SILC_FSM_WAIT;
2285 silc_packet_free(ske->packet);
2288 /* Process key material */
2289 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2290 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2291 hash_len = silc_hash_len(ske->prop->hash);
2292 ske->keymat = silc_ske_process_key_material(ske, block_len,
2296 /** Error processing key material */
2297 ske->status = SILC_SKE_STATUS_ERROR;
2298 silc_fsm_next(fsm, silc_ske_st_responder_error);
2299 return SILC_FSM_CONTINUE;
2302 /* Send SUCCESS packet */
2303 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2304 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2306 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2307 silc_schedule_task_del_by_context(ske->schedule, ske);
2309 /* Call completion */
2310 silc_ske_completion(ske);
2312 return SILC_FSM_FINISH;
2315 /* Aborted by application */
2317 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2319 SilcSKE ske = fsm_context;
2320 unsigned char tmp[4];
2322 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2324 /* Send FAILURE packet */
2325 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2326 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2328 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2329 silc_schedule_task_del_by_context(ske->schedule, ske);
2331 /* Call completion */
2332 silc_ske_completion(ske);
2334 return SILC_FSM_FINISH;
2337 /* Failure received from remote */
2339 SILC_FSM_STATE(silc_ske_st_responder_failure)
2341 SilcSKE ske = fsm_context;
2342 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2344 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2346 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2347 SILC_GET32_MSB(error, ske->packet->buffer.data);
2348 ske->status = error;
2349 silc_packet_free(ske->packet);
2353 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2354 silc_schedule_task_del_by_context(ske->schedule, ske);
2356 /* Call completion */
2357 silc_ske_completion(ske);
2359 return SILC_FSM_FINISH;
2362 /* Error occurred */
2364 SILC_FSM_STATE(silc_ske_st_responder_error)
2366 SilcSKE ske = fsm_context;
2367 unsigned char tmp[4];
2369 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2370 ske->status, silc_ske_map_status(ske->status)));
2372 /* Send FAILURE packet */
2373 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2374 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2375 SILC_PUT32_MSB(ske->status, tmp);
2376 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2378 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2379 silc_schedule_task_del_by_context(ske->schedule, ske);
2381 /* Call completion */
2382 silc_ske_completion(ske);
2384 return SILC_FSM_FINISH;
2387 /* Starts the protocol as responder. */
2389 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2390 SilcPacketStream stream,
2391 SilcSKEParams params)
2393 SILC_LOG_DEBUG(("Start SKE as responder"));
2395 if (!ske || !stream || !params || !params->version)
2398 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2401 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2404 ske->responder = TRUE;
2405 ske->flags = params->flags;
2406 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2407 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2408 ske->session_port = params->session_port;
2409 ske->version = strdup(params->version);
2412 ske->running = TRUE;
2414 /* Link to packet stream to get key exchange packets */
2415 ske->stream = stream;
2416 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2417 SILC_PACKET_KEY_EXCHANGE,
2418 SILC_PACKET_KEY_EXCHANGE_1,
2419 SILC_PACKET_SUCCESS,
2420 SILC_PACKET_FAILURE, -1);
2422 /* Start SKE as responder */
2423 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2428 /***************************** Initiator Rekey ******************************/
2432 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2434 SilcSKE ske = fsm_context;
2437 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2441 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2442 return SILC_FSM_CONTINUE;
2445 /* Add rekey exchange timeout */
2446 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2449 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2452 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2453 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2454 return SILC_FSM_CONTINUE;
2457 /* Send REKEY packet to start rekey protocol */
2458 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2459 /** Error sending packet */
2460 SILC_LOG_DEBUG(("Error sending packet"));
2461 ske->status = SILC_SKE_STATUS_ERROR;
2462 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2463 return SILC_FSM_CONTINUE;
2466 /* If doing rekey without PFS, move directly to the end of the protocol. */
2467 if (!ske->rekey->pfs) {
2468 /** Rekey without PFS */
2469 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2470 return SILC_FSM_CONTINUE;
2473 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2475 if (status != SILC_SKE_STATUS_OK) {
2476 /** Unknown group */
2477 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2478 return SILC_FSM_CONTINUE;
2481 /** Rekey with PFS */
2482 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2483 return SILC_FSM_CONTINUE;
2486 /* Sends REKEY_DONE packet to finish the protocol. */
2488 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2490 SilcSKE ske = fsm_context;
2491 SilcCipher send_key;
2494 SilcUInt32 key_len, block_len, hash_len, x_len;
2495 unsigned char *pfsbuf;
2497 SILC_LOG_DEBUG(("Start"));
2499 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2500 key_len = silc_cipher_get_key_len(send_key);
2501 block_len = silc_cipher_get_block_len(send_key);
2503 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2504 /** Cannot allocate hash */
2505 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2506 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2507 return SILC_FSM_CONTINUE;
2509 hash_len = silc_hash_len(hash);
2511 /* Process key material */
2512 if (ske->rekey->pfs) {
2514 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2516 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2519 memset(pfsbuf, 0, x_len);
2525 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2526 ske->rekey->enc_key_len / 8,
2532 SILC_LOG_ERROR(("Error processing key material"));
2533 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2534 return SILC_FSM_CONTINUE;
2537 ske->prop->cipher = send_key;
2538 ske->prop->hmac = hmac_send;
2539 ske->prop->hash = hash;
2541 /* Get sending keys */
2542 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2543 &hmac_send, NULL, NULL)) {
2544 /** Cannot get keys */
2545 ske->status = SILC_SKE_STATUS_ERROR;
2546 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2547 return SILC_FSM_CONTINUE;
2550 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2551 packet sent after this call will be protected with the new keys. */
2552 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2554 /** Cannot set keys */
2555 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2556 ske->status = SILC_SKE_STATUS_ERROR;
2557 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2558 return SILC_FSM_CONTINUE;
2561 /** Wait for REKEY_DONE */
2562 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2563 return SILC_FSM_WAIT;
2566 /* Rekey protocol end */
2568 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2570 SilcSKE ske = fsm_context;
2571 SilcCipher receive_key;
2572 SilcHmac hmac_receive;
2573 SilcSKERekeyMaterial rekey;
2575 SILC_LOG_DEBUG(("Start"));
2577 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2578 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2579 silc_packet_free(ske->packet);
2581 return SILC_FSM_WAIT;
2584 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2585 ske->prop->cipher = receive_key;
2586 ske->prop->hmac = hmac_receive;
2588 /* Get receiving keys */
2589 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2590 NULL, &hmac_receive, NULL)) {
2591 /** Cannot get keys */
2592 ske->status = SILC_SKE_STATUS_ERROR;
2593 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2594 return SILC_FSM_CONTINUE;
2597 /* Set new receiving keys into use. All packets received after this will
2598 be decrypted with the new keys. */
2599 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2600 hmac_receive, FALSE)) {
2601 /** Cannot set keys */
2602 SILC_LOG_DEBUG(("Cannot set new keys"));
2603 ske->status = SILC_SKE_STATUS_ERROR;
2604 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2605 return SILC_FSM_CONTINUE;
2608 SILC_LOG_DEBUG(("Rekey completed successfully"));
2610 /* Generate new rekey material */
2611 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2614 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2615 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2616 return SILC_FSM_CONTINUE;
2618 rekey->pfs = ske->rekey->pfs;
2621 ske->prop->cipher = NULL;
2622 ske->prop->hmac = NULL;
2623 silc_packet_free(ske->packet);
2625 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2626 silc_schedule_task_del_by_context(ske->schedule, ske);
2628 /* Call completion */
2629 silc_ske_completion(ske);
2631 return SILC_FSM_FINISH;
2634 /* Starts rekey protocol as initiator */
2637 silc_ske_rekey_initiator(SilcSKE ske,
2638 SilcPacketStream stream,
2639 SilcSKERekeyMaterial rekey)
2641 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2643 if (!ske || !stream || !rekey)
2646 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2649 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2653 ske->responder = FALSE;
2654 ske->running = TRUE;
2655 ske->rekeying = TRUE;
2657 /* Link to packet stream to get key exchange packets */
2658 ske->stream = stream;
2659 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2661 SILC_PACKET_REKEY_DONE,
2662 SILC_PACKET_KEY_EXCHANGE_2,
2663 SILC_PACKET_SUCCESS,
2664 SILC_PACKET_FAILURE, -1);
2666 /* Start SKE rekey as initiator */
2667 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2672 /***************************** Responder Rekey ******************************/
2674 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2676 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2678 return SILC_FSM_FINISH;
2681 /* Starts rekey protocol as responder */
2684 silc_ske_rekey_responder(SilcSKE ske,
2685 SilcPacketStream stream,
2686 SilcSKERekeyMaterial rekey)
2688 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2690 if (!ske || !stream || !rekey)
2693 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2696 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2700 ske->responder = TRUE;
2701 ske->running = TRUE;
2702 ske->rekeying = TRUE;
2704 /* Link to packet stream to get key exchange packets */
2705 ske->stream = stream;
2706 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2708 SILC_PACKET_REKEY_DONE,
2709 SILC_PACKET_KEY_EXCHANGE_1,
2710 SILC_PACKET_SUCCESS,
2711 SILC_PACKET_FAILURE, -1);
2713 /* Start SKE rekey as responder */
2714 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2719 /* Processes the provided key material `data' as the SILC protocol
2720 specification defines. */
2723 silc_ske_process_key_material_data(unsigned char *data,
2724 SilcUInt32 data_len,
2725 SilcUInt32 req_iv_len,
2726 SilcUInt32 req_enc_key_len,
2727 SilcUInt32 req_hmac_key_len,
2731 unsigned char hashd[SILC_HASH_MAXLEN];
2732 SilcUInt32 hash_len = req_hmac_key_len;
2733 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2734 SilcSKEKeyMaterial key;
2736 SILC_LOG_DEBUG(("Start"));
2738 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2741 key = silc_calloc(1, sizeof(*key));
2745 buf = silc_buffer_alloc_size(1 + data_len);
2748 silc_buffer_format(buf,
2749 SILC_STR_UI_CHAR(0),
2750 SILC_STR_UI_XNSTRING(data, data_len),
2754 memset(hashd, 0, sizeof(hashd));
2756 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2757 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2758 memcpy(key->send_iv, hashd, req_iv_len);
2759 memset(hashd, 0, sizeof(hashd));
2761 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2762 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2763 memcpy(key->receive_iv, hashd, req_iv_len);
2764 key->iv_len = req_iv_len;
2766 /* Take the encryption keys. If requested key size is more than
2767 the size of hash length we will distribute more key material
2768 as protocol defines. */
2770 if (enc_key_len > hash_len) {
2772 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2773 k3[SILC_HASH_MAXLEN];
2774 unsigned char *dtmp;
2777 if (enc_key_len > (3 * hash_len))
2780 /* Take first round */
2781 memset(k1, 0, sizeof(k1));
2782 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2784 /* Take second round */
2785 dist = silc_buffer_alloc_size(data_len + hash_len);
2788 silc_buffer_format(dist,
2789 SILC_STR_UI_XNSTRING(data, data_len),
2790 SILC_STR_UI_XNSTRING(k1, hash_len),
2792 memset(k2, 0, sizeof(k2));
2793 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2795 /* Take third round */
2796 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2797 silc_buffer_pull_tail(dist, hash_len);
2798 silc_buffer_pull(dist, data_len + hash_len);
2799 silc_buffer_format(dist,
2800 SILC_STR_UI_XNSTRING(k2, hash_len),
2802 silc_buffer_push(dist, data_len + hash_len);
2803 memset(k3, 0, sizeof(k3));
2804 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2806 /* Then, save the keys */
2807 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2808 memcpy(dtmp, k1, hash_len);
2809 memcpy(dtmp + hash_len, k2, hash_len);
2810 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2812 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2813 memcpy(key->send_enc_key, dtmp, enc_key_len);
2814 key->enc_key_len = req_enc_key_len;
2816 memset(dtmp, 0, (3 * hash_len));
2817 memset(k1, 0, sizeof(k1));
2818 memset(k2, 0, sizeof(k2));
2819 memset(k3, 0, sizeof(k3));
2821 silc_buffer_clear(dist);
2822 silc_buffer_free(dist);
2824 /* Take normal hash as key */
2825 memset(hashd, 0, sizeof(hashd));
2826 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2827 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2828 memcpy(key->send_enc_key, hashd, enc_key_len);
2829 key->enc_key_len = req_enc_key_len;
2833 if (enc_key_len > hash_len) {
2835 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2836 k3[SILC_HASH_MAXLEN];
2837 unsigned char *dtmp;
2840 if (enc_key_len > (3 * hash_len))
2843 /* Take first round */
2844 memset(k1, 0, sizeof(k1));
2845 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2847 /* Take second round */
2848 dist = silc_buffer_alloc_size(data_len + hash_len);
2851 silc_buffer_format(dist,
2852 SILC_STR_UI_XNSTRING(data, data_len),
2853 SILC_STR_UI_XNSTRING(k1, hash_len),
2855 memset(k2, 0, sizeof(k2));
2856 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2858 /* Take third round */
2859 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2860 silc_buffer_pull_tail(dist, hash_len);
2861 silc_buffer_pull(dist, data_len + hash_len);
2862 silc_buffer_format(dist,
2863 SILC_STR_UI_XNSTRING(k2, hash_len),
2865 silc_buffer_push(dist, data_len + hash_len);
2866 memset(k3, 0, sizeof(k3));
2867 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2869 /* Then, save the keys */
2870 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2871 memcpy(dtmp, k1, hash_len);
2872 memcpy(dtmp + hash_len, k2, hash_len);
2873 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2875 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2876 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2877 key->enc_key_len = req_enc_key_len;
2879 memset(dtmp, 0, (3 * hash_len));
2880 memset(k1, 0, sizeof(k1));
2881 memset(k2, 0, sizeof(k2));
2882 memset(k3, 0, sizeof(k3));
2884 silc_buffer_clear(dist);
2885 silc_buffer_free(dist);
2887 /* Take normal hash as key */
2888 memset(hashd, 0, sizeof(hashd));
2889 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2890 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2891 memcpy(key->receive_enc_key, hashd, enc_key_len);
2892 key->enc_key_len = req_enc_key_len;
2895 /* Take HMAC keys */
2896 memset(hashd, 0, sizeof(hashd));
2898 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2899 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2900 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2901 memset(hashd, 0, sizeof(hashd));
2903 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2904 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2905 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2906 key->hmac_key_len = req_hmac_key_len;
2907 memset(hashd, 0, sizeof(hashd));
2909 silc_buffer_clear(buf);
2910 silc_buffer_free(buf);
2912 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
2917 /* Processes negotiated key material as protocol specifies. This returns
2918 the actual keys to be used in the SILC. */
2921 silc_ske_process_key_material(SilcSKE ske,
2922 SilcUInt32 req_iv_len,
2923 SilcUInt32 req_enc_key_len,
2924 SilcUInt32 req_hmac_key_len,
2925 SilcSKERekeyMaterial *rekey)
2928 unsigned char *tmpbuf;
2930 SilcSKEKeyMaterial key;
2932 /* Encode KEY to binary data */
2933 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2935 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2938 silc_buffer_format(buf,
2939 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2940 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2943 /* Process the key material */
2944 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2945 req_iv_len, req_enc_key_len,
2949 memset(tmpbuf, 0, klen);
2951 silc_buffer_clear(buf);
2952 silc_buffer_free(buf);
2955 *rekey = silc_ske_make_rekey_material(ske, key);
2963 /* Free key material structure */
2965 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2971 silc_free(key->send_iv);
2972 if (key->receive_iv)
2973 silc_free(key->receive_iv);
2974 if (key->send_enc_key) {
2975 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2976 silc_free(key->send_enc_key);
2978 if (key->receive_enc_key) {
2979 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2980 silc_free(key->receive_enc_key);
2982 if (key->send_hmac_key) {
2983 memset(key->send_hmac_key, 0, key->hmac_key_len);
2984 silc_free(key->send_hmac_key);
2986 if (key->receive_hmac_key) {
2987 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2988 silc_free(key->receive_hmac_key);
2993 /* Free rekey material */
2995 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
2999 if (rekey->send_enc_key) {
3000 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3001 silc_free(rekey->send_enc_key);
3003 silc_free(rekey->hash);
3007 /* Set keys into use */
3009 SilcBool silc_ske_set_keys(SilcSKE ske,
3010 SilcSKEKeyMaterial keymat,
3011 SilcSKESecurityProperties prop,
3012 SilcCipher *ret_send_key,
3013 SilcCipher *ret_receive_key,
3014 SilcHmac *ret_hmac_send,
3015 SilcHmac *ret_hmac_receive,
3018 unsigned char iv[32];
3019 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3021 /* Allocate ciphers to be used in the communication */
3023 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3027 if (ret_receive_key) {
3028 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3033 /* Allocate HMACs */
3034 if (ret_hmac_send) {
3035 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3039 if (ret_hmac_receive) {
3040 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3045 /* Set key material */
3046 memset(iv, 0, sizeof(iv));
3047 if (ske->responder) {
3049 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3050 keymat->enc_key_len, TRUE);
3052 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3053 memcpy(iv, ske->hash, 4);
3054 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3055 silc_cipher_set_iv(*ret_send_key, iv);
3057 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3060 if (ret_receive_key) {
3061 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3062 keymat->enc_key_len, FALSE);
3064 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3065 memcpy(iv, ske->hash, 4);
3066 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3067 silc_cipher_set_iv(*ret_receive_key, iv);
3069 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3073 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3074 keymat->hmac_key_len);
3075 if (ret_hmac_receive)
3076 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3077 keymat->hmac_key_len);
3080 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3081 keymat->enc_key_len, TRUE);
3083 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3084 memcpy(iv, ske->hash, 4);
3085 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3086 silc_cipher_set_iv(*ret_send_key, iv);
3088 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3091 if (ret_receive_key) {
3092 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3093 keymat->enc_key_len, FALSE);
3095 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3096 memcpy(iv, ske->hash, 4);
3097 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3098 silc_cipher_set_iv(*ret_receive_key, iv);
3100 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3104 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3105 keymat->hmac_key_len);
3106 if (ret_hmac_receive)
3107 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3108 keymat->hmac_key_len);
3113 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3120 const char *silc_ske_status_string[] =
3124 "Unkown error occurred",
3125 "Bad payload in packet",
3126 "Unsupported group",
3127 "Unsupported cipher",
3129 "Unsupported hash function",
3131 "Unsupported public key (or certificate)",
3132 "Incorrect signature",
3133 "Bad or unsupported version",
3137 "Remote did not provide public key",
3138 "Bad reserved field in packet",
3139 "Bad payload length in packet",
3140 "Error computing signature",
3141 "System out of memory",
3142 "Key exchange timeout",
3147 /* Maps status to readable string and returns the string. If string is not
3148 found and empty character string ("") is returned. */
3150 const char *silc_ske_map_status(SilcSKEStatus status)
3154 for (i = 0; silc_ske_status_string[i]; i++)
3156 return silc_ske_status_string[i];
3161 /* Parses remote host's version string. */
3163 SilcBool silc_ske_parse_version(SilcSKE ske,
3164 SilcUInt32 *protocol_version,
3165 char **protocol_version_string,
3166 SilcUInt32 *software_version,
3167 char **software_version_string,
3168 char **vendor_version)
3170 return silc_parse_version_string(ske->remote_version,
3172 protocol_version_string,
3174 software_version_string,
3178 /* Get security properties */
3180 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3185 /* Get key material */
3187 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)