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);
1325 /* Find key from repository */
1326 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1327 silc_ske_skr_callback, ske));
1329 /* Verify from application */
1330 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1331 ske->callbacks->context,
1332 silc_ske_pk_verified, NULL));
1337 /** Process key material */
1338 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1339 return SILC_FSM_CONTINUE;
1342 silc_ske_payload_ke_free(payload);
1343 ske->ke2_payload = NULL;
1345 silc_mp_uninit(ske->KEY);
1346 silc_free(ske->KEY);
1349 if (status == SILC_SKE_STATUS_OK)
1350 return SILC_SKE_STATUS_ERROR;
1353 ske->status = status;
1354 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1355 return SILC_FSM_CONTINUE;
1358 /* Process key material */
1360 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1362 SilcSKE ske = fsm_context;
1363 SilcSKEStatus status;
1364 SilcSKEKEPayload payload;
1365 unsigned char hash[SILC_HASH_MAXLEN];
1366 SilcUInt32 hash_len;
1367 int key_len, block_len;
1371 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1372 return SILC_FSM_CONTINUE;
1375 /* Check result of public key verification */
1376 if (ske->status != SILC_SKE_STATUS_OK) {
1377 /** Public key not verified */
1378 SILC_LOG_DEBUG(("Public key verification failed"));
1379 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1380 return SILC_FSM_CONTINUE;
1383 payload = ske->ke2_payload;
1385 if (ske->prop->public_key) {
1386 SILC_LOG_DEBUG(("Public key is authentic"));
1388 /* Compute the hash value */
1389 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1390 if (status != SILC_SKE_STATUS_OK)
1393 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1395 /* Verify signature */
1396 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1397 payload->sign_len, hash, hash_len, NULL)) {
1398 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1399 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1403 SILC_LOG_DEBUG(("Signature is Ok"));
1405 ske->hash = silc_memdup(hash, hash_len);
1406 ske->hash_len = hash_len;
1407 memset(hash, 'F', hash_len);
1410 ske->status = SILC_SKE_STATUS_OK;
1412 /* Process key material */
1413 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1414 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1415 hash_len = silc_hash_len(ske->prop->hash);
1416 ske->keymat = silc_ske_process_key_material(ske, block_len,
1419 SILC_LOG_ERROR(("Error processing key material"));
1420 status = SILC_SKE_STATUS_ERROR;
1424 /* Send SUCCESS packet */
1425 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1426 if (!silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1427 /** Error sending packet */
1428 ske->status = SILC_SKE_STATUS_ERROR;
1429 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1430 return SILC_FSM_CONTINUE;
1433 /** Waiting completion */
1434 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1435 return SILC_FSM_WAIT;
1438 memset(hash, 'F', sizeof(hash));
1439 silc_ske_payload_ke_free(payload);
1440 ske->ke2_payload = NULL;
1442 silc_mp_uninit(ske->KEY);
1443 silc_free(ske->KEY);
1447 memset(ske->hash, 'F', hash_len);
1448 silc_free(ske->hash);
1452 if (status == SILC_SKE_STATUS_OK)
1453 status = SILC_SKE_STATUS_ERROR;
1456 ske->status = status;
1457 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1458 return SILC_FSM_CONTINUE;
1461 /* Protocol completed */
1463 SILC_FSM_STATE(silc_ske_st_initiator_end)
1465 SilcSKE ske = fsm_context;
1467 SILC_LOG_DEBUG(("Start"));
1471 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1472 return SILC_FSM_CONTINUE;
1475 /* See if received failure from remote */
1476 if (ske->packet->type == SILC_PACKET_FAILURE) {
1477 silc_packet_free(ske->packet);
1478 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1479 return SILC_FSM_CONTINUE;
1482 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1484 /* Call the completion callback */
1485 if (ske->callbacks->completed)
1486 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1487 ske->rekey, ske->user_data);
1489 silc_packet_free(ske->packet);
1491 return SILC_FSM_FINISH;
1494 /* Aborted by application */
1496 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1498 SilcSKE ske = fsm_context;
1499 unsigned char data[4];
1501 SILC_LOG_DEBUG(("Aborted by caller"));
1503 /* Send FAILURE packet */
1504 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1505 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1507 return SILC_FSM_FINISH;
1510 /* Error occurred. Send error to remote host */
1512 SILC_FSM_STATE(silc_ske_st_initiator_error)
1514 SilcSKE ske = fsm_context;
1515 SilcSKEStatus status;
1516 unsigned char data[4];
1518 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1519 silc_ske_map_status(ske->status), ske->status));
1521 status = ske->status;
1522 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1523 status = SILC_SKE_STATUS_ERROR;
1525 /* Send FAILURE packet */
1526 SILC_PUT32_MSB((SilcUInt32)status, data);
1527 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1529 /* Call the completion callback */
1530 if (ske->callbacks->completed)
1531 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1533 return SILC_FSM_FINISH;
1536 /* Failure received from remote */
1538 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1540 SilcSKE ske = fsm_context;
1542 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1543 silc_ske_map_status(ske->status), ske->status));
1545 /* Call the completion callback */
1546 if (ske->callbacks->completed)
1547 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1549 return SILC_FSM_FINISH;
1552 /* FSM destructor */
1554 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1555 void *destructor_context)
1557 SilcSKE ske = fsm_context;
1558 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1561 /* Starts the protocol as initiator */
1564 silc_ske_initiator(SilcSKE ske,
1565 SilcPacketStream stream,
1566 SilcSKEParams params,
1567 SilcSKEStartPayload start_payload)
1569 SILC_LOG_DEBUG(("Start SKE as initiator"));
1571 if (!ske || !stream || !params || !params->version)
1574 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1577 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1581 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1582 ske->session_port = params->session_port;
1584 /* Generate security properties if not provided */
1585 if (!start_payload) {
1586 start_payload = silc_ske_assemble_security_properties(ske,
1593 ske->start_payload = start_payload;
1594 ske->version = params->version;
1596 /* Link to packet stream to get key exchange packets */
1597 ske->stream = stream;
1598 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1599 SILC_PACKET_KEY_EXCHANGE,
1600 SILC_PACKET_KEY_EXCHANGE_2,
1601 SILC_PACKET_SUCCESS,
1602 SILC_PACKET_FAILURE, -1);
1604 /* Start SKE as initiator */
1605 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1611 /******************************** Responder *********************************/
1613 SILC_FSM_STATE(silc_ske_st_responder_start);
1614 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1615 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1616 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1617 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1618 SILC_FSM_STATE(silc_ske_st_responder_end);
1619 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1620 SILC_FSM_STATE(silc_ske_st_responder_failure);
1621 SILC_FSM_STATE(silc_ske_st_responder_error);
1623 /* Start protocol as responder. Wait initiator's start payload */
1625 SILC_FSM_STATE(silc_ske_st_responder_start)
1627 SilcSKE ske = fsm_context;
1629 SILC_LOG_DEBUG(("Start"));
1633 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1634 return SILC_FSM_CONTINUE;
1640 /** Wait for initiator */
1641 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1642 return SILC_FSM_WAIT;
1645 /* Decode initiator's start payload. Select the security properties from
1646 the initiator's start payload and send our reply start payload back. */
1648 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1650 SilcSKE ske = fsm_context;
1651 SilcSKEStatus status;
1652 SilcSKEStartPayload remote_payload = NULL;
1653 SilcBuffer packet_buf = &ske->packet->buffer;
1655 SILC_LOG_DEBUG(("Start"));
1659 silc_packet_free(ske->packet);
1660 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1661 return SILC_FSM_CONTINUE;
1664 /* See if received failure from remote */
1665 if (ske->packet->type == SILC_PACKET_FAILURE) {
1666 silc_packet_free(ske->packet);
1667 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1668 return SILC_FSM_CONTINUE;
1671 /* Decode the payload */
1672 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1673 if (status != SILC_SKE_STATUS_OK) {
1674 /** Error decoding Start Payload */
1675 silc_packet_free(ske->packet);
1676 ske->status = status;
1677 silc_fsm_next(fsm, silc_ske_st_responder_error);
1678 return SILC_FSM_CONTINUE;
1681 /* Take a copy of the payload buffer for future use. It is used to
1682 compute the HASH value. */
1683 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1685 silc_packet_free(ske->packet);
1687 /* Force the mutual authentication flag if we want to do it. */
1688 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1689 SILC_LOG_DEBUG(("Force mutual authentication"));
1690 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1693 /* Force PFS flag if we require it */
1694 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1695 SILC_LOG_DEBUG(("Force PFS"));
1696 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1699 /* Disable IV Included flag if requested */
1700 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1701 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1702 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1703 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1706 /* Check and select security properties */
1707 status = silc_ske_select_security_properties(ske, remote_payload,
1709 if (status != SILC_SKE_STATUS_OK) {
1710 /** Error selecting proposal */
1711 silc_ske_payload_start_free(remote_payload);
1712 ske->status = status;
1713 silc_fsm_next(fsm, silc_ske_st_responder_error);
1714 return SILC_FSM_CONTINUE;
1717 silc_ske_payload_start_free(remote_payload);
1719 /* Encode our reply payload to send the selected security properties */
1720 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1722 if (status != SILC_SKE_STATUS_OK)
1725 /* Send the packet. */
1726 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1727 silc_buffer_data(packet_buf),
1728 silc_buffer_len(packet_buf)))
1731 silc_buffer_free(packet_buf);
1733 /** Waiting initiator's KE payload */
1734 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1735 return SILC_FSM_WAIT;
1738 if (ske->prop->group)
1739 silc_ske_group_free(ske->prop->group);
1740 if (ske->prop->cipher)
1741 silc_cipher_free(ske->prop->cipher);
1742 if (ske->prop->hash)
1743 silc_hash_free(ske->prop->hash);
1744 if (ske->prop->hmac)
1745 silc_hmac_free(ske->prop->hmac);
1746 silc_free(ske->prop);
1749 if (status == SILC_SKE_STATUS_OK)
1750 status = SILC_SKE_STATUS_ERROR;
1753 ske->status = status;
1754 silc_fsm_next(fsm, silc_ske_st_responder_error);
1755 return SILC_FSM_CONTINUE;
1758 /* Phase-2. Decode initiator's KE payload */
1760 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1762 SilcSKE ske = fsm_context;
1763 SilcSKEStatus status;
1764 SilcSKEKEPayload recv_payload;
1765 SilcBuffer packet_buf = &ske->packet->buffer;
1767 SILC_LOG_DEBUG(("Start"));
1771 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1772 return SILC_FSM_CONTINUE;
1775 /* See if received failure from remote */
1776 if (ske->packet->type == SILC_PACKET_FAILURE) {
1777 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1778 return SILC_FSM_CONTINUE;
1781 /* Decode Key Exchange Payload */
1782 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1783 if (status != SILC_SKE_STATUS_OK) {
1784 /** Error decoding KE payload */
1785 silc_packet_free(ske->packet);
1786 ske->status = status;
1787 silc_fsm_next(fsm, silc_ske_st_responder_error);
1788 return SILC_FSM_CONTINUE;
1791 ske->ke1_payload = recv_payload;
1793 silc_packet_free(ske->packet);
1795 /* Verify the received public key and verify the signature if we are
1796 doing mutual authentication. */
1797 if (ske->start_payload &&
1798 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1800 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1802 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1804 /** Public key not provided */
1805 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1806 "certificate), even though we require it"));
1807 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1808 silc_fsm_next(fsm, silc_ske_st_responder_error);
1809 return SILC_FSM_CONTINUE;
1812 /* Decode the remote's public key */
1813 if (recv_payload->pk_data &&
1814 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1815 recv_payload->pk_data,
1816 recv_payload->pk_len,
1817 &ske->prop->public_key)) {
1818 /** Error decoding public key */
1819 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1820 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1821 silc_fsm_next(fsm, silc_ske_st_responder_error);
1822 return SILC_FSM_CONTINUE;
1825 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1827 SILC_LOG_DEBUG(("Verifying public key"));
1829 /** Waiting public key verification */
1830 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1832 /* If repository is provided, verify the key from there. */
1833 if (ske->repository) {
1836 find = silc_skr_find_alloc();
1838 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1839 silc_fsm_next(fsm, silc_ske_st_responder_error);
1840 return SILC_FSM_CONTINUE;
1842 silc_skr_find_set_pkcs_type(find,
1843 silc_pkcs_get_type(ske->prop->public_key));
1844 silc_skr_find_set_public_key(find, ske->prop->public_key);
1846 /* Find key from repository */
1847 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1848 silc_ske_skr_callback, ske));
1850 /* Verify from application */
1851 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1852 ske->callbacks->context,
1853 silc_ske_pk_verified, NULL));
1859 /** Generate KE2 payload */
1860 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1861 return SILC_FSM_CONTINUE;
1864 /* Phase-4. Generate KE2 payload */
1866 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1868 SilcSKE ske = fsm_context;
1869 SilcSKEStatus status;
1870 SilcSKEKEPayload recv_payload, send_payload;
1875 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1876 return SILC_FSM_CONTINUE;
1879 /* Check result of public key verification */
1880 if (ske->status != SILC_SKE_STATUS_OK) {
1881 /** Public key not verified */
1882 SILC_LOG_DEBUG(("Public key verification failed"));
1883 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1884 return SILC_FSM_CONTINUE;
1887 recv_payload = ske->ke1_payload;
1889 /* The public key verification was performed only if the Mutual
1890 Authentication flag is set. */
1891 if (ske->start_payload &&
1892 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1893 unsigned char hash[SILC_HASH_MAXLEN];
1894 SilcUInt32 hash_len;
1896 SILC_LOG_DEBUG(("Public key is authentic"));
1898 /* Compute the hash value */
1899 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1900 if (status != SILC_SKE_STATUS_OK) {
1901 /** Error computing hash */
1902 ske->status = status;
1903 silc_fsm_next(fsm, silc_ske_st_responder_error);
1904 return SILC_FSM_CONTINUE;
1907 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1909 /* Verify signature */
1910 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
1911 recv_payload->sign_len, hash, hash_len, NULL)) {
1912 /** Incorrect signature */
1913 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1914 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1915 silc_fsm_next(fsm, silc_ske_st_responder_error);
1916 return SILC_FSM_CONTINUE;
1919 SILC_LOG_DEBUG(("Signature is Ok"));
1921 memset(hash, 'F', hash_len);
1924 /* Create the random number x, 1 < x < q. */
1925 x = silc_calloc(1, sizeof(*x));
1928 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1929 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1931 if (status != SILC_SKE_STATUS_OK) {
1932 /** Error generating random number */
1935 ske->status = status;
1936 silc_fsm_next(fsm, silc_ske_st_responder_error);
1937 return SILC_FSM_CONTINUE;
1940 /* Save the results for later processing */
1941 send_payload = silc_calloc(1, sizeof(*send_payload));
1943 ske->ke2_payload = send_payload;
1945 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1947 /* Do the Diffie Hellman computation, f = g ^ x mod p */
1948 silc_mp_init(&send_payload->x);
1949 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1950 &ske->prop->group->group);
1952 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1954 /* Compute the shared secret key */
1955 KEY = silc_calloc(1, sizeof(*KEY));
1957 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1958 &ske->prop->group->group);
1961 /** Send KE2 payload */
1962 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1963 return SILC_FSM_CONTINUE;
1966 /* Phase-5. Send KE2 payload */
1968 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1970 SilcSKE ske = fsm_context;
1971 SilcSKEStatus status;
1972 SilcBuffer payload_buf;
1973 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1974 SilcUInt32 hash_len, sign_len, pk_len;
1976 SILC_LOG_DEBUG(("Start"));
1978 if (ske->public_key && ske->private_key) {
1979 SILC_LOG_DEBUG(("Getting public key"));
1981 /* Get the public key */
1982 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1984 /** Error encoding public key */
1985 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1986 silc_fsm_next(fsm, silc_ske_st_responder_error);
1987 return SILC_FSM_CONTINUE;
1989 ske->ke2_payload->pk_data = pk;
1990 ske->ke2_payload->pk_len = pk_len;
1992 SILC_LOG_DEBUG(("Computing HASH value"));
1994 /* Compute the hash value */
1995 memset(hash, 0, sizeof(hash));
1996 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1997 if (status != SILC_SKE_STATUS_OK) {
1998 /** Error computing hash */
1999 ske->status = status;
2000 silc_fsm_next(fsm, silc_ske_st_responder_error);
2001 return SILC_FSM_CONTINUE;
2004 ske->hash = silc_memdup(hash, hash_len);
2005 ske->hash_len = hash_len;
2007 SILC_LOG_DEBUG(("Signing HASH value"));
2009 /* Sign the hash value */
2010 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2011 sizeof(sign) - 1, &sign_len, NULL)) {
2012 /** Error computing signature */
2013 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2014 silc_fsm_next(fsm, silc_ske_st_responder_error);
2015 return SILC_FSM_CONTINUE;
2017 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2018 ske->ke2_payload->sign_len = sign_len;
2019 memset(sign, 0, sizeof(sign));
2021 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2023 /* Encode the Key Exchange Payload */
2024 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2026 if (status != SILC_SKE_STATUS_OK) {
2027 /** Error encoding KE payload */
2028 ske->status = status;
2029 silc_fsm_next(fsm, silc_ske_st_responder_error);
2030 return SILC_FSM_CONTINUE;
2033 /* Send the packet. */
2034 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
2035 payload_buf->data, silc_buffer_len(payload_buf))) {
2036 ske->status = SILC_SKE_STATUS_ERROR;
2037 silc_fsm_next(fsm, silc_ske_st_responder_error);
2038 return SILC_FSM_CONTINUE;
2041 silc_buffer_free(payload_buf);
2043 /** Waiting completion */
2044 silc_fsm_next(fsm, silc_ske_st_responder_end);
2045 return SILC_FSM_WAIT;
2048 /* Protocol completed */
2050 SILC_FSM_STATE(silc_ske_st_responder_end)
2052 SilcSKE ske = fsm_context;
2053 unsigned char tmp[4];
2054 SilcUInt32 hash_len, key_len, block_len;
2058 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2059 return SILC_FSM_CONTINUE;
2062 /* Check the result of the protocol */
2063 if (ske->packet->type == SILC_PACKET_FAILURE) {
2064 silc_fsm_next(fsm, silc_ske_st_responder_failure);
2065 return SILC_FSM_CONTINUE;
2067 silc_packet_free(ske->packet);
2069 /* Process key material */
2070 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2071 block_len = silc_cipher_get_key_len(ske->prop->cipher);
2072 hash_len = silc_hash_len(ske->prop->hash);
2073 ske->keymat = silc_ske_process_key_material(ske, block_len,
2076 /** Error processing key material */
2077 ske->status = SILC_SKE_STATUS_ERROR;
2078 silc_fsm_next(fsm, silc_ske_st_responder_error);
2079 return SILC_FSM_CONTINUE;
2082 /* Send SUCCESS packet */
2083 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2084 silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
2086 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2088 /* Call the completion callback */
2089 if (ske->callbacks->completed)
2090 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
2091 ske->rekey, ske->callbacks->context);
2093 return SILC_FSM_FINISH;
2096 /* Aborted by application */
2098 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2100 SilcSKE ske = fsm_context;
2101 unsigned char tmp[4];
2103 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2105 /* Send FAILURE packet */
2106 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2107 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2109 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2111 return SILC_FSM_FINISH;
2114 /* Failure received from remote */
2116 SILC_FSM_STATE(silc_ske_st_responder_failure)
2118 SilcSKE ske = fsm_context;
2119 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2121 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2123 if (silc_buffer_len(&ske->packet->buffer) == 4)
2124 SILC_GET32_MSB(error, ske->packet->buffer.data);
2125 ske->status = error;
2127 /* Call the completion callback */
2128 if (ske->callbacks->completed)
2129 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
2130 ske->callbacks->context);
2132 silc_packet_free(ske->packet);
2133 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2135 return SILC_FSM_FINISH;
2138 /* Error occurred */
2140 SILC_FSM_STATE(silc_ske_st_responder_error)
2142 SilcSKE ske = fsm_context;
2143 unsigned char tmp[4];
2145 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2146 ske->status, silc_ske_map_status(ske->status)));
2148 /* Send FAILURE packet */
2149 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2150 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2151 SILC_PUT32_MSB(ske->status, tmp);
2152 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2154 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2156 return SILC_FSM_FINISH;
2160 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
2161 void *destructor_context)
2166 /* Starts the protocol as responder. */
2169 silc_ske_responder(SilcSKE ske,
2170 SilcPacketStream stream,
2171 SilcSKEParams params)
2173 SILC_LOG_DEBUG(("Start SKE as responder"));
2175 if (!ske || !stream || !params || !params->version) {
2179 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2182 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2186 ske->responder = TRUE;
2187 ske->flags = params->flags;
2188 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2189 ske->session_port = params->session_port;
2190 ske->version = strdup(params->version);
2194 /* Link to packet stream to get key exchange packets */
2195 ske->stream = stream;
2196 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2197 SILC_PACKET_KEY_EXCHANGE,
2198 SILC_PACKET_KEY_EXCHANGE_1,
2199 SILC_PACKET_SUCCESS,
2200 SILC_PACKET_FAILURE, -1);
2202 /* Start SKE as responder */
2203 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2208 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2210 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2212 return SILC_FSM_FINISH;
2215 /* Starts rekey protocol as initiator */
2218 silc_ske_rekey_initiator(SilcSKE ske,
2219 SilcPacketStream stream,
2220 SilcSKERekeyMaterial rekey)
2222 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2224 if (!ske || !stream || !rekey)
2227 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2230 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2235 /* Link to packet stream to get key exchange packets */
2236 ske->stream = stream;
2238 /* Start SKE rekey as initiator */
2239 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2244 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2246 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2248 return SILC_FSM_FINISH;
2251 /* Starts rekey protocol as responder */
2254 silc_ske_rekey_responder(SilcSKE ske,
2255 SilcPacketStream stream,
2256 SilcBuffer ke_payload,
2257 SilcSKERekeyMaterial rekey)
2259 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2261 if (!ske || !stream || !rekey)
2263 if (rekey->pfs && !ke_payload)
2266 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2269 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2272 // ske->packet_buf = ke_payload;
2275 /* Link to packet stream to get key exchange packets */
2276 ske->stream = stream;
2278 /* Start SKE rekey as responder */
2279 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2284 /* Processes the provided key material `data' as the SILC protocol
2285 specification defines. */
2288 silc_ske_process_key_material_data(unsigned char *data,
2289 SilcUInt32 data_len,
2290 SilcUInt32 req_iv_len,
2291 SilcUInt32 req_enc_key_len,
2292 SilcUInt32 req_hmac_key_len,
2296 unsigned char hashd[SILC_HASH_MAXLEN];
2297 SilcUInt32 hash_len = req_hmac_key_len;
2298 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2299 SilcSKEKeyMaterial key;
2301 SILC_LOG_DEBUG(("Start"));
2303 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2306 key = silc_calloc(1, sizeof(*key));
2310 buf = silc_buffer_alloc_size(1 + data_len);
2313 silc_buffer_format(buf,
2314 SILC_STR_UI_CHAR(0),
2315 SILC_STR_UI_XNSTRING(data, data_len),
2319 memset(hashd, 0, sizeof(hashd));
2321 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2322 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2323 memcpy(key->send_iv, hashd, req_iv_len);
2324 memset(hashd, 0, sizeof(hashd));
2326 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2327 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2328 memcpy(key->receive_iv, hashd, req_iv_len);
2329 key->iv_len = req_iv_len;
2331 /* Take the encryption keys. If requested key size is more than
2332 the size of hash length we will distribute more key material
2333 as protocol defines. */
2335 if (enc_key_len > hash_len) {
2337 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2338 k3[SILC_HASH_MAXLEN];
2339 unsigned char *dtmp;
2342 if (enc_key_len > (3 * hash_len))
2345 /* Take first round */
2346 memset(k1, 0, sizeof(k1));
2347 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2349 /* Take second round */
2350 dist = silc_buffer_alloc_size(data_len + hash_len);
2353 silc_buffer_format(dist,
2354 SILC_STR_UI_XNSTRING(data, data_len),
2355 SILC_STR_UI_XNSTRING(k1, hash_len),
2357 memset(k2, 0, sizeof(k2));
2358 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2360 /* Take third round */
2361 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2362 silc_buffer_pull_tail(dist, hash_len);
2363 silc_buffer_pull(dist, data_len + hash_len);
2364 silc_buffer_format(dist,
2365 SILC_STR_UI_XNSTRING(k2, hash_len),
2367 silc_buffer_push(dist, data_len + hash_len);
2368 memset(k3, 0, sizeof(k3));
2369 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2371 /* Then, save the keys */
2372 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2373 memcpy(dtmp, k1, hash_len);
2374 memcpy(dtmp + hash_len, k2, hash_len);
2375 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2377 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2378 memcpy(key->send_enc_key, dtmp, enc_key_len);
2379 key->enc_key_len = req_enc_key_len;
2381 memset(dtmp, 0, (3 * hash_len));
2382 memset(k1, 0, sizeof(k1));
2383 memset(k2, 0, sizeof(k2));
2384 memset(k3, 0, sizeof(k3));
2386 silc_buffer_clear(dist);
2387 silc_buffer_free(dist);
2389 /* Take normal hash as key */
2390 memset(hashd, 0, sizeof(hashd));
2391 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2392 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2393 memcpy(key->send_enc_key, hashd, enc_key_len);
2394 key->enc_key_len = req_enc_key_len;
2398 if (enc_key_len > hash_len) {
2400 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2401 k3[SILC_HASH_MAXLEN];
2402 unsigned char *dtmp;
2405 if (enc_key_len > (3 * hash_len))
2408 /* Take first round */
2409 memset(k1, 0, sizeof(k1));
2410 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2412 /* Take second round */
2413 dist = silc_buffer_alloc_size(data_len + hash_len);
2416 silc_buffer_format(dist,
2417 SILC_STR_UI_XNSTRING(data, data_len),
2418 SILC_STR_UI_XNSTRING(k1, hash_len),
2420 memset(k2, 0, sizeof(k2));
2421 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2423 /* Take third round */
2424 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2425 silc_buffer_pull_tail(dist, hash_len);
2426 silc_buffer_pull(dist, data_len + hash_len);
2427 silc_buffer_format(dist,
2428 SILC_STR_UI_XNSTRING(k2, hash_len),
2430 silc_buffer_push(dist, data_len + hash_len);
2431 memset(k3, 0, sizeof(k3));
2432 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2434 /* Then, save the keys */
2435 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2436 memcpy(dtmp, k1, hash_len);
2437 memcpy(dtmp + hash_len, k2, hash_len);
2438 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2440 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2441 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2442 key->enc_key_len = req_enc_key_len;
2444 memset(dtmp, 0, (3 * hash_len));
2445 memset(k1, 0, sizeof(k1));
2446 memset(k2, 0, sizeof(k2));
2447 memset(k3, 0, sizeof(k3));
2449 silc_buffer_clear(dist);
2450 silc_buffer_free(dist);
2452 /* Take normal hash as key */
2453 memset(hashd, 0, sizeof(hashd));
2454 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2455 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2456 memcpy(key->receive_enc_key, hashd, enc_key_len);
2457 key->enc_key_len = req_enc_key_len;
2460 /* Take HMAC keys */
2461 memset(hashd, 0, sizeof(hashd));
2463 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2464 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2465 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2466 memset(hashd, 0, sizeof(hashd));
2468 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2469 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2470 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2471 key->hmac_key_len = req_hmac_key_len;
2472 memset(hashd, 0, sizeof(hashd));
2474 silc_buffer_clear(buf);
2475 silc_buffer_free(buf);
2480 /* Processes negotiated key material as protocol specifies. This returns
2481 the actual keys to be used in the SILC. */
2484 silc_ske_process_key_material(SilcSKE ske,
2485 SilcUInt32 req_iv_len,
2486 SilcUInt32 req_enc_key_len,
2487 SilcUInt32 req_hmac_key_len)
2490 unsigned char *tmpbuf;
2492 SilcSKEKeyMaterial key;
2494 /* Encode KEY to binary data */
2495 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2497 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2500 silc_buffer_format(buf,
2501 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2502 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2505 /* Process the key material */
2506 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2507 req_iv_len, req_enc_key_len,
2511 memset(tmpbuf, 0, klen);
2513 silc_buffer_clear(buf);
2514 silc_buffer_free(buf);
2519 /* Free key material structure */
2521 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2527 silc_free(key->send_iv);
2528 if (key->receive_iv)
2529 silc_free(key->receive_iv);
2530 if (key->send_enc_key) {
2531 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2532 silc_free(key->send_enc_key);
2534 if (key->receive_enc_key) {
2535 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2536 silc_free(key->receive_enc_key);
2538 if (key->send_hmac_key) {
2539 memset(key->send_hmac_key, 0, key->hmac_key_len);
2540 silc_free(key->send_hmac_key);
2542 if (key->receive_hmac_key) {
2543 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2544 silc_free(key->receive_hmac_key);
2549 /* Set keys into use */
2551 SilcBool silc_ske_set_keys(SilcSKE ske,
2552 SilcSKEKeyMaterial keymat,
2553 SilcSKESecurityProperties prop,
2554 SilcCipher *ret_send_key,
2555 SilcCipher *ret_receive_key,
2556 SilcHmac *ret_hmac_send,
2557 SilcHmac *ret_hmac_receive,
2560 /* Allocate ciphers to be used in the communication */
2562 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2566 if (ret_receive_key) {
2567 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2572 /* Allocate HMACs */
2573 if (ret_hmac_send) {
2574 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2578 if (ret_hmac_receive) {
2579 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2584 /* Set key material */
2585 if (ske->responder) {
2586 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2587 keymat->enc_key_len);
2588 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2589 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2590 keymat->enc_key_len);
2591 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2592 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2593 keymat->hmac_key_len);
2594 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2595 keymat->hmac_key_len);
2597 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2598 keymat->enc_key_len);
2599 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2600 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2601 keymat->enc_key_len);
2602 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2603 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2604 keymat->hmac_key_len);
2605 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2606 keymat->hmac_key_len);
2611 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2615 SILC_LOG_INFO(("Security properties: %s %s %s %s",
2616 ret_send_key ? silc_cipher_get_name(*ret_send_key) : "??",
2617 ret_hmac_send ? silc_hmac_get_name(*ret_hmac_send) : "??",
2618 ret_hash ? silc_hash_get_name(*ret_hash) : "??",
2619 ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : ""));
2624 const char *silc_ske_status_string[] =
2628 "Unkown error occurred",
2629 "Bad payload in packet",
2630 "Unsupported group",
2631 "Unsupported cipher",
2633 "Unsupported hash function",
2635 "Unsupported public key (or certificate)",
2636 "Incorrect signature",
2637 "Bad or unsupported version",
2641 "Remote did not provide public key",
2642 "Bad reserved field in packet",
2643 "Bad payload length in packet",
2644 "Error computing signature",
2645 "System out of memory",
2650 /* Maps status to readable string and returns the string. If string is not
2651 found and empty character string ("") is returned. */
2653 const char *silc_ske_map_status(SilcSKEStatus status)
2657 for (i = 0; silc_ske_status_string[i]; i++)
2659 return silc_ske_status_string[i];
2664 /* Parses remote host's version string. */
2666 SilcBool silc_ske_parse_version(SilcSKE ske,
2667 SilcUInt32 *protocol_version,
2668 char **protocol_version_string,
2669 SilcUInt32 *software_version,
2670 char **software_version_string,
2671 char **vendor_version)
2673 return silc_parse_version_string(ske->remote_version,
2675 protocol_version_string,
2677 software_version_string,
2681 /* Get security properties */
2683 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)