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;
123 SilcUInt32 r_software_version = 0;
125 if (!ske->remote_version || !ske->version)
126 return SILC_SKE_STATUS_BAD_VERSION;
128 if (!silc_parse_version_string(ske->remote_version, &r_protocol_version,
129 NULL, &r_software_version, NULL, NULL))
130 return SILC_SKE_STATUS_BAD_VERSION;
132 if (!silc_parse_version_string(ske->version, &l_protocol_version,
133 NULL, NULL, NULL, NULL))
134 return SILC_SKE_STATUS_BAD_VERSION;
136 /* If remote is too new, don't connect */
137 if (l_protocol_version < r_protocol_version)
138 return SILC_SKE_STATUS_BAD_VERSION;
140 /* Backwards compatibility checks */
142 /* Old server versions requires "valid" looking Source ID in the SILC
143 packets during initial key exchange. All version before 1.1.0. */
144 if (r_software_version < 110) {
146 memset(&id, 0, sizeof(id));
148 SILC_LOG_DEBUG(("Remote is old version, add dummy Source ID to packets"));
149 silc_packet_set_ids(ske->stream, SILC_ID_CLIENT, &id, 0, NULL);
152 return SILC_SKE_STATUS_OK;
155 /* Selects the supported security properties from the initiator's Key
156 Exchange Start Payload. A responder function. Saves our reply
157 start payload to ske->start_payload. */
160 silc_ske_select_security_properties(SilcSKE ske,
161 SilcSKEStartPayload remote_payload,
162 SilcSKESecurityProperties *prop)
164 SilcSKEStatus status;
165 SilcSKEStartPayload rp, payload;
169 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
173 /* Check for mandatory fields */
174 if (!rp->ke_grp_len) {
175 SILC_LOG_DEBUG(("KE group not defined in payload"));
176 return SILC_SKE_STATUS_BAD_PAYLOAD;
178 if (!rp->pkcs_alg_len) {
179 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
180 return SILC_SKE_STATUS_BAD_PAYLOAD;
182 if (!rp->enc_alg_len) {
183 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
184 return SILC_SKE_STATUS_BAD_PAYLOAD;
186 if (!rp->hash_alg_len) {
187 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
188 return SILC_SKE_STATUS_BAD_PAYLOAD;
190 if (!rp->hmac_alg_len) {
191 SILC_LOG_DEBUG(("HMAC not defined in payload"));
192 return SILC_SKE_STATUS_BAD_PAYLOAD;
195 /* Allocate security properties */
196 *prop = silc_calloc(1, sizeof(**prop));
198 return SILC_SKE_STATUS_OUT_OF_MEMORY;
200 /* Allocate our reply start payload */
201 payload = silc_calloc(1, sizeof(*payload));
204 return SILC_SKE_STATUS_OUT_OF_MEMORY;
207 /* Check version string */
208 ske->remote_version = silc_memdup(rp->version, rp->version_len);
209 status = silc_ske_check_version(ske);
210 if (status != SILC_SKE_STATUS_OK) {
211 ske->status = status;
215 /* Flags are returned unchanged. */
216 (*prop)->flags = payload->flags = rp->flags;
218 /* Take cookie, we must return it to sender unmodified. */
219 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
220 if (!payload->cookie) {
221 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
224 payload->cookie_len = SILC_SKE_COOKIE_LEN;
225 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
227 /* In case IV included flag and session port is set the first 16-bits of
228 cookie will include our session port. */
229 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
230 /* Take remote port */
231 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
234 SILC_PUT16_MSB(ske->session_port, payload->cookie);
237 /* Put our version to our reply */
238 payload->version = strdup(ske->version);
239 if (!payload->version) {
240 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
243 payload->version_len = strlen(ske->version);
245 /* Get supported Key Exchange groups */
246 cp = rp->ke_grp_list;
247 if (cp && strchr(cp, ',')) {
251 len = strcspn(cp, ",");
252 item = silc_calloc(len + 1, sizeof(char));
254 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
257 memcpy(item, cp, len);
259 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
261 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
262 SILC_LOG_DEBUG(("Found KE group `%s'", item));
264 payload->ke_grp_len = len;
265 payload->ke_grp_list = item;
279 if (!payload->ke_grp_len && !payload->ke_grp_list) {
280 SILC_LOG_DEBUG(("Could not find supported KE group"));
282 return SILC_SKE_STATUS_UNKNOWN_GROUP;
285 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
286 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
288 payload->ke_grp_len = rp->ke_grp_len;
289 payload->ke_grp_list = strdup(rp->ke_grp_list);
292 /* Save group to security properties */
293 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
294 if (status != SILC_SKE_STATUS_OK) {
296 return SILC_SKE_STATUS_UNKNOWN_GROUP;
299 /* Get supported PKCS algorithms */
300 cp = rp->pkcs_alg_list;
301 if (cp && strchr(cp, ',')) {
305 len = strcspn(cp, ",");
306 item = silc_calloc(len + 1, sizeof(char));
308 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
311 memcpy(item, cp, len);
313 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
315 if (silc_pkcs_find_algorithm(item, NULL)) {
316 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
318 payload->pkcs_alg_len = len;
319 payload->pkcs_alg_list = item;
333 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
334 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
335 silc_free(payload->ke_grp_list);
337 return SILC_SKE_STATUS_UNKNOWN_PKCS;
340 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
341 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
343 payload->pkcs_alg_len = rp->pkcs_alg_len;
344 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
347 /* Get supported encryption algorithms */
348 cp = rp->enc_alg_list;
349 if (cp && strchr(cp, ',')) {
353 len = strcspn(cp, ",");
354 item = silc_calloc(len + 1, sizeof(char));
356 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
359 memcpy(item, cp, len);
361 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
363 if (silc_cipher_is_supported(item) == TRUE) {
364 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
366 payload->enc_alg_len = len;
367 payload->enc_alg_list = item;
381 if (!payload->enc_alg_len && !payload->enc_alg_list) {
382 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
383 silc_free(payload->ke_grp_list);
384 silc_free(payload->pkcs_alg_list);
386 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
389 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
392 payload->enc_alg_len = rp->enc_alg_len;
393 payload->enc_alg_list = strdup(rp->enc_alg_list);
396 /* Save selected cipher to security properties */
397 if (silc_cipher_alloc(payload->enc_alg_list,
398 &(*prop)->cipher) == FALSE) {
399 silc_free(payload->ke_grp_list);
400 silc_free(payload->pkcs_alg_list);
402 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
405 /* Get supported hash algorithms */
406 cp = rp->hash_alg_list;
407 if (cp && strchr(cp, ',')) {
411 len = strcspn(cp, ",");
412 item = silc_calloc(len + 1, sizeof(char));
414 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
417 memcpy(item, cp, len);
419 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
421 if (silc_hash_is_supported(item) == TRUE) {
422 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
424 payload->hash_alg_len = len;
425 payload->hash_alg_list = item;
439 if (!payload->hash_alg_len && !payload->hash_alg_list) {
440 SILC_LOG_DEBUG(("Could not find supported hash alg"));
441 silc_free(payload->ke_grp_list);
442 silc_free(payload->pkcs_alg_list);
443 silc_free(payload->enc_alg_list);
445 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
448 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
451 payload->hash_alg_len = rp->hash_alg_len;
452 payload->hash_alg_list = strdup(rp->hash_alg_list);
455 /* Save selected hash algorithm to security properties */
456 if (silc_hash_alloc(ske->start_payload->hash_alg_list,
457 &(*prop)->hash) == FALSE) {
458 silc_free(payload->ke_grp_list);
459 silc_free(payload->pkcs_alg_list);
460 silc_free(payload->enc_alg_list);
462 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
465 /* Get supported HMACs */
466 cp = rp->hmac_alg_list;
467 if (cp && strchr(cp, ',')) {
471 len = strcspn(cp, ",");
472 item = silc_calloc(len + 1, sizeof(char));
474 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
477 memcpy(item, cp, len);
479 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
481 if (silc_hmac_is_supported(item) == TRUE) {
482 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
484 payload->hmac_alg_len = len;
485 payload->hmac_alg_list = item;
499 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
500 SILC_LOG_DEBUG(("Could not find supported HMAC"));
501 silc_free(payload->ke_grp_list);
502 silc_free(payload->pkcs_alg_list);
503 silc_free(payload->enc_alg_list);
504 silc_free(payload->hash_alg_list);
506 return SILC_SKE_STATUS_UNKNOWN_HMAC;
509 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
512 payload->hmac_alg_len = rp->hmac_alg_len;
513 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
516 /* Save selected HMACc to security properties */
517 if (silc_hmac_alloc(ske->start_payload->hmac_alg_list, NULL,
518 &(*prop)->hmac) == FALSE) {
519 silc_free(payload->ke_grp_list);
520 silc_free(payload->pkcs_alg_list);
521 silc_free(payload->enc_alg_list);
522 silc_free(payload->hash_alg_list);
524 return SILC_SKE_STATUS_UNKNOWN_HMAC;
527 /* Get supported compression algorithms */
528 cp = rp->comp_alg_list;
529 if (cp && strchr(cp, ',')) {
533 len = strcspn(cp, ",");
534 item = silc_calloc(len + 1, sizeof(char));
536 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
539 memcpy(item, cp, len);
541 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
544 if (!strcmp(item, "none")) {
545 SILC_LOG_DEBUG(("Found Compression `%s'", item));
546 payload->comp_alg_len = len;
547 payload->comp_alg_list = item;
551 if (silc_hmac_is_supported(item) == TRUE) {
552 SILC_LOG_DEBUG(("Found Compression `%s'", item));
553 payload->comp_alg_len = len;
554 payload->comp_alg_list = item;
570 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
571 2 + payload->version_len +
572 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
573 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
574 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
576 /* Save our reply payload */
577 ske->start_payload = payload;
579 return SILC_SKE_STATUS_OK;
582 /* Creates random number such that 1 < rnd < n and at most length
583 of len bits. The rnd sent as argument must be initialized. */
585 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
589 SilcSKEStatus status = SILC_SKE_STATUS_OK;
590 unsigned char *string;
594 return SILC_SKE_STATUS_ERROR;
596 SILC_LOG_DEBUG(("Creating random number"));
600 /* Get the random number as string */
601 string = silc_rng_get_rn_data(ske->rng, l);
603 return SILC_SKE_STATUS_OUT_OF_MEMORY;
605 /* Decode the string into a MP integer */
606 silc_mp_bin2mp(string, l, rnd);
607 silc_mp_mod_2exp(rnd, rnd, len);
610 if (silc_mp_cmp_ui(rnd, 1) < 0)
611 status = SILC_SKE_STATUS_ERROR;
612 if (silc_mp_cmp(rnd, n) >= 0)
613 status = SILC_SKE_STATUS_ERROR;
615 memset(string, 'F', l);
621 /* Creates a hash value HASH as defined in the SKE protocol. If the
622 `initiator' is TRUE then this function is used to create the HASH_i
623 hash value defined in the protocol. If it is FALSE then this is used
624 to create the HASH value defined by the protocol. */
626 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
627 unsigned char *return_hash,
628 SilcUInt32 *return_hash_len,
631 SilcSKEStatus status = SILC_SKE_STATUS_OK;
633 unsigned char *e, *f, *KEY;
634 SilcUInt32 e_len, f_len, KEY_len;
637 SILC_LOG_DEBUG(("Start"));
639 if (initiator == FALSE) {
640 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
641 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
642 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
644 /* Format the buffer used to compute the hash value */
645 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
646 ske->ke2_payload->pk_len +
647 ske->ke1_payload->pk_len +
648 e_len + f_len + KEY_len);
650 return SILC_SKE_STATUS_OUT_OF_MEMORY;
652 /* Initiator is not required to send its public key */
653 if (!ske->ke1_payload->pk_data) {
655 silc_buffer_format(buf,
656 SILC_STR_UI_XNSTRING(
657 ske->start_payload_copy->data,
658 silc_buffer_len(ske->start_payload_copy)),
659 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
660 ske->ke2_payload->pk_len),
661 SILC_STR_UI_XNSTRING(e, e_len),
662 SILC_STR_UI_XNSTRING(f, f_len),
663 SILC_STR_UI_XNSTRING(KEY, KEY_len),
667 silc_buffer_format(buf,
668 SILC_STR_UI_XNSTRING(
669 ske->start_payload_copy->data,
670 silc_buffer_len(ske->start_payload_copy)),
671 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
672 ske->ke2_payload->pk_len),
673 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
674 ske->ke1_payload->pk_len),
675 SILC_STR_UI_XNSTRING(e, e_len),
676 SILC_STR_UI_XNSTRING(f, f_len),
677 SILC_STR_UI_XNSTRING(KEY, KEY_len),
681 silc_buffer_free(buf);
684 memset(KEY, 0, KEY_len);
688 return SILC_SKE_STATUS_ERROR;
693 memset(KEY, 0, KEY_len);
698 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
700 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
701 ske->ke1_payload->pk_len + e_len);
703 return SILC_SKE_STATUS_OUT_OF_MEMORY;
705 /* Format the buffer used to compute the hash value */
707 silc_buffer_format(buf,
708 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
709 silc_buffer_len(ske->start_payload_copy)),
710 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
711 ske->ke1_payload->pk_len),
712 SILC_STR_UI_XNSTRING(e, e_len),
715 silc_buffer_free(buf);
718 return SILC_SKE_STATUS_ERROR;
721 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
728 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
730 *return_hash_len = silc_hash_len(ske->prop->hash);
732 if (initiator == FALSE) {
733 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
735 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
738 silc_buffer_free(buf);
743 /* Assembles security properties */
745 static SilcSKEStartPayload
746 silc_ske_assemble_security_properties(SilcSKE ske,
747 SilcSKESecurityPropertyFlag flags,
750 SilcSKEStartPayload rp;
753 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
755 rp = silc_calloc(1, sizeof(*rp));
758 rp->flags = (unsigned char)flags;
760 /* Set random cookie */
761 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
762 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
763 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
764 rp->cookie_len = SILC_SKE_COOKIE_LEN;
766 /* In case IV included flag and session port is set the first 16-bits of
767 cookie will include our session port. */
768 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
769 SILC_PUT16_MSB(ske->session_port, rp->cookie);
772 rp->version = strdup(version);
773 rp->version_len = strlen(version);
775 /* Get supported Key Exhange groups */
776 rp->ke_grp_list = silc_ske_get_supported_groups();
777 rp->ke_grp_len = strlen(rp->ke_grp_list);
779 /* Get supported PKCS algorithms */
780 rp->pkcs_alg_list = silc_pkcs_get_supported();
781 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
783 /* Get supported encryption algorithms */
784 rp->enc_alg_list = silc_cipher_get_supported();
785 rp->enc_alg_len = strlen(rp->enc_alg_list);
787 /* Get supported hash algorithms */
788 rp->hash_alg_list = silc_hash_get_supported();
789 rp->hash_alg_len = strlen(rp->hash_alg_list);
791 /* Get supported HMACs */
792 rp->hmac_alg_list = silc_hmac_get_supported();
793 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
796 /* Get supported compression algorithms */
797 rp->comp_alg_list = strdup("none");
798 rp->comp_alg_len = strlen("none");
800 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
801 2 + rp->version_len +
802 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
803 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
804 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
810 /******************************* Protocol API *******************************/
812 /* Allocates new SKE object. */
814 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
815 SilcSKR repository, SilcPublicKey public_key,
816 SilcPrivateKey private_key, void *context)
820 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
822 if (!rng || !schedule || !public_key)
825 ske = silc_calloc(1, sizeof(*ske));
828 ske->status = SILC_SKE_STATUS_OK;
830 ske->repository = repository;
831 ske->user_data = context;
832 ske->schedule = schedule;
833 ske->public_key = public_key;
834 ske->private_key = private_key;
839 /* Free's SKE object. */
841 void silc_ske_free(SilcSKE ske)
843 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
846 /* Free start payload */
847 if (ske->start_payload)
848 silc_ske_payload_start_free(ske->start_payload);
850 /* Free KE payload */
851 if (ske->ke1_payload)
852 silc_ske_payload_ke_free(ske->ke1_payload);
853 if (ske->ke2_payload)
854 silc_ske_payload_ke_free(ske->ke2_payload);
855 silc_free(ske->remote_version);
859 if (ske->prop->group)
860 silc_ske_group_free(ske->prop->group);
861 if (ske->prop->cipher)
862 silc_cipher_free(ske->prop->cipher);
864 silc_hash_free(ske->prop->hash);
866 silc_hmac_free(ske->prop->hmac);
867 silc_free(ske->prop);
869 if (ske->start_payload_copy)
870 silc_buffer_free(ske->start_payload_copy);
872 silc_mp_uninit(ske->x);
876 silc_mp_uninit(ske->KEY);
879 silc_free(ske->hash);
880 silc_free(ske->callbacks);
882 memset(ske, 'F', sizeof(*ske));
887 /* Return user context */
889 void *silc_ske_get_context(SilcSKE ske)
891 return ske->user_data;
894 /* Sets protocol callbacks */
896 void silc_ske_set_callbacks(SilcSKE ske,
897 SilcSKEVerifyCb verify_key,
898 SilcSKECompletionCb completed,
902 silc_free(ske->callbacks);
903 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
906 ske->callbacks->verify_key = verify_key;
907 ske->callbacks->completed = completed;
908 ske->callbacks->context = context;
912 /******************************** Initiator *********************************/
914 /* Initiator state machine */
915 SILC_FSM_STATE(silc_ske_st_initiator_start);
916 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
917 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
918 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
919 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
920 SILC_FSM_STATE(silc_ske_st_initiator_end);
921 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
922 SILC_FSM_STATE(silc_ske_st_initiator_error);
923 SILC_FSM_STATE(silc_ske_st_initiator_failure);
925 /* Start protocol. Send our proposal */
927 SILC_FSM_STATE(silc_ske_st_initiator_start)
929 SilcSKE ske = fsm_context;
930 SilcBuffer payload_buf;
933 SILC_LOG_DEBUG(("Start"));
937 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
938 return SILC_FSM_CONTINUE;
941 /* Encode the payload */
942 status = silc_ske_payload_start_encode(ske, ske->start_payload,
944 if (status != SILC_SKE_STATUS_OK) {
945 /** Error encoding Start Payload */
946 ske->status = status;
947 silc_fsm_next(fsm, silc_ske_st_initiator_error);
948 return SILC_FSM_CONTINUE;
951 /* Save the the payload buffer for future use. It is later used to
952 compute the HASH value. */
953 ske->start_payload_copy = payload_buf;
955 /* Send the packet. */
956 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
957 silc_buffer_data(payload_buf),
958 silc_buffer_len(payload_buf))) {
959 /** Error sending packet */
960 ske->status = SILC_SKE_STATUS_ERROR;
961 silc_fsm_next(fsm, silc_ske_st_initiator_error);
962 return SILC_FSM_CONTINUE;
967 /** Wait for responder proposal */
968 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
969 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
970 return SILC_FSM_WAIT;
973 /* Phase-1. Receives responder's proposal */
975 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
977 SilcSKE ske = fsm_context;
978 SilcSKEStatus status;
979 SilcSKEStartPayload payload;
980 SilcSKESecurityProperties prop;
981 SilcSKEDiffieHellmanGroup group;
982 SilcBuffer packet_buf = &ske->packet->buffer;
983 SilcUInt16 remote_port = 0;
987 SILC_LOG_DEBUG(("Start"));
991 silc_packet_free(ske->packet);
992 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
993 return SILC_FSM_CONTINUE;
996 /* Decode the payload */
997 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
998 if (status != SILC_SKE_STATUS_OK) {
999 /** Error decoding Start Payload */
1000 silc_packet_free(ske->packet);
1001 ske->status = status;
1002 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1003 return SILC_FSM_CONTINUE;
1006 /* Get remote ID and set it to stream */
1007 if (ske->packet->src_id_len) {
1008 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1009 ske->packet->src_id_type,
1010 (ske->packet->src_id_type == SILC_ID_SERVER ?
1011 (void *)&id.u.server_id : (void *)&id.u.client_id),
1012 (ske->packet->src_id_type == SILC_ID_SERVER ?
1013 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1014 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1015 (ske->packet->src_id_type == SILC_ID_SERVER ?
1016 (void *)&id.u.server_id : (void *)&id.u.client_id));
1019 silc_packet_free(ske->packet);
1021 /* Check that the cookie is returned unmodified. In case IV included
1022 flag and session port has been set, the first two bytes of cookie
1023 are the session port and we ignore them in this check. */
1024 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1025 /* Take remote port */
1026 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1029 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1030 SILC_SKE_COOKIE_LEN - coff)) {
1031 /** Invalid cookie */
1032 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1033 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1034 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1035 return SILC_FSM_CONTINUE;
1038 /* Check version string */
1039 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1040 status = silc_ske_check_version(ske);
1041 if (status != SILC_SKE_STATUS_OK) {
1042 /** Version mismatch */
1043 ske->status = status;
1044 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1045 return SILC_FSM_CONTINUE;
1048 /* Free our KE Start Payload context, we don't need it anymore. */
1049 silc_ske_payload_start_free(ske->start_payload);
1050 ske->start_payload = NULL;
1052 /* Take the selected security properties into use while doing
1053 the key exchange. This is used only while doing the key
1055 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1058 prop->flags = payload->flags;
1059 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1060 if (status != SILC_SKE_STATUS_OK)
1063 prop->group = group;
1064 prop->remote_port = remote_port;
1066 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1067 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1070 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1071 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1074 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1075 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1078 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1079 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1083 /* Save remote's KE Start Payload */
1084 ske->start_payload = payload;
1086 /** Send KE Payload */
1087 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1088 return SILC_FSM_CONTINUE;
1092 silc_ske_payload_start_free(payload);
1094 silc_ske_group_free(group);
1097 silc_cipher_free(prop->cipher);
1099 silc_hash_free(prop->hash);
1101 silc_hmac_free(prop->hmac);
1105 if (status == SILC_SKE_STATUS_OK)
1106 status = SILC_SKE_STATUS_ERROR;
1109 ske->status = status;
1110 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1111 return SILC_FSM_CONTINUE;
1114 /* Phase-2. Send KE payload */
1116 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1118 SilcSKE ske = fsm_context;
1119 SilcSKEStatus status;
1120 SilcBuffer payload_buf;
1122 SilcSKEKEPayload payload;
1125 SILC_LOG_DEBUG(("Start"));
1127 /* Create the random number x, 1 < x < q. */
1128 x = silc_calloc(1, sizeof(*x));
1130 /** Out of memory */
1131 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1132 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1133 return SILC_FSM_CONTINUE;
1137 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1138 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1140 if (status != SILC_SKE_STATUS_OK) {
1141 /** Error generating random number */
1144 ske->status = status;
1145 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1146 return SILC_FSM_CONTINUE;
1149 /* Encode the result to Key Exchange Payload. */
1151 payload = silc_calloc(1, sizeof(*payload));
1153 /** Out of memory */
1156 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1157 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1158 return SILC_FSM_CONTINUE;
1160 ske->ke1_payload = payload;
1162 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1164 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1165 silc_mp_init(&payload->x);
1166 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1167 &ske->prop->group->group);
1169 /* Get public key */
1170 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1171 if (!payload->pk_data) {
1172 /** Error encoding public key */
1175 silc_mp_uninit(&payload->x);
1177 ske->ke1_payload = NULL;
1178 ske->status = SILC_SKE_STATUS_ERROR;
1179 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1180 return SILC_FSM_CONTINUE;
1182 payload->pk_len = pk_len;
1183 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1185 /* Compute signature data if we are doing mutual authentication */
1186 if (ske->private_key &&
1187 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1188 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1189 SilcUInt32 hash_len, sign_len;
1191 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1192 SILC_LOG_DEBUG(("Computing HASH_i value"));
1194 /* Compute the hash value */
1195 memset(hash, 0, sizeof(hash));
1196 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1198 SILC_LOG_DEBUG(("Signing HASH_i value"));
1200 /* Sign the hash value */
1201 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1202 sizeof(sign) - 1, &sign_len, NULL)) {
1203 /** Error computing signature */
1206 silc_mp_uninit(&payload->x);
1207 silc_free(payload->pk_data);
1209 ske->ke1_payload = NULL;
1210 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1211 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1212 return SILC_FSM_CONTINUE;
1214 payload->sign_data = silc_memdup(sign, sign_len);
1215 if (payload->sign_data)
1216 payload->sign_len = sign_len;
1217 memset(sign, 0, sizeof(sign));
1220 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1221 if (status != SILC_SKE_STATUS_OK) {
1222 /** Error encoding KE payload */
1225 silc_mp_uninit(&payload->x);
1226 silc_free(payload->pk_data);
1227 silc_free(payload->sign_data);
1229 ske->ke1_payload = NULL;
1230 ske->status = status;
1231 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1232 return SILC_FSM_CONTINUE;
1237 /* Check for backwards compatibility */
1239 /* Send the packet. */
1240 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_1, 0,
1241 silc_buffer_data(payload_buf),
1242 silc_buffer_len(payload_buf))) {
1243 /** Error sending packet */
1244 ske->status = SILC_SKE_STATUS_ERROR;
1245 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1246 return SILC_FSM_CONTINUE;
1249 silc_buffer_free(payload_buf);
1251 /** Waiting responder's KE payload */
1252 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1253 return SILC_FSM_WAIT;
1256 /* Phase-3. Process responder's KE payload */
1258 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1260 SilcSKE ske = fsm_context;
1261 SilcSKEStatus status;
1262 SilcSKEKEPayload payload;
1264 SilcBuffer packet_buf = &ske->packet->buffer;
1266 SILC_LOG_DEBUG(("Start"));
1270 silc_packet_free(ske->packet);
1271 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1272 return SILC_FSM_CONTINUE;
1275 /* Decode the payload */
1276 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1277 if (status != SILC_SKE_STATUS_OK) {
1278 /** Error decoding KE payload */
1279 silc_packet_free(ske->packet);
1280 ske->status = status;
1281 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1282 return SILC_FSM_CONTINUE;
1284 silc_packet_free(ske->packet);
1285 ske->ke2_payload = payload;
1287 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1288 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1289 "even though we require it"));
1290 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1294 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1296 /* Compute the shared secret key */
1297 KEY = silc_calloc(1, sizeof(*KEY));
1299 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1302 /* Decode the remote's public key */
1303 if (payload->pk_data &&
1304 !silc_pkcs_public_key_alloc(payload->pk_type,
1305 payload->pk_data, payload->pk_len,
1306 &ske->prop->public_key)) {
1307 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1308 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1312 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1314 SILC_LOG_DEBUG(("Verifying public key"));
1316 /** Waiting public key verification */
1317 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1319 /* If repository is provided, verify the key from there. */
1320 if (ske->repository) {
1323 find = silc_skr_find_alloc();
1325 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1328 silc_skr_find_set_pkcs_type(find,
1329 silc_pkcs_get_type(ske->prop->public_key));
1330 silc_skr_find_set_public_key(find, ske->prop->public_key);
1332 /* Find key from repository */
1333 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1334 silc_ske_skr_callback, ske));
1336 /* Verify from application */
1337 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1338 ske->callbacks->context,
1339 silc_ske_pk_verified, NULL));
1344 /** Process key material */
1345 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1346 return SILC_FSM_CONTINUE;
1349 silc_ske_payload_ke_free(payload);
1350 ske->ke2_payload = NULL;
1352 silc_mp_uninit(ske->KEY);
1353 silc_free(ske->KEY);
1356 if (status == SILC_SKE_STATUS_OK)
1357 return SILC_SKE_STATUS_ERROR;
1360 ske->status = status;
1361 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1362 return SILC_FSM_CONTINUE;
1365 /* Process key material */
1367 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1369 SilcSKE ske = fsm_context;
1370 SilcSKEStatus status;
1371 SilcSKEKEPayload payload;
1372 unsigned char hash[SILC_HASH_MAXLEN];
1373 SilcUInt32 hash_len;
1374 int key_len, block_len;
1378 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1379 return SILC_FSM_CONTINUE;
1382 /* Check result of public key verification */
1383 if (ske->status != SILC_SKE_STATUS_OK) {
1384 /** Public key not verified */
1385 SILC_LOG_DEBUG(("Public key verification failed"));
1386 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1387 return SILC_FSM_CONTINUE;
1390 payload = ske->ke2_payload;
1392 if (ske->prop->public_key) {
1393 SILC_LOG_DEBUG(("Public key is authentic"));
1395 /* Compute the hash value */
1396 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1397 if (status != SILC_SKE_STATUS_OK)
1400 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1402 /* Verify signature */
1403 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1404 payload->sign_len, hash, hash_len, NULL)) {
1405 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1406 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1410 SILC_LOG_DEBUG(("Signature is Ok"));
1412 ske->hash = silc_memdup(hash, hash_len);
1413 ske->hash_len = hash_len;
1414 memset(hash, 'F', hash_len);
1417 ske->status = SILC_SKE_STATUS_OK;
1419 /* Process key material */
1420 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1421 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1422 hash_len = silc_hash_len(ske->prop->hash);
1423 ske->keymat = silc_ske_process_key_material(ske, block_len,
1426 SILC_LOG_ERROR(("Error processing key material"));
1427 status = SILC_SKE_STATUS_ERROR;
1431 /* Send SUCCESS packet */
1432 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1433 if (!silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1434 /** Error sending packet */
1435 ske->status = SILC_SKE_STATUS_ERROR;
1436 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1437 return SILC_FSM_CONTINUE;
1440 /** Waiting completion */
1441 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1442 return SILC_FSM_WAIT;
1445 memset(hash, 'F', sizeof(hash));
1446 silc_ske_payload_ke_free(payload);
1447 ske->ke2_payload = NULL;
1449 silc_mp_uninit(ske->KEY);
1450 silc_free(ske->KEY);
1454 memset(ske->hash, 'F', hash_len);
1455 silc_free(ske->hash);
1459 if (status == SILC_SKE_STATUS_OK)
1460 status = SILC_SKE_STATUS_ERROR;
1463 ske->status = status;
1464 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1465 return SILC_FSM_CONTINUE;
1468 /* Protocol completed */
1470 SILC_FSM_STATE(silc_ske_st_initiator_end)
1472 SilcSKE ske = fsm_context;
1474 SILC_LOG_DEBUG(("Start"));
1478 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1479 return SILC_FSM_CONTINUE;
1482 /* See if received failure from remote */
1483 if (ske->packet->type == SILC_PACKET_FAILURE) {
1484 silc_packet_free(ske->packet);
1485 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1486 return SILC_FSM_CONTINUE;
1489 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1491 /* Call the completion callback */
1492 if (ske->callbacks->completed)
1493 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1494 ske->rekey, ske->user_data);
1496 silc_packet_free(ske->packet);
1498 return SILC_FSM_FINISH;
1501 /* Aborted by application */
1503 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1505 SilcSKE ske = fsm_context;
1506 unsigned char data[4];
1508 SILC_LOG_DEBUG(("Aborted by caller"));
1510 /* Send FAILURE packet */
1511 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1512 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1514 return SILC_FSM_FINISH;
1517 /* Error occurred. Send error to remote host */
1519 SILC_FSM_STATE(silc_ske_st_initiator_error)
1521 SilcSKE ske = fsm_context;
1522 SilcSKEStatus status;
1523 unsigned char data[4];
1525 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1526 silc_ske_map_status(ske->status), ske->status));
1528 status = ske->status;
1529 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1530 status = SILC_SKE_STATUS_ERROR;
1532 /* Send FAILURE packet */
1533 SILC_PUT32_MSB((SilcUInt32)status, data);
1534 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1536 /* Call the completion callback */
1537 if (ske->callbacks->completed)
1538 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1540 return SILC_FSM_FINISH;
1543 /* Failure received from remote */
1545 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1547 SilcSKE ske = fsm_context;
1549 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1550 silc_ske_map_status(ske->status), ske->status));
1552 /* Call the completion callback */
1553 if (ske->callbacks->completed)
1554 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1556 return SILC_FSM_FINISH;
1559 /* FSM destructor */
1561 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1562 void *destructor_context)
1564 SilcSKE ske = fsm_context;
1565 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1568 /* Starts the protocol as initiator */
1571 silc_ske_initiator(SilcSKE ske,
1572 SilcPacketStream stream,
1573 SilcSKEParams params,
1574 SilcSKEStartPayload start_payload)
1576 SILC_LOG_DEBUG(("Start SKE as initiator"));
1578 if (!ske || !stream || !params || !params->version)
1581 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1584 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1588 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1589 ske->session_port = params->session_port;
1591 /* Generate security properties if not provided */
1592 if (!start_payload) {
1593 start_payload = silc_ske_assemble_security_properties(ske,
1600 ske->start_payload = start_payload;
1601 ske->version = params->version;
1603 /* Link to packet stream to get key exchange packets */
1604 ske->stream = stream;
1605 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1606 SILC_PACKET_KEY_EXCHANGE,
1607 SILC_PACKET_KEY_EXCHANGE_2,
1608 SILC_PACKET_SUCCESS,
1609 SILC_PACKET_FAILURE, -1);
1611 /* Start SKE as initiator */
1612 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1618 /******************************** Responder *********************************/
1620 SILC_FSM_STATE(silc_ske_st_responder_start);
1621 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1622 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1623 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1624 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1625 SILC_FSM_STATE(silc_ske_st_responder_end);
1626 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1627 SILC_FSM_STATE(silc_ske_st_responder_failure);
1628 SILC_FSM_STATE(silc_ske_st_responder_error);
1630 /* Start protocol as responder. Wait initiator's start payload */
1632 SILC_FSM_STATE(silc_ske_st_responder_start)
1634 SilcSKE ske = fsm_context;
1636 SILC_LOG_DEBUG(("Start"));
1640 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1641 return SILC_FSM_CONTINUE;
1647 /** Wait for initiator */
1648 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1649 return SILC_FSM_WAIT;
1652 /* Decode initiator's start payload. Select the security properties from
1653 the initiator's start payload and send our reply start payload back. */
1655 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1657 SilcSKE ske = fsm_context;
1658 SilcSKEStatus status;
1659 SilcSKEStartPayload remote_payload = NULL;
1660 SilcBuffer packet_buf = &ske->packet->buffer;
1662 SILC_LOG_DEBUG(("Start"));
1666 silc_packet_free(ske->packet);
1667 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1668 return SILC_FSM_CONTINUE;
1671 /* See if received failure from remote */
1672 if (ske->packet->type == SILC_PACKET_FAILURE) {
1673 silc_packet_free(ske->packet);
1674 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1675 return SILC_FSM_CONTINUE;
1678 /* Decode the payload */
1679 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1680 if (status != SILC_SKE_STATUS_OK) {
1681 /** Error decoding Start Payload */
1682 silc_packet_free(ske->packet);
1683 ske->status = status;
1684 silc_fsm_next(fsm, silc_ske_st_responder_error);
1685 return SILC_FSM_CONTINUE;
1688 /* Take a copy of the payload buffer for future use. It is used to
1689 compute the HASH value. */
1690 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1692 silc_packet_free(ske->packet);
1694 /* Force the mutual authentication flag if we want to do it. */
1695 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1696 SILC_LOG_DEBUG(("Force mutual authentication"));
1697 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1700 /* Force PFS flag if we require it */
1701 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1702 SILC_LOG_DEBUG(("Force PFS"));
1703 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1706 /* Disable IV Included flag if requested */
1707 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1708 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1709 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1710 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1713 /* Check and select security properties */
1714 status = silc_ske_select_security_properties(ske, remote_payload,
1716 if (status != SILC_SKE_STATUS_OK) {
1717 /** Error selecting proposal */
1718 silc_ske_payload_start_free(remote_payload);
1719 ske->status = status;
1720 silc_fsm_next(fsm, silc_ske_st_responder_error);
1721 return SILC_FSM_CONTINUE;
1724 silc_ske_payload_start_free(remote_payload);
1726 /* Encode our reply payload to send the selected security properties */
1727 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1729 if (status != SILC_SKE_STATUS_OK)
1732 /* Send the packet. */
1733 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1734 silc_buffer_data(packet_buf),
1735 silc_buffer_len(packet_buf)))
1738 silc_buffer_free(packet_buf);
1740 /** Waiting initiator's KE payload */
1741 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1742 return SILC_FSM_WAIT;
1745 if (ske->prop->group)
1746 silc_ske_group_free(ske->prop->group);
1747 if (ske->prop->cipher)
1748 silc_cipher_free(ske->prop->cipher);
1749 if (ske->prop->hash)
1750 silc_hash_free(ske->prop->hash);
1751 if (ske->prop->hmac)
1752 silc_hmac_free(ske->prop->hmac);
1753 silc_free(ske->prop);
1756 if (status == SILC_SKE_STATUS_OK)
1757 status = SILC_SKE_STATUS_ERROR;
1760 ske->status = status;
1761 silc_fsm_next(fsm, silc_ske_st_responder_error);
1762 return SILC_FSM_CONTINUE;
1765 /* Phase-2. Decode initiator's KE payload */
1767 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1769 SilcSKE ske = fsm_context;
1770 SilcSKEStatus status;
1771 SilcSKEKEPayload recv_payload;
1772 SilcBuffer packet_buf = &ske->packet->buffer;
1774 SILC_LOG_DEBUG(("Start"));
1778 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1779 return SILC_FSM_CONTINUE;
1782 /* See if received failure from remote */
1783 if (ske->packet->type == SILC_PACKET_FAILURE) {
1784 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1785 return SILC_FSM_CONTINUE;
1788 /* Decode Key Exchange Payload */
1789 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1790 if (status != SILC_SKE_STATUS_OK) {
1791 /** Error decoding KE payload */
1792 silc_packet_free(ske->packet);
1793 ske->status = status;
1794 silc_fsm_next(fsm, silc_ske_st_responder_error);
1795 return SILC_FSM_CONTINUE;
1798 ske->ke1_payload = recv_payload;
1800 silc_packet_free(ske->packet);
1802 /* Verify the received public key and verify the signature if we are
1803 doing mutual authentication. */
1804 if (ske->start_payload &&
1805 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1807 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1809 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1811 /** Public key not provided */
1812 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1813 "certificate), even though we require it"));
1814 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1815 silc_fsm_next(fsm, silc_ske_st_responder_error);
1816 return SILC_FSM_CONTINUE;
1819 /* Decode the remote's public key */
1820 if (recv_payload->pk_data &&
1821 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1822 recv_payload->pk_data,
1823 recv_payload->pk_len,
1824 &ske->prop->public_key)) {
1825 /** Error decoding public key */
1826 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1827 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1828 silc_fsm_next(fsm, silc_ske_st_responder_error);
1829 return SILC_FSM_CONTINUE;
1832 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1834 SILC_LOG_DEBUG(("Verifying public key"));
1836 /** Waiting public key verification */
1837 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1839 /* If repository is provided, verify the key from there. */
1840 if (ske->repository) {
1843 find = silc_skr_find_alloc();
1845 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1846 silc_fsm_next(fsm, silc_ske_st_responder_error);
1847 return SILC_FSM_CONTINUE;
1849 silc_skr_find_set_pkcs_type(find,
1850 silc_pkcs_get_type(ske->prop->public_key));
1851 silc_skr_find_set_public_key(find, ske->prop->public_key);
1853 /* Find key from repository */
1854 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1855 silc_ske_skr_callback, ske));
1857 /* Verify from application */
1858 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1859 ske->callbacks->context,
1860 silc_ske_pk_verified, NULL));
1866 /** Generate KE2 payload */
1867 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1868 return SILC_FSM_CONTINUE;
1871 /* Phase-4. Generate KE2 payload */
1873 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1875 SilcSKE ske = fsm_context;
1876 SilcSKEStatus status;
1877 SilcSKEKEPayload recv_payload, send_payload;
1882 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1883 return SILC_FSM_CONTINUE;
1886 /* Check result of public key verification */
1887 if (ske->status != SILC_SKE_STATUS_OK) {
1888 /** Public key not verified */
1889 SILC_LOG_DEBUG(("Public key verification failed"));
1890 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1891 return SILC_FSM_CONTINUE;
1894 recv_payload = ske->ke1_payload;
1896 /* The public key verification was performed only if the Mutual
1897 Authentication flag is set. */
1898 if (ske->start_payload &&
1899 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1900 unsigned char hash[SILC_HASH_MAXLEN];
1901 SilcUInt32 hash_len;
1903 SILC_LOG_DEBUG(("Public key is authentic"));
1905 /* Compute the hash value */
1906 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1907 if (status != SILC_SKE_STATUS_OK) {
1908 /** Error computing hash */
1909 ske->status = status;
1910 silc_fsm_next(fsm, silc_ske_st_responder_error);
1911 return SILC_FSM_CONTINUE;
1914 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1916 /* Verify signature */
1917 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
1918 recv_payload->sign_len, hash, hash_len, NULL)) {
1919 /** Incorrect signature */
1920 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1921 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1922 silc_fsm_next(fsm, silc_ske_st_responder_error);
1923 return SILC_FSM_CONTINUE;
1926 SILC_LOG_DEBUG(("Signature is Ok"));
1928 memset(hash, 'F', hash_len);
1931 /* Create the random number x, 1 < x < q. */
1932 x = silc_calloc(1, sizeof(*x));
1935 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1936 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1938 if (status != SILC_SKE_STATUS_OK) {
1939 /** Error generating random number */
1942 ske->status = status;
1943 silc_fsm_next(fsm, silc_ske_st_responder_error);
1944 return SILC_FSM_CONTINUE;
1947 /* Save the results for later processing */
1948 send_payload = silc_calloc(1, sizeof(*send_payload));
1950 ske->ke2_payload = send_payload;
1952 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1954 /* Do the Diffie Hellman computation, f = g ^ x mod p */
1955 silc_mp_init(&send_payload->x);
1956 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1957 &ske->prop->group->group);
1959 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1961 /* Compute the shared secret key */
1962 KEY = silc_calloc(1, sizeof(*KEY));
1964 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1965 &ske->prop->group->group);
1968 /** Send KE2 payload */
1969 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1970 return SILC_FSM_CONTINUE;
1973 /* Phase-5. Send KE2 payload */
1975 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1977 SilcSKE ske = fsm_context;
1978 SilcSKEStatus status;
1979 SilcBuffer payload_buf;
1980 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1981 SilcUInt32 hash_len, sign_len, pk_len;
1983 SILC_LOG_DEBUG(("Start"));
1985 if (ske->public_key && ske->private_key) {
1986 SILC_LOG_DEBUG(("Getting public key"));
1988 /* Get the public key */
1989 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1991 /** Error encoding public key */
1992 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1993 silc_fsm_next(fsm, silc_ske_st_responder_error);
1994 return SILC_FSM_CONTINUE;
1996 ske->ke2_payload->pk_data = pk;
1997 ske->ke2_payload->pk_len = pk_len;
1999 SILC_LOG_DEBUG(("Computing HASH value"));
2001 /* Compute the hash value */
2002 memset(hash, 0, sizeof(hash));
2003 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2004 if (status != SILC_SKE_STATUS_OK) {
2005 /** Error computing hash */
2006 ske->status = status;
2007 silc_fsm_next(fsm, silc_ske_st_responder_error);
2008 return SILC_FSM_CONTINUE;
2011 ske->hash = silc_memdup(hash, hash_len);
2012 ske->hash_len = hash_len;
2014 SILC_LOG_DEBUG(("Signing HASH value"));
2016 /* Sign the hash value */
2017 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2018 sizeof(sign) - 1, &sign_len, NULL)) {
2019 /** Error computing signature */
2020 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2021 silc_fsm_next(fsm, silc_ske_st_responder_error);
2022 return SILC_FSM_CONTINUE;
2024 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2025 ske->ke2_payload->sign_len = sign_len;
2026 memset(sign, 0, sizeof(sign));
2028 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2030 /* Encode the Key Exchange Payload */
2031 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2033 if (status != SILC_SKE_STATUS_OK) {
2034 /** Error encoding KE payload */
2035 ske->status = status;
2036 silc_fsm_next(fsm, silc_ske_st_responder_error);
2037 return SILC_FSM_CONTINUE;
2040 /* Send the packet. */
2041 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
2042 payload_buf->data, silc_buffer_len(payload_buf))) {
2043 ske->status = SILC_SKE_STATUS_ERROR;
2044 silc_fsm_next(fsm, silc_ske_st_responder_error);
2045 return SILC_FSM_CONTINUE;
2048 silc_buffer_free(payload_buf);
2050 /** Waiting completion */
2051 silc_fsm_next(fsm, silc_ske_st_responder_end);
2052 return SILC_FSM_WAIT;
2055 /* Protocol completed */
2057 SILC_FSM_STATE(silc_ske_st_responder_end)
2059 SilcSKE ske = fsm_context;
2060 unsigned char tmp[4];
2061 SilcUInt32 hash_len, key_len, block_len;
2065 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2066 return SILC_FSM_CONTINUE;
2069 /* Check the result of the protocol */
2070 if (ske->packet->type == SILC_PACKET_FAILURE) {
2071 silc_fsm_next(fsm, silc_ske_st_responder_failure);
2072 return SILC_FSM_CONTINUE;
2074 silc_packet_free(ske->packet);
2076 /* Process key material */
2077 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2078 block_len = silc_cipher_get_key_len(ske->prop->cipher);
2079 hash_len = silc_hash_len(ske->prop->hash);
2080 ske->keymat = silc_ske_process_key_material(ske, block_len,
2083 /** Error processing key material */
2084 ske->status = SILC_SKE_STATUS_ERROR;
2085 silc_fsm_next(fsm, silc_ske_st_responder_error);
2086 return SILC_FSM_CONTINUE;
2089 /* Send SUCCESS packet */
2090 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2091 silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
2093 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2095 /* Call the completion callback */
2096 if (ske->callbacks->completed)
2097 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
2098 ske->rekey, ske->callbacks->context);
2100 return SILC_FSM_FINISH;
2103 /* Aborted by application */
2105 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2107 SilcSKE ske = fsm_context;
2108 unsigned char tmp[4];
2110 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2112 /* Send FAILURE packet */
2113 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2114 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2116 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2118 return SILC_FSM_FINISH;
2121 /* Failure received from remote */
2123 SILC_FSM_STATE(silc_ske_st_responder_failure)
2125 SilcSKE ske = fsm_context;
2126 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2128 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2130 if (silc_buffer_len(&ske->packet->buffer) == 4)
2131 SILC_GET32_MSB(error, ske->packet->buffer.data);
2132 ske->status = error;
2134 /* Call the completion callback */
2135 if (ske->callbacks->completed)
2136 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
2137 ske->callbacks->context);
2139 silc_packet_free(ske->packet);
2140 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2142 return SILC_FSM_FINISH;
2145 /* Error occurred */
2147 SILC_FSM_STATE(silc_ske_st_responder_error)
2149 SilcSKE ske = fsm_context;
2150 unsigned char tmp[4];
2152 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2153 ske->status, silc_ske_map_status(ske->status)));
2155 /* Send FAILURE packet */
2156 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2157 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2158 SILC_PUT32_MSB(ske->status, tmp);
2159 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2161 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2163 return SILC_FSM_FINISH;
2167 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
2168 void *destructor_context)
2173 /* Starts the protocol as responder. */
2176 silc_ske_responder(SilcSKE ske,
2177 SilcPacketStream stream,
2178 SilcSKEParams params)
2180 SILC_LOG_DEBUG(("Start SKE as responder"));
2182 if (!ske || !stream || !params || !params->version) {
2186 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2189 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2193 ske->responder = TRUE;
2194 ske->flags = params->flags;
2195 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2196 ske->session_port = params->session_port;
2197 ske->version = strdup(params->version);
2201 /* Link to packet stream to get key exchange packets */
2202 ske->stream = stream;
2203 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2204 SILC_PACKET_KEY_EXCHANGE,
2205 SILC_PACKET_KEY_EXCHANGE_1,
2206 SILC_PACKET_SUCCESS,
2207 SILC_PACKET_FAILURE, -1);
2209 /* Start SKE as responder */
2210 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2215 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2217 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2219 return SILC_FSM_FINISH;
2222 /* Starts rekey protocol as initiator */
2225 silc_ske_rekey_initiator(SilcSKE ske,
2226 SilcPacketStream stream,
2227 SilcSKERekeyMaterial rekey)
2229 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2231 if (!ske || !stream || !rekey)
2234 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2237 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2242 /* Link to packet stream to get key exchange packets */
2243 ske->stream = stream;
2245 /* Start SKE rekey as initiator */
2246 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2251 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2253 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2255 return SILC_FSM_FINISH;
2258 /* Starts rekey protocol as responder */
2261 silc_ske_rekey_responder(SilcSKE ske,
2262 SilcPacketStream stream,
2263 SilcBuffer ke_payload,
2264 SilcSKERekeyMaterial rekey)
2266 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2268 if (!ske || !stream || !rekey)
2270 if (rekey->pfs && !ke_payload)
2273 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2276 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2279 // ske->packet_buf = ke_payload;
2282 /* Link to packet stream to get key exchange packets */
2283 ske->stream = stream;
2285 /* Start SKE rekey as responder */
2286 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2291 /* Processes the provided key material `data' as the SILC protocol
2292 specification defines. */
2295 silc_ske_process_key_material_data(unsigned char *data,
2296 SilcUInt32 data_len,
2297 SilcUInt32 req_iv_len,
2298 SilcUInt32 req_enc_key_len,
2299 SilcUInt32 req_hmac_key_len,
2303 unsigned char hashd[SILC_HASH_MAXLEN];
2304 SilcUInt32 hash_len = req_hmac_key_len;
2305 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2306 SilcSKEKeyMaterial key;
2308 SILC_LOG_DEBUG(("Start"));
2310 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2313 key = silc_calloc(1, sizeof(*key));
2317 buf = silc_buffer_alloc_size(1 + data_len);
2320 silc_buffer_format(buf,
2321 SILC_STR_UI_CHAR(0),
2322 SILC_STR_UI_XNSTRING(data, data_len),
2326 memset(hashd, 0, sizeof(hashd));
2328 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2329 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2330 memcpy(key->send_iv, hashd, req_iv_len);
2331 memset(hashd, 0, sizeof(hashd));
2333 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2334 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2335 memcpy(key->receive_iv, hashd, req_iv_len);
2336 key->iv_len = req_iv_len;
2338 /* Take the encryption keys. If requested key size is more than
2339 the size of hash length we will distribute more key material
2340 as protocol defines. */
2342 if (enc_key_len > hash_len) {
2344 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2345 k3[SILC_HASH_MAXLEN];
2346 unsigned char *dtmp;
2349 if (enc_key_len > (3 * hash_len))
2352 /* Take first round */
2353 memset(k1, 0, sizeof(k1));
2354 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2356 /* Take second round */
2357 dist = silc_buffer_alloc_size(data_len + hash_len);
2360 silc_buffer_format(dist,
2361 SILC_STR_UI_XNSTRING(data, data_len),
2362 SILC_STR_UI_XNSTRING(k1, hash_len),
2364 memset(k2, 0, sizeof(k2));
2365 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2367 /* Take third round */
2368 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2369 silc_buffer_pull_tail(dist, hash_len);
2370 silc_buffer_pull(dist, data_len + hash_len);
2371 silc_buffer_format(dist,
2372 SILC_STR_UI_XNSTRING(k2, hash_len),
2374 silc_buffer_push(dist, data_len + hash_len);
2375 memset(k3, 0, sizeof(k3));
2376 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2378 /* Then, save the keys */
2379 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2380 memcpy(dtmp, k1, hash_len);
2381 memcpy(dtmp + hash_len, k2, hash_len);
2382 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2384 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2385 memcpy(key->send_enc_key, dtmp, enc_key_len);
2386 key->enc_key_len = req_enc_key_len;
2388 memset(dtmp, 0, (3 * hash_len));
2389 memset(k1, 0, sizeof(k1));
2390 memset(k2, 0, sizeof(k2));
2391 memset(k3, 0, sizeof(k3));
2393 silc_buffer_clear(dist);
2394 silc_buffer_free(dist);
2396 /* Take normal hash as key */
2397 memset(hashd, 0, sizeof(hashd));
2398 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2399 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2400 memcpy(key->send_enc_key, hashd, enc_key_len);
2401 key->enc_key_len = req_enc_key_len;
2405 if (enc_key_len > hash_len) {
2407 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2408 k3[SILC_HASH_MAXLEN];
2409 unsigned char *dtmp;
2412 if (enc_key_len > (3 * hash_len))
2415 /* Take first round */
2416 memset(k1, 0, sizeof(k1));
2417 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2419 /* Take second round */
2420 dist = silc_buffer_alloc_size(data_len + hash_len);
2423 silc_buffer_format(dist,
2424 SILC_STR_UI_XNSTRING(data, data_len),
2425 SILC_STR_UI_XNSTRING(k1, hash_len),
2427 memset(k2, 0, sizeof(k2));
2428 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2430 /* Take third round */
2431 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2432 silc_buffer_pull_tail(dist, hash_len);
2433 silc_buffer_pull(dist, data_len + hash_len);
2434 silc_buffer_format(dist,
2435 SILC_STR_UI_XNSTRING(k2, hash_len),
2437 silc_buffer_push(dist, data_len + hash_len);
2438 memset(k3, 0, sizeof(k3));
2439 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2441 /* Then, save the keys */
2442 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2443 memcpy(dtmp, k1, hash_len);
2444 memcpy(dtmp + hash_len, k2, hash_len);
2445 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2447 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2448 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2449 key->enc_key_len = req_enc_key_len;
2451 memset(dtmp, 0, (3 * hash_len));
2452 memset(k1, 0, sizeof(k1));
2453 memset(k2, 0, sizeof(k2));
2454 memset(k3, 0, sizeof(k3));
2456 silc_buffer_clear(dist);
2457 silc_buffer_free(dist);
2459 /* Take normal hash as key */
2460 memset(hashd, 0, sizeof(hashd));
2461 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2462 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2463 memcpy(key->receive_enc_key, hashd, enc_key_len);
2464 key->enc_key_len = req_enc_key_len;
2467 /* Take HMAC keys */
2468 memset(hashd, 0, sizeof(hashd));
2470 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2471 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2472 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2473 memset(hashd, 0, sizeof(hashd));
2475 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2476 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2477 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2478 key->hmac_key_len = req_hmac_key_len;
2479 memset(hashd, 0, sizeof(hashd));
2481 silc_buffer_clear(buf);
2482 silc_buffer_free(buf);
2487 /* Processes negotiated key material as protocol specifies. This returns
2488 the actual keys to be used in the SILC. */
2491 silc_ske_process_key_material(SilcSKE ske,
2492 SilcUInt32 req_iv_len,
2493 SilcUInt32 req_enc_key_len,
2494 SilcUInt32 req_hmac_key_len)
2497 unsigned char *tmpbuf;
2499 SilcSKEKeyMaterial key;
2501 /* Encode KEY to binary data */
2502 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2504 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2507 silc_buffer_format(buf,
2508 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2509 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2512 /* Process the key material */
2513 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2514 req_iv_len, req_enc_key_len,
2518 memset(tmpbuf, 0, klen);
2520 silc_buffer_clear(buf);
2521 silc_buffer_free(buf);
2526 /* Free key material structure */
2528 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2534 silc_free(key->send_iv);
2535 if (key->receive_iv)
2536 silc_free(key->receive_iv);
2537 if (key->send_enc_key) {
2538 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2539 silc_free(key->send_enc_key);
2541 if (key->receive_enc_key) {
2542 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2543 silc_free(key->receive_enc_key);
2545 if (key->send_hmac_key) {
2546 memset(key->send_hmac_key, 0, key->hmac_key_len);
2547 silc_free(key->send_hmac_key);
2549 if (key->receive_hmac_key) {
2550 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2551 silc_free(key->receive_hmac_key);
2556 /* Set keys into use */
2558 SilcBool silc_ske_set_keys(SilcSKE ske,
2559 SilcSKEKeyMaterial keymat,
2560 SilcSKESecurityProperties prop,
2561 SilcCipher *ret_send_key,
2562 SilcCipher *ret_receive_key,
2563 SilcHmac *ret_hmac_send,
2564 SilcHmac *ret_hmac_receive,
2567 /* Allocate ciphers to be used in the communication */
2569 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2573 if (ret_receive_key) {
2574 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2579 /* Allocate HMACs */
2580 if (ret_hmac_send) {
2581 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2585 if (ret_hmac_receive) {
2586 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2591 /* Set key material */
2592 if (ske->responder) {
2593 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2594 keymat->enc_key_len);
2595 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2596 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2597 keymat->enc_key_len);
2598 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2599 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2600 keymat->hmac_key_len);
2601 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2602 keymat->hmac_key_len);
2604 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2605 keymat->enc_key_len);
2606 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2607 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2608 keymat->enc_key_len);
2609 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2610 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2611 keymat->hmac_key_len);
2612 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2613 keymat->hmac_key_len);
2618 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2622 SILC_LOG_INFO(("Security properties: %s %s %s %s",
2623 ret_send_key ? silc_cipher_get_name(*ret_send_key) : "??",
2624 ret_hmac_send ? silc_hmac_get_name(*ret_hmac_send) : "??",
2625 ret_hash ? silc_hash_get_name(*ret_hash) : "??",
2626 ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : ""));
2631 const char *silc_ske_status_string[] =
2635 "Unkown error occurred",
2636 "Bad payload in packet",
2637 "Unsupported group",
2638 "Unsupported cipher",
2640 "Unsupported hash function",
2642 "Unsupported public key (or certificate)",
2643 "Incorrect signature",
2644 "Bad or unsupported version",
2648 "Remote did not provide public key",
2649 "Bad reserved field in packet",
2650 "Bad payload length in packet",
2651 "Error computing signature",
2652 "System out of memory",
2657 /* Maps status to readable string and returns the string. If string is not
2658 found and empty character string ("") is returned. */
2660 const char *silc_ske_map_status(SilcSKEStatus status)
2664 for (i = 0; silc_ske_status_string[i]; i++)
2666 return silc_ske_status_string[i];
2671 /* Parses remote host's version string. */
2673 SilcBool silc_ske_parse_version(SilcSKE ske,
2674 SilcUInt32 *protocol_version,
2675 char **protocol_version_string,
2676 SilcUInt32 *software_version,
2677 char **software_version_string,
2678 char **vendor_version)
2680 return silc_parse_version_string(ske->remote_version,
2682 protocol_version_string,
2684 software_version_string,
2688 /* Get security properties */
2690 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)