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 SILC_LOG_DEBUG(("Error sending packet"));
954 ske->status = SILC_SKE_STATUS_ERROR;
955 silc_fsm_next(fsm, silc_ske_st_initiator_error);
956 return SILC_FSM_CONTINUE;
961 /** Wait for responder proposal */
962 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
963 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
964 return SILC_FSM_WAIT;
967 /* Phase-1. Receives responder's proposal */
969 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
971 SilcSKE ske = fsm_context;
972 SilcSKEStatus status;
973 SilcSKEStartPayload payload;
974 SilcSKESecurityProperties prop;
975 SilcSKEDiffieHellmanGroup group;
976 SilcBuffer packet_buf = &ske->packet->buffer;
977 SilcUInt16 remote_port = 0;
981 SILC_LOG_DEBUG(("Start"));
985 silc_packet_free(ske->packet);
986 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
987 return SILC_FSM_CONTINUE;
990 /* Decode the payload */
991 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
992 if (status != SILC_SKE_STATUS_OK) {
993 /** Error decoding Start Payload */
994 silc_packet_free(ske->packet);
995 ske->status = status;
996 silc_fsm_next(fsm, silc_ske_st_initiator_error);
997 return SILC_FSM_CONTINUE;
1000 /* Get remote ID and set it to stream */
1001 if (ske->packet->src_id_len) {
1002 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1003 ske->packet->src_id_type,
1004 (ske->packet->src_id_type == SILC_ID_SERVER ?
1005 (void *)&id.u.server_id : (void *)&id.u.client_id),
1006 (ske->packet->src_id_type == SILC_ID_SERVER ?
1007 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1008 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1009 (ske->packet->src_id_type == SILC_ID_SERVER ?
1010 (void *)&id.u.server_id : (void *)&id.u.client_id));
1013 silc_packet_free(ske->packet);
1015 /* Check that the cookie is returned unmodified. In case IV included
1016 flag and session port has been set, the first two bytes of cookie
1017 are the session port and we ignore them in this check. */
1018 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1019 /* Take remote port */
1020 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1023 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1024 SILC_SKE_COOKIE_LEN - coff)) {
1025 /** Invalid cookie */
1026 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1027 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1028 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1029 return SILC_FSM_CONTINUE;
1032 /* Check version string */
1033 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1034 status = silc_ske_check_version(ske);
1035 if (status != SILC_SKE_STATUS_OK) {
1036 /** Version mismatch */
1037 ske->status = status;
1038 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1039 return SILC_FSM_CONTINUE;
1042 /* Free our KE Start Payload context, we don't need it anymore. */
1043 silc_ske_payload_start_free(ske->start_payload);
1044 ske->start_payload = NULL;
1046 /* Take the selected security properties into use while doing
1047 the key exchange. This is used only while doing the key
1049 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1052 prop->flags = payload->flags;
1053 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1054 if (status != SILC_SKE_STATUS_OK)
1057 prop->group = group;
1058 prop->remote_port = remote_port;
1060 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1061 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1064 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1065 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1068 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1069 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1072 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1073 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1077 /* Save remote's KE Start Payload */
1078 ske->start_payload = payload;
1080 /** Send KE Payload */
1081 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1082 return SILC_FSM_CONTINUE;
1086 silc_ske_payload_start_free(payload);
1088 silc_ske_group_free(group);
1091 silc_cipher_free(prop->cipher);
1093 silc_hash_free(prop->hash);
1095 silc_hmac_free(prop->hmac);
1099 if (status == SILC_SKE_STATUS_OK)
1100 status = SILC_SKE_STATUS_ERROR;
1103 ske->status = status;
1104 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1105 return SILC_FSM_CONTINUE;
1108 /* Phase-2. Send KE payload */
1110 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1112 SilcSKE ske = fsm_context;
1113 SilcSKEStatus status;
1114 SilcBuffer payload_buf;
1116 SilcSKEKEPayload payload;
1119 SILC_LOG_DEBUG(("Start"));
1121 /* Create the random number x, 1 < x < q. */
1122 x = silc_calloc(1, sizeof(*x));
1124 /** Out of memory */
1125 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1126 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1127 return SILC_FSM_CONTINUE;
1131 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1132 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1134 if (status != SILC_SKE_STATUS_OK) {
1135 /** Error generating random number */
1138 ske->status = status;
1139 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1140 return SILC_FSM_CONTINUE;
1143 /* Encode the result to Key Exchange Payload. */
1145 payload = silc_calloc(1, sizeof(*payload));
1147 /** Out of memory */
1150 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1151 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1152 return SILC_FSM_CONTINUE;
1154 ske->ke1_payload = payload;
1156 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1158 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1159 silc_mp_init(&payload->x);
1160 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1161 &ske->prop->group->group);
1163 /* Get public key */
1164 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1165 if (!payload->pk_data) {
1166 /** Error encoding public key */
1169 silc_mp_uninit(&payload->x);
1171 ske->ke1_payload = NULL;
1172 ske->status = SILC_SKE_STATUS_ERROR;
1173 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1174 return SILC_FSM_CONTINUE;
1176 payload->pk_len = pk_len;
1177 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1179 /* Compute signature data if we are doing mutual authentication */
1180 if (ske->private_key &&
1181 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1182 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1183 SilcUInt32 hash_len, sign_len;
1185 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1186 SILC_LOG_DEBUG(("Computing HASH_i value"));
1188 /* Compute the hash value */
1189 memset(hash, 0, sizeof(hash));
1190 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1192 SILC_LOG_DEBUG(("Signing HASH_i value"));
1194 /* Sign the hash value */
1195 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1196 sizeof(sign) - 1, &sign_len, NULL)) {
1197 /** Error computing signature */
1200 silc_mp_uninit(&payload->x);
1201 silc_free(payload->pk_data);
1203 ske->ke1_payload = NULL;
1204 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1205 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1206 return SILC_FSM_CONTINUE;
1208 payload->sign_data = silc_memdup(sign, sign_len);
1209 if (payload->sign_data)
1210 payload->sign_len = sign_len;
1211 memset(sign, 0, sizeof(sign));
1214 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1215 if (status != SILC_SKE_STATUS_OK) {
1216 /** Error encoding KE payload */
1219 silc_mp_uninit(&payload->x);
1220 silc_free(payload->pk_data);
1221 silc_free(payload->sign_data);
1223 ske->ke1_payload = NULL;
1224 ske->status = status;
1225 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1226 return SILC_FSM_CONTINUE;
1231 /* Check for backwards compatibility */
1233 /* Send the packet. */
1234 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_1, 0,
1235 silc_buffer_data(payload_buf),
1236 silc_buffer_len(payload_buf))) {
1237 /** Error sending packet */
1238 SILC_LOG_DEBUG(("Error sending packet"));
1239 ske->status = SILC_SKE_STATUS_ERROR;
1240 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1241 return SILC_FSM_CONTINUE;
1244 silc_buffer_free(payload_buf);
1246 /** Waiting responder's KE payload */
1247 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1248 return SILC_FSM_WAIT;
1251 /* Phase-3. Process responder's KE payload */
1253 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1255 SilcSKE ske = fsm_context;
1256 SilcSKEStatus status;
1257 SilcSKEKEPayload payload;
1259 SilcBuffer packet_buf = &ske->packet->buffer;
1261 SILC_LOG_DEBUG(("Start"));
1265 silc_packet_free(ske->packet);
1266 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1267 return SILC_FSM_CONTINUE;
1270 /* Decode the payload */
1271 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1272 if (status != SILC_SKE_STATUS_OK) {
1273 /** Error decoding KE payload */
1274 silc_packet_free(ske->packet);
1275 ske->status = status;
1276 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1277 return SILC_FSM_CONTINUE;
1279 silc_packet_free(ske->packet);
1280 ske->ke2_payload = payload;
1282 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1283 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1284 "even though we require it"));
1285 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1289 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1291 /* Compute the shared secret key */
1292 KEY = silc_calloc(1, sizeof(*KEY));
1294 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1297 /* Decode the remote's public key */
1298 if (payload->pk_data &&
1299 !silc_pkcs_public_key_alloc(payload->pk_type,
1300 payload->pk_data, payload->pk_len,
1301 &ske->prop->public_key)) {
1302 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1303 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1307 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1309 SILC_LOG_DEBUG(("Verifying public key"));
1311 /** Waiting public key verification */
1312 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1314 /* If repository is provided, verify the key from there. */
1315 if (ske->repository) {
1318 find = silc_skr_find_alloc();
1320 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1323 silc_skr_find_set_pkcs_type(find,
1324 silc_pkcs_get_type(ske->prop->public_key));
1325 silc_skr_find_set_public_key(find, ske->prop->public_key);
1326 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1328 /* Find key from repository */
1329 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1330 silc_ske_skr_callback, ske));
1332 /* Verify from application */
1333 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1334 ske->callbacks->context,
1335 silc_ske_pk_verified, NULL));
1340 /** Process key material */
1341 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1342 return SILC_FSM_CONTINUE;
1345 silc_ske_payload_ke_free(payload);
1346 ske->ke2_payload = NULL;
1348 silc_mp_uninit(ske->KEY);
1349 silc_free(ske->KEY);
1352 if (status == SILC_SKE_STATUS_OK)
1353 return SILC_SKE_STATUS_ERROR;
1356 ske->status = status;
1357 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1358 return SILC_FSM_CONTINUE;
1361 /* Process key material */
1363 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1365 SilcSKE ske = fsm_context;
1366 SilcSKEStatus status;
1367 SilcSKEKEPayload payload;
1368 unsigned char hash[SILC_HASH_MAXLEN];
1369 SilcUInt32 hash_len;
1370 int key_len, block_len;
1374 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1375 return SILC_FSM_CONTINUE;
1378 /* Check result of public key verification */
1379 if (ske->status != SILC_SKE_STATUS_OK) {
1380 /** Public key not verified */
1381 SILC_LOG_DEBUG(("Public key verification failed"));
1382 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1383 return SILC_FSM_CONTINUE;
1386 payload = ske->ke2_payload;
1388 if (ske->prop->public_key) {
1389 SILC_LOG_DEBUG(("Public key is authentic"));
1391 /* Compute the hash value */
1392 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1393 if (status != SILC_SKE_STATUS_OK)
1396 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1398 /* Verify signature */
1399 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1400 payload->sign_len, hash, hash_len, NULL)) {
1401 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1402 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1406 SILC_LOG_DEBUG(("Signature is Ok"));
1408 ske->hash = silc_memdup(hash, hash_len);
1409 ske->hash_len = hash_len;
1410 memset(hash, 'F', hash_len);
1413 ske->status = SILC_SKE_STATUS_OK;
1415 /* Process key material */
1416 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1417 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1418 hash_len = silc_hash_len(ske->prop->hash);
1419 ske->keymat = silc_ske_process_key_material(ske, block_len,
1422 SILC_LOG_ERROR(("Error processing key material"));
1423 status = SILC_SKE_STATUS_ERROR;
1427 /* Send SUCCESS packet */
1428 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1429 if (!silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1430 /** Error sending packet */
1431 SILC_LOG_DEBUG(("Error sending packet"));
1432 ske->status = SILC_SKE_STATUS_ERROR;
1433 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1434 return SILC_FSM_CONTINUE;
1437 /** Waiting completion */
1438 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1439 return SILC_FSM_WAIT;
1442 memset(hash, 'F', sizeof(hash));
1443 silc_ske_payload_ke_free(payload);
1444 ske->ke2_payload = NULL;
1446 silc_mp_uninit(ske->KEY);
1447 silc_free(ske->KEY);
1451 memset(ske->hash, 'F', hash_len);
1452 silc_free(ske->hash);
1456 if (status == SILC_SKE_STATUS_OK)
1457 status = SILC_SKE_STATUS_ERROR;
1460 ske->status = status;
1461 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1462 return SILC_FSM_CONTINUE;
1465 /* Protocol completed */
1467 SILC_FSM_STATE(silc_ske_st_initiator_end)
1469 SilcSKE ske = fsm_context;
1471 SILC_LOG_DEBUG(("Start"));
1475 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1476 return SILC_FSM_CONTINUE;
1479 /* See if received failure from remote */
1480 if (ske->packet->type == SILC_PACKET_FAILURE) {
1481 silc_packet_free(ske->packet);
1482 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1483 return SILC_FSM_CONTINUE;
1486 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1488 /* Call the completion callback */
1489 if (ske->callbacks->completed)
1490 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1491 ske->rekey, ske->callbacks->context);
1493 silc_packet_free(ske->packet);
1495 return SILC_FSM_FINISH;
1498 /* Aborted by application */
1500 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1502 SilcSKE ske = fsm_context;
1503 unsigned char data[4];
1505 SILC_LOG_DEBUG(("Aborted by caller"));
1507 /* Send FAILURE packet */
1508 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1509 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1511 return SILC_FSM_FINISH;
1514 /* Error occurred. Send error to remote host */
1516 SILC_FSM_STATE(silc_ske_st_initiator_error)
1518 SilcSKE ske = fsm_context;
1519 SilcSKEStatus status;
1520 unsigned char data[4];
1522 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1523 silc_ske_map_status(ske->status), ske->status));
1525 status = ske->status;
1526 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1527 status = SILC_SKE_STATUS_ERROR;
1529 /* Send FAILURE packet */
1530 SILC_PUT32_MSB((SilcUInt32)status, data);
1531 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1533 /* Call the completion callback */
1534 if (ske->callbacks->completed)
1535 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1536 ske->callbacks->context);
1538 return SILC_FSM_FINISH;
1541 /* Failure received from remote */
1543 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1545 SilcSKE ske = fsm_context;
1547 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1548 silc_ske_map_status(ske->status), ske->status));
1550 /* Call the completion callback */
1551 if (ske->callbacks->completed)
1552 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1553 ske->callbacks->context);
1555 return SILC_FSM_FINISH;
1558 /* FSM destructor */
1560 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1561 void *destructor_context)
1563 SilcSKE ske = fsm_context;
1564 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1567 /* Starts the protocol as initiator */
1570 silc_ske_initiator(SilcSKE ske,
1571 SilcPacketStream stream,
1572 SilcSKEParams params,
1573 SilcSKEStartPayload start_payload)
1575 SILC_LOG_DEBUG(("Start SKE as initiator"));
1577 if (!ske || !stream || !params || !params->version)
1580 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1583 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1587 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1588 ske->session_port = params->session_port;
1590 /* Generate security properties if not provided */
1591 if (!start_payload) {
1592 start_payload = silc_ske_assemble_security_properties(ske,
1599 ske->start_payload = start_payload;
1600 ske->version = params->version;
1602 /* Link to packet stream to get key exchange packets */
1603 ske->stream = stream;
1604 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1605 SILC_PACKET_KEY_EXCHANGE,
1606 SILC_PACKET_KEY_EXCHANGE_2,
1607 SILC_PACKET_SUCCESS,
1608 SILC_PACKET_FAILURE, -1);
1610 /* Start SKE as initiator */
1611 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1617 /******************************** Responder *********************************/
1619 SILC_FSM_STATE(silc_ske_st_responder_start);
1620 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1621 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1622 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1623 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1624 SILC_FSM_STATE(silc_ske_st_responder_end);
1625 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1626 SILC_FSM_STATE(silc_ske_st_responder_failure);
1627 SILC_FSM_STATE(silc_ske_st_responder_error);
1629 /* Start protocol as responder. Wait initiator's start payload */
1631 SILC_FSM_STATE(silc_ske_st_responder_start)
1633 SilcSKE ske = fsm_context;
1635 SILC_LOG_DEBUG(("Start"));
1639 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1640 return SILC_FSM_CONTINUE;
1646 /** Wait for initiator */
1647 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1648 return SILC_FSM_WAIT;
1651 /* Decode initiator's start payload. Select the security properties from
1652 the initiator's start payload and send our reply start payload back. */
1654 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1656 SilcSKE ske = fsm_context;
1657 SilcSKEStatus status;
1658 SilcSKEStartPayload remote_payload = NULL;
1659 SilcBuffer packet_buf = &ske->packet->buffer;
1661 SILC_LOG_DEBUG(("Start"));
1665 silc_packet_free(ske->packet);
1666 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1667 return SILC_FSM_CONTINUE;
1670 /* See if received failure from remote */
1671 if (ske->packet->type == SILC_PACKET_FAILURE) {
1672 silc_packet_free(ske->packet);
1673 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1674 return SILC_FSM_CONTINUE;
1677 /* Decode the payload */
1678 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1679 if (status != SILC_SKE_STATUS_OK) {
1680 /** Error decoding Start Payload */
1681 silc_packet_free(ske->packet);
1682 ske->status = status;
1683 silc_fsm_next(fsm, silc_ske_st_responder_error);
1684 return SILC_FSM_CONTINUE;
1687 /* Take a copy of the payload buffer for future use. It is used to
1688 compute the HASH value. */
1689 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1691 silc_packet_free(ske->packet);
1693 /* Force the mutual authentication flag if we want to do it. */
1694 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1695 SILC_LOG_DEBUG(("Force mutual authentication"));
1696 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1699 /* Force PFS flag if we require it */
1700 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1701 SILC_LOG_DEBUG(("Force PFS"));
1702 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1705 /* Disable IV Included flag if requested */
1706 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1707 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1708 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1709 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1712 /* Check and select security properties */
1713 status = silc_ske_select_security_properties(ske, remote_payload,
1715 if (status != SILC_SKE_STATUS_OK) {
1716 /** Error selecting proposal */
1717 silc_ske_payload_start_free(remote_payload);
1718 ske->status = status;
1719 silc_fsm_next(fsm, silc_ske_st_responder_error);
1720 return SILC_FSM_CONTINUE;
1723 silc_ske_payload_start_free(remote_payload);
1725 /* Encode our reply payload to send the selected security properties */
1726 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1728 if (status != SILC_SKE_STATUS_OK)
1731 /* Send the packet. */
1732 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1733 silc_buffer_data(packet_buf),
1734 silc_buffer_len(packet_buf)))
1737 silc_buffer_free(packet_buf);
1739 /** Waiting initiator's KE payload */
1740 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1741 return SILC_FSM_WAIT;
1744 if (ske->prop->group)
1745 silc_ske_group_free(ske->prop->group);
1746 if (ske->prop->cipher)
1747 silc_cipher_free(ske->prop->cipher);
1748 if (ske->prop->hash)
1749 silc_hash_free(ske->prop->hash);
1750 if (ske->prop->hmac)
1751 silc_hmac_free(ske->prop->hmac);
1752 silc_free(ske->prop);
1755 if (status == SILC_SKE_STATUS_OK)
1756 status = SILC_SKE_STATUS_ERROR;
1759 ske->status = status;
1760 silc_fsm_next(fsm, silc_ske_st_responder_error);
1761 return SILC_FSM_CONTINUE;
1764 /* Phase-2. Decode initiator's KE payload */
1766 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1768 SilcSKE ske = fsm_context;
1769 SilcSKEStatus status;
1770 SilcSKEKEPayload recv_payload;
1771 SilcBuffer packet_buf = &ske->packet->buffer;
1773 SILC_LOG_DEBUG(("Start"));
1777 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1778 return SILC_FSM_CONTINUE;
1781 /* See if received failure from remote */
1782 if (ske->packet->type == SILC_PACKET_FAILURE) {
1783 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1784 return SILC_FSM_CONTINUE;
1787 /* Decode Key Exchange Payload */
1788 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1789 if (status != SILC_SKE_STATUS_OK) {
1790 /** Error decoding KE payload */
1791 silc_packet_free(ske->packet);
1792 ske->status = status;
1793 silc_fsm_next(fsm, silc_ske_st_responder_error);
1794 return SILC_FSM_CONTINUE;
1797 ske->ke1_payload = recv_payload;
1799 silc_packet_free(ske->packet);
1801 /* Verify the received public key and verify the signature if we are
1802 doing mutual authentication. */
1803 if (ske->start_payload &&
1804 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1806 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1808 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1810 /** Public key not provided */
1811 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1812 "certificate), even though we require it"));
1813 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1814 silc_fsm_next(fsm, silc_ske_st_responder_error);
1815 return SILC_FSM_CONTINUE;
1818 /* Decode the remote's public key */
1819 if (recv_payload->pk_data &&
1820 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1821 recv_payload->pk_data,
1822 recv_payload->pk_len,
1823 &ske->prop->public_key)) {
1824 /** Error decoding public key */
1825 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1826 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1827 silc_fsm_next(fsm, silc_ske_st_responder_error);
1828 return SILC_FSM_CONTINUE;
1831 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1833 SILC_LOG_DEBUG(("Verifying public key"));
1835 /** Waiting public key verification */
1836 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1838 /* If repository is provided, verify the key from there. */
1839 if (ske->repository) {
1842 find = silc_skr_find_alloc();
1844 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1845 silc_fsm_next(fsm, silc_ske_st_responder_error);
1846 return SILC_FSM_CONTINUE;
1848 silc_skr_find_set_pkcs_type(find,
1849 silc_pkcs_get_type(ske->prop->public_key));
1850 silc_skr_find_set_public_key(find, ske->prop->public_key);
1851 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1853 /* Find key from repository */
1854 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1855 silc_ske_skr_callback, ske));
1857 /* Verify from application */
1858 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1859 ske->callbacks->context,
1860 silc_ske_pk_verified, NULL));
1866 /** Generate KE2 payload */
1867 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1868 return SILC_FSM_CONTINUE;
1871 /* Phase-4. Generate KE2 payload */
1873 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1875 SilcSKE ske = fsm_context;
1876 SilcSKEStatus status;
1877 SilcSKEKEPayload recv_payload, send_payload;
1882 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1883 return SILC_FSM_CONTINUE;
1886 /* Check result of public key verification */
1887 if (ske->status != SILC_SKE_STATUS_OK) {
1888 /** Public key not verified */
1889 SILC_LOG_DEBUG(("Public key verification failed"));
1890 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1891 return SILC_FSM_CONTINUE;
1894 recv_payload = ske->ke1_payload;
1896 /* The public key verification was performed only if the Mutual
1897 Authentication flag is set. */
1898 if (ske->start_payload &&
1899 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1900 unsigned char hash[SILC_HASH_MAXLEN];
1901 SilcUInt32 hash_len;
1903 SILC_LOG_DEBUG(("Public key is authentic"));
1905 /* Compute the hash value */
1906 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1907 if (status != SILC_SKE_STATUS_OK) {
1908 /** Error computing hash */
1909 ske->status = status;
1910 silc_fsm_next(fsm, silc_ske_st_responder_error);
1911 return SILC_FSM_CONTINUE;
1914 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1916 /* Verify signature */
1917 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
1918 recv_payload->sign_len, hash, hash_len, NULL)) {
1919 /** Incorrect signature */
1920 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1921 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1922 silc_fsm_next(fsm, silc_ske_st_responder_error);
1923 return SILC_FSM_CONTINUE;
1926 SILC_LOG_DEBUG(("Signature is Ok"));
1928 memset(hash, 'F', hash_len);
1931 /* Create the random number x, 1 < x < q. */
1932 x = silc_calloc(1, sizeof(*x));
1935 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1936 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1938 if (status != SILC_SKE_STATUS_OK) {
1939 /** Error generating random number */
1942 ske->status = status;
1943 silc_fsm_next(fsm, silc_ske_st_responder_error);
1944 return SILC_FSM_CONTINUE;
1947 /* Save the results for later processing */
1948 send_payload = silc_calloc(1, sizeof(*send_payload));
1950 ske->ke2_payload = send_payload;
1952 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1954 /* Do the Diffie Hellman computation, f = g ^ x mod p */
1955 silc_mp_init(&send_payload->x);
1956 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1957 &ske->prop->group->group);
1959 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1961 /* Compute the shared secret key */
1962 KEY = silc_calloc(1, sizeof(*KEY));
1964 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1965 &ske->prop->group->group);
1968 /** Send KE2 payload */
1969 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1970 return SILC_FSM_CONTINUE;
1973 /* Phase-5. Send KE2 payload */
1975 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1977 SilcSKE ske = fsm_context;
1978 SilcSKEStatus status;
1979 SilcBuffer payload_buf;
1980 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1981 SilcUInt32 hash_len, sign_len, pk_len;
1983 SILC_LOG_DEBUG(("Start"));
1985 if (ske->public_key && ske->private_key) {
1986 SILC_LOG_DEBUG(("Getting public key"));
1988 /* Get the public key */
1989 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1991 /** Error encoding public key */
1992 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1993 silc_fsm_next(fsm, silc_ske_st_responder_error);
1994 return SILC_FSM_CONTINUE;
1996 ske->ke2_payload->pk_data = pk;
1997 ske->ke2_payload->pk_len = pk_len;
1999 SILC_LOG_DEBUG(("Computing HASH value"));
2001 /* Compute the hash value */
2002 memset(hash, 0, sizeof(hash));
2003 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2004 if (status != SILC_SKE_STATUS_OK) {
2005 /** Error computing hash */
2006 ske->status = status;
2007 silc_fsm_next(fsm, silc_ske_st_responder_error);
2008 return SILC_FSM_CONTINUE;
2011 ske->hash = silc_memdup(hash, hash_len);
2012 ske->hash_len = hash_len;
2014 SILC_LOG_DEBUG(("Signing HASH value"));
2016 /* Sign the hash value */
2017 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2018 sizeof(sign) - 1, &sign_len, NULL)) {
2019 /** Error computing signature */
2020 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2021 silc_fsm_next(fsm, silc_ske_st_responder_error);
2022 return SILC_FSM_CONTINUE;
2024 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2025 ske->ke2_payload->sign_len = sign_len;
2026 memset(sign, 0, sizeof(sign));
2028 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2030 /* Encode the Key Exchange Payload */
2031 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2033 if (status != SILC_SKE_STATUS_OK) {
2034 /** Error encoding KE payload */
2035 ske->status = status;
2036 silc_fsm_next(fsm, silc_ske_st_responder_error);
2037 return SILC_FSM_CONTINUE;
2040 /* Send the packet. */
2041 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
2042 payload_buf->data, silc_buffer_len(payload_buf))) {
2043 SILC_LOG_DEBUG(("Error sending packet"));
2044 ske->status = SILC_SKE_STATUS_ERROR;
2045 silc_fsm_next(fsm, silc_ske_st_responder_error);
2046 return SILC_FSM_CONTINUE;
2049 silc_buffer_free(payload_buf);
2051 /** Waiting completion */
2052 silc_fsm_next(fsm, silc_ske_st_responder_end);
2053 return SILC_FSM_WAIT;
2056 /* Protocol completed */
2058 SILC_FSM_STATE(silc_ske_st_responder_end)
2060 SilcSKE ske = fsm_context;
2061 unsigned char tmp[4];
2062 SilcUInt32 hash_len, key_len, block_len;
2066 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2067 return SILC_FSM_CONTINUE;
2070 /* Check the result of the protocol */
2071 if (ske->packet->type == SILC_PACKET_FAILURE) {
2072 silc_fsm_next(fsm, silc_ske_st_responder_failure);
2073 return SILC_FSM_CONTINUE;
2075 silc_packet_free(ske->packet);
2077 /* Process key material */
2078 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2079 block_len = silc_cipher_get_key_len(ske->prop->cipher);
2080 hash_len = silc_hash_len(ske->prop->hash);
2081 ske->keymat = silc_ske_process_key_material(ske, block_len,
2084 /** Error processing key material */
2085 ske->status = SILC_SKE_STATUS_ERROR;
2086 silc_fsm_next(fsm, silc_ske_st_responder_error);
2087 return SILC_FSM_CONTINUE;
2090 /* Send SUCCESS packet */
2091 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2092 silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
2094 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2096 /* Call the completion callback */
2097 if (ske->callbacks->completed)
2098 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
2099 ske->rekey, ske->callbacks->context);
2101 return SILC_FSM_FINISH;
2104 /* Aborted by application */
2106 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2108 SilcSKE ske = fsm_context;
2109 unsigned char tmp[4];
2111 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2113 /* Send FAILURE packet */
2114 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2115 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2117 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2119 return SILC_FSM_FINISH;
2122 /* Failure received from remote */
2124 SILC_FSM_STATE(silc_ske_st_responder_failure)
2126 SilcSKE ske = fsm_context;
2127 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2129 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2131 if (silc_buffer_len(&ske->packet->buffer) == 4)
2132 SILC_GET32_MSB(error, ske->packet->buffer.data);
2133 ske->status = error;
2135 /* Call the completion callback */
2136 if (ske->callbacks->completed)
2137 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
2138 ske->callbacks->context);
2140 silc_packet_free(ske->packet);
2141 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2143 return SILC_FSM_FINISH;
2146 /* Error occurred */
2148 SILC_FSM_STATE(silc_ske_st_responder_error)
2150 SilcSKE ske = fsm_context;
2151 unsigned char tmp[4];
2153 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2154 ske->status, silc_ske_map_status(ske->status)));
2156 /* Send FAILURE packet */
2157 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2158 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2159 SILC_PUT32_MSB(ske->status, tmp);
2160 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2162 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2164 return SILC_FSM_FINISH;
2168 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
2169 void *destructor_context)
2174 /* Starts the protocol as responder. */
2177 silc_ske_responder(SilcSKE ske,
2178 SilcPacketStream stream,
2179 SilcSKEParams params)
2181 SILC_LOG_DEBUG(("Start SKE as responder"));
2183 if (!ske || !stream || !params || !params->version) {
2187 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2190 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2194 ske->responder = TRUE;
2195 ske->flags = params->flags;
2196 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2197 ske->session_port = params->session_port;
2198 ske->version = strdup(params->version);
2202 /* Link to packet stream to get key exchange packets */
2203 ske->stream = stream;
2204 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2205 SILC_PACKET_KEY_EXCHANGE,
2206 SILC_PACKET_KEY_EXCHANGE_1,
2207 SILC_PACKET_SUCCESS,
2208 SILC_PACKET_FAILURE, -1);
2210 /* Start SKE as responder */
2211 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2216 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2218 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2220 return SILC_FSM_FINISH;
2223 /* Starts rekey protocol as initiator */
2226 silc_ske_rekey_initiator(SilcSKE ske,
2227 SilcPacketStream stream,
2228 SilcSKERekeyMaterial rekey)
2230 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2232 if (!ske || !stream || !rekey)
2235 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2238 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2243 /* Link to packet stream to get key exchange packets */
2244 ske->stream = stream;
2246 /* Start SKE rekey as initiator */
2247 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2252 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2254 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2256 return SILC_FSM_FINISH;
2259 /* Starts rekey protocol as responder */
2262 silc_ske_rekey_responder(SilcSKE ske,
2263 SilcPacketStream stream,
2264 SilcBuffer ke_payload,
2265 SilcSKERekeyMaterial rekey)
2267 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2269 if (!ske || !stream || !rekey)
2271 if (rekey->pfs && !ke_payload)
2274 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2277 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2280 // ske->packet_buf = ke_payload;
2283 /* Link to packet stream to get key exchange packets */
2284 ske->stream = stream;
2286 /* Start SKE rekey as responder */
2287 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2292 /* Processes the provided key material `data' as the SILC protocol
2293 specification defines. */
2296 silc_ske_process_key_material_data(unsigned char *data,
2297 SilcUInt32 data_len,
2298 SilcUInt32 req_iv_len,
2299 SilcUInt32 req_enc_key_len,
2300 SilcUInt32 req_hmac_key_len,
2304 unsigned char hashd[SILC_HASH_MAXLEN];
2305 SilcUInt32 hash_len = req_hmac_key_len;
2306 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2307 SilcSKEKeyMaterial key;
2309 SILC_LOG_DEBUG(("Start"));
2311 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2314 key = silc_calloc(1, sizeof(*key));
2318 buf = silc_buffer_alloc_size(1 + data_len);
2321 silc_buffer_format(buf,
2322 SILC_STR_UI_CHAR(0),
2323 SILC_STR_UI_XNSTRING(data, data_len),
2327 memset(hashd, 0, sizeof(hashd));
2329 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2330 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2331 memcpy(key->send_iv, hashd, req_iv_len);
2332 memset(hashd, 0, sizeof(hashd));
2334 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2335 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2336 memcpy(key->receive_iv, hashd, req_iv_len);
2337 key->iv_len = req_iv_len;
2339 /* Take the encryption keys. If requested key size is more than
2340 the size of hash length we will distribute more key material
2341 as protocol defines. */
2343 if (enc_key_len > hash_len) {
2345 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2346 k3[SILC_HASH_MAXLEN];
2347 unsigned char *dtmp;
2350 if (enc_key_len > (3 * hash_len))
2353 /* Take first round */
2354 memset(k1, 0, sizeof(k1));
2355 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2357 /* Take second round */
2358 dist = silc_buffer_alloc_size(data_len + hash_len);
2361 silc_buffer_format(dist,
2362 SILC_STR_UI_XNSTRING(data, data_len),
2363 SILC_STR_UI_XNSTRING(k1, hash_len),
2365 memset(k2, 0, sizeof(k2));
2366 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2368 /* Take third round */
2369 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2370 silc_buffer_pull_tail(dist, hash_len);
2371 silc_buffer_pull(dist, data_len + hash_len);
2372 silc_buffer_format(dist,
2373 SILC_STR_UI_XNSTRING(k2, hash_len),
2375 silc_buffer_push(dist, data_len + hash_len);
2376 memset(k3, 0, sizeof(k3));
2377 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2379 /* Then, save the keys */
2380 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2381 memcpy(dtmp, k1, hash_len);
2382 memcpy(dtmp + hash_len, k2, hash_len);
2383 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2385 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2386 memcpy(key->send_enc_key, dtmp, enc_key_len);
2387 key->enc_key_len = req_enc_key_len;
2389 memset(dtmp, 0, (3 * hash_len));
2390 memset(k1, 0, sizeof(k1));
2391 memset(k2, 0, sizeof(k2));
2392 memset(k3, 0, sizeof(k3));
2394 silc_buffer_clear(dist);
2395 silc_buffer_free(dist);
2397 /* Take normal hash as key */
2398 memset(hashd, 0, sizeof(hashd));
2399 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2400 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2401 memcpy(key->send_enc_key, hashd, enc_key_len);
2402 key->enc_key_len = req_enc_key_len;
2406 if (enc_key_len > hash_len) {
2408 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2409 k3[SILC_HASH_MAXLEN];
2410 unsigned char *dtmp;
2413 if (enc_key_len > (3 * hash_len))
2416 /* Take first round */
2417 memset(k1, 0, sizeof(k1));
2418 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2420 /* Take second round */
2421 dist = silc_buffer_alloc_size(data_len + hash_len);
2424 silc_buffer_format(dist,
2425 SILC_STR_UI_XNSTRING(data, data_len),
2426 SILC_STR_UI_XNSTRING(k1, hash_len),
2428 memset(k2, 0, sizeof(k2));
2429 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2431 /* Take third round */
2432 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2433 silc_buffer_pull_tail(dist, hash_len);
2434 silc_buffer_pull(dist, data_len + hash_len);
2435 silc_buffer_format(dist,
2436 SILC_STR_UI_XNSTRING(k2, hash_len),
2438 silc_buffer_push(dist, data_len + hash_len);
2439 memset(k3, 0, sizeof(k3));
2440 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2442 /* Then, save the keys */
2443 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2444 memcpy(dtmp, k1, hash_len);
2445 memcpy(dtmp + hash_len, k2, hash_len);
2446 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2448 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2449 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2450 key->enc_key_len = req_enc_key_len;
2452 memset(dtmp, 0, (3 * hash_len));
2453 memset(k1, 0, sizeof(k1));
2454 memset(k2, 0, sizeof(k2));
2455 memset(k3, 0, sizeof(k3));
2457 silc_buffer_clear(dist);
2458 silc_buffer_free(dist);
2460 /* Take normal hash as key */
2461 memset(hashd, 0, sizeof(hashd));
2462 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2463 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2464 memcpy(key->receive_enc_key, hashd, enc_key_len);
2465 key->enc_key_len = req_enc_key_len;
2468 /* Take HMAC keys */
2469 memset(hashd, 0, sizeof(hashd));
2471 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2472 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2473 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2474 memset(hashd, 0, sizeof(hashd));
2476 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2477 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2478 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2479 key->hmac_key_len = req_hmac_key_len;
2480 memset(hashd, 0, sizeof(hashd));
2482 silc_buffer_clear(buf);
2483 silc_buffer_free(buf);
2488 /* Processes negotiated key material as protocol specifies. This returns
2489 the actual keys to be used in the SILC. */
2492 silc_ske_process_key_material(SilcSKE ske,
2493 SilcUInt32 req_iv_len,
2494 SilcUInt32 req_enc_key_len,
2495 SilcUInt32 req_hmac_key_len)
2498 unsigned char *tmpbuf;
2500 SilcSKEKeyMaterial key;
2502 /* Encode KEY to binary data */
2503 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2505 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2508 silc_buffer_format(buf,
2509 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2510 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2513 /* Process the key material */
2514 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2515 req_iv_len, req_enc_key_len,
2519 memset(tmpbuf, 0, klen);
2521 silc_buffer_clear(buf);
2522 silc_buffer_free(buf);
2527 /* Free key material structure */
2529 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2535 silc_free(key->send_iv);
2536 if (key->receive_iv)
2537 silc_free(key->receive_iv);
2538 if (key->send_enc_key) {
2539 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2540 silc_free(key->send_enc_key);
2542 if (key->receive_enc_key) {
2543 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2544 silc_free(key->receive_enc_key);
2546 if (key->send_hmac_key) {
2547 memset(key->send_hmac_key, 0, key->hmac_key_len);
2548 silc_free(key->send_hmac_key);
2550 if (key->receive_hmac_key) {
2551 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2552 silc_free(key->receive_hmac_key);
2557 /* Set keys into use */
2559 SilcBool silc_ske_set_keys(SilcSKE ske,
2560 SilcSKEKeyMaterial keymat,
2561 SilcSKESecurityProperties prop,
2562 SilcCipher *ret_send_key,
2563 SilcCipher *ret_receive_key,
2564 SilcHmac *ret_hmac_send,
2565 SilcHmac *ret_hmac_receive,
2568 /* Allocate ciphers to be used in the communication */
2570 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2574 if (ret_receive_key) {
2575 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2580 /* Allocate HMACs */
2581 if (ret_hmac_send) {
2582 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2586 if (ret_hmac_receive) {
2587 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2592 /* Set key material */
2593 if (ske->responder) {
2594 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2595 keymat->enc_key_len);
2596 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2597 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2598 keymat->enc_key_len);
2599 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2600 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2601 keymat->hmac_key_len);
2602 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2603 keymat->hmac_key_len);
2605 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2606 keymat->enc_key_len);
2607 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2608 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2609 keymat->enc_key_len);
2610 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2611 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2612 keymat->hmac_key_len);
2613 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2614 keymat->hmac_key_len);
2619 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
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)