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, &(*prop)->cipher) == FALSE) {
391 silc_free(payload->ke_grp_list);
392 silc_free(payload->pkcs_alg_list);
394 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
397 /* Get supported hash algorithms */
398 cp = rp->hash_alg_list;
399 if (cp && strchr(cp, ',')) {
403 len = strcspn(cp, ",");
404 item = silc_calloc(len + 1, sizeof(char));
406 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
409 memcpy(item, cp, len);
411 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
413 if (silc_hash_is_supported(item) == TRUE) {
414 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
416 payload->hash_alg_len = len;
417 payload->hash_alg_list = item;
431 if (!payload->hash_alg_len && !payload->hash_alg_list) {
432 SILC_LOG_DEBUG(("Could not find supported hash alg"));
433 silc_free(payload->ke_grp_list);
434 silc_free(payload->pkcs_alg_list);
435 silc_free(payload->enc_alg_list);
437 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
440 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
443 payload->hash_alg_len = rp->hash_alg_len;
444 payload->hash_alg_list = strdup(rp->hash_alg_list);
447 /* Save selected hash algorithm to security properties */
448 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
449 silc_free(payload->ke_grp_list);
450 silc_free(payload->pkcs_alg_list);
451 silc_free(payload->enc_alg_list);
453 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
456 /* Get supported HMACs */
457 cp = rp->hmac_alg_list;
458 if (cp && strchr(cp, ',')) {
462 len = strcspn(cp, ",");
463 item = silc_calloc(len + 1, sizeof(char));
465 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
468 memcpy(item, cp, len);
470 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
472 if (silc_hmac_is_supported(item) == TRUE) {
473 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
475 payload->hmac_alg_len = len;
476 payload->hmac_alg_list = item;
490 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
491 SILC_LOG_DEBUG(("Could not find supported HMAC"));
492 silc_free(payload->ke_grp_list);
493 silc_free(payload->pkcs_alg_list);
494 silc_free(payload->enc_alg_list);
495 silc_free(payload->hash_alg_list);
497 return SILC_SKE_STATUS_UNKNOWN_HMAC;
500 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
503 payload->hmac_alg_len = rp->hmac_alg_len;
504 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
507 /* Save selected HMACc to security properties */
508 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
509 silc_free(payload->ke_grp_list);
510 silc_free(payload->pkcs_alg_list);
511 silc_free(payload->enc_alg_list);
512 silc_free(payload->hash_alg_list);
514 return SILC_SKE_STATUS_UNKNOWN_HMAC;
517 /* Get supported compression algorithms */
518 cp = rp->comp_alg_list;
519 if (cp && strchr(cp, ',')) {
523 len = strcspn(cp, ",");
524 item = silc_calloc(len + 1, sizeof(char));
526 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
529 memcpy(item, cp, len);
531 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
534 if (!strcmp(item, "none")) {
535 SILC_LOG_DEBUG(("Found Compression `%s'", item));
536 payload->comp_alg_len = len;
537 payload->comp_alg_list = item;
541 if (silc_hmac_is_supported(item) == TRUE) {
542 SILC_LOG_DEBUG(("Found Compression `%s'", item));
543 payload->comp_alg_len = len;
544 payload->comp_alg_list = item;
560 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
561 2 + payload->version_len +
562 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
563 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
564 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
566 /* Save our reply payload */
567 ske->start_payload = payload;
569 return SILC_SKE_STATUS_OK;
572 /* Creates random number such that 1 < rnd < n and at most length
573 of len bits. The rnd sent as argument must be initialized. */
575 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
579 SilcSKEStatus status = SILC_SKE_STATUS_OK;
580 unsigned char *string;
584 return SILC_SKE_STATUS_ERROR;
586 SILC_LOG_DEBUG(("Creating random number"));
590 /* Get the random number as string */
591 string = silc_rng_get_rn_data(ske->rng, l);
593 return SILC_SKE_STATUS_OUT_OF_MEMORY;
595 /* Decode the string into a MP integer */
596 silc_mp_bin2mp(string, l, rnd);
597 silc_mp_mod_2exp(rnd, rnd, len);
600 if (silc_mp_cmp_ui(rnd, 1) < 0)
601 status = SILC_SKE_STATUS_ERROR;
602 if (silc_mp_cmp(rnd, n) >= 0)
603 status = SILC_SKE_STATUS_ERROR;
605 memset(string, 'F', l);
611 /* Creates a hash value HASH as defined in the SKE protocol. If the
612 `initiator' is TRUE then this function is used to create the HASH_i
613 hash value defined in the protocol. If it is FALSE then this is used
614 to create the HASH value defined by the protocol. */
616 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
617 unsigned char *return_hash,
618 SilcUInt32 *return_hash_len,
621 SilcSKEStatus status = SILC_SKE_STATUS_OK;
623 unsigned char *e, *f, *KEY;
624 SilcUInt32 e_len, f_len, KEY_len;
627 SILC_LOG_DEBUG(("Start"));
629 if (initiator == FALSE) {
630 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
631 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
632 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
634 /* Format the buffer used to compute the hash value */
635 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
636 ske->ke2_payload->pk_len +
637 ske->ke1_payload->pk_len +
638 e_len + f_len + KEY_len);
640 return SILC_SKE_STATUS_OUT_OF_MEMORY;
642 /* Initiator is not required to send its public key */
643 if (!ske->ke1_payload->pk_data) {
645 silc_buffer_format(buf,
646 SILC_STR_UI_XNSTRING(
647 ske->start_payload_copy->data,
648 silc_buffer_len(ske->start_payload_copy)),
649 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
650 ske->ke2_payload->pk_len),
651 SILC_STR_UI_XNSTRING(e, e_len),
652 SILC_STR_UI_XNSTRING(f, f_len),
653 SILC_STR_UI_XNSTRING(KEY, KEY_len),
657 silc_buffer_format(buf,
658 SILC_STR_UI_XNSTRING(
659 ske->start_payload_copy->data,
660 silc_buffer_len(ske->start_payload_copy)),
661 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
662 ske->ke2_payload->pk_len),
663 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
664 ske->ke1_payload->pk_len),
665 SILC_STR_UI_XNSTRING(e, e_len),
666 SILC_STR_UI_XNSTRING(f, f_len),
667 SILC_STR_UI_XNSTRING(KEY, KEY_len),
671 silc_buffer_free(buf);
674 memset(KEY, 0, KEY_len);
678 return SILC_SKE_STATUS_ERROR;
683 memset(KEY, 0, KEY_len);
688 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
690 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
691 ske->ke1_payload->pk_len + e_len);
693 return SILC_SKE_STATUS_OUT_OF_MEMORY;
695 /* Format the buffer used to compute the hash value */
697 silc_buffer_format(buf,
698 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
699 silc_buffer_len(ske->start_payload_copy)),
700 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
701 ske->ke1_payload->pk_len),
702 SILC_STR_UI_XNSTRING(e, e_len),
705 silc_buffer_free(buf);
708 return SILC_SKE_STATUS_ERROR;
711 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
718 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
720 *return_hash_len = silc_hash_len(ske->prop->hash);
722 if (initiator == FALSE) {
723 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
725 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
728 silc_buffer_free(buf);
733 /* Assembles security properties */
735 static SilcSKEStartPayload
736 silc_ske_assemble_security_properties(SilcSKE ske,
737 SilcSKESecurityPropertyFlag flags,
740 SilcSKEStartPayload rp;
743 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
745 rp = silc_calloc(1, sizeof(*rp));
748 rp->flags = (unsigned char)flags;
750 /* Set random cookie */
751 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
752 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
753 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
754 rp->cookie_len = SILC_SKE_COOKIE_LEN;
756 /* In case IV included flag and session port is set the first 16-bits of
757 cookie will include our session port. */
758 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
759 SILC_PUT16_MSB(ske->session_port, rp->cookie);
762 rp->version = strdup(version);
763 rp->version_len = strlen(version);
765 /* Get supported Key Exhange groups */
766 rp->ke_grp_list = silc_ske_get_supported_groups();
767 rp->ke_grp_len = strlen(rp->ke_grp_list);
769 /* Get supported PKCS algorithms */
770 rp->pkcs_alg_list = silc_pkcs_get_supported();
771 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
773 /* Get supported encryption algorithms */
774 rp->enc_alg_list = silc_cipher_get_supported();
775 rp->enc_alg_len = strlen(rp->enc_alg_list);
777 /* Get supported hash algorithms */
778 rp->hash_alg_list = silc_hash_get_supported();
779 rp->hash_alg_len = strlen(rp->hash_alg_list);
781 /* Get supported HMACs */
782 rp->hmac_alg_list = silc_hmac_get_supported();
783 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
786 /* Get supported compression algorithms */
787 rp->comp_alg_list = strdup("none");
788 rp->comp_alg_len = strlen("none");
790 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
791 2 + rp->version_len +
792 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
793 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
794 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
800 /******************************* Protocol API *******************************/
802 /* Allocates new SKE object. */
804 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
805 SilcSKR repository, SilcPublicKey public_key,
806 SilcPrivateKey private_key, void *context)
810 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
812 if (!rng || !schedule)
816 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
820 ske = silc_calloc(1, sizeof(*ske));
823 ske->status = SILC_SKE_STATUS_OK;
825 ske->repository = repository;
826 ske->user_data = context;
827 ske->schedule = schedule;
828 ske->public_key = public_key;
829 ske->private_key = private_key;
834 /* Free's SKE object. */
836 void silc_ske_free(SilcSKE ske)
838 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
848 /* Free start payload */
849 if (ske->start_payload)
850 silc_ske_payload_start_free(ske->start_payload);
852 /* Free KE payload */
853 if (ske->ke1_payload)
854 silc_ske_payload_ke_free(ske->ke1_payload);
855 if (ske->ke2_payload)
856 silc_ske_payload_ke_free(ske->ke2_payload);
857 silc_free(ske->remote_version);
861 if (ske->prop->group)
862 silc_ske_group_free(ske->prop->group);
863 if (ske->prop->cipher)
864 silc_cipher_free(ske->prop->cipher);
866 silc_hash_free(ske->prop->hash);
868 silc_hmac_free(ske->prop->hmac);
869 silc_free(ske->prop);
871 if (ske->start_payload_copy)
872 silc_buffer_free(ske->start_payload_copy);
874 silc_mp_uninit(ske->x);
878 silc_mp_uninit(ske->KEY);
881 silc_free(ske->hash);
882 silc_free(ske->callbacks);
884 memset(ske, 'F', sizeof(*ske));
888 /* Return user context */
890 void *silc_ske_get_context(SilcSKE ske)
892 return ske->user_data;
895 /* Sets protocol callbacks */
897 void silc_ske_set_callbacks(SilcSKE ske,
898 SilcSKEVerifyCb verify_key,
899 SilcSKECompletionCb completed,
903 silc_free(ske->callbacks);
904 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
907 ske->callbacks->verify_key = verify_key;
908 ske->callbacks->completed = completed;
909 ske->callbacks->context = context;
913 /******************************** Initiator *********************************/
915 /* Initiator state machine */
916 SILC_FSM_STATE(silc_ske_st_initiator_start);
917 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
918 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
919 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
920 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
921 SILC_FSM_STATE(silc_ske_st_initiator_end);
922 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
923 SILC_FSM_STATE(silc_ske_st_initiator_error);
924 SILC_FSM_STATE(silc_ske_st_initiator_failure);
926 /* Start protocol. Send our proposal */
928 SILC_FSM_STATE(silc_ske_st_initiator_start)
930 SilcSKE ske = fsm_context;
931 SilcBuffer payload_buf;
934 SILC_LOG_DEBUG(("Start"));
938 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
939 return SILC_FSM_CONTINUE;
942 /* Encode the payload */
943 status = silc_ske_payload_start_encode(ske, ske->start_payload,
945 if (status != SILC_SKE_STATUS_OK) {
946 /** Error encoding Start Payload */
947 ske->status = status;
948 silc_fsm_next(fsm, silc_ske_st_initiator_error);
949 return SILC_FSM_CONTINUE;
952 /* Save the the payload buffer for future use. It is later used to
953 compute the HASH value. */
954 ske->start_payload_copy = payload_buf;
956 /* Send the packet. */
957 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
958 silc_buffer_data(payload_buf),
959 silc_buffer_len(payload_buf))) {
960 /** Error sending packet */
961 SILC_LOG_DEBUG(("Error sending packet"));
962 ske->status = SILC_SKE_STATUS_ERROR;
963 silc_fsm_next(fsm, silc_ske_st_initiator_error);
964 return SILC_FSM_CONTINUE;
969 /** Wait for responder proposal */
970 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
971 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
972 return SILC_FSM_WAIT;
975 /* Phase-1. Receives responder's proposal */
977 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
979 SilcSKE ske = fsm_context;
980 SilcSKEStatus status;
981 SilcSKEStartPayload payload;
982 SilcSKESecurityProperties prop;
983 SilcSKEDiffieHellmanGroup group = NULL;
984 SilcBuffer packet_buf = &ske->packet->buffer;
985 SilcUInt16 remote_port = 0;
989 SILC_LOG_DEBUG(("Start"));
993 silc_packet_free(ske->packet);
994 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
995 return SILC_FSM_CONTINUE;
998 /* Decode the payload */
999 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1000 if (status != SILC_SKE_STATUS_OK) {
1001 /** Error decoding Start Payload */
1002 silc_packet_free(ske->packet);
1003 ske->status = status;
1004 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1005 return SILC_FSM_CONTINUE;
1008 /* Get remote ID and set it to stream */
1009 if (ske->packet->src_id_len) {
1010 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1011 ske->packet->src_id_type,
1012 (ske->packet->src_id_type == SILC_ID_SERVER ?
1013 (void *)&id.u.server_id : (void *)&id.u.client_id),
1014 (ske->packet->src_id_type == SILC_ID_SERVER ?
1015 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1016 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1017 (ske->packet->src_id_type == SILC_ID_SERVER ?
1018 (void *)&id.u.server_id : (void *)&id.u.client_id));
1021 silc_packet_free(ske->packet);
1023 /* Check that the cookie is returned unmodified. In case IV included
1024 flag and session port has been set, the first two bytes of cookie
1025 are the session port and we ignore them in this check. */
1026 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1027 /* Take remote port */
1028 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1031 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1032 SILC_SKE_COOKIE_LEN - coff)) {
1033 /** Invalid cookie */
1034 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1035 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1036 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1037 return SILC_FSM_CONTINUE;
1040 /* Check version string */
1041 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1042 status = silc_ske_check_version(ske);
1043 if (status != SILC_SKE_STATUS_OK) {
1044 /** Version mismatch */
1045 ske->status = status;
1046 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1047 return SILC_FSM_CONTINUE;
1050 /* Free our KE Start Payload context, we don't need it anymore. */
1051 silc_ske_payload_start_free(ske->start_payload);
1052 ske->start_payload = NULL;
1054 /* Take the selected security properties into use while doing
1055 the key exchange. This is used only while doing the key
1057 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1060 prop->flags = payload->flags;
1061 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1062 if (status != SILC_SKE_STATUS_OK)
1065 prop->group = group;
1066 prop->remote_port = remote_port;
1068 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1069 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1072 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1073 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1076 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1077 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1080 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1081 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1085 /* Save remote's KE Start Payload */
1086 ske->start_payload = payload;
1088 /** Send KE Payload */
1089 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1090 return SILC_FSM_CONTINUE;
1094 silc_ske_payload_start_free(payload);
1096 silc_ske_group_free(group);
1098 silc_cipher_free(prop->cipher);
1100 silc_hash_free(prop->hash);
1102 silc_hmac_free(prop->hmac);
1106 if (status == SILC_SKE_STATUS_OK)
1107 status = SILC_SKE_STATUS_ERROR;
1110 ske->status = status;
1111 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1112 return SILC_FSM_CONTINUE;
1115 /* Phase-2. Send KE payload */
1117 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1119 SilcSKE ske = fsm_context;
1120 SilcSKEStatus status;
1121 SilcBuffer payload_buf;
1123 SilcSKEKEPayload payload;
1126 SILC_LOG_DEBUG(("Start"));
1128 /* Create the random number x, 1 < x < q. */
1129 x = silc_calloc(1, sizeof(*x));
1131 /** Out of memory */
1132 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1133 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1134 return SILC_FSM_CONTINUE;
1138 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1139 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1141 if (status != SILC_SKE_STATUS_OK) {
1142 /** Error generating random number */
1145 ske->status = status;
1146 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1147 return SILC_FSM_CONTINUE;
1150 /* Encode the result to Key Exchange Payload. */
1152 payload = silc_calloc(1, sizeof(*payload));
1154 /** Out of memory */
1157 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1158 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1159 return SILC_FSM_CONTINUE;
1161 ske->ke1_payload = payload;
1163 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1165 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1166 silc_mp_init(&payload->x);
1167 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1168 &ske->prop->group->group);
1170 /* Get public key */
1171 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1172 if (!payload->pk_data) {
1173 /** Error encoding public key */
1176 silc_mp_uninit(&payload->x);
1178 ske->ke1_payload = NULL;
1179 ske->status = SILC_SKE_STATUS_ERROR;
1180 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1181 return SILC_FSM_CONTINUE;
1183 payload->pk_len = pk_len;
1184 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1186 /* Compute signature data if we are doing mutual authentication */
1187 if (ske->private_key &&
1188 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1189 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1190 SilcUInt32 hash_len, sign_len;
1192 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1193 SILC_LOG_DEBUG(("Computing HASH_i value"));
1195 /* Compute the hash value */
1196 memset(hash, 0, sizeof(hash));
1197 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1199 SILC_LOG_DEBUG(("Signing HASH_i value"));
1201 /* Sign the hash value */
1202 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1203 sizeof(sign) - 1, &sign_len, NULL)) {
1204 /** Error computing signature */
1207 silc_mp_uninit(&payload->x);
1208 silc_free(payload->pk_data);
1210 ske->ke1_payload = NULL;
1211 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1212 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1213 return SILC_FSM_CONTINUE;
1215 payload->sign_data = silc_memdup(sign, sign_len);
1216 if (payload->sign_data)
1217 payload->sign_len = sign_len;
1218 memset(sign, 0, sizeof(sign));
1221 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1222 if (status != SILC_SKE_STATUS_OK) {
1223 /** Error encoding KE payload */
1226 silc_mp_uninit(&payload->x);
1227 silc_free(payload->pk_data);
1228 silc_free(payload->sign_data);
1230 ske->ke1_payload = NULL;
1231 ske->status = status;
1232 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1233 return SILC_FSM_CONTINUE;
1238 /* Check for backwards compatibility */
1240 /* Send the packet. */
1241 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_1, 0,
1242 silc_buffer_data(payload_buf),
1243 silc_buffer_len(payload_buf))) {
1244 /** Error sending packet */
1245 SILC_LOG_DEBUG(("Error sending packet"));
1246 ske->status = SILC_SKE_STATUS_ERROR;
1247 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1248 return SILC_FSM_CONTINUE;
1251 silc_buffer_free(payload_buf);
1253 /** Waiting responder's KE payload */
1254 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1255 return SILC_FSM_WAIT;
1258 /* Phase-3. Process responder's KE payload */
1260 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1262 SilcSKE ske = fsm_context;
1263 SilcSKEStatus status;
1264 SilcSKEKEPayload payload;
1266 SilcBuffer packet_buf = &ske->packet->buffer;
1268 SILC_LOG_DEBUG(("Start"));
1272 silc_packet_free(ske->packet);
1273 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1274 return SILC_FSM_CONTINUE;
1277 /* Decode the payload */
1278 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1279 if (status != SILC_SKE_STATUS_OK) {
1280 /** Error decoding KE payload */
1281 silc_packet_free(ske->packet);
1282 ske->status = status;
1283 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1284 return SILC_FSM_CONTINUE;
1286 silc_packet_free(ske->packet);
1287 ske->ke2_payload = payload;
1289 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1290 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1291 "even though we require it"));
1292 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1296 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1298 /* Compute the shared secret key */
1299 KEY = silc_calloc(1, sizeof(*KEY));
1301 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1304 /* Decode the remote's public key */
1305 if (payload->pk_data &&
1306 !silc_pkcs_public_key_alloc(payload->pk_type,
1307 payload->pk_data, payload->pk_len,
1308 &ske->prop->public_key)) {
1309 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1310 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1314 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1316 SILC_LOG_DEBUG(("Verifying public key"));
1318 /** Waiting public key verification */
1319 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1321 /* If repository is provided, verify the key from there. */
1322 if (ske->repository) {
1325 find = silc_skr_find_alloc();
1327 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1330 silc_skr_find_set_pkcs_type(find,
1331 silc_pkcs_get_type(ske->prop->public_key));
1332 silc_skr_find_set_public_key(find, ske->prop->public_key);
1333 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1335 /* Find key from repository */
1336 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1337 silc_ske_skr_callback, ske));
1339 /* Verify from application */
1340 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1341 ske->callbacks->context,
1342 silc_ske_pk_verified, NULL));
1347 /** Process key material */
1348 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1349 return SILC_FSM_CONTINUE;
1352 silc_ske_payload_ke_free(payload);
1353 ske->ke2_payload = NULL;
1355 silc_mp_uninit(ske->KEY);
1356 silc_free(ske->KEY);
1359 if (status == SILC_SKE_STATUS_OK)
1360 return SILC_SKE_STATUS_ERROR;
1363 ske->status = status;
1364 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1365 return SILC_FSM_CONTINUE;
1368 /* Process key material */
1370 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1372 SilcSKE ske = fsm_context;
1373 SilcSKEStatus status;
1374 SilcSKEKEPayload payload;
1375 unsigned char hash[SILC_HASH_MAXLEN];
1376 SilcUInt32 hash_len;
1377 int key_len, block_len;
1381 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1382 return SILC_FSM_CONTINUE;
1385 /* Check result of public key verification */
1386 if (ske->status != SILC_SKE_STATUS_OK) {
1387 /** Public key not verified */
1388 SILC_LOG_DEBUG(("Public key verification failed"));
1389 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1390 return SILC_FSM_CONTINUE;
1393 payload = ske->ke2_payload;
1395 if (ske->prop->public_key) {
1396 SILC_LOG_DEBUG(("Public key is authentic"));
1398 /* Compute the hash value */
1399 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1400 if (status != SILC_SKE_STATUS_OK)
1403 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1405 /* Verify signature */
1406 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1407 payload->sign_len, hash, hash_len, NULL)) {
1408 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1409 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1413 SILC_LOG_DEBUG(("Signature is Ok"));
1415 ske->hash = silc_memdup(hash, hash_len);
1416 ske->hash_len = hash_len;
1417 memset(hash, 'F', hash_len);
1420 ske->status = SILC_SKE_STATUS_OK;
1422 /* Process key material */
1423 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1424 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1425 hash_len = silc_hash_len(ske->prop->hash);
1426 ske->keymat = silc_ske_process_key_material(ske, block_len,
1429 SILC_LOG_ERROR(("Error processing key material"));
1430 status = SILC_SKE_STATUS_ERROR;
1434 /* Send SUCCESS packet */
1435 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1436 if (!silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1437 /** Error sending packet */
1438 SILC_LOG_DEBUG(("Error sending packet"));
1439 ske->status = SILC_SKE_STATUS_ERROR;
1440 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1441 return SILC_FSM_CONTINUE;
1444 /** Waiting completion */
1445 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1446 return SILC_FSM_WAIT;
1449 memset(hash, 'F', sizeof(hash));
1450 silc_ske_payload_ke_free(payload);
1451 ske->ke2_payload = NULL;
1453 silc_mp_uninit(ske->KEY);
1454 silc_free(ske->KEY);
1458 memset(ske->hash, 'F', hash_len);
1459 silc_free(ske->hash);
1463 if (status == SILC_SKE_STATUS_OK)
1464 status = SILC_SKE_STATUS_ERROR;
1467 ske->status = status;
1468 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1469 return SILC_FSM_CONTINUE;
1472 /* Protocol completed */
1474 SILC_FSM_STATE(silc_ske_st_initiator_end)
1476 SilcSKE ske = fsm_context;
1478 SILC_LOG_DEBUG(("Start"));
1482 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1483 return SILC_FSM_CONTINUE;
1486 /* See if received failure from remote */
1487 if (ske->packet->type == SILC_PACKET_FAILURE) {
1488 silc_packet_free(ske->packet);
1489 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1490 return SILC_FSM_CONTINUE;
1493 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1495 /* Call the completion callback */
1496 if (ske->callbacks->completed)
1497 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1498 ske->rekey, ske->callbacks->context);
1500 silc_packet_free(ske->packet);
1501 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1503 return SILC_FSM_FINISH;
1506 /* Aborted by application */
1508 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1510 SilcSKE ske = fsm_context;
1511 unsigned char data[4];
1513 SILC_LOG_DEBUG(("Aborted by caller"));
1515 /* Send FAILURE packet */
1516 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1517 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1518 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1520 return SILC_FSM_FINISH;
1523 /* Error occurred. Send error to remote host */
1525 SILC_FSM_STATE(silc_ske_st_initiator_error)
1527 SilcSKE ske = fsm_context;
1528 SilcSKEStatus status;
1529 unsigned char data[4];
1531 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1532 silc_ske_map_status(ske->status), ske->status));
1534 status = ske->status;
1535 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1536 status = SILC_SKE_STATUS_ERROR;
1538 /* Send FAILURE packet */
1539 SILC_PUT32_MSB((SilcUInt32)status, data);
1540 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, data, 4);
1542 /* Call the completion callback */
1543 if (ske->callbacks->completed)
1544 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1545 ske->callbacks->context);
1547 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1549 return SILC_FSM_FINISH;
1552 /* Failure received from remote */
1554 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1556 SilcSKE ske = fsm_context;
1558 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1559 silc_ske_map_status(ske->status), ske->status));
1561 /* Call the completion callback */
1562 if (ske->callbacks->completed)
1563 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1564 ske->callbacks->context);
1566 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1568 return SILC_FSM_FINISH;
1571 /* FSM destructor */
1573 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1574 void *destructor_context)
1576 SilcSKE ske = fsm_context;
1578 ske->running = FALSE;
1583 /* Starts the protocol as initiator */
1586 silc_ske_initiator(SilcSKE ske,
1587 SilcPacketStream stream,
1588 SilcSKEParams params,
1589 SilcSKEStartPayload start_payload)
1591 SILC_LOG_DEBUG(("Start SKE as initiator"));
1593 if (!ske || !stream || !params || !params->version)
1596 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1599 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1603 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1604 ske->session_port = params->session_port;
1606 /* Generate security properties if not provided */
1607 if (!start_payload) {
1608 start_payload = silc_ske_assemble_security_properties(ske,
1615 ske->start_payload = start_payload;
1616 ske->version = params->version;
1617 ske->running = TRUE;
1619 /* Link to packet stream to get key exchange packets */
1620 ske->stream = stream;
1621 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1622 SILC_PACKET_KEY_EXCHANGE,
1623 SILC_PACKET_KEY_EXCHANGE_2,
1624 SILC_PACKET_SUCCESS,
1625 SILC_PACKET_FAILURE, -1);
1627 /* Start SKE as initiator */
1628 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1634 /******************************** Responder *********************************/
1636 SILC_FSM_STATE(silc_ske_st_responder_start);
1637 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1638 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1639 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1640 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1641 SILC_FSM_STATE(silc_ske_st_responder_end);
1642 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1643 SILC_FSM_STATE(silc_ske_st_responder_failure);
1644 SILC_FSM_STATE(silc_ske_st_responder_error);
1646 /* Start protocol as responder. Wait initiator's start payload */
1648 SILC_FSM_STATE(silc_ske_st_responder_start)
1650 SilcSKE ske = fsm_context;
1652 SILC_LOG_DEBUG(("Start"));
1656 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1657 return SILC_FSM_CONTINUE;
1663 /** Wait for initiator */
1664 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1665 return SILC_FSM_WAIT;
1668 /* Decode initiator's start payload. Select the security properties from
1669 the initiator's start payload and send our reply start payload back. */
1671 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1673 SilcSKE ske = fsm_context;
1674 SilcSKEStatus status;
1675 SilcSKEStartPayload remote_payload = NULL;
1676 SilcBuffer packet_buf = &ske->packet->buffer;
1678 SILC_LOG_DEBUG(("Start"));
1682 silc_packet_free(ske->packet);
1683 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1684 return SILC_FSM_CONTINUE;
1687 /* See if received failure from remote */
1688 if (ske->packet->type == SILC_PACKET_FAILURE) {
1689 silc_packet_free(ske->packet);
1690 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1691 return SILC_FSM_CONTINUE;
1694 /* Decode the payload */
1695 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1696 if (status != SILC_SKE_STATUS_OK) {
1697 /** Error decoding Start Payload */
1698 silc_packet_free(ske->packet);
1699 ske->status = status;
1700 silc_fsm_next(fsm, silc_ske_st_responder_error);
1701 return SILC_FSM_CONTINUE;
1704 /* Take a copy of the payload buffer for future use. It is used to
1705 compute the HASH value. */
1706 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1708 silc_packet_free(ske->packet);
1710 /* Force the mutual authentication flag if we want to do it. */
1711 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1712 SILC_LOG_DEBUG(("Force mutual authentication"));
1713 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1716 /* Force PFS flag if we require it */
1717 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1718 SILC_LOG_DEBUG(("Force PFS"));
1719 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1722 /* Disable IV Included flag if requested */
1723 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1724 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1725 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1726 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1729 /* Check and select security properties */
1730 status = silc_ske_select_security_properties(ske, remote_payload,
1732 if (status != SILC_SKE_STATUS_OK) {
1733 /** Error selecting proposal */
1734 silc_ske_payload_start_free(remote_payload);
1735 ske->status = status;
1736 silc_fsm_next(fsm, silc_ske_st_responder_error);
1737 return SILC_FSM_CONTINUE;
1740 silc_ske_payload_start_free(remote_payload);
1742 /* Encode our reply payload to send the selected security properties */
1743 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1745 if (status != SILC_SKE_STATUS_OK)
1748 /* Send the packet. */
1749 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1750 silc_buffer_data(packet_buf),
1751 silc_buffer_len(packet_buf)))
1754 silc_buffer_free(packet_buf);
1756 /** Waiting initiator's KE payload */
1757 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1758 return SILC_FSM_WAIT;
1761 if (ske->prop->group)
1762 silc_ske_group_free(ske->prop->group);
1763 if (ske->prop->cipher)
1764 silc_cipher_free(ske->prop->cipher);
1765 if (ske->prop->hash)
1766 silc_hash_free(ske->prop->hash);
1767 if (ske->prop->hmac)
1768 silc_hmac_free(ske->prop->hmac);
1769 silc_free(ske->prop);
1772 if (status == SILC_SKE_STATUS_OK)
1773 status = SILC_SKE_STATUS_ERROR;
1776 ske->status = status;
1777 silc_fsm_next(fsm, silc_ske_st_responder_error);
1778 return SILC_FSM_CONTINUE;
1781 /* Phase-2. Decode initiator's KE payload */
1783 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1785 SilcSKE ske = fsm_context;
1786 SilcSKEStatus status;
1787 SilcSKEKEPayload recv_payload;
1788 SilcBuffer packet_buf = &ske->packet->buffer;
1790 SILC_LOG_DEBUG(("Start"));
1794 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1795 return SILC_FSM_CONTINUE;
1798 /* See if received failure from remote */
1799 if (ske->packet->type == SILC_PACKET_FAILURE) {
1800 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1801 return SILC_FSM_CONTINUE;
1804 /* Decode Key Exchange Payload */
1805 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1806 if (status != SILC_SKE_STATUS_OK) {
1807 /** Error decoding KE payload */
1808 silc_packet_free(ske->packet);
1809 ske->status = status;
1810 silc_fsm_next(fsm, silc_ske_st_responder_error);
1811 return SILC_FSM_CONTINUE;
1814 ske->ke1_payload = recv_payload;
1816 silc_packet_free(ske->packet);
1818 /* Verify the received public key and verify the signature if we are
1819 doing mutual authentication. */
1820 if (ske->start_payload &&
1821 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1823 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1825 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1827 /** Public key not provided */
1828 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1829 "certificate), even though we require it"));
1830 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1831 silc_fsm_next(fsm, silc_ske_st_responder_error);
1832 return SILC_FSM_CONTINUE;
1835 /* Decode the remote's public key */
1836 if (recv_payload->pk_data &&
1837 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1838 recv_payload->pk_data,
1839 recv_payload->pk_len,
1840 &ske->prop->public_key)) {
1841 /** Error decoding public key */
1842 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1843 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1844 silc_fsm_next(fsm, silc_ske_st_responder_error);
1845 return SILC_FSM_CONTINUE;
1848 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1850 SILC_LOG_DEBUG(("Verifying public key"));
1852 /** Waiting public key verification */
1853 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1855 /* If repository is provided, verify the key from there. */
1856 if (ske->repository) {
1859 find = silc_skr_find_alloc();
1861 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1862 silc_fsm_next(fsm, silc_ske_st_responder_error);
1863 return SILC_FSM_CONTINUE;
1865 silc_skr_find_set_pkcs_type(find,
1866 silc_pkcs_get_type(ske->prop->public_key));
1867 silc_skr_find_set_public_key(find, ske->prop->public_key);
1868 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1870 /* Find key from repository */
1871 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1872 silc_ske_skr_callback, ske));
1874 /* Verify from application */
1875 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1876 ske->callbacks->context,
1877 silc_ske_pk_verified, NULL));
1883 /** Generate KE2 payload */
1884 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1885 return SILC_FSM_CONTINUE;
1888 /* Phase-4. Generate KE2 payload */
1890 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1892 SilcSKE ske = fsm_context;
1893 SilcSKEStatus status;
1894 SilcSKEKEPayload recv_payload, send_payload;
1899 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1900 return SILC_FSM_CONTINUE;
1903 /* Check result of public key verification */
1904 if (ske->status != SILC_SKE_STATUS_OK) {
1905 /** Public key not verified */
1906 SILC_LOG_DEBUG(("Public key verification failed"));
1907 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1908 return SILC_FSM_CONTINUE;
1911 recv_payload = ske->ke1_payload;
1913 /* The public key verification was performed only if the Mutual
1914 Authentication flag is set. */
1915 if (ske->start_payload &&
1916 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1917 unsigned char hash[SILC_HASH_MAXLEN];
1918 SilcUInt32 hash_len;
1920 SILC_LOG_DEBUG(("Public key is authentic"));
1922 /* Compute the hash value */
1923 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1924 if (status != SILC_SKE_STATUS_OK) {
1925 /** Error computing hash */
1926 ske->status = status;
1927 silc_fsm_next(fsm, silc_ske_st_responder_error);
1928 return SILC_FSM_CONTINUE;
1931 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1933 /* Verify signature */
1934 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
1935 recv_payload->sign_len, hash, hash_len, NULL)) {
1936 /** Incorrect signature */
1937 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1938 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1939 silc_fsm_next(fsm, silc_ske_st_responder_error);
1940 return SILC_FSM_CONTINUE;
1943 SILC_LOG_DEBUG(("Signature is Ok"));
1945 memset(hash, 'F', hash_len);
1948 /* Create the random number x, 1 < x < q. */
1949 x = silc_calloc(1, sizeof(*x));
1952 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1953 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1955 if (status != SILC_SKE_STATUS_OK) {
1956 /** Error generating random number */
1959 ske->status = status;
1960 silc_fsm_next(fsm, silc_ske_st_responder_error);
1961 return SILC_FSM_CONTINUE;
1964 /* Save the results for later processing */
1965 send_payload = silc_calloc(1, sizeof(*send_payload));
1967 ske->ke2_payload = send_payload;
1969 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1971 /* Do the Diffie Hellman computation, f = g ^ x mod p */
1972 silc_mp_init(&send_payload->x);
1973 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1974 &ske->prop->group->group);
1976 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1978 /* Compute the shared secret key */
1979 KEY = silc_calloc(1, sizeof(*KEY));
1981 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1982 &ske->prop->group->group);
1985 /** Send KE2 payload */
1986 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1987 return SILC_FSM_CONTINUE;
1990 /* Phase-5. Send KE2 payload */
1992 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1994 SilcSKE ske = fsm_context;
1995 SilcSKEStatus status;
1996 SilcBuffer payload_buf;
1997 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1998 SilcUInt32 hash_len, sign_len, pk_len;
2000 SILC_LOG_DEBUG(("Start"));
2002 if (ske->public_key && ske->private_key) {
2003 SILC_LOG_DEBUG(("Getting public key"));
2005 /* Get the public key */
2006 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2008 /** Error encoding public key */
2009 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2010 silc_fsm_next(fsm, silc_ske_st_responder_error);
2011 return SILC_FSM_CONTINUE;
2013 ske->ke2_payload->pk_data = pk;
2014 ske->ke2_payload->pk_len = pk_len;
2016 SILC_LOG_DEBUG(("Computing HASH value"));
2018 /* Compute the hash value */
2019 memset(hash, 0, sizeof(hash));
2020 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2021 if (status != SILC_SKE_STATUS_OK) {
2022 /** Error computing hash */
2023 ske->status = status;
2024 silc_fsm_next(fsm, silc_ske_st_responder_error);
2025 return SILC_FSM_CONTINUE;
2028 ske->hash = silc_memdup(hash, hash_len);
2029 ske->hash_len = hash_len;
2031 SILC_LOG_DEBUG(("Signing HASH value"));
2033 /* Sign the hash value */
2034 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2035 sizeof(sign) - 1, &sign_len, NULL)) {
2036 /** Error computing signature */
2037 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2038 silc_fsm_next(fsm, silc_ske_st_responder_error);
2039 return SILC_FSM_CONTINUE;
2041 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2042 ske->ke2_payload->sign_len = sign_len;
2043 memset(sign, 0, sizeof(sign));
2045 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2047 /* Encode the Key Exchange Payload */
2048 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2050 if (status != SILC_SKE_STATUS_OK) {
2051 /** Error encoding KE payload */
2052 ske->status = status;
2053 silc_fsm_next(fsm, silc_ske_st_responder_error);
2054 return SILC_FSM_CONTINUE;
2057 /* Send the packet. */
2058 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
2059 payload_buf->data, silc_buffer_len(payload_buf))) {
2060 SILC_LOG_DEBUG(("Error sending packet"));
2061 ske->status = SILC_SKE_STATUS_ERROR;
2062 silc_fsm_next(fsm, silc_ske_st_responder_error);
2063 return SILC_FSM_CONTINUE;
2066 silc_buffer_free(payload_buf);
2068 /** Waiting completion */
2069 silc_fsm_next(fsm, silc_ske_st_responder_end);
2070 return SILC_FSM_WAIT;
2073 /* Protocol completed */
2075 SILC_FSM_STATE(silc_ske_st_responder_end)
2077 SilcSKE ske = fsm_context;
2078 unsigned char tmp[4];
2079 SilcUInt32 hash_len, key_len, block_len;
2083 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2084 return SILC_FSM_CONTINUE;
2087 /* Check the result of the protocol */
2088 if (ske->packet->type == SILC_PACKET_FAILURE) {
2089 silc_fsm_next(fsm, silc_ske_st_responder_failure);
2090 return SILC_FSM_CONTINUE;
2092 silc_packet_free(ske->packet);
2094 /* Process key material */
2095 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2096 block_len = silc_cipher_get_key_len(ske->prop->cipher);
2097 hash_len = silc_hash_len(ske->prop->hash);
2098 ske->keymat = silc_ske_process_key_material(ske, block_len,
2101 /** Error processing key material */
2102 ske->status = SILC_SKE_STATUS_ERROR;
2103 silc_fsm_next(fsm, silc_ske_st_responder_error);
2104 return SILC_FSM_CONTINUE;
2107 /* Send SUCCESS packet */
2108 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2109 silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
2111 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2113 /* Call the completion callback */
2114 if (ske->callbacks->completed)
2115 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
2116 ske->rekey, ske->callbacks->context);
2118 return SILC_FSM_FINISH;
2121 /* Aborted by application */
2123 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2125 SilcSKE ske = fsm_context;
2126 unsigned char tmp[4];
2128 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2130 /* Send FAILURE packet */
2131 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2132 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2134 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2136 return SILC_FSM_FINISH;
2139 /* Failure received from remote */
2141 SILC_FSM_STATE(silc_ske_st_responder_failure)
2143 SilcSKE ske = fsm_context;
2144 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2146 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2148 if (silc_buffer_len(&ske->packet->buffer) == 4)
2149 SILC_GET32_MSB(error, ske->packet->buffer.data);
2150 ske->status = error;
2152 /* Call the completion callback */
2153 if (ske->callbacks->completed)
2154 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
2155 ske->callbacks->context);
2157 silc_packet_free(ske->packet);
2158 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2160 return SILC_FSM_FINISH;
2163 /* Error occurred */
2165 SILC_FSM_STATE(silc_ske_st_responder_error)
2167 SilcSKE ske = fsm_context;
2168 unsigned char tmp[4];
2170 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2171 ske->status, silc_ske_map_status(ske->status)));
2173 /* Send FAILURE packet */
2174 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2175 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2176 SILC_PUT32_MSB(ske->status, tmp);
2177 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
2178 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2180 return SILC_FSM_FINISH;
2184 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
2185 void *destructor_context)
2187 SilcSKE ske = fsm_context;
2189 ske->running = FALSE;
2194 /* Starts the protocol as responder. */
2197 silc_ske_responder(SilcSKE ske,
2198 SilcPacketStream stream,
2199 SilcSKEParams params)
2201 SILC_LOG_DEBUG(("Start SKE as responder"));
2203 if (!ske || !stream || !params || !params->version) {
2207 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2210 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2214 ske->responder = TRUE;
2215 ske->flags = params->flags;
2216 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2217 ske->session_port = params->session_port;
2218 ske->version = strdup(params->version);
2221 ske->running = TRUE;
2223 /* Link to packet stream to get key exchange packets */
2224 ske->stream = stream;
2225 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2226 SILC_PACKET_KEY_EXCHANGE,
2227 SILC_PACKET_KEY_EXCHANGE_1,
2228 SILC_PACKET_SUCCESS,
2229 SILC_PACKET_FAILURE, -1);
2231 /* Start SKE as responder */
2232 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2237 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2239 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2241 return SILC_FSM_FINISH;
2244 /* Starts rekey protocol as initiator */
2247 silc_ske_rekey_initiator(SilcSKE ske,
2248 SilcPacketStream stream,
2249 SilcSKERekeyMaterial rekey)
2251 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2253 if (!ske || !stream || !rekey)
2256 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2259 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2264 /* Link to packet stream to get key exchange packets */
2265 ske->stream = stream;
2267 /* Start SKE rekey as initiator */
2268 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2273 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2275 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2277 return SILC_FSM_FINISH;
2280 /* Starts rekey protocol as responder */
2283 silc_ske_rekey_responder(SilcSKE ske,
2284 SilcPacketStream stream,
2285 SilcBuffer ke_payload,
2286 SilcSKERekeyMaterial rekey)
2288 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2290 if (!ske || !stream || !rekey)
2292 if (rekey->pfs && !ke_payload)
2295 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2298 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2301 // ske->packet_buf = ke_payload;
2304 /* Link to packet stream to get key exchange packets */
2305 ske->stream = stream;
2307 /* Start SKE rekey as responder */
2308 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2313 /* Processes the provided key material `data' as the SILC protocol
2314 specification defines. */
2317 silc_ske_process_key_material_data(unsigned char *data,
2318 SilcUInt32 data_len,
2319 SilcUInt32 req_iv_len,
2320 SilcUInt32 req_enc_key_len,
2321 SilcUInt32 req_hmac_key_len,
2325 unsigned char hashd[SILC_HASH_MAXLEN];
2326 SilcUInt32 hash_len = req_hmac_key_len;
2327 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2328 SilcSKEKeyMaterial key;
2330 SILC_LOG_DEBUG(("Start"));
2332 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2335 key = silc_calloc(1, sizeof(*key));
2339 buf = silc_buffer_alloc_size(1 + data_len);
2342 silc_buffer_format(buf,
2343 SILC_STR_UI_CHAR(0),
2344 SILC_STR_UI_XNSTRING(data, data_len),
2348 memset(hashd, 0, sizeof(hashd));
2350 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2351 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2352 memcpy(key->send_iv, hashd, req_iv_len);
2353 memset(hashd, 0, sizeof(hashd));
2355 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2356 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2357 memcpy(key->receive_iv, hashd, req_iv_len);
2358 key->iv_len = req_iv_len;
2360 /* Take the encryption keys. If requested key size is more than
2361 the size of hash length we will distribute more key material
2362 as protocol defines. */
2364 if (enc_key_len > hash_len) {
2366 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2367 k3[SILC_HASH_MAXLEN];
2368 unsigned char *dtmp;
2371 if (enc_key_len > (3 * hash_len))
2374 /* Take first round */
2375 memset(k1, 0, sizeof(k1));
2376 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2378 /* Take second round */
2379 dist = silc_buffer_alloc_size(data_len + hash_len);
2382 silc_buffer_format(dist,
2383 SILC_STR_UI_XNSTRING(data, data_len),
2384 SILC_STR_UI_XNSTRING(k1, hash_len),
2386 memset(k2, 0, sizeof(k2));
2387 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2389 /* Take third round */
2390 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2391 silc_buffer_pull_tail(dist, hash_len);
2392 silc_buffer_pull(dist, data_len + hash_len);
2393 silc_buffer_format(dist,
2394 SILC_STR_UI_XNSTRING(k2, hash_len),
2396 silc_buffer_push(dist, data_len + hash_len);
2397 memset(k3, 0, sizeof(k3));
2398 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2400 /* Then, save the keys */
2401 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2402 memcpy(dtmp, k1, hash_len);
2403 memcpy(dtmp + hash_len, k2, hash_len);
2404 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2406 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2407 memcpy(key->send_enc_key, dtmp, enc_key_len);
2408 key->enc_key_len = req_enc_key_len;
2410 memset(dtmp, 0, (3 * hash_len));
2411 memset(k1, 0, sizeof(k1));
2412 memset(k2, 0, sizeof(k2));
2413 memset(k3, 0, sizeof(k3));
2415 silc_buffer_clear(dist);
2416 silc_buffer_free(dist);
2418 /* Take normal hash as key */
2419 memset(hashd, 0, sizeof(hashd));
2420 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2421 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2422 memcpy(key->send_enc_key, hashd, enc_key_len);
2423 key->enc_key_len = req_enc_key_len;
2427 if (enc_key_len > hash_len) {
2429 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2430 k3[SILC_HASH_MAXLEN];
2431 unsigned char *dtmp;
2434 if (enc_key_len > (3 * hash_len))
2437 /* Take first round */
2438 memset(k1, 0, sizeof(k1));
2439 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2441 /* Take second round */
2442 dist = silc_buffer_alloc_size(data_len + hash_len);
2445 silc_buffer_format(dist,
2446 SILC_STR_UI_XNSTRING(data, data_len),
2447 SILC_STR_UI_XNSTRING(k1, hash_len),
2449 memset(k2, 0, sizeof(k2));
2450 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2452 /* Take third round */
2453 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2454 silc_buffer_pull_tail(dist, hash_len);
2455 silc_buffer_pull(dist, data_len + hash_len);
2456 silc_buffer_format(dist,
2457 SILC_STR_UI_XNSTRING(k2, hash_len),
2459 silc_buffer_push(dist, data_len + hash_len);
2460 memset(k3, 0, sizeof(k3));
2461 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2463 /* Then, save the keys */
2464 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2465 memcpy(dtmp, k1, hash_len);
2466 memcpy(dtmp + hash_len, k2, hash_len);
2467 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2469 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2470 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2471 key->enc_key_len = req_enc_key_len;
2473 memset(dtmp, 0, (3 * hash_len));
2474 memset(k1, 0, sizeof(k1));
2475 memset(k2, 0, sizeof(k2));
2476 memset(k3, 0, sizeof(k3));
2478 silc_buffer_clear(dist);
2479 silc_buffer_free(dist);
2481 /* Take normal hash as key */
2482 memset(hashd, 0, sizeof(hashd));
2483 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2484 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2485 memcpy(key->receive_enc_key, hashd, enc_key_len);
2486 key->enc_key_len = req_enc_key_len;
2489 /* Take HMAC keys */
2490 memset(hashd, 0, sizeof(hashd));
2492 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2493 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2494 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2495 memset(hashd, 0, sizeof(hashd));
2497 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2498 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2499 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2500 key->hmac_key_len = req_hmac_key_len;
2501 memset(hashd, 0, sizeof(hashd));
2503 silc_buffer_clear(buf);
2504 silc_buffer_free(buf);
2509 /* Processes negotiated key material as protocol specifies. This returns
2510 the actual keys to be used in the SILC. */
2513 silc_ske_process_key_material(SilcSKE ske,
2514 SilcUInt32 req_iv_len,
2515 SilcUInt32 req_enc_key_len,
2516 SilcUInt32 req_hmac_key_len)
2519 unsigned char *tmpbuf;
2521 SilcSKEKeyMaterial key;
2523 /* Encode KEY to binary data */
2524 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2526 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2529 silc_buffer_format(buf,
2530 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2531 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2534 /* Process the key material */
2535 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2536 req_iv_len, req_enc_key_len,
2540 memset(tmpbuf, 0, klen);
2542 silc_buffer_clear(buf);
2543 silc_buffer_free(buf);
2548 /* Free key material structure */
2550 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2556 silc_free(key->send_iv);
2557 if (key->receive_iv)
2558 silc_free(key->receive_iv);
2559 if (key->send_enc_key) {
2560 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2561 silc_free(key->send_enc_key);
2563 if (key->receive_enc_key) {
2564 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2565 silc_free(key->receive_enc_key);
2567 if (key->send_hmac_key) {
2568 memset(key->send_hmac_key, 0, key->hmac_key_len);
2569 silc_free(key->send_hmac_key);
2571 if (key->receive_hmac_key) {
2572 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2573 silc_free(key->receive_hmac_key);
2578 /* Set keys into use */
2580 SilcBool silc_ske_set_keys(SilcSKE ske,
2581 SilcSKEKeyMaterial keymat,
2582 SilcSKESecurityProperties prop,
2583 SilcCipher *ret_send_key,
2584 SilcCipher *ret_receive_key,
2585 SilcHmac *ret_hmac_send,
2586 SilcHmac *ret_hmac_receive,
2589 /* Allocate ciphers to be used in the communication */
2591 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2595 if (ret_receive_key) {
2596 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2601 /* Allocate HMACs */
2602 if (ret_hmac_send) {
2603 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2607 if (ret_hmac_receive) {
2608 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2613 /* Set key material */
2614 if (ske->responder) {
2615 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2616 keymat->enc_key_len);
2617 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2618 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2619 keymat->enc_key_len);
2620 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2621 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2622 keymat->hmac_key_len);
2623 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2624 keymat->hmac_key_len);
2626 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2627 keymat->enc_key_len);
2628 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2629 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2630 keymat->enc_key_len);
2631 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2632 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2633 keymat->hmac_key_len);
2634 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2635 keymat->hmac_key_len);
2640 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2647 const char *silc_ske_status_string[] =
2651 "Unkown error occurred",
2652 "Bad payload in packet",
2653 "Unsupported group",
2654 "Unsupported cipher",
2656 "Unsupported hash function",
2658 "Unsupported public key (or certificate)",
2659 "Incorrect signature",
2660 "Bad or unsupported version",
2664 "Remote did not provide public key",
2665 "Bad reserved field in packet",
2666 "Bad payload length in packet",
2667 "Error computing signature",
2668 "System out of memory",
2673 /* Maps status to readable string and returns the string. If string is not
2674 found and empty character string ("") is returned. */
2676 const char *silc_ske_map_status(SilcSKEStatus status)
2680 for (i = 0; silc_ske_status_string[i]; i++)
2682 return silc_ske_status_string[i];
2687 /* Parses remote host's version string. */
2689 SilcBool silc_ske_parse_version(SilcSKE ske,
2690 SilcUInt32 *protocol_version,
2691 char **protocol_version_string,
2692 SilcUInt32 *software_version,
2693 char **software_version_string,
2694 char **vendor_version)
2696 return silc_parse_version_string(ske->remote_version,
2698 protocol_version_string,
2700 software_version_string,
2704 /* Get security properties */
2706 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
2711 /* Get key material */
2713 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)