5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2006 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;
35 /************************ Static utility functions **************************/
38 silc_ske_process_key_material_data(unsigned char *data,
40 SilcUInt32 req_iv_len,
41 SilcUInt32 req_enc_key_len,
42 SilcUInt32 req_hmac_key_len,
45 silc_ske_process_key_material(SilcSKE ske,
46 SilcUInt32 req_iv_len,
47 SilcUInt32 req_enc_key_len,
48 SilcUInt32 req_hmac_key_len);
53 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
54 SilcPacketStream stream,
56 void *callback_context,
59 SilcSKE ske = callback_context;
61 silc_fsm_continue(&ske->fsm);
65 /* Packet stream callbacks */
66 static SilcPacketCallbacks silc_ske_stream_cbs =
68 silc_ske_packet_receive, NULL, NULL
71 /* Aborts SKE protocol */
73 static void silc_ske_abort(SilcAsyncOperation op, void *context)
75 SilcSKE ske = context;
79 /* Public key verification completion callback */
81 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
82 void *completion_context)
85 SILC_FSM_CALL_CONTINUE(&ske->fsm);
88 /* SKR find callback */
90 static void silc_ske_skr_callback(SilcSKR repository,
93 SilcDList keys, void *context)
95 SilcSKE ske = context;
97 silc_skr_find_free(find);
99 if (status != SILC_SKR_OK) {
100 if (ske->callbacks->verify_key) {
101 /* Verify from application */
102 ske->callbacks->verify_key(ske, ske->prop->public_key,
103 ske->callbacks->context,
104 silc_ske_pk_verified, NULL);
110 silc_dlist_uninit(keys);
113 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
114 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
115 SILC_FSM_CALL_CONTINUE(&ske->fsm);
118 /* Checks remote and local versions */
120 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
122 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
124 if (!ske->remote_version || !ske->version)
125 return SILC_SKE_STATUS_BAD_VERSION;
127 if (!silc_parse_version_string(ske->remote_version, &r_protocol_version,
128 NULL, NULL, NULL, NULL))
129 return SILC_SKE_STATUS_BAD_VERSION;
131 if (!silc_parse_version_string(ske->version, &l_protocol_version,
132 NULL, NULL, NULL, NULL))
133 return SILC_SKE_STATUS_BAD_VERSION;
135 /* If remote is too new, don't connect */
136 if (l_protocol_version < r_protocol_version)
137 return SILC_SKE_STATUS_BAD_VERSION;
139 return SILC_SKE_STATUS_OK;
142 /* Selects the supported security properties from the initiator's Key
143 Exchange Start Payload. */
146 silc_ske_select_security_properties(SilcSKE ske,
147 SilcSKEStartPayload payload,
148 SilcSKEStartPayload remote_payload)
150 SilcSKEStatus status;
151 SilcSKEStartPayload rp;
155 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
159 /* Check version string */
160 ske->remote_version = silc_memdup(rp->version, rp->version_len);
161 status = silc_ske_check_version(ske);
162 if (status != SILC_SKE_STATUS_OK) {
163 ske->status = status;
167 /* Flags are returned unchanged. */
168 payload->flags = rp->flags;
170 /* Take cookie, we must return it to sender unmodified. */
171 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
172 if (!payload->cookie) {
173 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
176 payload->cookie_len = SILC_SKE_COOKIE_LEN;
177 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
179 /* In case IV included flag and session port is set the first 16-bits of
180 cookie will include our session port. */
181 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
182 SILC_PUT16_MSB(ske->session_port, payload->cookie);
184 /* Put our version to our reply */
185 payload->version = strdup(ske->version);
186 if (!payload->version) {
187 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
190 payload->version_len = strlen(ske->version);
192 /* Get supported Key Exchange groups */
193 cp = rp->ke_grp_list;
194 if (cp && strchr(cp, ',')) {
198 len = strcspn(cp, ",");
199 item = silc_calloc(len + 1, sizeof(char));
201 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
204 memcpy(item, cp, len);
206 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
208 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
209 SILC_LOG_DEBUG(("Found KE group `%s'", item));
211 payload->ke_grp_len = len;
212 payload->ke_grp_list = item;
226 if (!payload->ke_grp_len && !payload->ke_grp_list) {
227 SILC_LOG_DEBUG(("Could not find supported KE group"));
229 return SILC_SKE_STATUS_UNKNOWN_GROUP;
233 if (!rp->ke_grp_len) {
234 SILC_LOG_DEBUG(("KE group not defined in payload"));
236 return SILC_SKE_STATUS_BAD_PAYLOAD;
239 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
240 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
242 payload->ke_grp_len = rp->ke_grp_len;
243 payload->ke_grp_list = strdup(rp->ke_grp_list);
246 /* Get supported PKCS algorithms */
247 cp = rp->pkcs_alg_list;
248 if (cp && strchr(cp, ',')) {
252 len = strcspn(cp, ",");
253 item = silc_calloc(len + 1, sizeof(char));
255 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
258 memcpy(item, cp, len);
260 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
262 if (silc_pkcs_find_algorithm(item, NULL)) {
263 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
265 payload->pkcs_alg_len = len;
266 payload->pkcs_alg_list = item;
280 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
281 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
282 silc_free(payload->ke_grp_list);
284 return SILC_SKE_STATUS_UNKNOWN_PKCS;
288 if (!rp->pkcs_alg_len) {
289 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
290 silc_free(payload->ke_grp_list);
292 return SILC_SKE_STATUS_BAD_PAYLOAD;
295 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
296 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
298 payload->pkcs_alg_len = rp->pkcs_alg_len;
299 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
302 /* Get supported encryption algorithms */
303 cp = rp->enc_alg_list;
304 if (cp && strchr(cp, ',')) {
308 len = strcspn(cp, ",");
309 item = silc_calloc(len + 1, sizeof(char));
311 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
314 memcpy(item, cp, len);
316 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
318 if (silc_cipher_is_supported(item) == TRUE) {
319 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
321 payload->enc_alg_len = len;
322 payload->enc_alg_list = item;
336 if (!payload->enc_alg_len && !payload->enc_alg_list) {
337 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
338 silc_free(payload->ke_grp_list);
339 silc_free(payload->pkcs_alg_list);
341 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
345 if (!rp->enc_alg_len) {
346 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
347 silc_free(payload->ke_grp_list);
348 silc_free(payload->pkcs_alg_list);
350 return SILC_SKE_STATUS_BAD_PAYLOAD;
353 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
356 payload->enc_alg_len = rp->enc_alg_len;
357 payload->enc_alg_list = strdup(rp->enc_alg_list);
360 /* Get supported hash algorithms */
361 cp = rp->hash_alg_list;
362 if (cp && strchr(cp, ',')) {
366 len = strcspn(cp, ",");
367 item = silc_calloc(len + 1, sizeof(char));
369 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
372 memcpy(item, cp, len);
374 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
376 if (silc_hash_is_supported(item) == TRUE) {
377 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
379 payload->hash_alg_len = len;
380 payload->hash_alg_list = item;
394 if (!payload->hash_alg_len && !payload->hash_alg_list) {
395 SILC_LOG_DEBUG(("Could not find supported hash alg"));
396 silc_free(payload->ke_grp_list);
397 silc_free(payload->pkcs_alg_list);
398 silc_free(payload->enc_alg_list);
400 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
404 if (!rp->hash_alg_len) {
405 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
406 silc_free(payload->ke_grp_list);
407 silc_free(payload->pkcs_alg_list);
408 silc_free(payload->enc_alg_list);
410 return SILC_SKE_STATUS_BAD_PAYLOAD;
413 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
416 payload->hash_alg_len = rp->hash_alg_len;
417 payload->hash_alg_list = strdup(rp->hash_alg_list);
420 /* Get supported HMACs */
421 cp = rp->hmac_alg_list;
422 if (cp && strchr(cp, ',')) {
426 len = strcspn(cp, ",");
427 item = silc_calloc(len + 1, sizeof(char));
429 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
432 memcpy(item, cp, len);
434 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
436 if (silc_hmac_is_supported(item) == TRUE) {
437 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
439 payload->hmac_alg_len = len;
440 payload->hmac_alg_list = item;
454 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
455 SILC_LOG_DEBUG(("Could not find supported HMAC"));
456 silc_free(payload->ke_grp_list);
457 silc_free(payload->pkcs_alg_list);
458 silc_free(payload->enc_alg_list);
459 silc_free(payload->hash_alg_list);
461 return SILC_SKE_STATUS_UNKNOWN_HMAC;
465 if (!rp->hmac_alg_len) {
466 SILC_LOG_DEBUG(("HMAC not defined in payload"));
467 silc_free(payload->ke_grp_list);
468 silc_free(payload->pkcs_alg_list);
469 silc_free(payload->enc_alg_list);
470 silc_free(payload->hash_alg_list);
472 return SILC_SKE_STATUS_BAD_PAYLOAD;
475 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
478 payload->hmac_alg_len = rp->hmac_alg_len;
479 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
482 /* Get supported compression algorithms */
483 cp = rp->comp_alg_list;
484 if (cp && strchr(cp, ',')) {
488 len = strcspn(cp, ",");
489 item = silc_calloc(len + 1, sizeof(char));
491 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
494 memcpy(item, cp, len);
496 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
499 if (!strcmp(item, "none")) {
500 SILC_LOG_DEBUG(("Found Compression `%s'", item));
501 payload->comp_alg_len = len;
502 payload->comp_alg_list = item;
506 if (silc_hmac_is_supported(item) == TRUE) {
507 SILC_LOG_DEBUG(("Found Compression `%s'", item));
508 payload->comp_alg_len = len;
509 payload->comp_alg_list = item;
525 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
526 2 + payload->version_len +
527 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
528 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
529 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
531 return SILC_SKE_STATUS_OK;
534 /* Creates random number such that 1 < rnd < n and at most length
535 of len bits. The rnd sent as argument must be initialized. */
537 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
541 SilcSKEStatus status = SILC_SKE_STATUS_OK;
542 unsigned char *string;
546 return SILC_SKE_STATUS_ERROR;
548 SILC_LOG_DEBUG(("Creating random number"));
552 /* Get the random number as string */
553 string = silc_rng_get_rn_data(ske->rng, l);
555 return SILC_SKE_STATUS_OUT_OF_MEMORY;
557 /* Decode the string into a MP integer */
558 silc_mp_bin2mp(string, l, rnd);
559 silc_mp_mod_2exp(rnd, rnd, len);
562 if (silc_mp_cmp_ui(rnd, 1) < 0)
563 status = SILC_SKE_STATUS_ERROR;
564 if (silc_mp_cmp(rnd, n) >= 0)
565 status = SILC_SKE_STATUS_ERROR;
567 memset(string, 'F', l);
573 /* Creates a hash value HASH as defined in the SKE protocol. If the
574 `initiator' is TRUE then this function is used to create the HASH_i
575 hash value defined in the protocol. If it is FALSE then this is used
576 to create the HASH value defined by the protocol. */
578 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
579 unsigned char *return_hash,
580 SilcUInt32 *return_hash_len,
583 SilcSKEStatus status = SILC_SKE_STATUS_OK;
585 unsigned char *e, *f, *KEY;
586 SilcUInt32 e_len, f_len, KEY_len;
589 SILC_LOG_DEBUG(("Start"));
591 if (initiator == FALSE) {
592 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
593 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
594 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
596 /* Format the buffer used to compute the hash value */
597 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
598 ske->ke2_payload->pk_len +
599 ske->ke1_payload->pk_len +
600 e_len + f_len + KEY_len);
602 return SILC_SKE_STATUS_OUT_OF_MEMORY;
604 /* Initiator is not required to send its public key */
605 if (!ske->ke1_payload->pk_data) {
607 silc_buffer_format(buf,
608 SILC_STR_UI_XNSTRING(
609 ske->start_payload_copy->data,
610 silc_buffer_len(ske->start_payload_copy)),
611 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
612 ske->ke2_payload->pk_len),
613 SILC_STR_UI_XNSTRING(e, e_len),
614 SILC_STR_UI_XNSTRING(f, f_len),
615 SILC_STR_UI_XNSTRING(KEY, KEY_len),
619 silc_buffer_format(buf,
620 SILC_STR_UI_XNSTRING(
621 ske->start_payload_copy->data,
622 silc_buffer_len(ske->start_payload_copy)),
623 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
624 ske->ke2_payload->pk_len),
625 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
626 ske->ke1_payload->pk_len),
627 SILC_STR_UI_XNSTRING(e, e_len),
628 SILC_STR_UI_XNSTRING(f, f_len),
629 SILC_STR_UI_XNSTRING(KEY, KEY_len),
633 silc_buffer_free(buf);
636 memset(KEY, 0, KEY_len);
640 return SILC_SKE_STATUS_ERROR;
645 memset(KEY, 0, KEY_len);
650 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
652 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
653 ske->ke1_payload->pk_len + e_len);
655 return SILC_SKE_STATUS_OUT_OF_MEMORY;
657 /* Format the buffer used to compute the hash value */
659 silc_buffer_format(buf,
660 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
661 silc_buffer_len(ske->start_payload_copy)),
662 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
663 ske->ke1_payload->pk_len),
664 SILC_STR_UI_XNSTRING(e, e_len),
667 silc_buffer_free(buf);
670 return SILC_SKE_STATUS_ERROR;
673 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
680 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
682 *return_hash_len = silc_hash_len(ske->prop->hash);
684 if (initiator == FALSE) {
685 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
687 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
690 silc_buffer_free(buf);
695 /* Assembles security properties */
697 static SilcSKEStartPayload
698 silc_ske_assemble_security_properties(SilcSKE ske,
699 SilcSKESecurityPropertyFlag flags,
702 SilcSKEStartPayload rp;
705 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
707 rp = silc_calloc(1, sizeof(*rp));
710 rp->flags = (unsigned char)flags;
712 /* Set random cookie */
713 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
714 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
715 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
716 rp->cookie_len = SILC_SKE_COOKIE_LEN;
718 /* In case IV included flag and session port is set the first 16-bits of
719 cookie will include our session port. */
720 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
721 SILC_PUT16_MSB(ske->session_port, rp->cookie);
724 rp->version = strdup(version);
725 rp->version_len = strlen(version);
727 /* Get supported Key Exhange groups */
728 rp->ke_grp_list = silc_ske_get_supported_groups();
729 rp->ke_grp_len = strlen(rp->ke_grp_list);
731 /* Get supported PKCS algorithms */
732 rp->pkcs_alg_list = silc_pkcs_get_supported();
733 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
735 /* Get supported encryption algorithms */
736 rp->enc_alg_list = silc_cipher_get_supported();
737 rp->enc_alg_len = strlen(rp->enc_alg_list);
739 /* Get supported hash algorithms */
740 rp->hash_alg_list = silc_hash_get_supported();
741 rp->hash_alg_len = strlen(rp->hash_alg_list);
743 /* Get supported HMACs */
744 rp->hmac_alg_list = silc_hmac_get_supported();
745 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
748 /* Get supported compression algorithms */
749 rp->comp_alg_list = strdup("none");
750 rp->comp_alg_len = strlen("none");
752 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
753 2 + rp->version_len +
754 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
755 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
756 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
762 /******************************* Protocol API *******************************/
764 /* Allocates new SKE object. */
766 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
767 SilcSKR repository, SilcPublicKey public_key,
768 SilcPrivateKey private_key, void *context)
772 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
774 if (!rng || !schedule)
777 ske = silc_calloc(1, sizeof(*ske));
780 ske->status = SILC_SKE_STATUS_OK;
782 ske->repository = repository;
783 ske->user_data = context;
784 ske->schedule = schedule;
785 ske->public_key = public_key;
786 ske->private_key = private_key;
791 /* Free's SKE object. */
793 void silc_ske_free(SilcSKE ske)
795 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
798 /* Free start payload */
799 if (ske->start_payload)
800 silc_ske_payload_start_free(ske->start_payload);
802 /* Free KE payload */
803 if (ske->ke1_payload)
804 silc_ske_payload_ke_free(ske->ke1_payload);
805 if (ske->ke2_payload)
806 silc_ske_payload_ke_free(ske->ke2_payload);
807 silc_free(ske->remote_version);
811 if (ske->prop->group)
812 silc_ske_group_free(ske->prop->group);
813 if (ske->prop->cipher)
814 silc_cipher_free(ske->prop->cipher);
816 silc_hash_free(ske->prop->hash);
818 silc_hmac_free(ske->prop->hmac);
819 silc_free(ske->prop);
821 if (ske->start_payload_copy)
822 silc_buffer_free(ske->start_payload_copy);
824 silc_mp_uninit(ske->x);
828 silc_mp_uninit(ske->KEY);
831 silc_free(ske->hash);
832 silc_free(ske->callbacks);
834 memset(ske, 'F', sizeof(*ske));
839 /* Return user context */
841 void *silc_ske_get_context(SilcSKE ske)
843 return ske->user_data;
846 /* Sets protocol callbacks */
848 void silc_ske_set_callbacks(SilcSKE ske,
849 SilcSKEVerifyCb verify_key,
850 SilcSKECompletionCb completed,
854 silc_free(ske->callbacks);
855 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
858 ske->callbacks->verify_key = verify_key;
859 ske->callbacks->completed = completed;
860 ske->callbacks->context = context;
864 /******************************** Initiator *********************************/
866 /* Initiator state machine */
867 SILC_FSM_STATE(silc_ske_st_initiator_start);
868 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
869 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
870 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
871 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
872 SILC_FSM_STATE(silc_ske_st_initiator_end);
873 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
874 SILC_FSM_STATE(silc_ske_st_initiator_error);
876 /* Start protocol. Send our proposal */
878 SILC_FSM_STATE(silc_ske_st_initiator_start)
880 SilcSKE ske = fsm_context;
881 SilcBuffer payload_buf;
884 SILC_LOG_DEBUG(("Start"));
888 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
889 return SILC_FSM_CONTINUE;
892 /* Encode the payload */
893 status = silc_ske_payload_start_encode(ske, ske->start_payload,
895 if (status != SILC_SKE_STATUS_OK) {
896 /** Error encoding Start Payload */
897 ske->status = status;
898 silc_fsm_next(fsm, silc_ske_st_initiator_error);
899 return SILC_FSM_CONTINUE;
902 /* Save the the payload buffer for future use. It is later used to
903 compute the HASH value. */
904 ske->start_payload_copy = payload_buf;
906 /* Send the packet */
909 /** Wait for responder proposal */
910 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
911 silc_fsm_next(ske, silc_ske_st_initiator_phase1);
912 return SILC_FSM_WAIT;
915 /* Phase-1. Receives responder's proposal */
917 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
919 SilcSKE ske = fsm_context;
920 SilcSKEStatus status;
921 SilcSKEStartPayload payload;
922 SilcSKESecurityProperties prop;
923 SilcSKEDiffieHellmanGroup group;
924 SilcBuffer packet_buf = &ske->packet->buffer;
927 SILC_LOG_DEBUG(("Start"));
931 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
932 return SILC_FSM_CONTINUE;
935 /* Decode the payload */
936 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
937 if (status != SILC_SKE_STATUS_OK) {
938 /** Error decoding Start Payload */
939 ske->status = status;
940 silc_fsm_next(fsm, silc_ske_st_initiator_error);
941 return SILC_FSM_CONTINUE;
944 /* Check that the cookie is returned unmodified. In case IV included
945 flag and session port has been set, the first two bytes of cookie
946 are the session port and we ignore them in this check. */
947 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
949 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
950 SILC_SKE_COOKIE_LEN - coff)) {
951 /** Invalid cookie */
952 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
953 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
954 silc_fsm_next(fsm, silc_ske_st_initiator_error);
955 return SILC_FSM_CONTINUE;
958 /* Check version string */
959 ske->remote_version = silc_memdup(payload->version, payload->version_len);
960 status = silc_ske_check_version(ske);
961 if (status != SILC_SKE_STATUS_OK) {
962 /** Version mismatch */
963 ske->status = status;
964 silc_fsm_next(fsm, silc_ske_st_initiator_error);
965 return SILC_FSM_CONTINUE;
968 /* Free our KE Start Payload context, we don't need it anymore. */
969 silc_ske_payload_start_free(ske->start_payload);
970 ske->start_payload = NULL;
972 /* Take the selected security properties into use while doing
973 the key exchange. This is used only while doing the key
975 ske->prop = prop = silc_calloc(1, sizeof(*prop));
978 prop->flags = payload->flags;
979 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
980 if (status != SILC_SKE_STATUS_OK)
985 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
986 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
989 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
990 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
993 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
994 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
997 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
998 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1002 /* Save remote's KE Start Payload */
1003 ske->start_payload = payload;
1005 /** Send KE Payload */
1006 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1007 return SILC_FSM_CONTINUE;
1011 silc_ske_payload_start_free(payload);
1013 silc_ske_group_free(group);
1016 silc_cipher_free(prop->cipher);
1018 silc_hash_free(prop->hash);
1020 silc_hmac_free(prop->hmac);
1024 if (status == SILC_SKE_STATUS_OK)
1025 status = SILC_SKE_STATUS_ERROR;
1028 ske->status = status;
1029 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1030 return SILC_FSM_CONTINUE;
1033 /* Phase-2. Send KE payload */
1035 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1037 SilcSKE ske = fsm_context;
1038 SilcSKEStatus status;
1039 SilcBuffer payload_buf;
1041 SilcSKEKEPayload payload;
1044 SILC_LOG_DEBUG(("Start"));
1046 /* Create the random number x, 1 < x < q. */
1047 x = silc_calloc(1, sizeof(*x));
1049 /** Out of memory */
1050 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1051 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1052 return SILC_FSM_CONTINUE;
1056 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1057 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1059 if (status != SILC_SKE_STATUS_OK) {
1060 /** Error generating random number */
1063 ske->status = status;
1064 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1065 return SILC_FSM_CONTINUE;
1068 /* Encode the result to Key Exchange Payload. */
1070 payload = silc_calloc(1, sizeof(*payload));
1072 /** Out of memory */
1075 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1076 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1077 return SILC_FSM_CONTINUE;
1079 ske->ke1_payload = payload;
1081 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1083 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1084 silc_mp_init(&payload->x);
1085 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1086 &ske->prop->group->group);
1088 /* Get public key */
1089 if (ske->public_key) {
1090 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1091 if (!payload->pk_data) {
1092 /** Error encoding public key */
1095 silc_mp_uninit(&payload->x);
1097 ske->ke1_payload = NULL;
1098 ske->status = SILC_SKE_STATUS_ERROR;
1099 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1100 return SILC_FSM_CONTINUE;
1102 payload->pk_len = pk_len;
1104 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1106 /* Compute signature data if we are doing mutual authentication */
1107 if (ske->private_key &&
1108 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1109 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1110 SilcUInt32 hash_len, sign_len;
1112 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1113 SILC_LOG_DEBUG(("Computing HASH_i value"));
1115 /* Compute the hash value */
1116 memset(hash, 0, sizeof(hash));
1117 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1119 SILC_LOG_DEBUG(("Signing HASH_i value"));
1121 /* Sign the hash value */
1122 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1123 sizeof(sign) - 1, &sign_len, NULL)) {
1124 /** Error computing signature */
1127 silc_mp_uninit(&payload->x);
1128 silc_free(payload->pk_data);
1130 ske->ke1_payload = NULL;
1131 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1132 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1133 return SILC_FSM_CONTINUE;
1135 payload->sign_data = silc_memdup(sign, sign_len);
1136 payload->sign_len = sign_len;
1137 memset(sign, 0, sizeof(sign));
1140 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1141 if (status != SILC_SKE_STATUS_OK) {
1142 /** Error encoding KE payload */
1145 silc_mp_uninit(&payload->x);
1146 silc_free(payload->pk_data);
1147 silc_free(payload->sign_data);
1149 ske->ke1_payload = NULL;
1150 ske->status = status;
1151 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1152 return SILC_FSM_CONTINUE;
1157 /* Send the packet. */
1160 silc_buffer_free(payload_buf);
1162 /** Waiting responder's KE payload */
1163 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1164 return SILC_FSM_WAIT;
1167 /* Phase-3. Process responder's KE payload */
1169 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1171 SilcSKE ske = fsm_context;
1172 SilcSKEStatus status;
1173 SilcSKEKEPayload payload;
1175 SilcBuffer packet_buf = &ske->packet->buffer;
1177 SILC_LOG_DEBUG(("Start"));
1181 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1182 return SILC_FSM_CONTINUE;
1185 /* Decode the payload */
1186 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1187 if (status != SILC_SKE_STATUS_OK) {
1188 /** Error decoding KE payload */
1189 ske->status = status;
1190 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1191 return SILC_FSM_CONTINUE;
1193 ske->ke2_payload = payload;
1195 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1196 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1197 "even though we require it"));
1198 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1202 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1204 /* Compute the shared secret key */
1205 KEY = silc_calloc(1, sizeof(*KEY));
1207 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1210 /* Decode the remote's public key */
1211 if (payload->pk_data &&
1212 !silc_pkcs_public_key_alloc(payload->pk_type,
1213 payload->pk_data, payload->pk_len,
1214 &ske->prop->public_key)) {
1215 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1216 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1220 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1222 SILC_LOG_DEBUG(("Verifying public key"));
1224 /** Waiting public key verification */
1225 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1227 /* If repository is provided, verify the key from there. */
1228 if (ske->repository) {
1231 find = silc_skr_find_alloc();
1233 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1236 silc_skr_find_set_pkcs_type(find,
1237 silc_pkcs_get_type(ske->prop->public_key));
1238 silc_skr_find_set_public_key(find, ske->prop->public_key);
1240 /* Find key from repository */
1241 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1242 silc_ske_skr_callback, ske));
1244 /* Verify from application */
1245 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1246 ske->callbacks->context,
1247 silc_ske_pk_verified, NULL));
1252 /** Process key material */
1253 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1254 return SILC_FSM_CONTINUE;
1257 silc_ske_payload_ke_free(payload);
1258 ske->ke2_payload = NULL;
1260 silc_mp_uninit(ske->KEY);
1261 silc_free(ske->KEY);
1264 if (status == SILC_SKE_STATUS_OK)
1265 return SILC_SKE_STATUS_ERROR;
1268 ske->status = status;
1269 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1270 return SILC_FSM_CONTINUE;
1273 /* Process key material */
1275 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1277 SilcSKE ske = fsm_context;
1278 SilcSKEStatus status;
1279 SilcSKEKEPayload payload;
1280 unsigned char hash[SILC_HASH_MAXLEN];
1281 SilcUInt32 hash_len;
1282 int key_len, block_len;
1286 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1287 return SILC_FSM_CONTINUE;
1290 /* Check result of public key verification */
1291 if (ske->status != SILC_SKE_STATUS_OK) {
1292 /** Public key not verified */
1293 SILC_LOG_DEBUG(("Public key verification failed"));
1294 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1295 return SILC_FSM_CONTINUE;
1298 payload = ske->ke2_payload;
1300 if (ske->prop->public_key) {
1301 SILC_LOG_DEBUG(("Public key is authentic"));
1303 /* Compute the hash value */
1304 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1305 if (status != SILC_SKE_STATUS_OK)
1308 ske->hash = silc_memdup(hash, hash_len);
1309 ske->hash_len = hash_len;
1311 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1313 /* Verify signature */
1314 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1315 payload->sign_len, hash, hash_len, NULL)) {
1316 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1317 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1321 SILC_LOG_DEBUG(("Signature is Ok"));
1323 memset(hash, 'F', hash_len);
1326 ske->status = SILC_SKE_STATUS_OK;
1328 /* Process key material */
1329 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1330 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1331 hash_len = silc_hash_len(ske->prop->hash);
1332 ske->keymat = silc_ske_process_key_material(ske, block_len,
1335 SILC_LOG_ERROR(("Error processing key material"));
1336 status = SILC_SKE_STATUS_ERROR;
1340 /* Send SUCCESS packet */
1343 /** Waiting completion */
1344 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1345 return SILC_FSM_WAIT;
1348 memset(hash, 'F', sizeof(hash));
1349 silc_ske_payload_ke_free(payload);
1350 ske->ke2_payload = NULL;
1352 silc_mp_uninit(ske->KEY);
1353 silc_free(ske->KEY);
1357 memset(ske->hash, 'F', hash_len);
1358 silc_free(ske->hash);
1362 if (status == SILC_SKE_STATUS_OK)
1363 status = SILC_SKE_STATUS_ERROR;
1366 ske->status = status;
1367 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1368 return SILC_FSM_CONTINUE;
1371 /* Protocol completed */
1373 SILC_FSM_STATE(silc_ske_st_initiator_end)
1375 SilcSKE ske = fsm_context;
1379 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1380 return SILC_FSM_CONTINUE;
1383 /* Call the completion callback */
1384 if (ske->callbacks->completed)
1385 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1387 return SILC_FSM_FINISH;
1390 /* Aborted by application */
1392 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1395 return SILC_FSM_FINISH;
1398 /* Error occurred */
1400 SILC_FSM_STATE(silc_ske_st_initiator_error)
1403 return SILC_FSM_FINISH;
1407 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1408 void *destructor_context)
1413 /* Starts the protocol as initiator */
1416 silc_ske_initiator(SilcSKE ske,
1417 SilcPacketStream stream,
1418 SilcSKEParams params,
1419 SilcSKEStartPayload start_payload)
1421 SILC_LOG_DEBUG(("Start SKE as initiator"));
1423 if (!ske || !stream || !params || !params->version)
1426 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1429 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1433 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1434 ske->session_port = params->session_port;
1436 /* Generate security properties if not provided */
1437 if (!start_payload) {
1438 start_payload = silc_ske_assemble_security_properties(ske,
1445 ske->start_payload = start_payload;
1447 /* Link to packet stream to get key exchange packets */
1448 ske->stream = stream;
1449 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1450 SILC_PACKET_KEY_EXCHANGE,
1451 SILC_PACKET_KEY_EXCHANGE_2,
1452 SILC_PACKET_SUCCESS,
1453 SILC_PACKET_FAILURE, -1);
1455 /* Start SKE as initiator */
1456 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1462 /******************************** Responder *********************************/
1464 SILC_FSM_STATE(silc_ske_st_responder_start);
1465 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1466 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1467 SILC_FSM_STATE(silc_ske_st_responder_phase3);
1468 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1469 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1470 SILC_FSM_STATE(silc_ske_st_responder_end);
1471 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1472 SILC_FSM_STATE(silc_ske_st_responder_failure);
1473 SILC_FSM_STATE(silc_ske_st_responder_error);
1475 /* Start protocol as responder. Wait initiator's start payload */
1477 SILC_FSM_STATE(silc_ske_st_responder_start)
1479 SilcSKE ske = fsm_context;
1481 SILC_LOG_DEBUG(("Start"));
1485 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1486 return SILC_FSM_CONTINUE;
1492 /** Wait for initiator */
1493 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1494 return SILC_FSM_WAIT;
1497 /* Decode initiator's start payload */
1499 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1501 SilcSKE ske = fsm_context;
1502 SilcSKEStatus status;
1503 SilcSKEStartPayload remote_payload = NULL, payload = NULL;
1504 SilcBuffer packet_buf = &ske->packet->buffer;
1506 SILC_LOG_DEBUG(("Start"));
1510 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1511 return SILC_FSM_CONTINUE;
1514 /* See if received failure from remote */
1515 if (ske->packet->type == SILC_PACKET_FAILURE) {
1516 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1517 return SILC_FSM_CONTINUE;
1520 /* Decode the payload */
1521 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1522 if (status != SILC_SKE_STATUS_OK) {
1523 /** Error decoding Start Payload */
1524 silc_packet_free(ske->packet);
1525 ske->status = status;
1526 silc_fsm_next(fsm, silc_ske_st_responder_error);
1527 return SILC_FSM_CONTINUE;
1530 /* Take a copy of the payload buffer for future use. It is used to
1531 compute the HASH value. */
1532 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1534 silc_packet_free(ske->packet);
1536 /* Force the mutual authentication flag if we want to do it. */
1537 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1538 SILC_LOG_DEBUG(("Force mutual authentication"));
1539 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1542 /* Force PFS flag if we require it */
1543 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1544 SILC_LOG_DEBUG(("Force PFS"));
1545 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1548 /* Disable IV Included flag if requested */
1549 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1550 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1551 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1552 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1555 /* Parse and select the security properties from the payload */
1556 payload = silc_calloc(1, sizeof(*payload));
1557 status = silc_ske_select_security_properties(ske, payload, remote_payload);
1558 if (status != SILC_SKE_STATUS_OK) {
1559 /** Error selecting proposal */
1561 silc_ske_payload_start_free(remote_payload);
1563 ske->status = status;
1564 silc_fsm_next(fsm, silc_ske_st_responder_error);
1565 return SILC_FSM_CONTINUE;
1568 ske->start_payload = payload;
1570 silc_ske_payload_start_free(remote_payload);
1572 /** Send proposal to initiator */
1573 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1574 return SILC_FSM_CONTINUE;
1577 /* Phase-2. Send Start Payload */
1579 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1581 SilcSKE ske = fsm_context;
1582 SilcSKEStatus status;
1583 SilcBuffer payload_buf;
1584 SilcSKESecurityProperties prop;
1585 SilcSKEDiffieHellmanGroup group = NULL;
1587 SILC_LOG_DEBUG(("Start"));
1589 /* Allocate security properties from the payload. These are allocated
1590 only for this negotiation and will be free'd after KE is over. */
1591 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1593 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1596 prop->flags = ske->start_payload->flags;
1597 status = silc_ske_group_get_by_name(ske->start_payload->ke_grp_list,
1599 if (status != SILC_SKE_STATUS_OK)
1602 prop->group = group;
1604 /* XXX these shouldn't be allocated before we know the remote's
1605 public key type. It's unnecessary to allocate these because the
1606 select_security_properties has succeeded already. */
1607 if (!silc_pkcs_find_algorithm(ske->start_payload->pkcs_alg_list, NULL)) {
1608 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1611 if (silc_cipher_alloc(ske->start_payload->enc_alg_list,
1612 &prop->cipher) == FALSE) {
1613 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1616 if (silc_hash_alloc(ske->start_payload->hash_alg_list,
1617 &prop->hash) == FALSE) {
1618 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1621 if (silc_hmac_alloc(ske->start_payload->hmac_alg_list, NULL,
1622 &prop->hmac) == FALSE) {
1623 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1627 /* Encode the payload */
1628 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1630 if (status != SILC_SKE_STATUS_OK)
1633 /* Send the packet. */
1634 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1635 payload_buf->data, silc_buffer_len(payload_buf)))
1638 silc_buffer_free(payload_buf);
1640 /** Waiting initiator's KE payload */
1641 silc_fsm_next(fsm, silc_ske_st_responder_phase3);
1642 return SILC_FSM_WAIT;
1646 silc_ske_group_free(group);
1649 silc_cipher_free(prop->cipher);
1651 silc_hash_free(prop->hash);
1653 silc_hmac_free(prop->hmac);
1657 if (status == SILC_SKE_STATUS_OK)
1658 status = SILC_SKE_STATUS_ERROR;
1661 ske->status = status;
1662 silc_fsm_next(fsm, silc_ske_st_responder_error);
1663 return SILC_FSM_CONTINUE;
1666 /* Phase-3. Decode initiator's KE payload */
1668 SILC_FSM_STATE(silc_ske_st_responder_phase3)
1670 SilcSKE ske = fsm_context;
1671 SilcSKEStatus status;
1672 SilcSKEKEPayload recv_payload;
1673 SilcBuffer packet_buf = &ske->packet->buffer;
1675 SILC_LOG_DEBUG(("Start"));
1679 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1680 return SILC_FSM_CONTINUE;
1683 /* See if received failure from remote */
1684 if (ske->packet->type == SILC_PACKET_FAILURE) {
1685 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1686 return SILC_FSM_CONTINUE;
1689 /* Decode Key Exchange Payload */
1690 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1691 if (status != SILC_SKE_STATUS_OK) {
1692 /** Error decoding KE payload */
1693 silc_packet_free(ske->packet);
1694 ske->status = status;
1695 silc_fsm_next(fsm, silc_ske_st_responder_error);
1696 return SILC_FSM_CONTINUE;
1699 ske->ke1_payload = recv_payload;
1701 silc_packet_free(ske->packet);
1703 /* Verify the received public key and verify the signature if we are
1704 doing mutual authentication. */
1705 if (ske->start_payload &&
1706 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1708 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1710 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1712 /** Public key not provided */
1713 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1714 "certificate), even though we require it"));
1715 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1716 silc_fsm_next(fsm, silc_ske_st_responder_error);
1717 return SILC_FSM_CONTINUE;
1720 /* Decode the remote's public key */
1721 if (recv_payload->pk_data &&
1722 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1723 recv_payload->pk_data,
1724 recv_payload->pk_len,
1725 &ske->prop->public_key)) {
1726 /** Error decoding public key */
1727 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1728 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1729 silc_fsm_next(fsm, silc_ske_st_responder_error);
1730 return SILC_FSM_CONTINUE;
1733 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1735 SILC_LOG_DEBUG(("Verifying public key"));
1737 /** Waiting public key verification */
1738 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1740 /* If repository is provided, verify the key from there. */
1741 if (ske->repository) {
1744 find = silc_skr_find_alloc();
1746 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1747 silc_fsm_next(fsm, silc_ske_st_responder_error);
1748 return SILC_FSM_CONTINUE;
1750 silc_skr_find_set_pkcs_type(find,
1751 silc_pkcs_get_type(ske->prop->public_key));
1752 silc_skr_find_set_public_key(find, ske->prop->public_key);
1754 /* Find key from repository */
1755 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1756 silc_ske_skr_callback, ske));
1758 /* Verify from application */
1759 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1760 ske->callbacks->context,
1761 silc_ske_pk_verified, NULL));
1767 /** Generate KE2 payload */
1768 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1769 return SILC_FSM_CONTINUE;
1772 /* Phase-4. Generate KE2 payload */
1774 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1776 SilcSKE ske = fsm_context;
1777 SilcSKEStatus status;
1778 SilcSKEKEPayload recv_payload, send_payload;
1783 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1784 return SILC_FSM_CONTINUE;
1787 /* Check result of public key verification */
1788 if (ske->status != SILC_SKE_STATUS_OK) {
1789 /** Public key not verified */
1790 SILC_LOG_DEBUG(("Public key verification failed"));
1791 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1792 return SILC_FSM_CONTINUE;
1795 recv_payload = ske->ke1_payload;
1797 /* The public key verification was performed only if the Mutual
1798 Authentication flag is set. */
1799 if (ske->start_payload &&
1800 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1801 unsigned char hash[SILC_HASH_MAXLEN];
1802 SilcUInt32 hash_len;
1804 SILC_LOG_DEBUG(("Public key is authentic"));
1806 /* Compute the hash value */
1807 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1808 if (status != SILC_SKE_STATUS_OK) {
1809 /** Error computing hash */
1810 ske->status = status;
1811 silc_fsm_next(fsm, silc_ske_st_responder_error);
1812 return SILC_FSM_CONTINUE;
1815 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1817 /* Verify signature */
1818 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
1819 recv_payload->sign_len, hash, hash_len, NULL)) {
1820 /** Incorrect signature */
1821 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1822 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1823 silc_fsm_next(fsm, silc_ske_st_responder_error);
1824 return SILC_FSM_CONTINUE;
1827 SILC_LOG_DEBUG(("Signature is Ok"));
1829 memset(hash, 'F', hash_len);
1832 /* Create the random number x, 1 < x < q. */
1833 x = silc_calloc(1, sizeof(*x));
1836 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1837 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1839 if (status != SILC_SKE_STATUS_OK) {
1840 /** Error generating random number */
1843 ske->status = status;
1844 silc_fsm_next(fsm, silc_ske_st_responder_error);
1845 return SILC_FSM_CONTINUE;
1848 /* Save the results for later processing */
1849 send_payload = silc_calloc(1, sizeof(*send_payload));
1851 ske->ke2_payload = send_payload;
1853 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1855 /* Do the Diffie Hellman computation, f = g ^ x mod p */
1856 silc_mp_init(&send_payload->x);
1857 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1858 &ske->prop->group->group);
1860 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1862 /* Compute the shared secret key */
1863 KEY = silc_calloc(1, sizeof(*KEY));
1865 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1866 &ske->prop->group->group);
1869 /** Send KE2 payload */
1870 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1871 return SILC_FSM_CONTINUE;
1874 /* Phase-5. Send KE2 payload */
1876 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1878 SilcSKE ske = fsm_context;
1879 SilcSKEStatus status;
1880 SilcBuffer payload_buf;
1881 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1882 SilcUInt32 hash_len, sign_len, pk_len;
1884 SILC_LOG_DEBUG(("Start"));
1886 if (ske->public_key && ske->private_key) {
1887 SILC_LOG_DEBUG(("Getting public key"));
1889 /* Get the public key */
1890 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1892 /** Error encoding public key */
1893 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1894 silc_fsm_next(fsm, silc_ske_st_responder_error);
1895 return SILC_FSM_CONTINUE;
1897 ske->ke2_payload->pk_data = pk;
1898 ske->ke2_payload->pk_len = pk_len;
1900 SILC_LOG_DEBUG(("Computing HASH value"));
1902 /* Compute the hash value */
1903 memset(hash, 0, sizeof(hash));
1904 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1905 if (status != SILC_SKE_STATUS_OK) {
1906 /** Error computing hash */
1907 ske->status = status;
1908 silc_fsm_next(fsm, silc_ske_st_responder_error);
1909 return SILC_FSM_CONTINUE;
1912 ske->hash = silc_memdup(hash, hash_len);
1913 ske->hash_len = hash_len;
1915 SILC_LOG_DEBUG(("Signing HASH value"));
1917 /* Sign the hash value */
1918 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1919 sizeof(sign) - 1, &sign_len, NULL)) {
1920 /** Error computing signature */
1921 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1922 silc_fsm_next(fsm, silc_ske_st_responder_error);
1923 return SILC_FSM_CONTINUE;
1925 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
1926 ske->ke2_payload->sign_len = sign_len;
1927 memset(sign, 0, sizeof(sign));
1929 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
1931 /* Encode the Key Exchange Payload */
1932 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
1934 if (status != SILC_SKE_STATUS_OK) {
1935 /** Error encoding KE payload */
1936 ske->status = status;
1937 silc_fsm_next(fsm, silc_ske_st_responder_error);
1938 return SILC_FSM_CONTINUE;
1941 /* Send the packet. */
1942 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
1943 payload_buf->data, silc_buffer_len(payload_buf))) {
1944 ske->status = SILC_SKE_STATUS_ERROR;
1945 silc_fsm_next(fsm, silc_ske_st_responder_error);
1946 return SILC_FSM_CONTINUE;
1949 silc_buffer_free(payload_buf);
1951 /** Waiting completion */
1952 silc_fsm_next(fsm, silc_ske_st_responder_end);
1953 return SILC_FSM_WAIT;
1956 /* Protocol completed */
1958 SILC_FSM_STATE(silc_ske_st_responder_end)
1960 SilcSKE ske = fsm_context;
1961 unsigned char tmp[4];
1962 SilcUInt32 hash_len, key_len, block_len;
1966 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1967 return SILC_FSM_CONTINUE;
1970 /* Check the result of the protocol */
1971 if (ske->packet->type == SILC_PACKET_FAILURE) {
1972 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1973 return SILC_FSM_CONTINUE;
1975 silc_packet_free(ske->packet);
1977 /* Process key material */
1978 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1979 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1980 hash_len = silc_hash_len(ske->prop->hash);
1981 ske->keymat = silc_ske_process_key_material(ske, block_len,
1984 /** Error processing key material */
1985 ske->status = SILC_SKE_STATUS_ERROR;
1986 silc_fsm_next(fsm, silc_ske_st_responder_error);
1987 return SILC_FSM_CONTINUE;
1990 /* Send SUCCESS packet */
1991 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
1992 silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
1994 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1996 /* Call the completion callback */
1997 if (ske->callbacks->completed)
1998 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1999 ske->rekey, ske->callbacks->context);
2001 return SILC_FSM_FINISH;
2004 /* Aborted by application */
2006 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2008 SilcSKE ske = fsm_context;
2009 unsigned char tmp[4];
2011 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2013 /* Send FAILURE packet */
2014 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2015 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2017 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2019 return SILC_FSM_FINISH;
2022 /* Failure received from remote */
2024 SILC_FSM_STATE(silc_ske_st_responder_failure)
2026 SilcSKE ske = fsm_context;
2027 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2029 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2031 if (silc_buffer_len(&ske->packet->buffer) == 4)
2032 SILC_GET32_MSB(error, ske->packet->buffer.data);
2033 ske->status = error;
2035 /* Call the completion callback */
2036 if (ske->callbacks->completed)
2037 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
2038 ske->callbacks->context);
2040 silc_packet_free(ske->packet);
2041 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2043 return SILC_FSM_FINISH;
2046 /* Error occurred */
2048 SILC_FSM_STATE(silc_ske_st_responder_error)
2050 SilcSKE ske = fsm_context;
2051 unsigned char tmp[4];
2053 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2054 ske->status, silc_ske_map_status(ske->status)));
2056 /* Send FAILURE packet */
2057 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2058 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2059 SILC_PUT32_MSB(ske->status, tmp);
2060 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2062 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2064 return SILC_FSM_FINISH;
2068 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
2069 void *destructor_context)
2074 /* Starts the protocol as responder. */
2077 silc_ske_responder(SilcSKE ske,
2078 SilcPacketStream stream,
2079 SilcSKEParams params)
2081 SILC_LOG_DEBUG(("Start SKE as responder"));
2083 if (!ske || !stream || !params || !params->version) {
2087 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2090 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2094 ske->responder = TRUE;
2095 ske->flags = params->flags;
2096 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2097 ske->session_port = params->session_port;
2098 ske->version = strdup(params->version);
2102 /* Link to packet stream to get key exchange packets */
2103 ske->stream = stream;
2104 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2105 SILC_PACKET_KEY_EXCHANGE,
2106 SILC_PACKET_KEY_EXCHANGE_1,
2107 SILC_PACKET_SUCCESS,
2108 SILC_PACKET_FAILURE, -1);
2110 /* Start SKE as responder */
2111 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2116 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2118 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2120 return SILC_FSM_FINISH;
2123 /* Starts rekey protocol as initiator */
2126 silc_ske_rekey_initiator(SilcSKE ske,
2127 SilcPacketStream stream,
2128 SilcSKERekeyMaterial rekey)
2130 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2132 if (!ske || !stream || !rekey)
2135 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2138 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2143 /* Link to packet stream to get key exchange packets */
2144 ske->stream = stream;
2146 /* Start SKE rekey as initiator */
2147 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2152 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2154 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2156 return SILC_FSM_FINISH;
2159 /* Starts rekey protocol as responder */
2162 silc_ske_rekey_responder(SilcSKE ske,
2163 SilcPacketStream stream,
2164 SilcBuffer ke_payload,
2165 SilcSKERekeyMaterial rekey)
2167 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2169 if (!ske || !stream || !rekey)
2171 if (rekey->pfs && !ke_payload)
2174 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2177 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2180 // ske->packet_buf = ke_payload;
2183 /* Link to packet stream to get key exchange packets */
2184 ske->stream = stream;
2186 /* Start SKE rekey as responder */
2187 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2192 /* Processes the provided key material `data' as the SILC protocol
2193 specification defines. */
2196 silc_ske_process_key_material_data(unsigned char *data,
2197 SilcUInt32 data_len,
2198 SilcUInt32 req_iv_len,
2199 SilcUInt32 req_enc_key_len,
2200 SilcUInt32 req_hmac_key_len,
2204 unsigned char hashd[SILC_HASH_MAXLEN];
2205 SilcUInt32 hash_len = req_hmac_key_len;
2206 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2207 SilcSKEKeyMaterial key;
2209 SILC_LOG_DEBUG(("Start"));
2211 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2214 key = silc_calloc(1, sizeof(*key));
2218 buf = silc_buffer_alloc_size(1 + data_len);
2221 silc_buffer_format(buf,
2222 SILC_STR_UI_CHAR(0),
2223 SILC_STR_UI_XNSTRING(data, data_len),
2227 memset(hashd, 0, sizeof(hashd));
2229 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2230 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2231 memcpy(key->send_iv, hashd, req_iv_len);
2232 memset(hashd, 0, sizeof(hashd));
2234 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2235 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2236 memcpy(key->receive_iv, hashd, req_iv_len);
2237 key->iv_len = req_iv_len;
2239 /* Take the encryption keys. If requested key size is more than
2240 the size of hash length we will distribute more key material
2241 as protocol defines. */
2243 if (enc_key_len > hash_len) {
2245 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2246 k3[SILC_HASH_MAXLEN];
2247 unsigned char *dtmp;
2250 if (enc_key_len > (3 * hash_len))
2253 /* Take first round */
2254 memset(k1, 0, sizeof(k1));
2255 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2257 /* Take second round */
2258 dist = silc_buffer_alloc_size(data_len + hash_len);
2261 silc_buffer_format(dist,
2262 SILC_STR_UI_XNSTRING(data, data_len),
2263 SILC_STR_UI_XNSTRING(k1, hash_len),
2265 memset(k2, 0, sizeof(k2));
2266 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2268 /* Take third round */
2269 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2270 silc_buffer_pull_tail(dist, hash_len);
2271 silc_buffer_pull(dist, data_len + hash_len);
2272 silc_buffer_format(dist,
2273 SILC_STR_UI_XNSTRING(k2, hash_len),
2275 silc_buffer_push(dist, data_len + hash_len);
2276 memset(k3, 0, sizeof(k3));
2277 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2279 /* Then, save the keys */
2280 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2281 memcpy(dtmp, k1, hash_len);
2282 memcpy(dtmp + hash_len, k2, hash_len);
2283 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2285 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2286 memcpy(key->send_enc_key, dtmp, enc_key_len);
2287 key->enc_key_len = req_enc_key_len;
2289 memset(dtmp, 0, (3 * hash_len));
2290 memset(k1, 0, sizeof(k1));
2291 memset(k2, 0, sizeof(k2));
2292 memset(k3, 0, sizeof(k3));
2294 silc_buffer_clear(dist);
2295 silc_buffer_free(dist);
2297 /* Take normal hash as key */
2298 memset(hashd, 0, sizeof(hashd));
2299 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2300 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2301 memcpy(key->send_enc_key, hashd, enc_key_len);
2302 key->enc_key_len = req_enc_key_len;
2306 if (enc_key_len > hash_len) {
2308 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2309 k3[SILC_HASH_MAXLEN];
2310 unsigned char *dtmp;
2313 if (enc_key_len > (3 * hash_len))
2316 /* Take first round */
2317 memset(k1, 0, sizeof(k1));
2318 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2320 /* Take second round */
2321 dist = silc_buffer_alloc_size(data_len + hash_len);
2324 silc_buffer_format(dist,
2325 SILC_STR_UI_XNSTRING(data, data_len),
2326 SILC_STR_UI_XNSTRING(k1, hash_len),
2328 memset(k2, 0, sizeof(k2));
2329 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2331 /* Take third round */
2332 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2333 silc_buffer_pull_tail(dist, hash_len);
2334 silc_buffer_pull(dist, data_len + hash_len);
2335 silc_buffer_format(dist,
2336 SILC_STR_UI_XNSTRING(k2, hash_len),
2338 silc_buffer_push(dist, data_len + hash_len);
2339 memset(k3, 0, sizeof(k3));
2340 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2342 /* Then, save the keys */
2343 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2344 memcpy(dtmp, k1, hash_len);
2345 memcpy(dtmp + hash_len, k2, hash_len);
2346 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2348 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2349 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2350 key->enc_key_len = req_enc_key_len;
2352 memset(dtmp, 0, (3 * hash_len));
2353 memset(k1, 0, sizeof(k1));
2354 memset(k2, 0, sizeof(k2));
2355 memset(k3, 0, sizeof(k3));
2357 silc_buffer_clear(dist);
2358 silc_buffer_free(dist);
2360 /* Take normal hash as key */
2361 memset(hashd, 0, sizeof(hashd));
2362 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2363 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2364 memcpy(key->receive_enc_key, hashd, enc_key_len);
2365 key->enc_key_len = req_enc_key_len;
2368 /* Take HMAC keys */
2369 memset(hashd, 0, sizeof(hashd));
2371 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2372 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2373 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2374 memset(hashd, 0, sizeof(hashd));
2376 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2377 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2378 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2379 key->hmac_key_len = req_hmac_key_len;
2380 memset(hashd, 0, sizeof(hashd));
2382 silc_buffer_clear(buf);
2383 silc_buffer_free(buf);
2388 /* Processes negotiated key material as protocol specifies. This returns
2389 the actual keys to be used in the SILC. */
2392 silc_ske_process_key_material(SilcSKE ske,
2393 SilcUInt32 req_iv_len,
2394 SilcUInt32 req_enc_key_len,
2395 SilcUInt32 req_hmac_key_len)
2398 unsigned char *tmpbuf;
2400 SilcSKEKeyMaterial key;
2402 /* Encode KEY to binary data */
2403 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2405 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2408 silc_buffer_format(buf,
2409 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2410 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2413 /* Process the key material */
2414 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2415 req_iv_len, req_enc_key_len,
2419 memset(tmpbuf, 0, klen);
2421 silc_buffer_clear(buf);
2422 silc_buffer_free(buf);
2427 /* Free key material structure */
2429 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2435 silc_free(key->send_iv);
2436 if (key->receive_iv)
2437 silc_free(key->receive_iv);
2438 if (key->send_enc_key) {
2439 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2440 silc_free(key->send_enc_key);
2442 if (key->receive_enc_key) {
2443 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2444 silc_free(key->receive_enc_key);
2446 if (key->send_hmac_key) {
2447 memset(key->send_hmac_key, 0, key->hmac_key_len);
2448 silc_free(key->send_hmac_key);
2450 if (key->receive_hmac_key) {
2451 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2452 silc_free(key->receive_hmac_key);
2457 /* Set keys into use */
2459 SilcBool silc_ske_set_keys(SilcSKE ske,
2460 SilcSKEKeyMaterial keymat,
2461 SilcSKESecurityProperties prop,
2462 SilcCipher *ret_send_key,
2463 SilcCipher *ret_receive_key,
2464 SilcHmac *ret_hmac_send,
2465 SilcHmac *ret_hmac_receive,
2468 /* Allocate ciphers to be used in the communication */
2470 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2474 if (ret_receive_key) {
2475 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2480 /* Allocate HMACs */
2481 if (ret_hmac_send) {
2482 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2486 if (ret_hmac_receive) {
2487 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2492 /* Set key material */
2493 if (ske->responder) {
2494 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2495 keymat->enc_key_len);
2496 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2497 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2498 keymat->enc_key_len);
2499 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2500 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2501 keymat->hmac_key_len);
2502 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2503 keymat->hmac_key_len);
2505 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2506 keymat->enc_key_len);
2507 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2508 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2509 keymat->enc_key_len);
2510 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2511 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2512 keymat->hmac_key_len);
2513 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2514 keymat->hmac_key_len);
2519 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2523 SILC_LOG_INFO(("Security properties: %s %s %s %s",
2524 ret_send_key ? silc_cipher_get_name(*ret_send_key) : "??",
2525 ret_hmac_send ? silc_hmac_get_name(*ret_hmac_send) : "??",
2526 ret_hash ? silc_hash_get_name(*ret_hash) : "??",
2527 ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : ""));
2532 const char *silc_ske_status_string[] =
2536 "Unkown error occurred",
2537 "Bad payload in packet",
2538 "Unsupported group",
2539 "Unsupported cipher",
2541 "Unsupported hash function",
2543 "Unsupported public key (or certificate)",
2544 "Incorrect signature",
2545 "Bad or unsupported version",
2549 "Remote did not provide public key",
2550 "Bad reserved field in packet",
2551 "Bad payload length in packet",
2552 "Error computing signature",
2553 "System out of memory",
2558 /* Maps status to readable string and returns the string. If string is not
2559 found and empty character string ("") is returned. */
2561 const char *silc_ske_map_status(SilcSKEStatus status)
2565 for (i = 0; silc_ske_status_string[i]; i++)
2567 return silc_ske_status_string[i];
2572 /* Parses remote host's version string. */
2574 SilcBool silc_ske_parse_version(SilcSKE ske,
2575 SilcUInt32 *protocol_version,
2576 char **protocol_version_string,
2577 SilcUInt32 *software_version,
2578 char **software_version_string,
2579 char **vendor_version)
2581 return silc_parse_version_string(ske->remote_version,
2583 protocol_version_string,
2585 software_version_string,