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;
34 /************************ Static utility functions **************************/
36 SILC_FSM_STATE(silc_ske_st_initiator_start);
37 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
38 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
39 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
40 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
41 SILC_FSM_STATE(silc_ske_st_initiator_end);
42 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
43 SILC_FSM_STATE(silc_ske_st_initiator_error);
44 SILC_FSM_STATE(silc_ske_st_initiator_failure);
45 SILC_FSM_STATE(silc_ske_st_responder_start);
46 SILC_FSM_STATE(silc_ske_st_responder_phase1);
47 SILC_FSM_STATE(silc_ske_st_responder_phase2);
48 SILC_FSM_STATE(silc_ske_st_responder_phase4);
49 SILC_FSM_STATE(silc_ske_st_responder_phase5);
50 SILC_FSM_STATE(silc_ske_st_responder_end);
51 SILC_FSM_STATE(silc_ske_st_responder_aborted);
52 SILC_FSM_STATE(silc_ske_st_responder_failure);
53 SILC_FSM_STATE(silc_ske_st_responder_error);
56 silc_ske_process_key_material(SilcSKE ske,
57 SilcUInt32 req_iv_len,
58 SilcUInt32 req_enc_key_len,
59 SilcUInt32 req_hmac_key_len);
60 static SilcBool silc_ske_packet_send(SilcSKE ske,
62 SilcPacketFlags flags,
63 const unsigned char *data,
68 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
69 SilcPacketStream stream,
71 void *callback_context,
74 SilcSKE ske = callback_context;
76 silc_fsm_continue(&ske->fsm);
80 /* Packet stream callbacks */
81 static SilcPacketCallbacks silc_ske_stream_cbs =
83 silc_ske_packet_receive, NULL, NULL
86 /* Aborts SKE protocol */
88 static void silc_ske_abort(SilcAsyncOperation op, void *context)
90 SilcSKE ske = context;
94 /* Public key verification completion callback */
96 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
97 void *completion_context)
100 SILC_FSM_CALL_CONTINUE(&ske->fsm);
103 /* SKR find callback */
105 static void silc_ske_skr_callback(SilcSKR repository,
107 SilcSKRStatus status,
108 SilcDList keys, void *context)
110 SilcSKE ske = context;
112 silc_skr_find_free(find);
114 if (status != SILC_SKR_OK) {
115 if (ske->callbacks->verify_key) {
116 /* Verify from application */
117 ske->callbacks->verify_key(ske, ske->prop->public_key,
118 ske->callbacks->context,
119 silc_ske_pk_verified, NULL);
125 silc_dlist_uninit(keys);
128 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
129 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
130 SILC_FSM_CALL_CONTINUE(&ske->fsm);
133 /* Checks remote and local versions */
135 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
137 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
138 SilcUInt32 r_software_version = 0;
140 if (!ske->remote_version || !ske->version)
141 return SILC_SKE_STATUS_BAD_VERSION;
143 if (!silc_parse_version_string(ske->remote_version, &r_protocol_version,
144 NULL, &r_software_version, NULL, NULL))
145 return SILC_SKE_STATUS_BAD_VERSION;
147 if (!silc_parse_version_string(ske->version, &l_protocol_version,
148 NULL, NULL, NULL, NULL))
149 return SILC_SKE_STATUS_BAD_VERSION;
151 /* If remote is too new, don't connect */
152 if (l_protocol_version < r_protocol_version)
153 return SILC_SKE_STATUS_BAD_VERSION;
155 /* Backwards compatibility checks */
157 /* Old server versions requires "valid" looking Source ID in the SILC
158 packets during initial key exchange. All version before 1.1.0. */
159 if (r_software_version < 110) {
161 memset(&id, 0, sizeof(id));
163 SILC_LOG_DEBUG(("Remote is old version, add dummy Source ID to packets"));
164 silc_packet_set_ids(ske->stream, SILC_ID_CLIENT, &id, 0, NULL);
167 return SILC_SKE_STATUS_OK;
170 /* Selects the supported security properties from the initiator's Key
171 Exchange Start Payload. A responder function. Saves our reply
172 start payload to ske->start_payload. */
175 silc_ske_select_security_properties(SilcSKE ske,
176 SilcSKEStartPayload remote_payload,
177 SilcSKESecurityProperties *prop)
179 SilcSKEStatus status;
180 SilcSKEStartPayload rp, payload;
184 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
188 /* Check for mandatory fields */
189 if (!rp->ke_grp_len) {
190 SILC_LOG_DEBUG(("KE group not defined in payload"));
191 return SILC_SKE_STATUS_BAD_PAYLOAD;
193 if (!rp->pkcs_alg_len) {
194 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
195 return SILC_SKE_STATUS_BAD_PAYLOAD;
197 if (!rp->enc_alg_len) {
198 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
199 return SILC_SKE_STATUS_BAD_PAYLOAD;
201 if (!rp->hash_alg_len) {
202 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
203 return SILC_SKE_STATUS_BAD_PAYLOAD;
205 if (!rp->hmac_alg_len) {
206 SILC_LOG_DEBUG(("HMAC not defined in payload"));
207 return SILC_SKE_STATUS_BAD_PAYLOAD;
210 /* Allocate security properties */
211 *prop = silc_calloc(1, sizeof(**prop));
213 return SILC_SKE_STATUS_OUT_OF_MEMORY;
215 /* Allocate our reply start payload */
216 payload = silc_calloc(1, sizeof(*payload));
219 return SILC_SKE_STATUS_OUT_OF_MEMORY;
222 /* Check version string */
223 ske->remote_version = silc_memdup(rp->version, rp->version_len);
224 status = silc_ske_check_version(ske);
225 if (status != SILC_SKE_STATUS_OK) {
226 ske->status = status;
230 /* Flags are returned unchanged. */
231 (*prop)->flags = payload->flags = rp->flags;
233 /* Take cookie, we must return it to sender unmodified. */
234 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
235 if (!payload->cookie) {
236 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
239 payload->cookie_len = SILC_SKE_COOKIE_LEN;
240 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
242 /* In case IV included flag and session port is set the first 16-bits of
243 cookie will include our session port. */
244 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
245 /* Take remote port */
246 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
249 SILC_PUT16_MSB(ske->session_port, payload->cookie);
252 /* Put our version to our reply */
253 payload->version = strdup(ske->version);
254 if (!payload->version) {
255 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
258 payload->version_len = strlen(ske->version);
260 /* Get supported Key Exchange groups */
261 cp = rp->ke_grp_list;
262 if (cp && strchr(cp, ',')) {
266 len = strcspn(cp, ",");
267 item = silc_calloc(len + 1, sizeof(char));
269 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
272 memcpy(item, cp, len);
274 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
276 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
277 SILC_LOG_DEBUG(("Found KE group `%s'", item));
279 payload->ke_grp_len = len;
280 payload->ke_grp_list = item;
294 if (!payload->ke_grp_len && !payload->ke_grp_list) {
295 SILC_LOG_DEBUG(("Could not find supported KE group"));
297 return SILC_SKE_STATUS_UNKNOWN_GROUP;
300 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
301 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
303 payload->ke_grp_len = rp->ke_grp_len;
304 payload->ke_grp_list = strdup(rp->ke_grp_list);
307 /* Save group to security properties */
308 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
309 if (status != SILC_SKE_STATUS_OK) {
311 return SILC_SKE_STATUS_UNKNOWN_GROUP;
314 /* Get supported PKCS algorithms */
315 cp = rp->pkcs_alg_list;
316 if (cp && strchr(cp, ',')) {
320 len = strcspn(cp, ",");
321 item = silc_calloc(len + 1, sizeof(char));
323 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
326 memcpy(item, cp, len);
328 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
330 if (silc_pkcs_find_algorithm(item, NULL)) {
331 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
333 payload->pkcs_alg_len = len;
334 payload->pkcs_alg_list = item;
348 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
349 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
350 silc_free(payload->ke_grp_list);
352 return SILC_SKE_STATUS_UNKNOWN_PKCS;
355 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
356 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
358 payload->pkcs_alg_len = rp->pkcs_alg_len;
359 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
362 /* Get supported encryption algorithms */
363 cp = rp->enc_alg_list;
364 if (cp && strchr(cp, ',')) {
368 len = strcspn(cp, ",");
369 item = silc_calloc(len + 1, sizeof(char));
371 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
374 memcpy(item, cp, len);
376 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
378 if (silc_cipher_is_supported(item) == TRUE) {
379 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
381 payload->enc_alg_len = len;
382 payload->enc_alg_list = item;
396 if (!payload->enc_alg_len && !payload->enc_alg_list) {
397 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
398 silc_free(payload->ke_grp_list);
399 silc_free(payload->pkcs_alg_list);
401 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
404 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
407 payload->enc_alg_len = rp->enc_alg_len;
408 payload->enc_alg_list = strdup(rp->enc_alg_list);
411 /* Save selected cipher to security properties */
412 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
413 silc_free(payload->ke_grp_list);
414 silc_free(payload->pkcs_alg_list);
416 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
419 /* Get supported hash algorithms */
420 cp = rp->hash_alg_list;
421 if (cp && strchr(cp, ',')) {
425 len = strcspn(cp, ",");
426 item = silc_calloc(len + 1, sizeof(char));
428 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
431 memcpy(item, cp, len);
433 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
435 if (silc_hash_is_supported(item) == TRUE) {
436 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
438 payload->hash_alg_len = len;
439 payload->hash_alg_list = item;
453 if (!payload->hash_alg_len && !payload->hash_alg_list) {
454 SILC_LOG_DEBUG(("Could not find supported hash alg"));
455 silc_free(payload->ke_grp_list);
456 silc_free(payload->pkcs_alg_list);
457 silc_free(payload->enc_alg_list);
459 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
462 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
465 payload->hash_alg_len = rp->hash_alg_len;
466 payload->hash_alg_list = strdup(rp->hash_alg_list);
469 /* Save selected hash algorithm to security properties */
470 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
471 silc_free(payload->ke_grp_list);
472 silc_free(payload->pkcs_alg_list);
473 silc_free(payload->enc_alg_list);
475 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
478 /* Get supported HMACs */
479 cp = rp->hmac_alg_list;
480 if (cp && strchr(cp, ',')) {
484 len = strcspn(cp, ",");
485 item = silc_calloc(len + 1, sizeof(char));
487 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
490 memcpy(item, cp, len);
492 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
494 if (silc_hmac_is_supported(item) == TRUE) {
495 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
497 payload->hmac_alg_len = len;
498 payload->hmac_alg_list = item;
512 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
513 SILC_LOG_DEBUG(("Could not find supported HMAC"));
514 silc_free(payload->ke_grp_list);
515 silc_free(payload->pkcs_alg_list);
516 silc_free(payload->enc_alg_list);
517 silc_free(payload->hash_alg_list);
519 return SILC_SKE_STATUS_UNKNOWN_HMAC;
522 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
525 payload->hmac_alg_len = rp->hmac_alg_len;
526 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
529 /* Save selected HMACc to security properties */
530 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
531 silc_free(payload->ke_grp_list);
532 silc_free(payload->pkcs_alg_list);
533 silc_free(payload->enc_alg_list);
534 silc_free(payload->hash_alg_list);
536 return SILC_SKE_STATUS_UNKNOWN_HMAC;
539 /* Get supported compression algorithms */
540 cp = rp->comp_alg_list;
541 if (cp && strchr(cp, ',')) {
545 len = strcspn(cp, ",");
546 item = silc_calloc(len + 1, sizeof(char));
548 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
551 memcpy(item, cp, len);
553 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
556 if (!strcmp(item, "none")) {
557 SILC_LOG_DEBUG(("Found Compression `%s'", item));
558 payload->comp_alg_len = len;
559 payload->comp_alg_list = item;
563 if (silc_hmac_is_supported(item) == TRUE) {
564 SILC_LOG_DEBUG(("Found Compression `%s'", item));
565 payload->comp_alg_len = len;
566 payload->comp_alg_list = item;
582 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
583 2 + payload->version_len +
584 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
585 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
586 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
588 /* Save our reply payload */
589 ske->start_payload = payload;
591 return SILC_SKE_STATUS_OK;
594 /* Creates random number such that 1 < rnd < n and at most length
595 of len bits. The rnd sent as argument must be initialized. */
597 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
601 SilcSKEStatus status = SILC_SKE_STATUS_OK;
602 unsigned char *string;
606 return SILC_SKE_STATUS_ERROR;
608 SILC_LOG_DEBUG(("Creating random number"));
612 /* Get the random number as string */
613 string = silc_rng_get_rn_data(ske->rng, l);
615 return SILC_SKE_STATUS_OUT_OF_MEMORY;
617 /* Decode the string into a MP integer */
618 silc_mp_bin2mp(string, l, rnd);
619 silc_mp_mod_2exp(rnd, rnd, len);
622 if (silc_mp_cmp_ui(rnd, 1) < 0)
623 status = SILC_SKE_STATUS_ERROR;
624 if (silc_mp_cmp(rnd, n) >= 0)
625 status = SILC_SKE_STATUS_ERROR;
627 memset(string, 'F', l);
633 /* Creates a hash value HASH as defined in the SKE protocol. If the
634 `initiator' is TRUE then this function is used to create the HASH_i
635 hash value defined in the protocol. If it is FALSE then this is used
636 to create the HASH value defined by the protocol. */
638 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
639 unsigned char *return_hash,
640 SilcUInt32 *return_hash_len,
643 SilcSKEStatus status = SILC_SKE_STATUS_OK;
645 unsigned char *e, *f, *KEY;
646 SilcUInt32 e_len, f_len, KEY_len;
649 SILC_LOG_DEBUG(("Start"));
651 if (initiator == FALSE) {
652 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
653 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
654 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
656 /* Format the buffer used to compute the hash value */
657 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
658 ske->ke2_payload->pk_len +
659 ske->ke1_payload->pk_len +
660 e_len + f_len + KEY_len);
662 return SILC_SKE_STATUS_OUT_OF_MEMORY;
664 /* Initiator is not required to send its public key */
665 if (!ske->ke1_payload->pk_data) {
667 silc_buffer_format(buf,
668 SILC_STR_UI_XNSTRING(
669 ske->start_payload_copy->data,
670 silc_buffer_len(ske->start_payload_copy)),
671 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
672 ske->ke2_payload->pk_len),
673 SILC_STR_UI_XNSTRING(e, e_len),
674 SILC_STR_UI_XNSTRING(f, f_len),
675 SILC_STR_UI_XNSTRING(KEY, KEY_len),
679 silc_buffer_format(buf,
680 SILC_STR_UI_XNSTRING(
681 ske->start_payload_copy->data,
682 silc_buffer_len(ske->start_payload_copy)),
683 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
684 ske->ke2_payload->pk_len),
685 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
686 ske->ke1_payload->pk_len),
687 SILC_STR_UI_XNSTRING(e, e_len),
688 SILC_STR_UI_XNSTRING(f, f_len),
689 SILC_STR_UI_XNSTRING(KEY, KEY_len),
693 silc_buffer_free(buf);
696 memset(KEY, 0, KEY_len);
700 return SILC_SKE_STATUS_ERROR;
705 memset(KEY, 0, KEY_len);
710 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
712 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
713 ske->ke1_payload->pk_len + e_len);
715 return SILC_SKE_STATUS_OUT_OF_MEMORY;
717 /* Format the buffer used to compute the hash value */
719 silc_buffer_format(buf,
720 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
721 silc_buffer_len(ske->start_payload_copy)),
722 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
723 ske->ke1_payload->pk_len),
724 SILC_STR_UI_XNSTRING(e, e_len),
727 silc_buffer_free(buf);
730 return SILC_SKE_STATUS_ERROR;
733 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
740 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
742 *return_hash_len = silc_hash_len(ske->prop->hash);
744 if (initiator == FALSE) {
745 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
747 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
750 silc_buffer_free(buf);
755 /* Assembles security properties */
757 static SilcSKEStartPayload
758 silc_ske_assemble_security_properties(SilcSKE ske,
759 SilcSKESecurityPropertyFlag flags,
762 SilcSKEStartPayload rp;
765 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
767 rp = silc_calloc(1, sizeof(*rp));
770 rp->flags = (unsigned char)flags;
772 /* Set random cookie */
773 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
774 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
775 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
776 rp->cookie_len = SILC_SKE_COOKIE_LEN;
778 /* In case IV included flag and session port is set the first 16-bits of
779 cookie will include our session port. */
780 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
781 SILC_PUT16_MSB(ske->session_port, rp->cookie);
784 rp->version = strdup(version);
785 rp->version_len = strlen(version);
787 /* Get supported Key Exhange groups */
788 rp->ke_grp_list = silc_ske_get_supported_groups();
789 rp->ke_grp_len = strlen(rp->ke_grp_list);
791 /* Get supported PKCS algorithms */
792 rp->pkcs_alg_list = silc_pkcs_get_supported();
793 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
795 /* Get supported encryption algorithms */
796 rp->enc_alg_list = silc_cipher_get_supported();
797 rp->enc_alg_len = strlen(rp->enc_alg_list);
799 /* Get supported hash algorithms */
800 rp->hash_alg_list = silc_hash_get_supported();
801 rp->hash_alg_len = strlen(rp->hash_alg_list);
803 /* Get supported HMACs */
804 rp->hmac_alg_list = silc_hmac_get_supported();
805 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
808 /* Get supported compression algorithms */
809 rp->comp_alg_list = strdup("none");
810 rp->comp_alg_len = strlen("none");
812 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
813 2 + rp->version_len +
814 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
815 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
816 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
821 /* Packet retransmission callback. */
823 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
825 SilcSKE ske = context;
827 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
829 SILC_LOG_DEBUG(("Retry limit reached, packet was lost"));
830 ske->retry_count = 0;
831 ske->retry_timer = SILC_SKE_RETRY_MIN;
832 silc_free(ske->retrans.data);
833 ske->retrans.data = NULL;
834 ske->status = SILC_SKE_STATUS_TIMEOUT;
836 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
838 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
839 silc_fsm_continue_sync(&ske->fsm);
843 SILC_LOG_DEBUG(("Retransmitting packet"));
844 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
845 ske->retrans.data, ske->retrans.data_len);
848 /* Sends SILC packet. Handles retransmissions with UDP streams. */
850 static SilcBool silc_ske_packet_send(SilcSKE ske,
852 SilcPacketFlags flags,
853 const unsigned char *data,
858 /* Send the packet */
859 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
861 if (silc_packet_stream_is_udp(ske->stream) &&
862 type != SILC_PACKET_FAILURE) {
863 silc_free(ske->retrans.data);
864 ske->retrans.type = type;
865 ske->retrans.flags = flags;
866 ske->retrans.data = silc_memdup(data, data_len);
867 ske->retrans.data_len = data_len;
868 if (ske->retrans.data) {
869 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
871 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
872 ske, ske->retry_timer, 0);
874 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
875 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
882 /******************************* Protocol API *******************************/
884 /* Allocates new SKE object. */
886 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
887 SilcSKR repository, SilcPublicKey public_key,
888 SilcPrivateKey private_key, void *context)
892 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
894 if (!rng || !schedule)
898 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
902 ske = silc_calloc(1, sizeof(*ske));
905 ske->status = SILC_SKE_STATUS_OK;
907 ske->repository = repository;
908 ske->user_data = context;
909 ske->schedule = schedule;
910 ske->public_key = public_key;
911 ske->private_key = private_key;
912 ske->retry_timer = SILC_SKE_RETRY_MIN;
917 /* Free's SKE object. */
919 void silc_ske_free(SilcSKE ske)
921 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
931 /* Free start payload */
932 if (ske->start_payload)
933 silc_ske_payload_start_free(ske->start_payload);
935 /* Free KE payload */
936 if (ske->ke1_payload)
937 silc_ske_payload_ke_free(ske->ke1_payload);
938 if (ske->ke2_payload)
939 silc_ske_payload_ke_free(ske->ke2_payload);
940 silc_free(ske->remote_version);
944 if (ske->prop->group)
945 silc_ske_group_free(ske->prop->group);
946 if (ske->prop->cipher)
947 silc_cipher_free(ske->prop->cipher);
949 silc_hash_free(ske->prop->hash);
951 silc_hmac_free(ske->prop->hmac);
952 silc_free(ske->prop);
954 if (ske->start_payload_copy)
955 silc_buffer_free(ske->start_payload_copy);
957 silc_mp_uninit(ske->x);
961 silc_mp_uninit(ske->KEY);
964 silc_free(ske->retrans.data);
965 silc_free(ske->hash);
966 silc_free(ske->callbacks);
968 memset(ske, 'F', sizeof(*ske));
972 /* Return user context */
974 void *silc_ske_get_context(SilcSKE ske)
976 return ske->user_data;
979 /* Sets protocol callbacks */
981 void silc_ske_set_callbacks(SilcSKE ske,
982 SilcSKEVerifyCb verify_key,
983 SilcSKECompletionCb completed,
987 silc_free(ske->callbacks);
988 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
991 ske->callbacks->verify_key = verify_key;
992 ske->callbacks->completed = completed;
993 ske->callbacks->context = context;
997 /******************************** Initiator *********************************/
999 /* Start protocol. Send our proposal */
1001 SILC_FSM_STATE(silc_ske_st_initiator_start)
1003 SilcSKE ske = fsm_context;
1004 SilcBuffer payload_buf;
1007 SILC_LOG_DEBUG(("Start"));
1011 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1012 return SILC_FSM_CONTINUE;
1015 /* Encode the payload */
1016 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1018 if (status != SILC_SKE_STATUS_OK) {
1019 /** Error encoding Start Payload */
1020 ske->status = status;
1021 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1022 return SILC_FSM_CONTINUE;
1025 /* Save the the payload buffer for future use. It is later used to
1026 compute the HASH value. */
1027 ske->start_payload_copy = payload_buf;
1029 /* Send the packet. */
1030 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1031 silc_buffer_data(payload_buf),
1032 silc_buffer_len(payload_buf))) {
1033 /** Error sending packet */
1034 SILC_LOG_DEBUG(("Error sending packet"));
1035 ske->status = SILC_SKE_STATUS_ERROR;
1036 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1037 return SILC_FSM_CONTINUE;
1042 /** Wait for responder proposal */
1043 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
1044 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1045 return SILC_FSM_WAIT;
1048 /* Phase-1. Receives responder's proposal */
1050 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1052 SilcSKE ske = fsm_context;
1053 SilcSKEStatus status;
1054 SilcSKEStartPayload payload;
1055 SilcSKESecurityProperties prop;
1056 SilcSKEDiffieHellmanGroup group = NULL;
1057 SilcBuffer packet_buf = &ske->packet->buffer;
1058 SilcUInt16 remote_port = 0;
1062 SILC_LOG_DEBUG(("Start"));
1064 ske->retry_timer = SILC_SKE_RETRY_MIN;
1065 silc_schedule_task_del_by_context(ske->schedule, ske);
1069 silc_packet_free(ske->packet);
1071 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1072 return SILC_FSM_CONTINUE;
1075 /* See if received failure from remote */
1076 if (ske->packet->type == SILC_PACKET_FAILURE) {
1077 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1078 return SILC_FSM_CONTINUE;
1081 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1082 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1083 silc_packet_free(ske->packet);
1085 return SILC_FSM_WAIT;
1088 /* Decode the payload */
1089 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1090 if (status != SILC_SKE_STATUS_OK) {
1091 /** Error decoding Start Payload */
1092 silc_packet_free(ske->packet);
1094 ske->status = status;
1095 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1096 return SILC_FSM_CONTINUE;
1099 /* Get remote ID and set it to stream */
1100 if (ske->packet->src_id_len) {
1101 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1102 ske->packet->src_id_type,
1103 (ske->packet->src_id_type == SILC_ID_SERVER ?
1104 (void *)&id.u.server_id : (void *)&id.u.client_id),
1105 (ske->packet->src_id_type == SILC_ID_SERVER ?
1106 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1107 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1108 (ske->packet->src_id_type == SILC_ID_SERVER ?
1109 (void *)&id.u.server_id : (void *)&id.u.client_id));
1112 silc_packet_free(ske->packet);
1115 /* Check that the cookie is returned unmodified. In case IV included
1116 flag and session port has been set, the first two bytes of cookie
1117 are the session port and we ignore them in this check. */
1118 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1119 /* Take remote port */
1120 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1123 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1124 SILC_SKE_COOKIE_LEN - coff)) {
1125 /** Invalid cookie */
1126 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1127 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1128 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1129 return SILC_FSM_CONTINUE;
1132 /* Check version string */
1133 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1134 status = silc_ske_check_version(ske);
1135 if (status != SILC_SKE_STATUS_OK) {
1136 /** Version mismatch */
1137 ske->status = status;
1138 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1139 return SILC_FSM_CONTINUE;
1142 /* Free our KE Start Payload context, we don't need it anymore. */
1143 silc_ske_payload_start_free(ske->start_payload);
1144 ske->start_payload = NULL;
1146 /* Take the selected security properties into use while doing
1147 the key exchange. This is used only while doing the key
1149 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1152 prop->flags = payload->flags;
1153 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1154 if (status != SILC_SKE_STATUS_OK)
1157 prop->group = group;
1158 prop->remote_port = remote_port;
1160 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1161 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1164 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1165 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1168 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1169 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1172 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1173 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1177 /* Save remote's KE Start Payload */
1178 ske->start_payload = payload;
1180 /** Send KE Payload */
1181 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1182 return SILC_FSM_CONTINUE;
1186 silc_ske_payload_start_free(payload);
1188 silc_ske_group_free(group);
1190 silc_cipher_free(prop->cipher);
1192 silc_hash_free(prop->hash);
1194 silc_hmac_free(prop->hmac);
1198 if (status == SILC_SKE_STATUS_OK)
1199 status = SILC_SKE_STATUS_ERROR;
1202 ske->status = status;
1203 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1204 return SILC_FSM_CONTINUE;
1207 /* Phase-2. Send KE payload */
1209 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1211 SilcSKE ske = fsm_context;
1212 SilcSKEStatus status;
1213 SilcBuffer payload_buf;
1215 SilcSKEKEPayload payload;
1218 SILC_LOG_DEBUG(("Start"));
1220 /* Create the random number x, 1 < x < q. */
1221 x = silc_calloc(1, sizeof(*x));
1223 /** Out of memory */
1224 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1225 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1226 return SILC_FSM_CONTINUE;
1230 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1231 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1233 if (status != SILC_SKE_STATUS_OK) {
1234 /** Error generating random number */
1237 ske->status = status;
1238 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1239 return SILC_FSM_CONTINUE;
1242 /* Encode the result to Key Exchange Payload. */
1244 payload = silc_calloc(1, sizeof(*payload));
1246 /** Out of memory */
1249 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1250 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1251 return SILC_FSM_CONTINUE;
1253 ske->ke1_payload = payload;
1255 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1257 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1258 silc_mp_init(&payload->x);
1259 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1260 &ske->prop->group->group);
1262 /* Get public key */
1263 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1264 if (!payload->pk_data) {
1265 /** Error encoding public key */
1268 silc_mp_uninit(&payload->x);
1270 ske->ke1_payload = NULL;
1271 ske->status = SILC_SKE_STATUS_ERROR;
1272 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1273 return SILC_FSM_CONTINUE;
1275 payload->pk_len = pk_len;
1276 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1278 /* Compute signature data if we are doing mutual authentication */
1279 if (ske->private_key &&
1280 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1281 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1282 SilcUInt32 hash_len, sign_len;
1284 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1285 SILC_LOG_DEBUG(("Computing HASH_i value"));
1287 /* Compute the hash value */
1288 memset(hash, 0, sizeof(hash));
1289 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1291 SILC_LOG_DEBUG(("Signing HASH_i value"));
1293 /* Sign the hash value */
1294 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1295 sizeof(sign) - 1, &sign_len, NULL)) {
1296 /** Error computing signature */
1299 silc_mp_uninit(&payload->x);
1300 silc_free(payload->pk_data);
1302 ske->ke1_payload = NULL;
1303 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1304 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1305 return SILC_FSM_CONTINUE;
1307 payload->sign_data = silc_memdup(sign, sign_len);
1308 if (payload->sign_data)
1309 payload->sign_len = sign_len;
1310 memset(sign, 0, sizeof(sign));
1313 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1314 if (status != SILC_SKE_STATUS_OK) {
1315 /** Error encoding KE payload */
1318 silc_mp_uninit(&payload->x);
1319 silc_free(payload->pk_data);
1320 silc_free(payload->sign_data);
1322 ske->ke1_payload = NULL;
1323 ske->status = status;
1324 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1325 return SILC_FSM_CONTINUE;
1330 /* Check for backwards compatibility */
1332 /* Send the packet. */
1333 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1334 silc_buffer_data(payload_buf),
1335 silc_buffer_len(payload_buf))) {
1336 /** Error sending packet */
1337 SILC_LOG_DEBUG(("Error sending packet"));
1338 ske->status = SILC_SKE_STATUS_ERROR;
1339 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1340 return SILC_FSM_CONTINUE;
1343 silc_buffer_free(payload_buf);
1345 /** Waiting responder's KE payload */
1346 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1347 return SILC_FSM_WAIT;
1350 /* Phase-3. Process responder's KE payload */
1352 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1354 SilcSKE ske = fsm_context;
1355 SilcSKEStatus status;
1356 SilcSKEKEPayload payload;
1358 SilcBuffer packet_buf = &ske->packet->buffer;
1360 SILC_LOG_DEBUG(("Start"));
1362 ske->retry_timer = SILC_SKE_RETRY_MIN;
1363 silc_schedule_task_del_by_context(ske->schedule, ske);
1367 silc_packet_free(ske->packet);
1369 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1370 return SILC_FSM_CONTINUE;
1373 /* See if received failure from remote */
1374 if (ske->packet->type == SILC_PACKET_FAILURE) {
1375 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1376 return SILC_FSM_CONTINUE;
1379 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1380 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1381 silc_packet_free(ske->packet);
1383 return SILC_FSM_WAIT;
1386 /* Decode the payload */
1387 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1388 if (status != SILC_SKE_STATUS_OK) {
1389 /** Error decoding KE payload */
1390 silc_packet_free(ske->packet);
1392 ske->status = status;
1393 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1394 return SILC_FSM_CONTINUE;
1396 silc_packet_free(ske->packet);
1398 ske->ke2_payload = payload;
1400 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1401 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1402 "even though we require it"));
1403 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1407 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1409 /* Compute the shared secret key */
1410 KEY = silc_calloc(1, sizeof(*KEY));
1412 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1415 /* Decode the remote's public key */
1416 if (payload->pk_data &&
1417 !silc_pkcs_public_key_alloc(payload->pk_type,
1418 payload->pk_data, payload->pk_len,
1419 &ske->prop->public_key)) {
1420 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1421 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1425 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1427 SILC_LOG_DEBUG(("Verifying public key"));
1429 /** Waiting public key verification */
1430 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1432 /* If repository is provided, verify the key from there. */
1433 if (ske->repository) {
1436 find = silc_skr_find_alloc();
1438 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1441 silc_skr_find_set_pkcs_type(find,
1442 silc_pkcs_get_type(ske->prop->public_key));
1443 silc_skr_find_set_public_key(find, ske->prop->public_key);
1444 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1446 /* Find key from repository */
1447 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1448 silc_ske_skr_callback, ske));
1450 /* Verify from application */
1451 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1452 ske->callbacks->context,
1453 silc_ske_pk_verified, NULL));
1458 /** Process key material */
1459 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1460 return SILC_FSM_CONTINUE;
1463 silc_ske_payload_ke_free(payload);
1464 ske->ke2_payload = NULL;
1466 silc_mp_uninit(ske->KEY);
1467 silc_free(ske->KEY);
1470 if (status == SILC_SKE_STATUS_OK)
1471 return SILC_SKE_STATUS_ERROR;
1474 ske->status = status;
1475 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1476 return SILC_FSM_CONTINUE;
1479 /* Process key material */
1481 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1483 SilcSKE ske = fsm_context;
1484 SilcSKEStatus status;
1485 SilcSKEKEPayload payload;
1486 unsigned char hash[SILC_HASH_MAXLEN];
1487 SilcUInt32 hash_len;
1488 int key_len, block_len;
1492 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1493 return SILC_FSM_CONTINUE;
1496 /* Check result of public key verification */
1497 if (ske->status != SILC_SKE_STATUS_OK) {
1498 /** Public key not verified */
1499 SILC_LOG_DEBUG(("Public key verification failed"));
1500 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1501 return SILC_FSM_CONTINUE;
1504 payload = ske->ke2_payload;
1506 if (ske->prop->public_key) {
1507 SILC_LOG_DEBUG(("Public key is authentic"));
1509 /* Compute the hash value */
1510 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1511 if (status != SILC_SKE_STATUS_OK)
1514 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1516 /* Verify signature */
1517 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1518 payload->sign_len, hash, hash_len, NULL)) {
1519 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1520 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1524 SILC_LOG_DEBUG(("Signature is Ok"));
1526 ske->hash = silc_memdup(hash, hash_len);
1527 ske->hash_len = hash_len;
1528 memset(hash, 'F', hash_len);
1531 ske->status = SILC_SKE_STATUS_OK;
1533 /* Process key material */
1534 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1535 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1536 hash_len = silc_hash_len(ske->prop->hash);
1537 ske->keymat = silc_ske_process_key_material(ske, block_len,
1540 SILC_LOG_ERROR(("Error processing key material"));
1541 status = SILC_SKE_STATUS_ERROR;
1545 /* Send SUCCESS packet */
1546 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1547 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1548 /** Error sending packet */
1549 SILC_LOG_DEBUG(("Error sending packet"));
1550 ske->status = SILC_SKE_STATUS_ERROR;
1551 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1552 return SILC_FSM_CONTINUE;
1555 /** Waiting completion */
1556 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1557 return SILC_FSM_WAIT;
1560 memset(hash, 'F', sizeof(hash));
1561 silc_ske_payload_ke_free(payload);
1562 ske->ke2_payload = NULL;
1564 silc_mp_uninit(ske->KEY);
1565 silc_free(ske->KEY);
1569 memset(ske->hash, 'F', hash_len);
1570 silc_free(ske->hash);
1574 if (status == SILC_SKE_STATUS_OK)
1575 status = SILC_SKE_STATUS_ERROR;
1578 ske->status = status;
1579 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1580 return SILC_FSM_CONTINUE;
1583 /* Protocol completed */
1585 SILC_FSM_STATE(silc_ske_st_initiator_end)
1587 SilcSKE ske = fsm_context;
1589 SILC_LOG_DEBUG(("Start"));
1591 ske->retry_timer = SILC_SKE_RETRY_MIN;
1592 silc_schedule_task_del_by_context(ske->schedule, ske);
1596 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1597 return SILC_FSM_CONTINUE;
1600 /* See if received failure from remote */
1601 if (ske->packet->type == SILC_PACKET_FAILURE) {
1602 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1603 return SILC_FSM_CONTINUE;
1606 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1607 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1608 silc_packet_free(ske->packet);
1610 return SILC_FSM_WAIT;
1613 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1615 /* Call the completion callback */
1616 if (ske->callbacks->completed)
1617 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1618 ske->rekey, ske->callbacks->context);
1620 silc_packet_free(ske->packet);
1622 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1623 silc_schedule_task_del_by_context(ske->schedule, ske);
1625 return SILC_FSM_FINISH;
1628 /* Aborted by application */
1630 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1632 SilcSKE ske = fsm_context;
1633 unsigned char data[4];
1635 SILC_LOG_DEBUG(("Aborted by caller"));
1637 /* Send FAILURE packet */
1638 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1639 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1640 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1641 silc_schedule_task_del_by_context(ske->schedule, ske);
1643 return SILC_FSM_FINISH;
1646 /* Error occurred. Send error to remote host */
1648 SILC_FSM_STATE(silc_ske_st_initiator_error)
1650 SilcSKE ske = fsm_context;
1651 SilcSKEStatus status;
1652 unsigned char data[4];
1654 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1655 silc_ske_map_status(ske->status), ske->status));
1657 status = ske->status;
1658 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1659 status = SILC_SKE_STATUS_ERROR;
1661 /* Send FAILURE packet */
1662 SILC_PUT32_MSB((SilcUInt32)status, data);
1663 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1665 /* Call the completion callback */
1666 if (!ske->aborted && ske->callbacks->completed)
1667 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1668 ske->callbacks->context);
1670 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1671 silc_schedule_task_del_by_context(ske->schedule, ske);
1673 return SILC_FSM_FINISH;
1676 /* Failure received from remote */
1678 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1680 SilcSKE ske = fsm_context;
1681 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1683 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1684 silc_ske_map_status(ske->status), ske->status));
1686 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1687 SILC_GET32_MSB(error, ske->packet->buffer.data);
1688 ske->status = error;
1689 silc_packet_free(ske->packet);
1693 /* Call the completion callback */
1694 if (!ske->aborted && ske->callbacks->completed)
1695 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1696 ske->callbacks->context);
1698 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1699 silc_schedule_task_del_by_context(ske->schedule, ske);
1701 return SILC_FSM_FINISH;
1704 /* FSM destructor */
1706 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1707 void *destructor_context)
1709 SilcSKE ske = fsm_context;
1711 ske->running = FALSE;
1716 /* Starts the protocol as initiator */
1719 silc_ske_initiator(SilcSKE ske,
1720 SilcPacketStream stream,
1721 SilcSKEParams params,
1722 SilcSKEStartPayload start_payload)
1724 SILC_LOG_DEBUG(("Start SKE as initiator"));
1726 if (!ske || !stream || !params || !params->version)
1729 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1732 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1736 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1737 ske->session_port = params->session_port;
1739 /* Generate security properties if not provided */
1740 if (!start_payload) {
1741 start_payload = silc_ske_assemble_security_properties(ske,
1748 ske->start_payload = start_payload;
1749 ske->version = params->version;
1750 ske->running = TRUE;
1752 /* Link to packet stream to get key exchange packets */
1753 ske->stream = stream;
1754 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1755 SILC_PACKET_KEY_EXCHANGE,
1756 SILC_PACKET_KEY_EXCHANGE_2,
1757 SILC_PACKET_SUCCESS,
1758 SILC_PACKET_FAILURE, -1);
1760 /* Start SKE as initiator */
1761 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1766 /******************************** Responder *********************************/
1768 /* Start protocol as responder. Wait initiator's start payload */
1770 SILC_FSM_STATE(silc_ske_st_responder_start)
1772 SilcSKE ske = fsm_context;
1774 SILC_LOG_DEBUG(("Start"));
1778 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1779 return SILC_FSM_CONTINUE;
1785 /** Wait for initiator */
1786 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1787 return SILC_FSM_WAIT;
1790 /* Decode initiator's start payload. Select the security properties from
1791 the initiator's start payload and send our reply start payload back. */
1793 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1795 SilcSKE ske = fsm_context;
1796 SilcSKEStatus status;
1797 SilcSKEStartPayload remote_payload = NULL;
1798 SilcBuffer packet_buf = &ske->packet->buffer;
1800 SILC_LOG_DEBUG(("Start"));
1804 silc_packet_free(ske->packet);
1806 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1807 return SILC_FSM_CONTINUE;
1810 /* See if received failure from remote */
1811 if (ske->packet->type == SILC_PACKET_FAILURE) {
1812 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1813 return SILC_FSM_CONTINUE;
1816 /* Decode the payload */
1817 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1818 if (status != SILC_SKE_STATUS_OK) {
1819 /** Error decoding Start Payload */
1820 silc_packet_free(ske->packet);
1822 ske->status = status;
1823 silc_fsm_next(fsm, silc_ske_st_responder_error);
1824 return SILC_FSM_CONTINUE;
1827 /* Take a copy of the payload buffer for future use. It is used to
1828 compute the HASH value. */
1829 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1831 silc_packet_free(ske->packet);
1834 /* Force the mutual authentication flag if we want to do it. */
1835 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1836 SILC_LOG_DEBUG(("Force mutual authentication"));
1837 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1840 /* Force PFS flag if we require it */
1841 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1842 SILC_LOG_DEBUG(("Force PFS"));
1843 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1846 /* Disable IV Included flag if requested */
1847 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1848 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1849 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1850 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1853 /* Check and select security properties */
1854 status = silc_ske_select_security_properties(ske, remote_payload,
1856 if (status != SILC_SKE_STATUS_OK) {
1857 /** Error selecting proposal */
1858 silc_ske_payload_start_free(remote_payload);
1859 ske->status = status;
1860 silc_fsm_next(fsm, silc_ske_st_responder_error);
1861 return SILC_FSM_CONTINUE;
1864 silc_ske_payload_start_free(remote_payload);
1866 /* Encode our reply payload to send the selected security properties */
1867 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1869 if (status != SILC_SKE_STATUS_OK)
1872 /* Send the packet. */
1873 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1874 silc_buffer_data(packet_buf),
1875 silc_buffer_len(packet_buf)))
1878 silc_buffer_free(packet_buf);
1880 /** Waiting initiator's KE payload */
1881 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1882 return SILC_FSM_WAIT;
1885 if (ske->prop->group)
1886 silc_ske_group_free(ske->prop->group);
1887 if (ske->prop->cipher)
1888 silc_cipher_free(ske->prop->cipher);
1889 if (ske->prop->hash)
1890 silc_hash_free(ske->prop->hash);
1891 if (ske->prop->hmac)
1892 silc_hmac_free(ske->prop->hmac);
1893 silc_free(ske->prop);
1896 if (status == SILC_SKE_STATUS_OK)
1897 status = SILC_SKE_STATUS_ERROR;
1900 ske->status = status;
1901 silc_fsm_next(fsm, silc_ske_st_responder_error);
1902 return SILC_FSM_CONTINUE;
1905 /* Phase-2. Decode initiator's KE payload */
1907 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1909 SilcSKE ske = fsm_context;
1910 SilcSKEStatus status;
1911 SilcSKEKEPayload recv_payload;
1912 SilcBuffer packet_buf = &ske->packet->buffer;
1914 SILC_LOG_DEBUG(("Start"));
1916 ske->retry_timer = SILC_SKE_RETRY_MIN;
1917 silc_schedule_task_del_by_context(ske->schedule, ske);
1921 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1922 return SILC_FSM_CONTINUE;
1925 /* See if received failure from remote */
1926 if (ske->packet->type == SILC_PACKET_FAILURE) {
1927 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1928 return SILC_FSM_CONTINUE;
1931 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1932 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1933 silc_packet_free(ske->packet);
1935 return SILC_FSM_WAIT;
1938 /* Decode Key Exchange Payload */
1939 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1940 if (status != SILC_SKE_STATUS_OK) {
1941 /** Error decoding KE payload */
1942 silc_packet_free(ske->packet);
1944 ske->status = status;
1945 silc_fsm_next(fsm, silc_ske_st_responder_error);
1946 return SILC_FSM_CONTINUE;
1949 ske->ke1_payload = recv_payload;
1951 silc_packet_free(ske->packet);
1954 /* Verify the received public key and verify the signature if we are
1955 doing mutual authentication. */
1956 if (ske->start_payload &&
1957 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1959 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1961 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1963 /** Public key not provided */
1964 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1965 "certificate), even though we require it"));
1966 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1967 silc_fsm_next(fsm, silc_ske_st_responder_error);
1968 return SILC_FSM_CONTINUE;
1971 /* Decode the remote's public key */
1972 if (recv_payload->pk_data &&
1973 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1974 recv_payload->pk_data,
1975 recv_payload->pk_len,
1976 &ske->prop->public_key)) {
1977 /** Error decoding public key */
1978 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1979 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1980 silc_fsm_next(fsm, silc_ske_st_responder_error);
1981 return SILC_FSM_CONTINUE;
1984 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1986 SILC_LOG_DEBUG(("Verifying public key"));
1988 /** Waiting public key verification */
1989 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1991 /* If repository is provided, verify the key from there. */
1992 if (ske->repository) {
1995 find = silc_skr_find_alloc();
1997 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1998 silc_fsm_next(fsm, silc_ske_st_responder_error);
1999 return SILC_FSM_CONTINUE;
2001 silc_skr_find_set_pkcs_type(find,
2002 silc_pkcs_get_type(ske->prop->public_key));
2003 silc_skr_find_set_public_key(find, ske->prop->public_key);
2004 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2006 /* Find key from repository */
2007 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2008 silc_ske_skr_callback, ske));
2010 /* Verify from application */
2011 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2012 ske->callbacks->context,
2013 silc_ske_pk_verified, NULL));
2019 /** Generate KE2 payload */
2020 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2021 return SILC_FSM_CONTINUE;
2024 /* Phase-4. Generate KE2 payload */
2026 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2028 SilcSKE ske = fsm_context;
2029 SilcSKEStatus status;
2030 SilcSKEKEPayload recv_payload, send_payload;
2035 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2036 return SILC_FSM_CONTINUE;
2039 /* Check result of public key verification */
2040 if (ske->status != SILC_SKE_STATUS_OK) {
2041 /** Public key not verified */
2042 SILC_LOG_DEBUG(("Public key verification failed"));
2043 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2044 return SILC_FSM_CONTINUE;
2047 recv_payload = ske->ke1_payload;
2049 /* The public key verification was performed only if the Mutual
2050 Authentication flag is set. */
2051 if (ske->start_payload &&
2052 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2053 unsigned char hash[SILC_HASH_MAXLEN];
2054 SilcUInt32 hash_len;
2056 SILC_LOG_DEBUG(("Public key is authentic"));
2058 /* Compute the hash value */
2059 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2060 if (status != SILC_SKE_STATUS_OK) {
2061 /** Error computing hash */
2062 ske->status = status;
2063 silc_fsm_next(fsm, silc_ske_st_responder_error);
2064 return SILC_FSM_CONTINUE;
2067 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2069 /* Verify signature */
2070 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2071 recv_payload->sign_len, hash, hash_len, NULL)) {
2072 /** Incorrect signature */
2073 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2074 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2075 silc_fsm_next(fsm, silc_ske_st_responder_error);
2076 return SILC_FSM_CONTINUE;
2079 SILC_LOG_DEBUG(("Signature is Ok"));
2081 memset(hash, 'F', hash_len);
2084 /* Create the random number x, 1 < x < q. */
2085 x = silc_calloc(1, sizeof(*x));
2088 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2089 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2091 if (status != SILC_SKE_STATUS_OK) {
2092 /** Error generating random number */
2095 ske->status = status;
2096 silc_fsm_next(fsm, silc_ske_st_responder_error);
2097 return SILC_FSM_CONTINUE;
2100 /* Save the results for later processing */
2101 send_payload = silc_calloc(1, sizeof(*send_payload));
2103 ske->ke2_payload = send_payload;
2105 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2107 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2108 silc_mp_init(&send_payload->x);
2109 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2110 &ske->prop->group->group);
2112 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2114 /* Compute the shared secret key */
2115 KEY = silc_calloc(1, sizeof(*KEY));
2117 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2118 &ske->prop->group->group);
2121 /** Send KE2 payload */
2122 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2123 return SILC_FSM_CONTINUE;
2126 /* Phase-5. Send KE2 payload */
2128 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2130 SilcSKE ske = fsm_context;
2131 SilcSKEStatus status;
2132 SilcBuffer payload_buf;
2133 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2134 SilcUInt32 hash_len, sign_len, pk_len;
2136 SILC_LOG_DEBUG(("Start"));
2138 if (ske->public_key && ske->private_key) {
2139 SILC_LOG_DEBUG(("Getting public key"));
2141 /* Get the public key */
2142 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2144 /** Error encoding public key */
2145 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2146 silc_fsm_next(fsm, silc_ske_st_responder_error);
2147 return SILC_FSM_CONTINUE;
2149 ske->ke2_payload->pk_data = pk;
2150 ske->ke2_payload->pk_len = pk_len;
2152 SILC_LOG_DEBUG(("Computing HASH value"));
2154 /* Compute the hash value */
2155 memset(hash, 0, sizeof(hash));
2156 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2157 if (status != SILC_SKE_STATUS_OK) {
2158 /** Error computing hash */
2159 ske->status = status;
2160 silc_fsm_next(fsm, silc_ske_st_responder_error);
2161 return SILC_FSM_CONTINUE;
2164 ske->hash = silc_memdup(hash, hash_len);
2165 ske->hash_len = hash_len;
2167 SILC_LOG_DEBUG(("Signing HASH value"));
2169 /* Sign the hash value */
2170 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2171 sizeof(sign) - 1, &sign_len, NULL)) {
2172 /** Error computing signature */
2173 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2174 silc_fsm_next(fsm, silc_ske_st_responder_error);
2175 return SILC_FSM_CONTINUE;
2177 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2178 ske->ke2_payload->sign_len = sign_len;
2179 memset(sign, 0, sizeof(sign));
2181 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2183 /* Encode the Key Exchange Payload */
2184 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2186 if (status != SILC_SKE_STATUS_OK) {
2187 /** Error encoding KE payload */
2188 ske->status = status;
2189 silc_fsm_next(fsm, silc_ske_st_responder_error);
2190 return SILC_FSM_CONTINUE;
2193 /* Send the packet. */
2194 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2195 payload_buf->data, silc_buffer_len(payload_buf))) {
2196 SILC_LOG_DEBUG(("Error sending packet"));
2197 ske->status = SILC_SKE_STATUS_ERROR;
2198 silc_fsm_next(fsm, silc_ske_st_responder_error);
2199 return SILC_FSM_CONTINUE;
2202 silc_buffer_free(payload_buf);
2204 /** Waiting completion */
2205 silc_fsm_next(fsm, silc_ske_st_responder_end);
2206 return SILC_FSM_WAIT;
2209 /* Protocol completed */
2211 SILC_FSM_STATE(silc_ske_st_responder_end)
2213 SilcSKE ske = fsm_context;
2214 unsigned char tmp[4];
2215 SilcUInt32 hash_len, key_len, block_len;
2217 ske->retry_timer = SILC_SKE_RETRY_MIN;
2218 silc_schedule_task_del_by_context(ske->schedule, ske);
2222 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2223 return SILC_FSM_CONTINUE;
2226 /* Check the result of the protocol */
2227 if (ske->packet->type == SILC_PACKET_FAILURE) {
2228 silc_fsm_next(fsm, silc_ske_st_responder_failure);
2229 return SILC_FSM_CONTINUE;
2232 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2233 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2234 silc_packet_free(ske->packet);
2236 return SILC_FSM_WAIT;
2238 silc_packet_free(ske->packet);
2241 /* Process key material */
2242 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2243 block_len = silc_cipher_get_key_len(ske->prop->cipher);
2244 hash_len = silc_hash_len(ske->prop->hash);
2245 ske->keymat = silc_ske_process_key_material(ske, block_len,
2248 /** Error processing key material */
2249 ske->status = SILC_SKE_STATUS_ERROR;
2250 silc_fsm_next(fsm, silc_ske_st_responder_error);
2251 return SILC_FSM_CONTINUE;
2254 /* Send SUCCESS packet */
2255 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2256 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2258 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2259 silc_schedule_task_del_by_context(ske->schedule, ske);
2261 /* Call the completion callback */
2262 if (ske->callbacks->completed)
2263 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
2264 ske->rekey, ske->callbacks->context);
2266 return SILC_FSM_FINISH;
2269 /* Aborted by application */
2271 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2273 SilcSKE ske = fsm_context;
2274 unsigned char tmp[4];
2276 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2278 /* Send FAILURE packet */
2279 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2280 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2282 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2283 silc_schedule_task_del_by_context(ske->schedule, ske);
2285 return SILC_FSM_FINISH;
2288 /* Failure received from remote */
2290 SILC_FSM_STATE(silc_ske_st_responder_failure)
2292 SilcSKE ske = fsm_context;
2293 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2295 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2297 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2298 SILC_GET32_MSB(error, ske->packet->buffer.data);
2299 ske->status = error;
2300 silc_packet_free(ske->packet);
2304 /* Call the completion callback */
2305 if (!ske->aborted && ske->callbacks->completed)
2306 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
2307 ske->callbacks->context);
2309 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2310 silc_schedule_task_del_by_context(ske->schedule, ske);
2312 return SILC_FSM_FINISH;
2315 /* Error occurred */
2317 SILC_FSM_STATE(silc_ske_st_responder_error)
2319 SilcSKE ske = fsm_context;
2320 unsigned char tmp[4];
2322 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2323 ske->status, silc_ske_map_status(ske->status)));
2325 /* Send FAILURE packet */
2326 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2327 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2328 SILC_PUT32_MSB(ske->status, tmp);
2329 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2330 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2331 silc_schedule_task_del_by_context(ske->schedule, ske);
2333 return SILC_FSM_FINISH;
2337 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
2338 void *destructor_context)
2340 SilcSKE ske = fsm_context;
2342 ske->running = FALSE;
2347 /* Starts the protocol as responder. */
2350 silc_ske_responder(SilcSKE ske,
2351 SilcPacketStream stream,
2352 SilcSKEParams params)
2354 SILC_LOG_DEBUG(("Start SKE as responder"));
2356 if (!ske || !stream || !params || !params->version) {
2360 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2363 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2367 ske->responder = TRUE;
2368 ske->flags = params->flags;
2369 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2370 ske->session_port = params->session_port;
2371 ske->version = strdup(params->version);
2374 ske->running = TRUE;
2376 /* Link to packet stream to get key exchange packets */
2377 ske->stream = stream;
2378 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2379 SILC_PACKET_KEY_EXCHANGE,
2380 SILC_PACKET_KEY_EXCHANGE_1,
2381 SILC_PACKET_SUCCESS,
2382 SILC_PACKET_FAILURE, -1);
2384 /* Start SKE as responder */
2385 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2390 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2392 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2394 return SILC_FSM_FINISH;
2397 /* Starts rekey protocol as initiator */
2400 silc_ske_rekey_initiator(SilcSKE ske,
2401 SilcPacketStream stream,
2402 SilcSKERekeyMaterial rekey)
2404 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2406 if (!ske || !stream || !rekey)
2409 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2412 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2417 /* Link to packet stream to get key exchange packets */
2418 ske->stream = stream;
2420 /* Start SKE rekey as initiator */
2421 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2426 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2428 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2430 return SILC_FSM_FINISH;
2433 /* Starts rekey protocol as responder */
2436 silc_ske_rekey_responder(SilcSKE ske,
2437 SilcPacketStream stream,
2438 SilcBuffer ke_payload,
2439 SilcSKERekeyMaterial rekey)
2441 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2443 if (!ske || !stream || !rekey)
2445 if (rekey->pfs && !ke_payload)
2448 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2451 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2454 // ske->packet_buf = ke_payload;
2457 /* Link to packet stream to get key exchange packets */
2458 ske->stream = stream;
2460 /* Start SKE rekey as responder */
2461 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2466 /* Processes the provided key material `data' as the SILC protocol
2467 specification defines. */
2470 silc_ske_process_key_material_data(unsigned char *data,
2471 SilcUInt32 data_len,
2472 SilcUInt32 req_iv_len,
2473 SilcUInt32 req_enc_key_len,
2474 SilcUInt32 req_hmac_key_len,
2478 unsigned char hashd[SILC_HASH_MAXLEN];
2479 SilcUInt32 hash_len = req_hmac_key_len;
2480 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2481 SilcSKEKeyMaterial key;
2483 SILC_LOG_DEBUG(("Start"));
2485 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2488 key = silc_calloc(1, sizeof(*key));
2492 buf = silc_buffer_alloc_size(1 + data_len);
2495 silc_buffer_format(buf,
2496 SILC_STR_UI_CHAR(0),
2497 SILC_STR_UI_XNSTRING(data, data_len),
2501 memset(hashd, 0, sizeof(hashd));
2503 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2504 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2505 memcpy(key->send_iv, hashd, req_iv_len);
2506 memset(hashd, 0, sizeof(hashd));
2508 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2509 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2510 memcpy(key->receive_iv, hashd, req_iv_len);
2511 key->iv_len = req_iv_len;
2513 /* Take the encryption keys. If requested key size is more than
2514 the size of hash length we will distribute more key material
2515 as protocol defines. */
2517 if (enc_key_len > hash_len) {
2519 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2520 k3[SILC_HASH_MAXLEN];
2521 unsigned char *dtmp;
2524 if (enc_key_len > (3 * hash_len))
2527 /* Take first round */
2528 memset(k1, 0, sizeof(k1));
2529 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2531 /* Take second round */
2532 dist = silc_buffer_alloc_size(data_len + hash_len);
2535 silc_buffer_format(dist,
2536 SILC_STR_UI_XNSTRING(data, data_len),
2537 SILC_STR_UI_XNSTRING(k1, hash_len),
2539 memset(k2, 0, sizeof(k2));
2540 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2542 /* Take third round */
2543 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2544 silc_buffer_pull_tail(dist, hash_len);
2545 silc_buffer_pull(dist, data_len + hash_len);
2546 silc_buffer_format(dist,
2547 SILC_STR_UI_XNSTRING(k2, hash_len),
2549 silc_buffer_push(dist, data_len + hash_len);
2550 memset(k3, 0, sizeof(k3));
2551 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2553 /* Then, save the keys */
2554 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2555 memcpy(dtmp, k1, hash_len);
2556 memcpy(dtmp + hash_len, k2, hash_len);
2557 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2559 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2560 memcpy(key->send_enc_key, dtmp, enc_key_len);
2561 key->enc_key_len = req_enc_key_len;
2563 memset(dtmp, 0, (3 * hash_len));
2564 memset(k1, 0, sizeof(k1));
2565 memset(k2, 0, sizeof(k2));
2566 memset(k3, 0, sizeof(k3));
2568 silc_buffer_clear(dist);
2569 silc_buffer_free(dist);
2571 /* Take normal hash as key */
2572 memset(hashd, 0, sizeof(hashd));
2573 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2574 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2575 memcpy(key->send_enc_key, hashd, enc_key_len);
2576 key->enc_key_len = req_enc_key_len;
2580 if (enc_key_len > hash_len) {
2582 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2583 k3[SILC_HASH_MAXLEN];
2584 unsigned char *dtmp;
2587 if (enc_key_len > (3 * hash_len))
2590 /* Take first round */
2591 memset(k1, 0, sizeof(k1));
2592 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2594 /* Take second round */
2595 dist = silc_buffer_alloc_size(data_len + hash_len);
2598 silc_buffer_format(dist,
2599 SILC_STR_UI_XNSTRING(data, data_len),
2600 SILC_STR_UI_XNSTRING(k1, hash_len),
2602 memset(k2, 0, sizeof(k2));
2603 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2605 /* Take third round */
2606 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2607 silc_buffer_pull_tail(dist, hash_len);
2608 silc_buffer_pull(dist, data_len + hash_len);
2609 silc_buffer_format(dist,
2610 SILC_STR_UI_XNSTRING(k2, hash_len),
2612 silc_buffer_push(dist, data_len + hash_len);
2613 memset(k3, 0, sizeof(k3));
2614 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2616 /* Then, save the keys */
2617 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2618 memcpy(dtmp, k1, hash_len);
2619 memcpy(dtmp + hash_len, k2, hash_len);
2620 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2622 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2623 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2624 key->enc_key_len = req_enc_key_len;
2626 memset(dtmp, 0, (3 * hash_len));
2627 memset(k1, 0, sizeof(k1));
2628 memset(k2, 0, sizeof(k2));
2629 memset(k3, 0, sizeof(k3));
2631 silc_buffer_clear(dist);
2632 silc_buffer_free(dist);
2634 /* Take normal hash as key */
2635 memset(hashd, 0, sizeof(hashd));
2636 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2637 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2638 memcpy(key->receive_enc_key, hashd, enc_key_len);
2639 key->enc_key_len = req_enc_key_len;
2642 /* Take HMAC keys */
2643 memset(hashd, 0, sizeof(hashd));
2645 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2646 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2647 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2648 memset(hashd, 0, sizeof(hashd));
2650 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2651 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2652 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2653 key->hmac_key_len = req_hmac_key_len;
2654 memset(hashd, 0, sizeof(hashd));
2656 silc_buffer_clear(buf);
2657 silc_buffer_free(buf);
2662 /* Processes negotiated key material as protocol specifies. This returns
2663 the actual keys to be used in the SILC. */
2666 silc_ske_process_key_material(SilcSKE ske,
2667 SilcUInt32 req_iv_len,
2668 SilcUInt32 req_enc_key_len,
2669 SilcUInt32 req_hmac_key_len)
2672 unsigned char *tmpbuf;
2674 SilcSKEKeyMaterial key;
2676 /* Encode KEY to binary data */
2677 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2679 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2682 silc_buffer_format(buf,
2683 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2684 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2687 /* Process the key material */
2688 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2689 req_iv_len, req_enc_key_len,
2693 memset(tmpbuf, 0, klen);
2695 silc_buffer_clear(buf);
2696 silc_buffer_free(buf);
2701 /* Free key material structure */
2703 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2709 silc_free(key->send_iv);
2710 if (key->receive_iv)
2711 silc_free(key->receive_iv);
2712 if (key->send_enc_key) {
2713 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2714 silc_free(key->send_enc_key);
2716 if (key->receive_enc_key) {
2717 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2718 silc_free(key->receive_enc_key);
2720 if (key->send_hmac_key) {
2721 memset(key->send_hmac_key, 0, key->hmac_key_len);
2722 silc_free(key->send_hmac_key);
2724 if (key->receive_hmac_key) {
2725 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2726 silc_free(key->receive_hmac_key);
2731 /* Set keys into use */
2733 SilcBool silc_ske_set_keys(SilcSKE ske,
2734 SilcSKEKeyMaterial keymat,
2735 SilcSKESecurityProperties prop,
2736 SilcCipher *ret_send_key,
2737 SilcCipher *ret_receive_key,
2738 SilcHmac *ret_hmac_send,
2739 SilcHmac *ret_hmac_receive,
2742 /* Allocate ciphers to be used in the communication */
2744 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2748 if (ret_receive_key) {
2749 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2754 /* Allocate HMACs */
2755 if (ret_hmac_send) {
2756 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2760 if (ret_hmac_receive) {
2761 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2766 /* Set key material */
2767 if (ske->responder) {
2768 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2769 keymat->enc_key_len);
2770 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2771 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2772 keymat->enc_key_len);
2773 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2774 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2775 keymat->hmac_key_len);
2776 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2777 keymat->hmac_key_len);
2779 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2780 keymat->enc_key_len);
2781 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2782 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2783 keymat->enc_key_len);
2784 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2785 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2786 keymat->hmac_key_len);
2787 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2788 keymat->hmac_key_len);
2793 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2800 const char *silc_ske_status_string[] =
2804 "Unkown error occurred",
2805 "Bad payload in packet",
2806 "Unsupported group",
2807 "Unsupported cipher",
2809 "Unsupported hash function",
2811 "Unsupported public key (or certificate)",
2812 "Incorrect signature",
2813 "Bad or unsupported version",
2817 "Remote did not provide public key",
2818 "Bad reserved field in packet",
2819 "Bad payload length in packet",
2820 "Error computing signature",
2821 "System out of memory",
2826 /* Maps status to readable string and returns the string. If string is not
2827 found and empty character string ("") is returned. */
2829 const char *silc_ske_map_status(SilcSKEStatus status)
2833 for (i = 0; silc_ske_status_string[i]; i++)
2835 return silc_ske_status_string[i];
2840 /* Parses remote host's version string. */
2842 SilcBool silc_ske_parse_version(SilcSKE ske,
2843 SilcUInt32 *protocol_version,
2844 char **protocol_version_string,
2845 SilcUInt32 *software_version,
2846 char **software_version_string,
2847 char **vendor_version)
2849 return silc_parse_version_string(ske->remote_version,
2851 protocol_version_string,
2853 software_version_string,
2857 /* Get security properties */
2859 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
2864 /* Get key material */
2866 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)