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) {
828 SILC_LOG_DEBUG(("Retry limit reached, packet was lost"));
829 ske->retry_count = 0;
830 ske->retry_timer = SILC_SKE_RETRY_MIN;
831 silc_free(ske->retrans.data);
832 ske->retrans.data = NULL;
833 ske->status = SILC_SKE_STATUS_TIMEOUT;
835 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
837 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
838 silc_fsm_continue_sync(&ske->fsm);
842 SILC_LOG_DEBUG(("Retransmitting packet"));
843 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
844 ske->retrans.data, ske->retrans.data_len);
847 /* Sends SILC packet. Handles retransmissions with UDP streams. */
849 static SilcBool silc_ske_packet_send(SilcSKE ske,
851 SilcPacketFlags flags,
852 const unsigned char *data,
857 /* Send the packet */
858 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
860 if (silc_packet_stream_is_udp(ske->stream) &&
861 type != SILC_PACKET_FAILURE) {
862 silc_free(ske->retrans.data);
863 ske->retrans.type = type;
864 ske->retrans.flags = flags;
865 ske->retrans.data = silc_memdup(data, data_len);
866 ske->retrans.data_len = data_len;
867 if (ske->retrans.data) {
868 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
870 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
871 ske, ske->retry_timer, 0);
873 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
874 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
881 /******************************* Protocol API *******************************/
883 /* Allocates new SKE object. */
885 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
886 SilcSKR repository, SilcPublicKey public_key,
887 SilcPrivateKey private_key, void *context)
891 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
893 if (!rng || !schedule)
897 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
901 ske = silc_calloc(1, sizeof(*ske));
904 ske->status = SILC_SKE_STATUS_OK;
906 ske->repository = repository;
907 ske->user_data = context;
908 ske->schedule = schedule;
909 ske->public_key = public_key;
910 ske->private_key = private_key;
911 ske->retry_timer = SILC_SKE_RETRY_MIN;
916 /* Free's SKE object. */
918 void silc_ske_free(SilcSKE ske)
920 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
930 /* Free start payload */
931 if (ske->start_payload)
932 silc_ske_payload_start_free(ske->start_payload);
934 /* Free KE payload */
935 if (ske->ke1_payload)
936 silc_ske_payload_ke_free(ske->ke1_payload);
937 if (ske->ke2_payload)
938 silc_ske_payload_ke_free(ske->ke2_payload);
939 silc_free(ske->remote_version);
943 if (ske->prop->group)
944 silc_ske_group_free(ske->prop->group);
945 if (ske->prop->cipher)
946 silc_cipher_free(ske->prop->cipher);
948 silc_hash_free(ske->prop->hash);
950 silc_hmac_free(ske->prop->hmac);
951 silc_free(ske->prop);
953 if (ske->start_payload_copy)
954 silc_buffer_free(ske->start_payload_copy);
956 silc_mp_uninit(ske->x);
960 silc_mp_uninit(ske->KEY);
963 silc_free(ske->retrans.data);
964 silc_free(ske->hash);
965 silc_free(ske->callbacks);
967 memset(ske, 'F', sizeof(*ske));
971 /* Return user context */
973 void *silc_ske_get_context(SilcSKE ske)
975 return ske->user_data;
978 /* Sets protocol callbacks */
980 void silc_ske_set_callbacks(SilcSKE ske,
981 SilcSKEVerifyCb verify_key,
982 SilcSKECompletionCb completed,
986 silc_free(ske->callbacks);
987 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
990 ske->callbacks->verify_key = verify_key;
991 ske->callbacks->completed = completed;
992 ske->callbacks->context = context;
996 /******************************** Initiator *********************************/
998 /* Start protocol. Send our proposal */
1000 SILC_FSM_STATE(silc_ske_st_initiator_start)
1002 SilcSKE ske = fsm_context;
1003 SilcBuffer payload_buf;
1006 SILC_LOG_DEBUG(("Start"));
1010 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1011 return SILC_FSM_CONTINUE;
1014 /* Encode the payload */
1015 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1017 if (status != SILC_SKE_STATUS_OK) {
1018 /** Error encoding Start Payload */
1019 ske->status = status;
1020 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1021 return SILC_FSM_CONTINUE;
1024 /* Save the the payload buffer for future use. It is later used to
1025 compute the HASH value. */
1026 ske->start_payload_copy = payload_buf;
1028 /* Send the packet. */
1029 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1030 silc_buffer_data(payload_buf),
1031 silc_buffer_len(payload_buf))) {
1032 /** Error sending packet */
1033 SILC_LOG_DEBUG(("Error sending packet"));
1034 ske->status = SILC_SKE_STATUS_ERROR;
1035 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1036 return SILC_FSM_CONTINUE;
1041 /** Wait for responder proposal */
1042 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
1043 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1044 return SILC_FSM_WAIT;
1047 /* Phase-1. Receives responder's proposal */
1049 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1051 SilcSKE ske = fsm_context;
1052 SilcSKEStatus status;
1053 SilcSKEStartPayload payload;
1054 SilcSKESecurityProperties prop;
1055 SilcSKEDiffieHellmanGroup group = NULL;
1056 SilcBuffer packet_buf = &ske->packet->buffer;
1057 SilcUInt16 remote_port = 0;
1061 SILC_LOG_DEBUG(("Start"));
1063 ske->retry_timer = SILC_SKE_RETRY_MIN;
1064 silc_schedule_task_del_by_context(ske->schedule, ske);
1068 silc_packet_free(ske->packet);
1069 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1070 return SILC_FSM_CONTINUE;
1073 /* See if received failure from remote */
1074 if (ske->packet->type == SILC_PACKET_FAILURE) {
1075 silc_packet_free(ske->packet);
1076 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1077 return SILC_FSM_CONTINUE;
1080 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1081 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1082 silc_packet_free(ske->packet);
1083 return SILC_FSM_WAIT;
1086 /* Decode the payload */
1087 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1088 if (status != SILC_SKE_STATUS_OK) {
1089 /** Error decoding Start Payload */
1090 silc_packet_free(ske->packet);
1091 ske->status = status;
1092 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1093 return SILC_FSM_CONTINUE;
1096 /* Get remote ID and set it to stream */
1097 if (ske->packet->src_id_len) {
1098 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1099 ske->packet->src_id_type,
1100 (ske->packet->src_id_type == SILC_ID_SERVER ?
1101 (void *)&id.u.server_id : (void *)&id.u.client_id),
1102 (ske->packet->src_id_type == SILC_ID_SERVER ?
1103 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1104 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1105 (ske->packet->src_id_type == SILC_ID_SERVER ?
1106 (void *)&id.u.server_id : (void *)&id.u.client_id));
1109 silc_packet_free(ske->packet);
1111 /* Check that the cookie is returned unmodified. In case IV included
1112 flag and session port has been set, the first two bytes of cookie
1113 are the session port and we ignore them in this check. */
1114 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1115 /* Take remote port */
1116 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1119 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1120 SILC_SKE_COOKIE_LEN - coff)) {
1121 /** Invalid cookie */
1122 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1123 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1124 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1125 return SILC_FSM_CONTINUE;
1128 /* Check version string */
1129 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1130 status = silc_ske_check_version(ske);
1131 if (status != SILC_SKE_STATUS_OK) {
1132 /** Version mismatch */
1133 ske->status = status;
1134 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1135 return SILC_FSM_CONTINUE;
1138 /* Free our KE Start Payload context, we don't need it anymore. */
1139 silc_ske_payload_start_free(ske->start_payload);
1140 ske->start_payload = NULL;
1142 /* Take the selected security properties into use while doing
1143 the key exchange. This is used only while doing the key
1145 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1148 prop->flags = payload->flags;
1149 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1150 if (status != SILC_SKE_STATUS_OK)
1153 prop->group = group;
1154 prop->remote_port = remote_port;
1156 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1157 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1160 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1161 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1164 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1165 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1168 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1169 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1173 /* Save remote's KE Start Payload */
1174 ske->start_payload = payload;
1176 /** Send KE Payload */
1177 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1178 return SILC_FSM_CONTINUE;
1182 silc_ske_payload_start_free(payload);
1184 silc_ske_group_free(group);
1186 silc_cipher_free(prop->cipher);
1188 silc_hash_free(prop->hash);
1190 silc_hmac_free(prop->hmac);
1194 if (status == SILC_SKE_STATUS_OK)
1195 status = SILC_SKE_STATUS_ERROR;
1198 ske->status = status;
1199 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1200 return SILC_FSM_CONTINUE;
1203 /* Phase-2. Send KE payload */
1205 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1207 SilcSKE ske = fsm_context;
1208 SilcSKEStatus status;
1209 SilcBuffer payload_buf;
1211 SilcSKEKEPayload payload;
1214 SILC_LOG_DEBUG(("Start"));
1216 /* Create the random number x, 1 < x < q. */
1217 x = silc_calloc(1, sizeof(*x));
1219 /** Out of memory */
1220 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1221 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1222 return SILC_FSM_CONTINUE;
1226 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1227 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1229 if (status != SILC_SKE_STATUS_OK) {
1230 /** Error generating random number */
1233 ske->status = status;
1234 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1235 return SILC_FSM_CONTINUE;
1238 /* Encode the result to Key Exchange Payload. */
1240 payload = silc_calloc(1, sizeof(*payload));
1242 /** Out of memory */
1245 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1246 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1247 return SILC_FSM_CONTINUE;
1249 ske->ke1_payload = payload;
1251 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1253 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1254 silc_mp_init(&payload->x);
1255 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1256 &ske->prop->group->group);
1258 /* Get public key */
1259 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1260 if (!payload->pk_data) {
1261 /** Error encoding public key */
1264 silc_mp_uninit(&payload->x);
1266 ske->ke1_payload = NULL;
1267 ske->status = SILC_SKE_STATUS_ERROR;
1268 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1269 return SILC_FSM_CONTINUE;
1271 payload->pk_len = pk_len;
1272 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1274 /* Compute signature data if we are doing mutual authentication */
1275 if (ske->private_key &&
1276 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1277 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1278 SilcUInt32 hash_len, sign_len;
1280 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1281 SILC_LOG_DEBUG(("Computing HASH_i value"));
1283 /* Compute the hash value */
1284 memset(hash, 0, sizeof(hash));
1285 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1287 SILC_LOG_DEBUG(("Signing HASH_i value"));
1289 /* Sign the hash value */
1290 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1291 sizeof(sign) - 1, &sign_len, NULL)) {
1292 /** Error computing signature */
1295 silc_mp_uninit(&payload->x);
1296 silc_free(payload->pk_data);
1298 ske->ke1_payload = NULL;
1299 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1300 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1301 return SILC_FSM_CONTINUE;
1303 payload->sign_data = silc_memdup(sign, sign_len);
1304 if (payload->sign_data)
1305 payload->sign_len = sign_len;
1306 memset(sign, 0, sizeof(sign));
1309 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1310 if (status != SILC_SKE_STATUS_OK) {
1311 /** Error encoding KE payload */
1314 silc_mp_uninit(&payload->x);
1315 silc_free(payload->pk_data);
1316 silc_free(payload->sign_data);
1318 ske->ke1_payload = NULL;
1319 ske->status = status;
1320 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1321 return SILC_FSM_CONTINUE;
1326 /* Check for backwards compatibility */
1328 /* Send the packet. */
1329 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1330 silc_buffer_data(payload_buf),
1331 silc_buffer_len(payload_buf))) {
1332 /** Error sending packet */
1333 SILC_LOG_DEBUG(("Error sending packet"));
1334 ske->status = SILC_SKE_STATUS_ERROR;
1335 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1336 return SILC_FSM_CONTINUE;
1339 silc_buffer_free(payload_buf);
1341 /** Waiting responder's KE payload */
1342 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1343 return SILC_FSM_WAIT;
1346 /* Phase-3. Process responder's KE payload */
1348 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1350 SilcSKE ske = fsm_context;
1351 SilcSKEStatus status;
1352 SilcSKEKEPayload payload;
1354 SilcBuffer packet_buf = &ske->packet->buffer;
1356 SILC_LOG_DEBUG(("Start"));
1358 ske->retry_timer = SILC_SKE_RETRY_MIN;
1359 silc_schedule_task_del_by_context(ske->schedule, ske);
1363 silc_packet_free(ske->packet);
1364 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1365 return SILC_FSM_CONTINUE;
1368 /* See if received failure from remote */
1369 if (ske->packet->type == SILC_PACKET_FAILURE) {
1370 silc_packet_free(ske->packet);
1371 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1372 return SILC_FSM_CONTINUE;
1375 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1376 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1377 silc_packet_free(ske->packet);
1378 return SILC_FSM_WAIT;
1381 /* Decode the payload */
1382 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1383 if (status != SILC_SKE_STATUS_OK) {
1384 /** Error decoding KE payload */
1385 silc_packet_free(ske->packet);
1386 ske->status = status;
1387 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1388 return SILC_FSM_CONTINUE;
1390 silc_packet_free(ske->packet);
1391 ske->ke2_payload = payload;
1393 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1394 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1395 "even though we require it"));
1396 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1400 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1402 /* Compute the shared secret key */
1403 KEY = silc_calloc(1, sizeof(*KEY));
1405 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1408 /* Decode the remote's public key */
1409 if (payload->pk_data &&
1410 !silc_pkcs_public_key_alloc(payload->pk_type,
1411 payload->pk_data, payload->pk_len,
1412 &ske->prop->public_key)) {
1413 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1414 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1418 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1420 SILC_LOG_DEBUG(("Verifying public key"));
1422 /** Waiting public key verification */
1423 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1425 /* If repository is provided, verify the key from there. */
1426 if (ske->repository) {
1429 find = silc_skr_find_alloc();
1431 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1434 silc_skr_find_set_pkcs_type(find,
1435 silc_pkcs_get_type(ske->prop->public_key));
1436 silc_skr_find_set_public_key(find, ske->prop->public_key);
1437 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1439 /* Find key from repository */
1440 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1441 silc_ske_skr_callback, ske));
1443 /* Verify from application */
1444 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1445 ske->callbacks->context,
1446 silc_ske_pk_verified, NULL));
1451 /** Process key material */
1452 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1453 return SILC_FSM_CONTINUE;
1456 silc_ske_payload_ke_free(payload);
1457 ske->ke2_payload = NULL;
1459 silc_mp_uninit(ske->KEY);
1460 silc_free(ske->KEY);
1463 if (status == SILC_SKE_STATUS_OK)
1464 return SILC_SKE_STATUS_ERROR;
1467 ske->status = status;
1468 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1469 return SILC_FSM_CONTINUE;
1472 /* Process key material */
1474 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1476 SilcSKE ske = fsm_context;
1477 SilcSKEStatus status;
1478 SilcSKEKEPayload payload;
1479 unsigned char hash[SILC_HASH_MAXLEN];
1480 SilcUInt32 hash_len;
1481 int key_len, block_len;
1485 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1486 return SILC_FSM_CONTINUE;
1489 /* Check result of public key verification */
1490 if (ske->status != SILC_SKE_STATUS_OK) {
1491 /** Public key not verified */
1492 SILC_LOG_DEBUG(("Public key verification failed"));
1493 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1494 return SILC_FSM_CONTINUE;
1497 payload = ske->ke2_payload;
1499 if (ske->prop->public_key) {
1500 SILC_LOG_DEBUG(("Public key is authentic"));
1502 /* Compute the hash value */
1503 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1504 if (status != SILC_SKE_STATUS_OK)
1507 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1509 /* Verify signature */
1510 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1511 payload->sign_len, hash, hash_len, NULL)) {
1512 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1513 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1517 SILC_LOG_DEBUG(("Signature is Ok"));
1519 ske->hash = silc_memdup(hash, hash_len);
1520 ske->hash_len = hash_len;
1521 memset(hash, 'F', hash_len);
1524 ske->status = SILC_SKE_STATUS_OK;
1526 /* Process key material */
1527 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1528 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1529 hash_len = silc_hash_len(ske->prop->hash);
1530 ske->keymat = silc_ske_process_key_material(ske, block_len,
1533 SILC_LOG_ERROR(("Error processing key material"));
1534 status = SILC_SKE_STATUS_ERROR;
1538 /* Send SUCCESS packet */
1539 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1540 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1541 /** Error sending packet */
1542 SILC_LOG_DEBUG(("Error sending packet"));
1543 ske->status = SILC_SKE_STATUS_ERROR;
1544 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1545 return SILC_FSM_CONTINUE;
1548 /** Waiting completion */
1549 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1550 return SILC_FSM_WAIT;
1553 memset(hash, 'F', sizeof(hash));
1554 silc_ske_payload_ke_free(payload);
1555 ske->ke2_payload = NULL;
1557 silc_mp_uninit(ske->KEY);
1558 silc_free(ske->KEY);
1562 memset(ske->hash, 'F', hash_len);
1563 silc_free(ske->hash);
1567 if (status == SILC_SKE_STATUS_OK)
1568 status = SILC_SKE_STATUS_ERROR;
1571 ske->status = status;
1572 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1573 return SILC_FSM_CONTINUE;
1576 /* Protocol completed */
1578 SILC_FSM_STATE(silc_ske_st_initiator_end)
1580 SilcSKE ske = fsm_context;
1582 SILC_LOG_DEBUG(("Start"));
1584 ske->retry_timer = SILC_SKE_RETRY_MIN;
1585 silc_schedule_task_del_by_context(ske->schedule, ske);
1589 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1590 return SILC_FSM_CONTINUE;
1593 /* See if received failure from remote */
1594 if (ske->packet->type == SILC_PACKET_FAILURE) {
1595 silc_packet_free(ske->packet);
1596 silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1597 return SILC_FSM_CONTINUE;
1600 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1601 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1602 silc_packet_free(ske->packet);
1603 return SILC_FSM_WAIT;
1606 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1608 /* Call the completion callback */
1609 if (ske->callbacks->completed)
1610 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1611 ske->rekey, ske->callbacks->context);
1613 silc_packet_free(ske->packet);
1614 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1615 silc_schedule_task_del_by_context(ske->schedule, ske);
1617 return SILC_FSM_FINISH;
1620 /* Aborted by application */
1622 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1624 SilcSKE ske = fsm_context;
1625 unsigned char data[4];
1627 SILC_LOG_DEBUG(("Aborted by caller"));
1629 /* Send FAILURE packet */
1630 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1631 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1632 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1633 silc_schedule_task_del_by_context(ske->schedule, ske);
1635 return SILC_FSM_FINISH;
1638 /* Error occurred. Send error to remote host */
1640 SILC_FSM_STATE(silc_ske_st_initiator_error)
1642 SilcSKE ske = fsm_context;
1643 SilcSKEStatus status;
1644 unsigned char data[4];
1646 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1647 silc_ske_map_status(ske->status), ske->status));
1649 status = ske->status;
1650 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1651 status = SILC_SKE_STATUS_ERROR;
1653 /* Send FAILURE packet */
1654 SILC_PUT32_MSB((SilcUInt32)status, data);
1655 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1657 /* Call the completion callback */
1658 if (ske->callbacks->completed)
1659 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1660 ske->callbacks->context);
1662 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1663 silc_schedule_task_del_by_context(ske->schedule, ske);
1665 return SILC_FSM_FINISH;
1668 /* Failure received from remote */
1670 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1672 SilcSKE ske = fsm_context;
1674 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1675 silc_ske_map_status(ske->status), ske->status));
1677 /* Call the completion callback */
1678 if (ske->callbacks->completed)
1679 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1680 ske->callbacks->context);
1682 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1683 silc_schedule_task_del_by_context(ske->schedule, ske);
1685 return SILC_FSM_FINISH;
1688 /* FSM destructor */
1690 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1691 void *destructor_context)
1693 SilcSKE ske = fsm_context;
1695 ske->running = FALSE;
1700 /* Starts the protocol as initiator */
1703 silc_ske_initiator(SilcSKE ske,
1704 SilcPacketStream stream,
1705 SilcSKEParams params,
1706 SilcSKEStartPayload start_payload)
1708 SILC_LOG_DEBUG(("Start SKE as initiator"));
1710 if (!ske || !stream || !params || !params->version)
1713 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1716 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1720 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1721 ske->session_port = params->session_port;
1723 /* Generate security properties if not provided */
1724 if (!start_payload) {
1725 start_payload = silc_ske_assemble_security_properties(ske,
1732 ske->start_payload = start_payload;
1733 ske->version = params->version;
1734 ske->running = TRUE;
1736 /* Link to packet stream to get key exchange packets */
1737 ske->stream = stream;
1738 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1739 SILC_PACKET_KEY_EXCHANGE,
1740 SILC_PACKET_KEY_EXCHANGE_2,
1741 SILC_PACKET_SUCCESS,
1742 SILC_PACKET_FAILURE, -1);
1744 /* Start SKE as initiator */
1745 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1750 /******************************** Responder *********************************/
1752 /* Start protocol as responder. Wait initiator's start payload */
1754 SILC_FSM_STATE(silc_ske_st_responder_start)
1756 SilcSKE ske = fsm_context;
1758 SILC_LOG_DEBUG(("Start"));
1762 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1763 return SILC_FSM_CONTINUE;
1769 /** Wait for initiator */
1770 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1771 return SILC_FSM_WAIT;
1774 /* Decode initiator's start payload. Select the security properties from
1775 the initiator's start payload and send our reply start payload back. */
1777 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1779 SilcSKE ske = fsm_context;
1780 SilcSKEStatus status;
1781 SilcSKEStartPayload remote_payload = NULL;
1782 SilcBuffer packet_buf = &ske->packet->buffer;
1784 SILC_LOG_DEBUG(("Start"));
1788 silc_packet_free(ske->packet);
1789 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1790 return SILC_FSM_CONTINUE;
1793 /* See if received failure from remote */
1794 if (ske->packet->type == SILC_PACKET_FAILURE) {
1795 silc_packet_free(ske->packet);
1796 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1797 return SILC_FSM_CONTINUE;
1800 /* Decode the payload */
1801 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1802 if (status != SILC_SKE_STATUS_OK) {
1803 /** Error decoding Start Payload */
1804 silc_packet_free(ske->packet);
1805 ske->status = status;
1806 silc_fsm_next(fsm, silc_ske_st_responder_error);
1807 return SILC_FSM_CONTINUE;
1810 /* Take a copy of the payload buffer for future use. It is used to
1811 compute the HASH value. */
1812 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1814 silc_packet_free(ske->packet);
1816 /* Force the mutual authentication flag if we want to do it. */
1817 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1818 SILC_LOG_DEBUG(("Force mutual authentication"));
1819 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1822 /* Force PFS flag if we require it */
1823 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1824 SILC_LOG_DEBUG(("Force PFS"));
1825 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1828 /* Disable IV Included flag if requested */
1829 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1830 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1831 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1832 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1835 /* Check and select security properties */
1836 status = silc_ske_select_security_properties(ske, remote_payload,
1838 if (status != SILC_SKE_STATUS_OK) {
1839 /** Error selecting proposal */
1840 silc_ske_payload_start_free(remote_payload);
1841 ske->status = status;
1842 silc_fsm_next(fsm, silc_ske_st_responder_error);
1843 return SILC_FSM_CONTINUE;
1846 silc_ske_payload_start_free(remote_payload);
1848 /* Encode our reply payload to send the selected security properties */
1849 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1851 if (status != SILC_SKE_STATUS_OK)
1854 /* Send the packet. */
1855 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1856 silc_buffer_data(packet_buf),
1857 silc_buffer_len(packet_buf)))
1860 silc_buffer_free(packet_buf);
1862 /** Waiting initiator's KE payload */
1863 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1864 return SILC_FSM_WAIT;
1867 if (ske->prop->group)
1868 silc_ske_group_free(ske->prop->group);
1869 if (ske->prop->cipher)
1870 silc_cipher_free(ske->prop->cipher);
1871 if (ske->prop->hash)
1872 silc_hash_free(ske->prop->hash);
1873 if (ske->prop->hmac)
1874 silc_hmac_free(ske->prop->hmac);
1875 silc_free(ske->prop);
1878 if (status == SILC_SKE_STATUS_OK)
1879 status = SILC_SKE_STATUS_ERROR;
1882 ske->status = status;
1883 silc_fsm_next(fsm, silc_ske_st_responder_error);
1884 return SILC_FSM_CONTINUE;
1887 /* Phase-2. Decode initiator's KE payload */
1889 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1891 SilcSKE ske = fsm_context;
1892 SilcSKEStatus status;
1893 SilcSKEKEPayload recv_payload;
1894 SilcBuffer packet_buf = &ske->packet->buffer;
1896 SILC_LOG_DEBUG(("Start"));
1898 ske->retry_timer = SILC_SKE_RETRY_MIN;
1899 silc_schedule_task_del_by_context(ske->schedule, ske);
1903 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1904 return SILC_FSM_CONTINUE;
1907 /* See if received failure from remote */
1908 if (ske->packet->type == SILC_PACKET_FAILURE) {
1909 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1910 return SILC_FSM_CONTINUE;
1913 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1914 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1915 silc_packet_free(ske->packet);
1916 return SILC_FSM_WAIT;
1919 /* Decode Key Exchange Payload */
1920 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1921 if (status != SILC_SKE_STATUS_OK) {
1922 /** Error decoding KE payload */
1923 silc_packet_free(ske->packet);
1924 ske->status = status;
1925 silc_fsm_next(fsm, silc_ske_st_responder_error);
1926 return SILC_FSM_CONTINUE;
1929 ske->ke1_payload = recv_payload;
1931 silc_packet_free(ske->packet);
1933 /* Verify the received public key and verify the signature if we are
1934 doing mutual authentication. */
1935 if (ske->start_payload &&
1936 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1938 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1940 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1942 /** Public key not provided */
1943 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1944 "certificate), even though we require it"));
1945 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1946 silc_fsm_next(fsm, silc_ske_st_responder_error);
1947 return SILC_FSM_CONTINUE;
1950 /* Decode the remote's public key */
1951 if (recv_payload->pk_data &&
1952 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1953 recv_payload->pk_data,
1954 recv_payload->pk_len,
1955 &ske->prop->public_key)) {
1956 /** Error decoding public key */
1957 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1958 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1959 silc_fsm_next(fsm, silc_ske_st_responder_error);
1960 return SILC_FSM_CONTINUE;
1963 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1965 SILC_LOG_DEBUG(("Verifying public key"));
1967 /** Waiting public key verification */
1968 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1970 /* If repository is provided, verify the key from there. */
1971 if (ske->repository) {
1974 find = silc_skr_find_alloc();
1976 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1977 silc_fsm_next(fsm, silc_ske_st_responder_error);
1978 return SILC_FSM_CONTINUE;
1980 silc_skr_find_set_pkcs_type(find,
1981 silc_pkcs_get_type(ske->prop->public_key));
1982 silc_skr_find_set_public_key(find, ske->prop->public_key);
1983 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1985 /* Find key from repository */
1986 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1987 silc_ske_skr_callback, ske));
1989 /* Verify from application */
1990 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1991 ske->callbacks->context,
1992 silc_ske_pk_verified, NULL));
1998 /** Generate KE2 payload */
1999 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2000 return SILC_FSM_CONTINUE;
2003 /* Phase-4. Generate KE2 payload */
2005 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2007 SilcSKE ske = fsm_context;
2008 SilcSKEStatus status;
2009 SilcSKEKEPayload recv_payload, send_payload;
2014 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2015 return SILC_FSM_CONTINUE;
2018 /* Check result of public key verification */
2019 if (ske->status != SILC_SKE_STATUS_OK) {
2020 /** Public key not verified */
2021 SILC_LOG_DEBUG(("Public key verification failed"));
2022 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2023 return SILC_FSM_CONTINUE;
2026 recv_payload = ske->ke1_payload;
2028 /* The public key verification was performed only if the Mutual
2029 Authentication flag is set. */
2030 if (ske->start_payload &&
2031 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2032 unsigned char hash[SILC_HASH_MAXLEN];
2033 SilcUInt32 hash_len;
2035 SILC_LOG_DEBUG(("Public key is authentic"));
2037 /* Compute the hash value */
2038 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2039 if (status != SILC_SKE_STATUS_OK) {
2040 /** Error computing hash */
2041 ske->status = status;
2042 silc_fsm_next(fsm, silc_ske_st_responder_error);
2043 return SILC_FSM_CONTINUE;
2046 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2048 /* Verify signature */
2049 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2050 recv_payload->sign_len, hash, hash_len, NULL)) {
2051 /** Incorrect signature */
2052 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2053 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2054 silc_fsm_next(fsm, silc_ske_st_responder_error);
2055 return SILC_FSM_CONTINUE;
2058 SILC_LOG_DEBUG(("Signature is Ok"));
2060 memset(hash, 'F', hash_len);
2063 /* Create the random number x, 1 < x < q. */
2064 x = silc_calloc(1, sizeof(*x));
2067 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2068 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2070 if (status != SILC_SKE_STATUS_OK) {
2071 /** Error generating random number */
2074 ske->status = status;
2075 silc_fsm_next(fsm, silc_ske_st_responder_error);
2076 return SILC_FSM_CONTINUE;
2079 /* Save the results for later processing */
2080 send_payload = silc_calloc(1, sizeof(*send_payload));
2082 ske->ke2_payload = send_payload;
2084 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2086 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2087 silc_mp_init(&send_payload->x);
2088 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2089 &ske->prop->group->group);
2091 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2093 /* Compute the shared secret key */
2094 KEY = silc_calloc(1, sizeof(*KEY));
2096 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2097 &ske->prop->group->group);
2100 /** Send KE2 payload */
2101 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2102 return SILC_FSM_CONTINUE;
2105 /* Phase-5. Send KE2 payload */
2107 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2109 SilcSKE ske = fsm_context;
2110 SilcSKEStatus status;
2111 SilcBuffer payload_buf;
2112 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2113 SilcUInt32 hash_len, sign_len, pk_len;
2115 SILC_LOG_DEBUG(("Start"));
2117 if (ske->public_key && ske->private_key) {
2118 SILC_LOG_DEBUG(("Getting public key"));
2120 /* Get the public key */
2121 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2123 /** Error encoding public key */
2124 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2125 silc_fsm_next(fsm, silc_ske_st_responder_error);
2126 return SILC_FSM_CONTINUE;
2128 ske->ke2_payload->pk_data = pk;
2129 ske->ke2_payload->pk_len = pk_len;
2131 SILC_LOG_DEBUG(("Computing HASH value"));
2133 /* Compute the hash value */
2134 memset(hash, 0, sizeof(hash));
2135 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2136 if (status != SILC_SKE_STATUS_OK) {
2137 /** Error computing hash */
2138 ske->status = status;
2139 silc_fsm_next(fsm, silc_ske_st_responder_error);
2140 return SILC_FSM_CONTINUE;
2143 ske->hash = silc_memdup(hash, hash_len);
2144 ske->hash_len = hash_len;
2146 SILC_LOG_DEBUG(("Signing HASH value"));
2148 /* Sign the hash value */
2149 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2150 sizeof(sign) - 1, &sign_len, NULL)) {
2151 /** Error computing signature */
2152 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2153 silc_fsm_next(fsm, silc_ske_st_responder_error);
2154 return SILC_FSM_CONTINUE;
2156 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2157 ske->ke2_payload->sign_len = sign_len;
2158 memset(sign, 0, sizeof(sign));
2160 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2162 /* Encode the Key Exchange Payload */
2163 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2165 if (status != SILC_SKE_STATUS_OK) {
2166 /** Error encoding KE payload */
2167 ske->status = status;
2168 silc_fsm_next(fsm, silc_ske_st_responder_error);
2169 return SILC_FSM_CONTINUE;
2172 /* Send the packet. */
2173 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2174 payload_buf->data, silc_buffer_len(payload_buf))) {
2175 SILC_LOG_DEBUG(("Error sending packet"));
2176 ske->status = SILC_SKE_STATUS_ERROR;
2177 silc_fsm_next(fsm, silc_ske_st_responder_error);
2178 return SILC_FSM_CONTINUE;
2181 silc_buffer_free(payload_buf);
2183 /** Waiting completion */
2184 silc_fsm_next(fsm, silc_ske_st_responder_end);
2185 return SILC_FSM_WAIT;
2188 /* Protocol completed */
2190 SILC_FSM_STATE(silc_ske_st_responder_end)
2192 SilcSKE ske = fsm_context;
2193 unsigned char tmp[4];
2194 SilcUInt32 hash_len, key_len, block_len;
2196 ske->retry_timer = SILC_SKE_RETRY_MIN;
2197 silc_schedule_task_del_by_context(ske->schedule, ske);
2201 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2202 return SILC_FSM_CONTINUE;
2205 /* Check the result of the protocol */
2206 if (ske->packet->type == SILC_PACKET_FAILURE) {
2207 silc_fsm_next(fsm, silc_ske_st_responder_failure);
2208 return SILC_FSM_CONTINUE;
2211 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2212 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2213 silc_packet_free(ske->packet);
2214 return SILC_FSM_WAIT;
2216 silc_packet_free(ske->packet);
2218 /* Process key material */
2219 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2220 block_len = silc_cipher_get_key_len(ske->prop->cipher);
2221 hash_len = silc_hash_len(ske->prop->hash);
2222 ske->keymat = silc_ske_process_key_material(ske, block_len,
2225 /** Error processing key material */
2226 ske->status = SILC_SKE_STATUS_ERROR;
2227 silc_fsm_next(fsm, silc_ske_st_responder_error);
2228 return SILC_FSM_CONTINUE;
2231 /* Send SUCCESS packet */
2232 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2233 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2235 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2236 silc_schedule_task_del_by_context(ske->schedule, ske);
2238 /* Call the completion callback */
2239 if (ske->callbacks->completed)
2240 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
2241 ske->rekey, ske->callbacks->context);
2243 return SILC_FSM_FINISH;
2246 /* Aborted by application */
2248 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2250 SilcSKE ske = fsm_context;
2251 unsigned char tmp[4];
2253 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2255 /* Send FAILURE packet */
2256 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2257 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2259 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2260 silc_schedule_task_del_by_context(ske->schedule, ske);
2262 return SILC_FSM_FINISH;
2265 /* Failure received from remote */
2267 SILC_FSM_STATE(silc_ske_st_responder_failure)
2269 SilcSKE ske = fsm_context;
2270 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2272 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2274 if (silc_buffer_len(&ske->packet->buffer) == 4)
2275 SILC_GET32_MSB(error, ske->packet->buffer.data);
2276 ske->status = error;
2278 /* Call the completion callback */
2279 if (ske->callbacks->completed)
2280 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
2281 ske->callbacks->context);
2283 silc_packet_free(ske->packet);
2284 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2285 silc_schedule_task_del_by_context(ske->schedule, ske);
2287 return SILC_FSM_FINISH;
2290 /* Error occurred */
2292 SILC_FSM_STATE(silc_ske_st_responder_error)
2294 SilcSKE ske = fsm_context;
2295 unsigned char tmp[4];
2297 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2298 ske->status, silc_ske_map_status(ske->status)));
2300 /* Send FAILURE packet */
2301 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2302 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2303 SILC_PUT32_MSB(ske->status, tmp);
2304 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2305 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2306 silc_schedule_task_del_by_context(ske->schedule, ske);
2308 return SILC_FSM_FINISH;
2312 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
2313 void *destructor_context)
2315 SilcSKE ske = fsm_context;
2317 ske->running = FALSE;
2322 /* Starts the protocol as responder. */
2325 silc_ske_responder(SilcSKE ske,
2326 SilcPacketStream stream,
2327 SilcSKEParams params)
2329 SILC_LOG_DEBUG(("Start SKE as responder"));
2331 if (!ske || !stream || !params || !params->version) {
2335 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2338 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2342 ske->responder = TRUE;
2343 ske->flags = params->flags;
2344 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2345 ske->session_port = params->session_port;
2346 ske->version = strdup(params->version);
2349 ske->running = TRUE;
2351 /* Link to packet stream to get key exchange packets */
2352 ske->stream = stream;
2353 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2354 SILC_PACKET_KEY_EXCHANGE,
2355 SILC_PACKET_KEY_EXCHANGE_1,
2356 SILC_PACKET_SUCCESS,
2357 SILC_PACKET_FAILURE, -1);
2359 /* Start SKE as responder */
2360 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2365 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2367 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2369 return SILC_FSM_FINISH;
2372 /* Starts rekey protocol as initiator */
2375 silc_ske_rekey_initiator(SilcSKE ske,
2376 SilcPacketStream stream,
2377 SilcSKERekeyMaterial rekey)
2379 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2381 if (!ske || !stream || !rekey)
2384 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2387 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2392 /* Link to packet stream to get key exchange packets */
2393 ske->stream = stream;
2395 /* Start SKE rekey as initiator */
2396 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2401 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2403 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2405 return SILC_FSM_FINISH;
2408 /* Starts rekey protocol as responder */
2411 silc_ske_rekey_responder(SilcSKE ske,
2412 SilcPacketStream stream,
2413 SilcBuffer ke_payload,
2414 SilcSKERekeyMaterial rekey)
2416 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2418 if (!ske || !stream || !rekey)
2420 if (rekey->pfs && !ke_payload)
2423 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2426 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2429 // ske->packet_buf = ke_payload;
2432 /* Link to packet stream to get key exchange packets */
2433 ske->stream = stream;
2435 /* Start SKE rekey as responder */
2436 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2441 /* Processes the provided key material `data' as the SILC protocol
2442 specification defines. */
2445 silc_ske_process_key_material_data(unsigned char *data,
2446 SilcUInt32 data_len,
2447 SilcUInt32 req_iv_len,
2448 SilcUInt32 req_enc_key_len,
2449 SilcUInt32 req_hmac_key_len,
2453 unsigned char hashd[SILC_HASH_MAXLEN];
2454 SilcUInt32 hash_len = req_hmac_key_len;
2455 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2456 SilcSKEKeyMaterial key;
2458 SILC_LOG_DEBUG(("Start"));
2460 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2463 key = silc_calloc(1, sizeof(*key));
2467 buf = silc_buffer_alloc_size(1 + data_len);
2470 silc_buffer_format(buf,
2471 SILC_STR_UI_CHAR(0),
2472 SILC_STR_UI_XNSTRING(data, data_len),
2476 memset(hashd, 0, sizeof(hashd));
2478 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2479 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2480 memcpy(key->send_iv, hashd, req_iv_len);
2481 memset(hashd, 0, sizeof(hashd));
2483 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2484 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2485 memcpy(key->receive_iv, hashd, req_iv_len);
2486 key->iv_len = req_iv_len;
2488 /* Take the encryption keys. If requested key size is more than
2489 the size of hash length we will distribute more key material
2490 as protocol defines. */
2492 if (enc_key_len > hash_len) {
2494 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2495 k3[SILC_HASH_MAXLEN];
2496 unsigned char *dtmp;
2499 if (enc_key_len > (3 * hash_len))
2502 /* Take first round */
2503 memset(k1, 0, sizeof(k1));
2504 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2506 /* Take second round */
2507 dist = silc_buffer_alloc_size(data_len + hash_len);
2510 silc_buffer_format(dist,
2511 SILC_STR_UI_XNSTRING(data, data_len),
2512 SILC_STR_UI_XNSTRING(k1, hash_len),
2514 memset(k2, 0, sizeof(k2));
2515 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2517 /* Take third round */
2518 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2519 silc_buffer_pull_tail(dist, hash_len);
2520 silc_buffer_pull(dist, data_len + hash_len);
2521 silc_buffer_format(dist,
2522 SILC_STR_UI_XNSTRING(k2, hash_len),
2524 silc_buffer_push(dist, data_len + hash_len);
2525 memset(k3, 0, sizeof(k3));
2526 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2528 /* Then, save the keys */
2529 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2530 memcpy(dtmp, k1, hash_len);
2531 memcpy(dtmp + hash_len, k2, hash_len);
2532 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2534 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2535 memcpy(key->send_enc_key, dtmp, enc_key_len);
2536 key->enc_key_len = req_enc_key_len;
2538 memset(dtmp, 0, (3 * hash_len));
2539 memset(k1, 0, sizeof(k1));
2540 memset(k2, 0, sizeof(k2));
2541 memset(k3, 0, sizeof(k3));
2543 silc_buffer_clear(dist);
2544 silc_buffer_free(dist);
2546 /* Take normal hash as key */
2547 memset(hashd, 0, sizeof(hashd));
2548 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2549 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2550 memcpy(key->send_enc_key, hashd, enc_key_len);
2551 key->enc_key_len = req_enc_key_len;
2555 if (enc_key_len > hash_len) {
2557 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2558 k3[SILC_HASH_MAXLEN];
2559 unsigned char *dtmp;
2562 if (enc_key_len > (3 * hash_len))
2565 /* Take first round */
2566 memset(k1, 0, sizeof(k1));
2567 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2569 /* Take second round */
2570 dist = silc_buffer_alloc_size(data_len + hash_len);
2573 silc_buffer_format(dist,
2574 SILC_STR_UI_XNSTRING(data, data_len),
2575 SILC_STR_UI_XNSTRING(k1, hash_len),
2577 memset(k2, 0, sizeof(k2));
2578 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2580 /* Take third round */
2581 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2582 silc_buffer_pull_tail(dist, hash_len);
2583 silc_buffer_pull(dist, data_len + hash_len);
2584 silc_buffer_format(dist,
2585 SILC_STR_UI_XNSTRING(k2, hash_len),
2587 silc_buffer_push(dist, data_len + hash_len);
2588 memset(k3, 0, sizeof(k3));
2589 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2591 /* Then, save the keys */
2592 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2593 memcpy(dtmp, k1, hash_len);
2594 memcpy(dtmp + hash_len, k2, hash_len);
2595 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2597 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2598 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2599 key->enc_key_len = req_enc_key_len;
2601 memset(dtmp, 0, (3 * hash_len));
2602 memset(k1, 0, sizeof(k1));
2603 memset(k2, 0, sizeof(k2));
2604 memset(k3, 0, sizeof(k3));
2606 silc_buffer_clear(dist);
2607 silc_buffer_free(dist);
2609 /* Take normal hash as key */
2610 memset(hashd, 0, sizeof(hashd));
2611 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2612 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2613 memcpy(key->receive_enc_key, hashd, enc_key_len);
2614 key->enc_key_len = req_enc_key_len;
2617 /* Take HMAC keys */
2618 memset(hashd, 0, sizeof(hashd));
2620 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2621 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2622 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2623 memset(hashd, 0, sizeof(hashd));
2625 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2626 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2627 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2628 key->hmac_key_len = req_hmac_key_len;
2629 memset(hashd, 0, sizeof(hashd));
2631 silc_buffer_clear(buf);
2632 silc_buffer_free(buf);
2637 /* Processes negotiated key material as protocol specifies. This returns
2638 the actual keys to be used in the SILC. */
2641 silc_ske_process_key_material(SilcSKE ske,
2642 SilcUInt32 req_iv_len,
2643 SilcUInt32 req_enc_key_len,
2644 SilcUInt32 req_hmac_key_len)
2647 unsigned char *tmpbuf;
2649 SilcSKEKeyMaterial key;
2651 /* Encode KEY to binary data */
2652 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2654 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2657 silc_buffer_format(buf,
2658 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2659 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2662 /* Process the key material */
2663 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2664 req_iv_len, req_enc_key_len,
2668 memset(tmpbuf, 0, klen);
2670 silc_buffer_clear(buf);
2671 silc_buffer_free(buf);
2676 /* Free key material structure */
2678 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2684 silc_free(key->send_iv);
2685 if (key->receive_iv)
2686 silc_free(key->receive_iv);
2687 if (key->send_enc_key) {
2688 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2689 silc_free(key->send_enc_key);
2691 if (key->receive_enc_key) {
2692 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2693 silc_free(key->receive_enc_key);
2695 if (key->send_hmac_key) {
2696 memset(key->send_hmac_key, 0, key->hmac_key_len);
2697 silc_free(key->send_hmac_key);
2699 if (key->receive_hmac_key) {
2700 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2701 silc_free(key->receive_hmac_key);
2706 /* Set keys into use */
2708 SilcBool silc_ske_set_keys(SilcSKE ske,
2709 SilcSKEKeyMaterial keymat,
2710 SilcSKESecurityProperties prop,
2711 SilcCipher *ret_send_key,
2712 SilcCipher *ret_receive_key,
2713 SilcHmac *ret_hmac_send,
2714 SilcHmac *ret_hmac_receive,
2717 /* Allocate ciphers to be used in the communication */
2719 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2723 if (ret_receive_key) {
2724 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2729 /* Allocate HMACs */
2730 if (ret_hmac_send) {
2731 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2735 if (ret_hmac_receive) {
2736 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2741 /* Set key material */
2742 if (ske->responder) {
2743 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2744 keymat->enc_key_len);
2745 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2746 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2747 keymat->enc_key_len);
2748 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2749 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2750 keymat->hmac_key_len);
2751 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2752 keymat->hmac_key_len);
2754 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2755 keymat->enc_key_len);
2756 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2757 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2758 keymat->enc_key_len);
2759 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2760 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2761 keymat->hmac_key_len);
2762 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2763 keymat->hmac_key_len);
2768 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2775 const char *silc_ske_status_string[] =
2779 "Unkown error occurred",
2780 "Bad payload in packet",
2781 "Unsupported group",
2782 "Unsupported cipher",
2784 "Unsupported hash function",
2786 "Unsupported public key (or certificate)",
2787 "Incorrect signature",
2788 "Bad or unsupported version",
2792 "Remote did not provide public key",
2793 "Bad reserved field in packet",
2794 "Bad payload length in packet",
2795 "Error computing signature",
2796 "System out of memory",
2801 /* Maps status to readable string and returns the string. If string is not
2802 found and empty character string ("") is returned. */
2804 const char *silc_ske_map_status(SilcSKEStatus status)
2808 for (i = 0; silc_ske_status_string[i]; i++)
2810 return silc_ske_status_string[i];
2815 /* Parses remote host's version string. */
2817 SilcBool silc_ske_parse_version(SilcSKE ske,
2818 SilcUInt32 *protocol_version,
2819 char **protocol_version_string,
2820 SilcUInt32 *software_version,
2821 char **software_version_string,
2822 char **vendor_version)
2824 return silc_parse_version_string(ske->remote_version,
2826 protocol_version_string,
2828 software_version_string,
2832 /* Get security properties */
2834 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
2839 /* Get key material */
2841 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)