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(SilcSKE ske,
39 SilcUInt32 req_iv_len,
40 SilcUInt32 req_enc_key_len,
41 SilcUInt32 req_hmac_key_len);
46 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
47 SilcPacketStream stream,
49 void *callback_context,
52 SilcSKE ske = callback_context;
54 silc_fsm_continue(&ske->fsm);
58 /* Packet stream callbacks */
59 static SilcPacketCallbacks silc_ske_stream_cbs =
61 silc_ske_packet_receive, NULL, NULL
64 /* Aborts SKE protocol */
66 static void silc_ske_abort(SilcAsyncOperation op, void *context)
68 SilcSKE ske = context;
72 /* Public key verification completion callback */
74 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
75 void *completion_context)
78 SILC_FSM_CALL_CONTINUE(&ske->fsm);
81 /* SKR find callback */
83 static void silc_ske_skr_callback(SilcSKR repository,
86 SilcDList keys, void *context)
88 SilcSKE ske = context;
90 silc_skr_find_free(find);
92 if (status != SILC_SKR_OK) {
93 if (ske->callbacks->verify_key) {
94 /* Verify from application */
95 ske->callbacks->verify_key(ske, ske->prop->public_key,
96 ske->callbacks->context,
97 silc_ske_pk_verified, NULL);
103 silc_dlist_uninit(keys);
106 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
107 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
108 SILC_FSM_CALL_CONTINUE(&ske->fsm);
111 /* Checks remote and local versions */
113 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
115 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
116 SilcUInt32 r_software_version = 0;
118 if (!ske->remote_version || !ske->version)
119 return SILC_SKE_STATUS_BAD_VERSION;
121 if (!silc_parse_version_string(ske->remote_version, &r_protocol_version,
122 NULL, &r_software_version, NULL, NULL))
123 return SILC_SKE_STATUS_BAD_VERSION;
125 if (!silc_parse_version_string(ske->version, &l_protocol_version,
126 NULL, NULL, NULL, NULL))
127 return SILC_SKE_STATUS_BAD_VERSION;
129 /* If remote is too new, don't connect */
130 if (l_protocol_version < r_protocol_version)
131 return SILC_SKE_STATUS_BAD_VERSION;
133 /* Backwards compatibility checks */
135 /* Old server versions requires "valid" looking Source ID in the SILC
136 packets during initial key exchange. All version before 1.1.0. */
137 if (r_software_version < 110) {
139 memset(&id, 0, sizeof(id));
141 SILC_LOG_DEBUG(("Remote is old version, add dummy Source ID to packets"));
142 silc_packet_set_ids(ske->stream, SILC_ID_CLIENT, &id, 0, NULL);
145 return SILC_SKE_STATUS_OK;
148 /* Selects the supported security properties from the initiator's Key
149 Exchange Start Payload. A responder function. Saves our reply
150 start payload to ske->start_payload. */
153 silc_ske_select_security_properties(SilcSKE ske,
154 SilcSKEStartPayload remote_payload,
155 SilcSKESecurityProperties *prop)
157 SilcSKEStatus status;
158 SilcSKEStartPayload rp, payload;
162 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
166 /* Check for mandatory fields */
167 if (!rp->ke_grp_len) {
168 SILC_LOG_DEBUG(("KE group not defined in payload"));
169 return SILC_SKE_STATUS_BAD_PAYLOAD;
171 if (!rp->pkcs_alg_len) {
172 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
173 return SILC_SKE_STATUS_BAD_PAYLOAD;
175 if (!rp->enc_alg_len) {
176 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
177 return SILC_SKE_STATUS_BAD_PAYLOAD;
179 if (!rp->hash_alg_len) {
180 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
181 return SILC_SKE_STATUS_BAD_PAYLOAD;
183 if (!rp->hmac_alg_len) {
184 SILC_LOG_DEBUG(("HMAC not defined in payload"));
185 return SILC_SKE_STATUS_BAD_PAYLOAD;
188 /* Allocate security properties */
189 *prop = silc_calloc(1, sizeof(**prop));
191 return SILC_SKE_STATUS_OUT_OF_MEMORY;
193 /* Allocate our reply start payload */
194 payload = silc_calloc(1, sizeof(*payload));
197 return SILC_SKE_STATUS_OUT_OF_MEMORY;
200 /* Check version string */
201 ske->remote_version = silc_memdup(rp->version, rp->version_len);
202 status = silc_ske_check_version(ske);
203 if (status != SILC_SKE_STATUS_OK) {
204 ske->status = status;
208 /* Flags are returned unchanged. */
209 (*prop)->flags = payload->flags = rp->flags;
211 /* Take cookie, we must return it to sender unmodified. */
212 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
213 if (!payload->cookie) {
214 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
217 payload->cookie_len = SILC_SKE_COOKIE_LEN;
218 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
220 /* In case IV included flag and session port is set the first 16-bits of
221 cookie will include our session port. */
222 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
223 /* Take remote port */
224 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
227 SILC_PUT16_MSB(ske->session_port, payload->cookie);
230 /* Put our version to our reply */
231 payload->version = strdup(ske->version);
232 if (!payload->version) {
233 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
236 payload->version_len = strlen(ske->version);
238 /* Get supported Key Exchange groups */
239 cp = rp->ke_grp_list;
240 if (cp && strchr(cp, ',')) {
244 len = strcspn(cp, ",");
245 item = silc_calloc(len + 1, sizeof(char));
247 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
250 memcpy(item, cp, len);
252 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
254 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
255 SILC_LOG_DEBUG(("Found KE group `%s'", item));
257 payload->ke_grp_len = len;
258 payload->ke_grp_list = item;
272 if (!payload->ke_grp_len && !payload->ke_grp_list) {
273 SILC_LOG_DEBUG(("Could not find supported KE group"));
275 return SILC_SKE_STATUS_UNKNOWN_GROUP;
278 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
279 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
281 payload->ke_grp_len = rp->ke_grp_len;
282 payload->ke_grp_list = strdup(rp->ke_grp_list);
285 /* Save group to security properties */
286 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
287 if (status != SILC_SKE_STATUS_OK) {
289 return SILC_SKE_STATUS_UNKNOWN_GROUP;
292 /* Get supported PKCS algorithms */
293 cp = rp->pkcs_alg_list;
294 if (cp && strchr(cp, ',')) {
298 len = strcspn(cp, ",");
299 item = silc_calloc(len + 1, sizeof(char));
301 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
304 memcpy(item, cp, len);
306 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
308 if (silc_pkcs_find_algorithm(item, NULL)) {
309 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
311 payload->pkcs_alg_len = len;
312 payload->pkcs_alg_list = item;
326 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
327 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
328 silc_free(payload->ke_grp_list);
330 return SILC_SKE_STATUS_UNKNOWN_PKCS;
333 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
334 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
336 payload->pkcs_alg_len = rp->pkcs_alg_len;
337 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
340 /* Get supported encryption algorithms */
341 cp = rp->enc_alg_list;
342 if (cp && strchr(cp, ',')) {
346 len = strcspn(cp, ",");
347 item = silc_calloc(len + 1, sizeof(char));
349 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
352 memcpy(item, cp, len);
354 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
356 if (silc_cipher_is_supported(item) == TRUE) {
357 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
359 payload->enc_alg_len = len;
360 payload->enc_alg_list = item;
374 if (!payload->enc_alg_len && !payload->enc_alg_list) {
375 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
376 silc_free(payload->ke_grp_list);
377 silc_free(payload->pkcs_alg_list);
379 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
382 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
385 payload->enc_alg_len = rp->enc_alg_len;
386 payload->enc_alg_list = strdup(rp->enc_alg_list);
389 /* Save selected cipher to security properties */
390 if (silc_cipher_alloc(payload->enc_alg_list,
391 &(*prop)->cipher) == FALSE) {
392 silc_free(payload->ke_grp_list);
393 silc_free(payload->pkcs_alg_list);
395 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
398 /* Get supported hash algorithms */
399 cp = rp->hash_alg_list;
400 if (cp && strchr(cp, ',')) {
404 len = strcspn(cp, ",");
405 item = silc_calloc(len + 1, sizeof(char));
407 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
410 memcpy(item, cp, len);
412 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
414 if (silc_hash_is_supported(item) == TRUE) {
415 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
417 payload->hash_alg_len = len;
418 payload->hash_alg_list = item;
432 if (!payload->hash_alg_len && !payload->hash_alg_list) {
433 SILC_LOG_DEBUG(("Could not find supported hash alg"));
434 silc_free(payload->ke_grp_list);
435 silc_free(payload->pkcs_alg_list);
436 silc_free(payload->enc_alg_list);
438 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
441 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
444 payload->hash_alg_len = rp->hash_alg_len;
445 payload->hash_alg_list = strdup(rp->hash_alg_list);
448 /* Save selected hash algorithm to security properties */
449 if (silc_hash_alloc(ske->start_payload->hash_alg_list,
450 &(*prop)->hash) == FALSE) {
451 silc_free(payload->ke_grp_list);
452 silc_free(payload->pkcs_alg_list);
453 silc_free(payload->enc_alg_list);
455 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
458 /* Get supported HMACs */
459 cp = rp->hmac_alg_list;
460 if (cp && strchr(cp, ',')) {
464 len = strcspn(cp, ",");
465 item = silc_calloc(len + 1, sizeof(char));
467 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
470 memcpy(item, cp, len);
472 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
474 if (silc_hmac_is_supported(item) == TRUE) {
475 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
477 payload->hmac_alg_len = len;
478 payload->hmac_alg_list = item;
492 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
493 SILC_LOG_DEBUG(("Could not find supported HMAC"));
494 silc_free(payload->ke_grp_list);
495 silc_free(payload->pkcs_alg_list);
496 silc_free(payload->enc_alg_list);
497 silc_free(payload->hash_alg_list);
499 return SILC_SKE_STATUS_UNKNOWN_HMAC;
502 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
505 payload->hmac_alg_len = rp->hmac_alg_len;
506 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
509 /* Save selected HMACc to security properties */
510 if (silc_hmac_alloc(ske->start_payload->hmac_alg_list, NULL,
511 &(*prop)->hmac) == FALSE) {
512 silc_free(payload->ke_grp_list);
513 silc_free(payload->pkcs_alg_list);
514 silc_free(payload->enc_alg_list);
515 silc_free(payload->hash_alg_list);
517 return SILC_SKE_STATUS_UNKNOWN_HMAC;
520 /* Get supported compression algorithms */
521 cp = rp->comp_alg_list;
522 if (cp && strchr(cp, ',')) {
526 len = strcspn(cp, ",");
527 item = silc_calloc(len + 1, sizeof(char));
529 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
532 memcpy(item, cp, len);
534 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
537 if (!strcmp(item, "none")) {
538 SILC_LOG_DEBUG(("Found Compression `%s'", item));
539 payload->comp_alg_len = len;
540 payload->comp_alg_list = item;
544 if (silc_hmac_is_supported(item) == TRUE) {
545 SILC_LOG_DEBUG(("Found Compression `%s'", item));
546 payload->comp_alg_len = len;
547 payload->comp_alg_list = item;
563 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
564 2 + payload->version_len +
565 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
566 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
567 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
569 /* Save our reply payload */
570 ske->start_payload = payload;
572 return SILC_SKE_STATUS_OK;
575 /* Creates random number such that 1 < rnd < n and at most length
576 of len bits. The rnd sent as argument must be initialized. */
578 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
582 SilcSKEStatus status = SILC_SKE_STATUS_OK;
583 unsigned char *string;
587 return SILC_SKE_STATUS_ERROR;
589 SILC_LOG_DEBUG(("Creating random number"));
593 /* Get the random number as string */
594 string = silc_rng_get_rn_data(ske->rng, l);
596 return SILC_SKE_STATUS_OUT_OF_MEMORY;
598 /* Decode the string into a MP integer */
599 silc_mp_bin2mp(string, l, rnd);
600 silc_mp_mod_2exp(rnd, rnd, len);
603 if (silc_mp_cmp_ui(rnd, 1) < 0)
604 status = SILC_SKE_STATUS_ERROR;
605 if (silc_mp_cmp(rnd, n) >= 0)
606 status = SILC_SKE_STATUS_ERROR;
608 memset(string, 'F', l);
614 /* Creates a hash value HASH as defined in the SKE protocol. If the
615 `initiator' is TRUE then this function is used to create the HASH_i
616 hash value defined in the protocol. If it is FALSE then this is used
617 to create the HASH value defined by the protocol. */
619 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
620 unsigned char *return_hash,
621 SilcUInt32 *return_hash_len,
624 SilcSKEStatus status = SILC_SKE_STATUS_OK;
626 unsigned char *e, *f, *KEY;
627 SilcUInt32 e_len, f_len, KEY_len;
630 SILC_LOG_DEBUG(("Start"));
632 if (initiator == FALSE) {
633 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
634 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
635 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
637 /* Format the buffer used to compute the hash value */
638 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
639 ske->ke2_payload->pk_len +
640 ske->ke1_payload->pk_len +
641 e_len + f_len + KEY_len);
643 return SILC_SKE_STATUS_OUT_OF_MEMORY;
645 /* Initiator is not required to send its public key */
646 if (!ske->ke1_payload->pk_data) {
648 silc_buffer_format(buf,
649 SILC_STR_UI_XNSTRING(
650 ske->start_payload_copy->data,
651 silc_buffer_len(ske->start_payload_copy)),
652 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
653 ske->ke2_payload->pk_len),
654 SILC_STR_UI_XNSTRING(e, e_len),
655 SILC_STR_UI_XNSTRING(f, f_len),
656 SILC_STR_UI_XNSTRING(KEY, KEY_len),
660 silc_buffer_format(buf,
661 SILC_STR_UI_XNSTRING(
662 ske->start_payload_copy->data,
663 silc_buffer_len(ske->start_payload_copy)),
664 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
665 ske->ke2_payload->pk_len),
666 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
667 ske->ke1_payload->pk_len),
668 SILC_STR_UI_XNSTRING(e, e_len),
669 SILC_STR_UI_XNSTRING(f, f_len),
670 SILC_STR_UI_XNSTRING(KEY, KEY_len),
674 silc_buffer_free(buf);
677 memset(KEY, 0, KEY_len);
681 return SILC_SKE_STATUS_ERROR;
686 memset(KEY, 0, KEY_len);
691 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
693 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
694 ske->ke1_payload->pk_len + e_len);
696 return SILC_SKE_STATUS_OUT_OF_MEMORY;
698 /* Format the buffer used to compute the hash value */
700 silc_buffer_format(buf,
701 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
702 silc_buffer_len(ske->start_payload_copy)),
703 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
704 ske->ke1_payload->pk_len),
705 SILC_STR_UI_XNSTRING(e, e_len),
708 silc_buffer_free(buf);
711 return SILC_SKE_STATUS_ERROR;
714 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
721 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
723 *return_hash_len = silc_hash_len(ske->prop->hash);
725 if (initiator == FALSE) {
726 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
728 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
731 silc_buffer_free(buf);
736 /* Assembles security properties */
738 static SilcSKEStartPayload
739 silc_ske_assemble_security_properties(SilcSKE ske,
740 SilcSKESecurityPropertyFlag flags,
743 SilcSKEStartPayload rp;
746 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
748 rp = silc_calloc(1, sizeof(*rp));
751 rp->flags = (unsigned char)flags;
753 /* Set random cookie */
754 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
755 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
756 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
757 rp->cookie_len = SILC_SKE_COOKIE_LEN;
759 /* In case IV included flag and session port is set the first 16-bits of
760 cookie will include our session port. */
761 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
762 SILC_PUT16_MSB(ske->session_port, rp->cookie);
765 rp->version = strdup(version);
766 rp->version_len = strlen(version);
768 /* Get supported Key Exhange groups */
769 rp->ke_grp_list = silc_ske_get_supported_groups();
770 rp->ke_grp_len = strlen(rp->ke_grp_list);
772 /* Get supported PKCS algorithms */
773 rp->pkcs_alg_list = silc_pkcs_get_supported();
774 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
776 /* Get supported encryption algorithms */
777 rp->enc_alg_list = silc_cipher_get_supported();
778 rp->enc_alg_len = strlen(rp->enc_alg_list);
780 /* Get supported hash algorithms */
781 rp->hash_alg_list = silc_hash_get_supported();
782 rp->hash_alg_len = strlen(rp->hash_alg_list);
784 /* Get supported HMACs */
785 rp->hmac_alg_list = silc_hmac_get_supported();
786 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
789 /* Get supported compression algorithms */
790 rp->comp_alg_list = strdup("none");
791 rp->comp_alg_len = strlen("none");
793 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
794 2 + rp->version_len +
795 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
796 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
797 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
803 /******************************* Protocol API *******************************/
805 /* Allocates new SKE object. */
807 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
808 SilcSKR repository, SilcPublicKey public_key,
809 SilcPrivateKey private_key, void *context)
813 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
815 if (!rng || !schedule || !public_key)
818 ske = silc_calloc(1, sizeof(*ske));
821 ske->status = SILC_SKE_STATUS_OK;
823 ske->repository = repository;
824 ske->user_data = context;
825 ske->schedule = schedule;
826 ske->public_key = public_key;
827 ske->private_key = private_key;
832 /* Free's SKE object. */
834 void silc_ske_free(SilcSKE ske)
836 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
839 /* Free start payload */
840 if (ske->start_payload)
841 silc_ske_payload_start_free(ske->start_payload);
843 /* Free KE payload */
844 if (ske->ke1_payload)
845 silc_ske_payload_ke_free(ske->ke1_payload);
846 if (ske->ke2_payload)
847 silc_ske_payload_ke_free(ske->ke2_payload);
848 silc_free(ske->remote_version);
852 if (ske->prop->group)
853 silc_ske_group_free(ske->prop->group);
854 if (ske->prop->cipher)
855 silc_cipher_free(ske->prop->cipher);
857 silc_hash_free(ske->prop->hash);
859 silc_hmac_free(ske->prop->hmac);
860 silc_free(ske->prop);
862 if (ske->start_payload_copy)
863 silc_buffer_free(ske->start_payload_copy);
865 silc_mp_uninit(ske->x);
869 silc_mp_uninit(ske->KEY);
872 silc_free(ske->hash);
873 silc_free(ske->callbacks);
875 memset(ske, 'F', sizeof(*ske));
880 /* Return user context */
882 void *silc_ske_get_context(SilcSKE ske)
884 return ske->user_data;
887 /* Sets protocol callbacks */
889 void silc_ske_set_callbacks(SilcSKE ske,
890 SilcSKEVerifyCb verify_key,
891 SilcSKECompletionCb completed,
895 silc_free(ske->callbacks);
896 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
899 ske->callbacks->verify_key = verify_key;
900 ske->callbacks->completed = completed;
901 ske->callbacks->context = context;
905 /******************************** Initiator *********************************/
907 /* Initiator state machine */
908 SILC_FSM_STATE(silc_ske_st_initiator_start);
909 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
910 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
911 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
912 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
913 SILC_FSM_STATE(silc_ske_st_initiator_end);
914 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
915 SILC_FSM_STATE(silc_ske_st_initiator_error);
916 SILC_FSM_STATE(silc_ske_st_initiator_failure);
918 /* Start protocol. Send our proposal */
920 SILC_FSM_STATE(silc_ske_st_initiator_start)
922 SilcSKE ske = fsm_context;
923 SilcBuffer payload_buf;
926 SILC_LOG_DEBUG(("Start"));
930 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
931 return SILC_FSM_CONTINUE;
934 /* Encode the payload */
935 status = silc_ske_payload_start_encode(ske, ske->start_payload,
937 if (status != SILC_SKE_STATUS_OK) {
938 /** Error encoding Start Payload */
939 ske->status = status;
940 silc_fsm_next(fsm, silc_ske_st_initiator_error);
941 return SILC_FSM_CONTINUE;
944 /* Save the the payload buffer for future use. It is later used to
945 compute the HASH value. */
946 ske->start_payload_copy = payload_buf;
948 /* Send the packet. */
949 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
950 silc_buffer_data(payload_buf),
951 silc_buffer_len(payload_buf))) {
952 /** Error sending packet */
953 ske->status = SILC_SKE_STATUS_ERROR;
954 silc_fsm_next(fsm, silc_ske_st_initiator_error);
955 return SILC_FSM_CONTINUE;
960 /** Wait for responder proposal */
961 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
962 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
963 return SILC_FSM_WAIT;
966 /* Phase-1. Receives responder's proposal */
968 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
970 SilcSKE ske = fsm_context;
971 SilcSKEStatus status;
972 SilcSKEStartPayload payload;
973 SilcSKESecurityProperties prop;
974 SilcSKEDiffieHellmanGroup group;
975 SilcBuffer packet_buf = &ske->packet->buffer;
976 SilcUInt16 remote_port = 0;
980 SILC_LOG_DEBUG(("Start"));
984 silc_packet_free(ske->packet);
985 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
986 return SILC_FSM_CONTINUE;
989 /* Decode the payload */
990 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
991 if (status != SILC_SKE_STATUS_OK) {
992 /** Error decoding Start Payload */
993 silc_packet_free(ske->packet);
994 ske->status = status;
995 silc_fsm_next(fsm, silc_ske_st_initiator_error);
996 return SILC_FSM_CONTINUE;
999 /* Get remote ID and set it to stream */
1000 if (ske->packet->src_id_len) {
1001 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1002 ske->packet->src_id_type,
1003 (ske->packet->src_id_type == SILC_ID_SERVER ?
1004 (void *)&id.u.server_id : (void *)&id.u.client_id),
1005 (ske->packet->src_id_type == SILC_ID_SERVER ?
1006 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1007 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1008 (ske->packet->src_id_type == SILC_ID_SERVER ?
1009 (void *)&id.u.server_id : (void *)&id.u.client_id));
1012 silc_packet_free(ske->packet);
1014 /* Check that the cookie is returned unmodified. In case IV included
1015 flag and session port has been set, the first two bytes of cookie
1016 are the session port and we ignore them in this check. */
1017 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1018 /* Take remote port */
1019 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1022 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1023 SILC_SKE_COOKIE_LEN - coff)) {
1024 /** Invalid cookie */
1025 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1026 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1027 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1028 return SILC_FSM_CONTINUE;
1031 /* Check version string */
1032 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1033 status = silc_ske_check_version(ske);
1034 if (status != SILC_SKE_STATUS_OK) {
1035 /** Version mismatch */
1036 ske->status = status;
1037 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1038 return SILC_FSM_CONTINUE;
1041 /* Free our KE Start Payload context, we don't need it anymore. */
1042 silc_ske_payload_start_free(ske->start_payload);
1043 ske->start_payload = NULL;
1045 /* Take the selected security properties into use while doing
1046 the key exchange. This is used only while doing the key
1048 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1051 prop->flags = payload->flags;
1052 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1053 if (status != SILC_SKE_STATUS_OK)
1056 prop->group = group;
1057 prop->remote_port = remote_port;
1059 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1060 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1063 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1064 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1067 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1068 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1071 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1072 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1076 /* Save remote's KE Start Payload */
1077 ske->start_payload = payload;
1079 /** Send KE Payload */
1080 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1081 return SILC_FSM_CONTINUE;
1085 silc_ske_payload_start_free(payload);
1087 silc_ske_group_free(group);
1090 silc_cipher_free(prop->cipher);
1092 silc_hash_free(prop->hash);
1094 silc_hmac_free(prop->hmac);
1098 if (status == SILC_SKE_STATUS_OK)
1099 status = SILC_SKE_STATUS_ERROR;
1102 ske->status = status;
1103 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1104 return SILC_FSM_CONTINUE;
1107 /* Phase-2. Send KE payload */
1109 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1111 SilcSKE ske = fsm_context;
1112 SilcSKEStatus status;
1113 SilcBuffer payload_buf;
1115 SilcSKEKEPayload payload;
1118 SILC_LOG_DEBUG(("Start"));
1120 /* Create the random number x, 1 < x < q. */
1121 x = silc_calloc(1, sizeof(*x));
1123 /** Out of memory */
1124 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1125 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1126 return SILC_FSM_CONTINUE;
1130 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1131 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1133 if (status != SILC_SKE_STATUS_OK) {
1134 /** Error generating random number */
1137 ske->status = status;
1138 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1139 return SILC_FSM_CONTINUE;
1142 /* Encode the result to Key Exchange Payload. */
1144 payload = silc_calloc(1, sizeof(*payload));
1146 /** Out of memory */
1149 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1150 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1151 return SILC_FSM_CONTINUE;
1153 ske->ke1_payload = payload;
1155 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1157 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1158 silc_mp_init(&payload->x);
1159 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1160 &ske->prop->group->group);
1162 /* Get public key */
1163 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1164 if (!payload->pk_data) {
1165 /** Error encoding public key */
1168 silc_mp_uninit(&payload->x);
1170 ske->ke1_payload = NULL;
1171 ske->status = SILC_SKE_STATUS_ERROR;
1172 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1173 return SILC_FSM_CONTINUE;
1175 payload->pk_len = pk_len;
1176 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1178 /* Compute signature data if we are doing mutual authentication */
1179 if (ske->private_key &&
1180 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1181 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1182 SilcUInt32 hash_len, sign_len;
1184 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1185 SILC_LOG_DEBUG(("Computing HASH_i value"));
1187 /* Compute the hash value */
1188 memset(hash, 0, sizeof(hash));
1189 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1191 SILC_LOG_DEBUG(("Signing HASH_i value"));
1193 /* Sign the hash value */
1194 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1195 sizeof(sign) - 1, &sign_len, NULL)) {
1196 /** Error computing signature */
1199 silc_mp_uninit(&payload->x);
1200 silc_free(payload->pk_data);
1202 ske->ke1_payload = NULL;
1203 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1204 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1205 return SILC_FSM_CONTINUE;
1207 payload->sign_data = silc_memdup(sign, sign_len);
1208 if (payload->sign_data)
1209 payload->sign_len = sign_len;
1210 memset(sign, 0, sizeof(sign));
1213 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1214 if (status != SILC_SKE_STATUS_OK) {
1215 /** Error encoding KE payload */
1218 silc_mp_uninit(&payload->x);
1219 silc_free(payload->pk_data);
1220 silc_free(payload->sign_data);
1222 ske->ke1_payload = NULL;
1223 ske->status = status;
1224 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1225 return SILC_FSM_CONTINUE;
1230 /* Check for backwards compatibility */
1232 /* Send the packet. */
1233 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_1, 0,
1234 silc_buffer_data(payload_buf),
1235 silc_buffer_len(payload_buf))) {
1236 /** Error sending packet */
1237 ske->status = SILC_SKE_STATUS_ERROR;
1238 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1239 return SILC_FSM_CONTINUE;
1242 silc_buffer_free(payload_buf);
1244 /** Waiting responder's KE payload */
1245 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1246 return SILC_FSM_WAIT;
1249 /* Phase-3. Process responder's KE payload */
1251 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1253 SilcSKE ske = fsm_context;
1254 SilcSKEStatus status;
1255 SilcSKEKEPayload payload;
1257 SilcBuffer packet_buf = &ske->packet->buffer;
1259 SILC_LOG_DEBUG(("Start"));
1263 silc_packet_free(ske->packet);
1264 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1265 return SILC_FSM_CONTINUE;
1268 /* Decode the payload */
1269 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1270 if (status != SILC_SKE_STATUS_OK) {
1271 /** Error decoding KE payload */
1272 silc_packet_free(ske->packet);
1273 ske->status = status;
1274 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1275 return SILC_FSM_CONTINUE;
1277 silc_packet_free(ske->packet);
1278 ske->ke2_payload = payload;
1280 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1281 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1282 "even though we require it"));
1283 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1287 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1289 /* Compute the shared secret key */
1290 KEY = silc_calloc(1, sizeof(*KEY));
1292 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1295 /* Decode the remote's public key */
1296 if (payload->pk_data &&
1297 !silc_pkcs_public_key_alloc(payload->pk_type,
1298 payload->pk_data, payload->pk_len,
1299 &ske->prop->public_key)) {
1300 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1301 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1305 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1307 SILC_LOG_DEBUG(("Verifying public key"));
1309 /** Waiting public key verification */
1310 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1312 /* If repository is provided, verify the key from there. */
1313 if (ske->repository) {
1316 find = silc_skr_find_alloc();
1318 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1321 silc_skr_find_set_pkcs_type(find,
1322 silc_pkcs_get_type(ske->prop->public_key));
1323 silc_skr_find_set_public_key(find, ske->prop->public_key);
1324 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1326 /* Find key from repository */
1327 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1328 silc_ske_skr_callback, ske));
1330 /* Verify from application */
1331 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1332 ske->callbacks->context,
1333 silc_ske_pk_verified, NULL));
1338 /** Process key material */
1339 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1340 return SILC_FSM_CONTINUE;
1343 silc_ske_payload_ke_free(payload);
1344 ske->ke2_payload = NULL;
1346 silc_mp_uninit(ske->KEY);
1347 silc_free(ske->KEY);
1350 if (status == SILC_SKE_STATUS_OK)
1351 return SILC_SKE_STATUS_ERROR;
1354 ske->status = status;
1355 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1356 return SILC_FSM_CONTINUE;
1359 /* Process key material */
1361 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1363 SilcSKE ske = fsm_context;
1364 SilcSKEStatus status;
1365 SilcSKEKEPayload payload;
1366 unsigned char hash[SILC_HASH_MAXLEN];
1367 SilcUInt32 hash_len;
1368 int key_len, block_len;
1372 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1373 return SILC_FSM_CONTINUE;
1376 /* Check result of public key verification */
1377 if (ske->status != SILC_SKE_STATUS_OK) {
1378 /** Public key not verified */
1379 SILC_LOG_DEBUG(("Public key verification failed"));
1380 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1381 return SILC_FSM_CONTINUE;
1384 payload = ske->ke2_payload;
1386 if (ske->prop->public_key) {
1387 SILC_LOG_DEBUG(("Public key is authentic"));
1389 /* Compute the hash value */
1390 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1391 if (status != SILC_SKE_STATUS_OK)
1394 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1396 /* Verify signature */
1397 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1398 payload->sign_len, hash, hash_len, NULL)) {
1399 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1400 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1404 SILC_LOG_DEBUG(("Signature is Ok"));
1406 ske->hash = silc_memdup(hash, hash_len);
1407 ske->hash_len = hash_len;
1408 memset(hash, 'F', hash_len);
1411 ske->status = SILC_SKE_STATUS_OK;
1413 /* Process key material */
1414 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1415 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1416 hash_len = silc_hash_len(ske->prop->hash);
1417 ske->keymat = silc_ske_process_key_material(ske, block_len,
1420 SILC_LOG_ERROR(("Error processing key material"));
1421 status = SILC_SKE_STATUS_ERROR;
1425 /* Send SUCCESS packet */
1426 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1427 if (!silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1428 /** Error sending packet */
1429 ske->status = SILC_SKE_STATUS_ERROR;
1430 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1431 return SILC_FSM_CONTINUE;
1434 /** Waiting completion */
1435 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1436 return SILC_FSM_WAIT;
1439 memset(hash, 'F', sizeof(hash));
1440 silc_ske_payload_ke_free(payload);
1441 ske->ke2_payload = NULL;
1443 silc_mp_uninit(ske->KEY);
1444 silc_free(ske->KEY);
1448 memset(ske->hash, 'F', hash_len);
1449 silc_free(ske->hash);
1453 if (status == SILC_SKE_STATUS_OK)
1454 status = SILC_SKE_STATUS_ERROR;
1457 ske->status = status;
1458 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1459 return SILC_FSM_CONTINUE;
1462 /* Protocol completed */
1464 SILC_FSM_STATE(silc_ske_st_initiator_end)
1466 SilcSKE ske = fsm_context;
1468 SILC_LOG_DEBUG(("Start"));
1472 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1473 return SILC_FSM_CONTINUE;
1476 /* See if received failure from remote */
1477 if (ske->packet->type == SILC_PACKET_FAILURE) {
1478 silc_packet_free(ske->packet);
1479 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1480 return SILC_FSM_CONTINUE;
1483 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1485 /* Call the completion callback */
1486 if (ske->callbacks->completed)
1487 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1488 ske->rekey, ske->user_data);
1490 silc_packet_free(ske->packet);
1492 return SILC_FSM_FINISH;
1495 /* Aborted by application */
1497 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1499 SilcSKE ske = fsm_context;
1500 unsigned char data[4];
1502 SILC_LOG_DEBUG(("Aborted by caller"));
1504 /* Send FAILURE packet */
1505 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1506 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1508 return SILC_FSM_FINISH;
1511 /* Error occurred. Send error to remote host */
1513 SILC_FSM_STATE(silc_ske_st_initiator_error)
1515 SilcSKE ske = fsm_context;
1516 SilcSKEStatus status;
1517 unsigned char data[4];
1519 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1520 silc_ske_map_status(ske->status), ske->status));
1522 status = ske->status;
1523 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1524 status = SILC_SKE_STATUS_ERROR;
1526 /* Send FAILURE packet */
1527 SILC_PUT32_MSB((SilcUInt32)status, data);
1528 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1530 /* Call the completion callback */
1531 if (ske->callbacks->completed)
1532 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1534 return SILC_FSM_FINISH;
1537 /* Failure received from remote */
1539 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1541 SilcSKE ske = fsm_context;
1543 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1544 silc_ske_map_status(ske->status), ske->status));
1546 /* Call the completion callback */
1547 if (ske->callbacks->completed)
1548 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1550 return SILC_FSM_FINISH;
1553 /* FSM destructor */
1555 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1556 void *destructor_context)
1558 SilcSKE ske = fsm_context;
1559 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1562 /* Starts the protocol as initiator */
1565 silc_ske_initiator(SilcSKE ske,
1566 SilcPacketStream stream,
1567 SilcSKEParams params,
1568 SilcSKEStartPayload start_payload)
1570 SILC_LOG_DEBUG(("Start SKE as initiator"));
1572 if (!ske || !stream || !params || !params->version)
1575 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1578 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1582 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1583 ske->session_port = params->session_port;
1585 /* Generate security properties if not provided */
1586 if (!start_payload) {
1587 start_payload = silc_ske_assemble_security_properties(ske,
1594 ske->start_payload = start_payload;
1595 ske->version = params->version;
1597 /* Link to packet stream to get key exchange packets */
1598 ske->stream = stream;
1599 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1600 SILC_PACKET_KEY_EXCHANGE,
1601 SILC_PACKET_KEY_EXCHANGE_2,
1602 SILC_PACKET_SUCCESS,
1603 SILC_PACKET_FAILURE, -1);
1605 /* Start SKE as initiator */
1606 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1612 /******************************** Responder *********************************/
1614 SILC_FSM_STATE(silc_ske_st_responder_start);
1615 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1616 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1617 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1618 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1619 SILC_FSM_STATE(silc_ske_st_responder_end);
1620 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1621 SILC_FSM_STATE(silc_ske_st_responder_failure);
1622 SILC_FSM_STATE(silc_ske_st_responder_error);
1624 /* Start protocol as responder. Wait initiator's start payload */
1626 SILC_FSM_STATE(silc_ske_st_responder_start)
1628 SilcSKE ske = fsm_context;
1630 SILC_LOG_DEBUG(("Start"));
1634 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1635 return SILC_FSM_CONTINUE;
1641 /** Wait for initiator */
1642 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1643 return SILC_FSM_WAIT;
1646 /* Decode initiator's start payload. Select the security properties from
1647 the initiator's start payload and send our reply start payload back. */
1649 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1651 SilcSKE ske = fsm_context;
1652 SilcSKEStatus status;
1653 SilcSKEStartPayload remote_payload = NULL;
1654 SilcBuffer packet_buf = &ske->packet->buffer;
1656 SILC_LOG_DEBUG(("Start"));
1660 silc_packet_free(ske->packet);
1661 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1662 return SILC_FSM_CONTINUE;
1665 /* See if received failure from remote */
1666 if (ske->packet->type == SILC_PACKET_FAILURE) {
1667 silc_packet_free(ske->packet);
1668 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1669 return SILC_FSM_CONTINUE;
1672 /* Decode the payload */
1673 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1674 if (status != SILC_SKE_STATUS_OK) {
1675 /** Error decoding Start Payload */
1676 silc_packet_free(ske->packet);
1677 ske->status = status;
1678 silc_fsm_next(fsm, silc_ske_st_responder_error);
1679 return SILC_FSM_CONTINUE;
1682 /* Take a copy of the payload buffer for future use. It is used to
1683 compute the HASH value. */
1684 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1686 silc_packet_free(ske->packet);
1688 /* Force the mutual authentication flag if we want to do it. */
1689 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1690 SILC_LOG_DEBUG(("Force mutual authentication"));
1691 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1694 /* Force PFS flag if we require it */
1695 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1696 SILC_LOG_DEBUG(("Force PFS"));
1697 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1700 /* Disable IV Included flag if requested */
1701 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1702 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1703 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1704 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1707 /* Check and select security properties */
1708 status = silc_ske_select_security_properties(ske, remote_payload,
1710 if (status != SILC_SKE_STATUS_OK) {
1711 /** Error selecting proposal */
1712 silc_ske_payload_start_free(remote_payload);
1713 ske->status = status;
1714 silc_fsm_next(fsm, silc_ske_st_responder_error);
1715 return SILC_FSM_CONTINUE;
1718 silc_ske_payload_start_free(remote_payload);
1720 /* Encode our reply payload to send the selected security properties */
1721 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1723 if (status != SILC_SKE_STATUS_OK)
1726 /* Send the packet. */
1727 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1728 silc_buffer_data(packet_buf),
1729 silc_buffer_len(packet_buf)))
1732 silc_buffer_free(packet_buf);
1734 /** Waiting initiator's KE payload */
1735 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1736 return SILC_FSM_WAIT;
1739 if (ske->prop->group)
1740 silc_ske_group_free(ske->prop->group);
1741 if (ske->prop->cipher)
1742 silc_cipher_free(ske->prop->cipher);
1743 if (ske->prop->hash)
1744 silc_hash_free(ske->prop->hash);
1745 if (ske->prop->hmac)
1746 silc_hmac_free(ske->prop->hmac);
1747 silc_free(ske->prop);
1750 if (status == SILC_SKE_STATUS_OK)
1751 status = SILC_SKE_STATUS_ERROR;
1754 ske->status = status;
1755 silc_fsm_next(fsm, silc_ske_st_responder_error);
1756 return SILC_FSM_CONTINUE;
1759 /* Phase-2. Decode initiator's KE payload */
1761 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1763 SilcSKE ske = fsm_context;
1764 SilcSKEStatus status;
1765 SilcSKEKEPayload recv_payload;
1766 SilcBuffer packet_buf = &ske->packet->buffer;
1768 SILC_LOG_DEBUG(("Start"));
1772 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1773 return SILC_FSM_CONTINUE;
1776 /* See if received failure from remote */
1777 if (ske->packet->type == SILC_PACKET_FAILURE) {
1778 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1779 return SILC_FSM_CONTINUE;
1782 /* Decode Key Exchange Payload */
1783 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1784 if (status != SILC_SKE_STATUS_OK) {
1785 /** Error decoding KE payload */
1786 silc_packet_free(ske->packet);
1787 ske->status = status;
1788 silc_fsm_next(fsm, silc_ske_st_responder_error);
1789 return SILC_FSM_CONTINUE;
1792 ske->ke1_payload = recv_payload;
1794 silc_packet_free(ske->packet);
1796 /* Verify the received public key and verify the signature if we are
1797 doing mutual authentication. */
1798 if (ske->start_payload &&
1799 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1801 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1803 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1805 /** Public key not provided */
1806 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1807 "certificate), even though we require it"));
1808 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1809 silc_fsm_next(fsm, silc_ske_st_responder_error);
1810 return SILC_FSM_CONTINUE;
1813 /* Decode the remote's public key */
1814 if (recv_payload->pk_data &&
1815 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1816 recv_payload->pk_data,
1817 recv_payload->pk_len,
1818 &ske->prop->public_key)) {
1819 /** Error decoding public key */
1820 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1821 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1822 silc_fsm_next(fsm, silc_ske_st_responder_error);
1823 return SILC_FSM_CONTINUE;
1826 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1828 SILC_LOG_DEBUG(("Verifying public key"));
1830 /** Waiting public key verification */
1831 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1833 /* If repository is provided, verify the key from there. */
1834 if (ske->repository) {
1837 find = silc_skr_find_alloc();
1839 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1840 silc_fsm_next(fsm, silc_ske_st_responder_error);
1841 return SILC_FSM_CONTINUE;
1843 silc_skr_find_set_pkcs_type(find,
1844 silc_pkcs_get_type(ske->prop->public_key));
1845 silc_skr_find_set_public_key(find, ske->prop->public_key);
1846 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1848 /* Find key from repository */
1849 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1850 silc_ske_skr_callback, ske));
1852 /* Verify from application */
1853 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1854 ske->callbacks->context,
1855 silc_ske_pk_verified, NULL));
1861 /** Generate KE2 payload */
1862 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1863 return SILC_FSM_CONTINUE;
1866 /* Phase-4. Generate KE2 payload */
1868 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1870 SilcSKE ske = fsm_context;
1871 SilcSKEStatus status;
1872 SilcSKEKEPayload recv_payload, send_payload;
1877 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1878 return SILC_FSM_CONTINUE;
1881 /* Check result of public key verification */
1882 if (ske->status != SILC_SKE_STATUS_OK) {
1883 /** Public key not verified */
1884 SILC_LOG_DEBUG(("Public key verification failed"));
1885 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1886 return SILC_FSM_CONTINUE;
1889 recv_payload = ske->ke1_payload;
1891 /* The public key verification was performed only if the Mutual
1892 Authentication flag is set. */
1893 if (ske->start_payload &&
1894 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1895 unsigned char hash[SILC_HASH_MAXLEN];
1896 SilcUInt32 hash_len;
1898 SILC_LOG_DEBUG(("Public key is authentic"));
1900 /* Compute the hash value */
1901 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1902 if (status != SILC_SKE_STATUS_OK) {
1903 /** Error computing hash */
1904 ske->status = status;
1905 silc_fsm_next(fsm, silc_ske_st_responder_error);
1906 return SILC_FSM_CONTINUE;
1909 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1911 /* Verify signature */
1912 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
1913 recv_payload->sign_len, hash, hash_len, NULL)) {
1914 /** Incorrect signature */
1915 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1916 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1917 silc_fsm_next(fsm, silc_ske_st_responder_error);
1918 return SILC_FSM_CONTINUE;
1921 SILC_LOG_DEBUG(("Signature is Ok"));
1923 memset(hash, 'F', hash_len);
1926 /* Create the random number x, 1 < x < q. */
1927 x = silc_calloc(1, sizeof(*x));
1930 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1931 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1933 if (status != SILC_SKE_STATUS_OK) {
1934 /** Error generating random number */
1937 ske->status = status;
1938 silc_fsm_next(fsm, silc_ske_st_responder_error);
1939 return SILC_FSM_CONTINUE;
1942 /* Save the results for later processing */
1943 send_payload = silc_calloc(1, sizeof(*send_payload));
1945 ske->ke2_payload = send_payload;
1947 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1949 /* Do the Diffie Hellman computation, f = g ^ x mod p */
1950 silc_mp_init(&send_payload->x);
1951 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1952 &ske->prop->group->group);
1954 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1956 /* Compute the shared secret key */
1957 KEY = silc_calloc(1, sizeof(*KEY));
1959 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1960 &ske->prop->group->group);
1963 /** Send KE2 payload */
1964 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1965 return SILC_FSM_CONTINUE;
1968 /* Phase-5. Send KE2 payload */
1970 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1972 SilcSKE ske = fsm_context;
1973 SilcSKEStatus status;
1974 SilcBuffer payload_buf;
1975 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1976 SilcUInt32 hash_len, sign_len, pk_len;
1978 SILC_LOG_DEBUG(("Start"));
1980 if (ske->public_key && ske->private_key) {
1981 SILC_LOG_DEBUG(("Getting public key"));
1983 /* Get the public key */
1984 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1986 /** Error encoding public key */
1987 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1988 silc_fsm_next(fsm, silc_ske_st_responder_error);
1989 return SILC_FSM_CONTINUE;
1991 ske->ke2_payload->pk_data = pk;
1992 ske->ke2_payload->pk_len = pk_len;
1994 SILC_LOG_DEBUG(("Computing HASH value"));
1996 /* Compute the hash value */
1997 memset(hash, 0, sizeof(hash));
1998 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1999 if (status != SILC_SKE_STATUS_OK) {
2000 /** Error computing hash */
2001 ske->status = status;
2002 silc_fsm_next(fsm, silc_ske_st_responder_error);
2003 return SILC_FSM_CONTINUE;
2006 ske->hash = silc_memdup(hash, hash_len);
2007 ske->hash_len = hash_len;
2009 SILC_LOG_DEBUG(("Signing HASH value"));
2011 /* Sign the hash value */
2012 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2013 sizeof(sign) - 1, &sign_len, NULL)) {
2014 /** Error computing signature */
2015 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2016 silc_fsm_next(fsm, silc_ske_st_responder_error);
2017 return SILC_FSM_CONTINUE;
2019 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2020 ske->ke2_payload->sign_len = sign_len;
2021 memset(sign, 0, sizeof(sign));
2023 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2025 /* Encode the Key Exchange Payload */
2026 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2028 if (status != SILC_SKE_STATUS_OK) {
2029 /** Error encoding KE payload */
2030 ske->status = status;
2031 silc_fsm_next(fsm, silc_ske_st_responder_error);
2032 return SILC_FSM_CONTINUE;
2035 /* Send the packet. */
2036 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
2037 payload_buf->data, silc_buffer_len(payload_buf))) {
2038 ske->status = SILC_SKE_STATUS_ERROR;
2039 silc_fsm_next(fsm, silc_ske_st_responder_error);
2040 return SILC_FSM_CONTINUE;
2043 silc_buffer_free(payload_buf);
2045 /** Waiting completion */
2046 silc_fsm_next(fsm, silc_ske_st_responder_end);
2047 return SILC_FSM_WAIT;
2050 /* Protocol completed */
2052 SILC_FSM_STATE(silc_ske_st_responder_end)
2054 SilcSKE ske = fsm_context;
2055 unsigned char tmp[4];
2056 SilcUInt32 hash_len, key_len, block_len;
2060 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2061 return SILC_FSM_CONTINUE;
2064 /* Check the result of the protocol */
2065 if (ske->packet->type == SILC_PACKET_FAILURE) {
2066 silc_fsm_next(fsm, silc_ske_st_responder_failure);
2067 return SILC_FSM_CONTINUE;
2069 silc_packet_free(ske->packet);
2071 /* Process key material */
2072 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2073 block_len = silc_cipher_get_key_len(ske->prop->cipher);
2074 hash_len = silc_hash_len(ske->prop->hash);
2075 ske->keymat = silc_ske_process_key_material(ske, block_len,
2078 /** Error processing key material */
2079 ske->status = SILC_SKE_STATUS_ERROR;
2080 silc_fsm_next(fsm, silc_ske_st_responder_error);
2081 return SILC_FSM_CONTINUE;
2084 /* Send SUCCESS packet */
2085 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2086 silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
2088 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2090 /* Call the completion callback */
2091 if (ske->callbacks->completed)
2092 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
2093 ske->rekey, ske->callbacks->context);
2095 return SILC_FSM_FINISH;
2098 /* Aborted by application */
2100 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2102 SilcSKE ske = fsm_context;
2103 unsigned char tmp[4];
2105 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2107 /* Send FAILURE packet */
2108 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2109 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2111 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2113 return SILC_FSM_FINISH;
2116 /* Failure received from remote */
2118 SILC_FSM_STATE(silc_ske_st_responder_failure)
2120 SilcSKE ske = fsm_context;
2121 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2123 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2125 if (silc_buffer_len(&ske->packet->buffer) == 4)
2126 SILC_GET32_MSB(error, ske->packet->buffer.data);
2127 ske->status = error;
2129 /* Call the completion callback */
2130 if (ske->callbacks->completed)
2131 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
2132 ske->callbacks->context);
2134 silc_packet_free(ske->packet);
2135 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2137 return SILC_FSM_FINISH;
2140 /* Error occurred */
2142 SILC_FSM_STATE(silc_ske_st_responder_error)
2144 SilcSKE ske = fsm_context;
2145 unsigned char tmp[4];
2147 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2148 ske->status, silc_ske_map_status(ske->status)));
2150 /* Send FAILURE packet */
2151 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2152 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2153 SILC_PUT32_MSB(ske->status, tmp);
2154 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2156 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2158 return SILC_FSM_FINISH;
2162 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
2163 void *destructor_context)
2168 /* Starts the protocol as responder. */
2171 silc_ske_responder(SilcSKE ske,
2172 SilcPacketStream stream,
2173 SilcSKEParams params)
2175 SILC_LOG_DEBUG(("Start SKE as responder"));
2177 if (!ske || !stream || !params || !params->version) {
2181 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2184 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2188 ske->responder = TRUE;
2189 ske->flags = params->flags;
2190 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2191 ske->session_port = params->session_port;
2192 ske->version = strdup(params->version);
2196 /* Link to packet stream to get key exchange packets */
2197 ske->stream = stream;
2198 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2199 SILC_PACKET_KEY_EXCHANGE,
2200 SILC_PACKET_KEY_EXCHANGE_1,
2201 SILC_PACKET_SUCCESS,
2202 SILC_PACKET_FAILURE, -1);
2204 /* Start SKE as responder */
2205 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2210 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2212 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2214 return SILC_FSM_FINISH;
2217 /* Starts rekey protocol as initiator */
2220 silc_ske_rekey_initiator(SilcSKE ske,
2221 SilcPacketStream stream,
2222 SilcSKERekeyMaterial rekey)
2224 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2226 if (!ske || !stream || !rekey)
2229 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2232 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2237 /* Link to packet stream to get key exchange packets */
2238 ske->stream = stream;
2240 /* Start SKE rekey as initiator */
2241 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2246 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2248 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2250 return SILC_FSM_FINISH;
2253 /* Starts rekey protocol as responder */
2256 silc_ske_rekey_responder(SilcSKE ske,
2257 SilcPacketStream stream,
2258 SilcBuffer ke_payload,
2259 SilcSKERekeyMaterial rekey)
2261 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2263 if (!ske || !stream || !rekey)
2265 if (rekey->pfs && !ke_payload)
2268 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2271 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2274 // ske->packet_buf = ke_payload;
2277 /* Link to packet stream to get key exchange packets */
2278 ske->stream = stream;
2280 /* Start SKE rekey as responder */
2281 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2286 /* Processes the provided key material `data' as the SILC protocol
2287 specification defines. */
2290 silc_ske_process_key_material_data(unsigned char *data,
2291 SilcUInt32 data_len,
2292 SilcUInt32 req_iv_len,
2293 SilcUInt32 req_enc_key_len,
2294 SilcUInt32 req_hmac_key_len,
2298 unsigned char hashd[SILC_HASH_MAXLEN];
2299 SilcUInt32 hash_len = req_hmac_key_len;
2300 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2301 SilcSKEKeyMaterial key;
2303 SILC_LOG_DEBUG(("Start"));
2305 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2308 key = silc_calloc(1, sizeof(*key));
2312 buf = silc_buffer_alloc_size(1 + data_len);
2315 silc_buffer_format(buf,
2316 SILC_STR_UI_CHAR(0),
2317 SILC_STR_UI_XNSTRING(data, data_len),
2321 memset(hashd, 0, sizeof(hashd));
2323 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2324 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2325 memcpy(key->send_iv, hashd, req_iv_len);
2326 memset(hashd, 0, sizeof(hashd));
2328 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2329 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2330 memcpy(key->receive_iv, hashd, req_iv_len);
2331 key->iv_len = req_iv_len;
2333 /* Take the encryption keys. If requested key size is more than
2334 the size of hash length we will distribute more key material
2335 as protocol defines. */
2337 if (enc_key_len > hash_len) {
2339 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2340 k3[SILC_HASH_MAXLEN];
2341 unsigned char *dtmp;
2344 if (enc_key_len > (3 * hash_len))
2347 /* Take first round */
2348 memset(k1, 0, sizeof(k1));
2349 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2351 /* Take second round */
2352 dist = silc_buffer_alloc_size(data_len + hash_len);
2355 silc_buffer_format(dist,
2356 SILC_STR_UI_XNSTRING(data, data_len),
2357 SILC_STR_UI_XNSTRING(k1, hash_len),
2359 memset(k2, 0, sizeof(k2));
2360 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2362 /* Take third round */
2363 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2364 silc_buffer_pull_tail(dist, hash_len);
2365 silc_buffer_pull(dist, data_len + hash_len);
2366 silc_buffer_format(dist,
2367 SILC_STR_UI_XNSTRING(k2, hash_len),
2369 silc_buffer_push(dist, data_len + hash_len);
2370 memset(k3, 0, sizeof(k3));
2371 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2373 /* Then, save the keys */
2374 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2375 memcpy(dtmp, k1, hash_len);
2376 memcpy(dtmp + hash_len, k2, hash_len);
2377 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2379 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2380 memcpy(key->send_enc_key, dtmp, enc_key_len);
2381 key->enc_key_len = req_enc_key_len;
2383 memset(dtmp, 0, (3 * hash_len));
2384 memset(k1, 0, sizeof(k1));
2385 memset(k2, 0, sizeof(k2));
2386 memset(k3, 0, sizeof(k3));
2388 silc_buffer_clear(dist);
2389 silc_buffer_free(dist);
2391 /* Take normal hash as key */
2392 memset(hashd, 0, sizeof(hashd));
2393 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2394 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2395 memcpy(key->send_enc_key, hashd, enc_key_len);
2396 key->enc_key_len = req_enc_key_len;
2400 if (enc_key_len > hash_len) {
2402 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2403 k3[SILC_HASH_MAXLEN];
2404 unsigned char *dtmp;
2407 if (enc_key_len > (3 * hash_len))
2410 /* Take first round */
2411 memset(k1, 0, sizeof(k1));
2412 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2414 /* Take second round */
2415 dist = silc_buffer_alloc_size(data_len + hash_len);
2418 silc_buffer_format(dist,
2419 SILC_STR_UI_XNSTRING(data, data_len),
2420 SILC_STR_UI_XNSTRING(k1, hash_len),
2422 memset(k2, 0, sizeof(k2));
2423 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2425 /* Take third round */
2426 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2427 silc_buffer_pull_tail(dist, hash_len);
2428 silc_buffer_pull(dist, data_len + hash_len);
2429 silc_buffer_format(dist,
2430 SILC_STR_UI_XNSTRING(k2, hash_len),
2432 silc_buffer_push(dist, data_len + hash_len);
2433 memset(k3, 0, sizeof(k3));
2434 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2436 /* Then, save the keys */
2437 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2438 memcpy(dtmp, k1, hash_len);
2439 memcpy(dtmp + hash_len, k2, hash_len);
2440 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2442 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2443 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2444 key->enc_key_len = req_enc_key_len;
2446 memset(dtmp, 0, (3 * hash_len));
2447 memset(k1, 0, sizeof(k1));
2448 memset(k2, 0, sizeof(k2));
2449 memset(k3, 0, sizeof(k3));
2451 silc_buffer_clear(dist);
2452 silc_buffer_free(dist);
2454 /* Take normal hash as key */
2455 memset(hashd, 0, sizeof(hashd));
2456 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2457 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2458 memcpy(key->receive_enc_key, hashd, enc_key_len);
2459 key->enc_key_len = req_enc_key_len;
2462 /* Take HMAC keys */
2463 memset(hashd, 0, sizeof(hashd));
2465 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2466 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2467 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2468 memset(hashd, 0, sizeof(hashd));
2470 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2471 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2472 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2473 key->hmac_key_len = req_hmac_key_len;
2474 memset(hashd, 0, sizeof(hashd));
2476 silc_buffer_clear(buf);
2477 silc_buffer_free(buf);
2482 /* Processes negotiated key material as protocol specifies. This returns
2483 the actual keys to be used in the SILC. */
2486 silc_ske_process_key_material(SilcSKE ske,
2487 SilcUInt32 req_iv_len,
2488 SilcUInt32 req_enc_key_len,
2489 SilcUInt32 req_hmac_key_len)
2492 unsigned char *tmpbuf;
2494 SilcSKEKeyMaterial key;
2496 /* Encode KEY to binary data */
2497 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2499 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2502 silc_buffer_format(buf,
2503 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2504 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2507 /* Process the key material */
2508 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2509 req_iv_len, req_enc_key_len,
2513 memset(tmpbuf, 0, klen);
2515 silc_buffer_clear(buf);
2516 silc_buffer_free(buf);
2521 /* Free key material structure */
2523 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2529 silc_free(key->send_iv);
2530 if (key->receive_iv)
2531 silc_free(key->receive_iv);
2532 if (key->send_enc_key) {
2533 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2534 silc_free(key->send_enc_key);
2536 if (key->receive_enc_key) {
2537 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2538 silc_free(key->receive_enc_key);
2540 if (key->send_hmac_key) {
2541 memset(key->send_hmac_key, 0, key->hmac_key_len);
2542 silc_free(key->send_hmac_key);
2544 if (key->receive_hmac_key) {
2545 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2546 silc_free(key->receive_hmac_key);
2551 /* Set keys into use */
2553 SilcBool silc_ske_set_keys(SilcSKE ske,
2554 SilcSKEKeyMaterial keymat,
2555 SilcSKESecurityProperties prop,
2556 SilcCipher *ret_send_key,
2557 SilcCipher *ret_receive_key,
2558 SilcHmac *ret_hmac_send,
2559 SilcHmac *ret_hmac_receive,
2562 /* Allocate ciphers to be used in the communication */
2564 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2568 if (ret_receive_key) {
2569 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2574 /* Allocate HMACs */
2575 if (ret_hmac_send) {
2576 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2580 if (ret_hmac_receive) {
2581 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2586 /* Set key material */
2587 if (ske->responder) {
2588 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2589 keymat->enc_key_len);
2590 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2591 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2592 keymat->enc_key_len);
2593 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2594 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2595 keymat->hmac_key_len);
2596 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2597 keymat->hmac_key_len);
2599 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2600 keymat->enc_key_len);
2601 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2602 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2603 keymat->enc_key_len);
2604 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2605 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2606 keymat->hmac_key_len);
2607 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2608 keymat->hmac_key_len);
2613 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2617 SILC_LOG_INFO(("Security properties: %s %s %s %s",
2618 ret_send_key ? silc_cipher_get_name(*ret_send_key) : "??",
2619 ret_hmac_send ? silc_hmac_get_name(*ret_hmac_send) : "??",
2620 ret_hash ? silc_hash_get_name(*ret_hash) : "??",
2621 ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : ""));
2626 const char *silc_ske_status_string[] =
2630 "Unkown error occurred",
2631 "Bad payload in packet",
2632 "Unsupported group",
2633 "Unsupported cipher",
2635 "Unsupported hash function",
2637 "Unsupported public key (or certificate)",
2638 "Incorrect signature",
2639 "Bad or unsupported version",
2643 "Remote did not provide public key",
2644 "Bad reserved field in packet",
2645 "Bad payload length in packet",
2646 "Error computing signature",
2647 "System out of memory",
2652 /* Maps status to readable string and returns the string. If string is not
2653 found and empty character string ("") is returned. */
2655 const char *silc_ske_map_status(SilcSKEStatus status)
2659 for (i = 0; silc_ske_status_string[i]; i++)
2661 return silc_ske_status_string[i];
2666 /* Parses remote host's version string. */
2668 SilcBool silc_ske_parse_version(SilcSKE ske,
2669 SilcUInt32 *protocol_version,
2670 char **protocol_version_string,
2671 SilcUInt32 *software_version,
2672 char **software_version_string,
2673 char **vendor_version)
2675 return silc_parse_version_string(ske->remote_version,
2677 protocol_version_string,
2679 software_version_string,
2683 /* Get security properties */
2685 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)