5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2007 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 **************************/
37 SILC_FSM_STATE(silc_ske_st_initiator_start);
38 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
39 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
40 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
41 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
42 SILC_FSM_STATE(silc_ske_st_initiator_end);
43 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
44 SILC_FSM_STATE(silc_ske_st_initiator_error);
45 SILC_FSM_STATE(silc_ske_st_initiator_failure);
46 SILC_FSM_STATE(silc_ske_st_responder_start);
47 SILC_FSM_STATE(silc_ske_st_responder_phase1);
48 SILC_FSM_STATE(silc_ske_st_responder_phase2);
49 SILC_FSM_STATE(silc_ske_st_responder_phase4);
50 SILC_FSM_STATE(silc_ske_st_responder_phase5);
51 SILC_FSM_STATE(silc_ske_st_responder_end);
52 SILC_FSM_STATE(silc_ske_st_responder_aborted);
53 SILC_FSM_STATE(silc_ske_st_responder_failure);
54 SILC_FSM_STATE(silc_ske_st_responder_error);
55 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
56 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done);
57 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end);
58 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait);
59 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
60 SILC_FSM_STATE(silc_ske_st_rekey_responder_done);
61 SILC_FSM_STATE(silc_ske_st_rekey_responder_end);
62 SILC_TASK_CALLBACK(silc_ske_packet_send_retry);
65 silc_ske_process_key_material(SilcSKE ske,
66 SilcUInt32 req_iv_len,
67 SilcUInt32 req_enc_key_len,
68 SilcUInt32 req_hmac_key_len,
69 SilcSKERekeyMaterial *rekey);
70 static SilcBool silc_ske_packet_send(SilcSKE ske,
72 SilcPacketFlags flags,
73 const unsigned char *data,
78 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
79 SilcPacketStream stream,
81 void *callback_context,
84 SilcSKE ske = callback_context;
86 /* Clear retransmission */
87 ske->retry_timer = SILC_SKE_RETRY_MIN;
89 silc_schedule_task_del_by_callback(ske->schedule,
90 silc_ske_packet_send_retry);
92 /* Signal for new packet */
95 /* Check if we were aborted */
97 silc_packet_free(packet);
101 silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
103 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
105 silc_fsm_continue_sync(&ske->fsm);
109 /* See if received failure from remote */
110 if (packet->type == SILC_PACKET_FAILURE) {
112 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
114 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
117 /* Handle rekey and SUCCESS packets synchronously. After SUCCESS packets
118 they keys are taken into use immediately, hence the synchronous
119 processing to get the keys in use as soon as possible. */
120 if (ske->rekeying || packet->type == SILC_PACKET_SUCCESS)
121 silc_fsm_continue_sync(&ske->fsm);
123 silc_fsm_continue(&ske->fsm);
128 /* Packet stream callbacks */
129 static SilcPacketCallbacks silc_ske_stream_cbs =
131 silc_ske_packet_receive, NULL, NULL
134 /* Aborts SKE protocol */
136 static void silc_ske_abort(SilcAsyncOperation op, void *context)
138 SilcSKE ske = context;
142 /* Public key verification completion callback */
144 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
145 void *completion_context)
147 ske->status = status;
148 SILC_FSM_CALL_CONTINUE(&ske->fsm);
151 /* SKR find callback */
153 static void silc_ske_skr_callback(SilcSKR repository,
155 SilcSKRStatus status,
156 SilcDList keys, void *context)
158 SilcSKE ske = context;
160 silc_skr_find_free(find);
162 if (status != SILC_SKR_OK) {
163 if (ske->callbacks->verify_key) {
164 /* Verify from application */
165 ske->callbacks->verify_key(ske, ske->prop->public_key,
166 ske->callbacks->context,
167 silc_ske_pk_verified, NULL);
173 silc_dlist_uninit(keys);
176 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
177 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
178 SILC_FSM_CALL_CONTINUE(&ske->fsm);
181 /* Checks remote and local versions */
183 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
185 SilcUInt32 r_software_version = 0;
186 char *r_software_string = NULL;
188 if (!ske->remote_version || !ske->version)
189 return SILC_SKE_STATUS_BAD_VERSION;
191 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
193 &r_software_string, NULL))
194 return SILC_SKE_STATUS_BAD_VERSION;
196 return SILC_SKE_STATUS_OK;
199 /* Selects the supported security properties from the initiator's Key
200 Exchange Start Payload. A responder function. Saves our reply
201 start payload to ske->start_payload. */
204 silc_ske_select_security_properties(SilcSKE ske,
205 SilcSKEStartPayload remote_payload,
206 SilcSKESecurityProperties *prop)
208 SilcSKEStatus status;
209 SilcSKEStartPayload rp, payload;
213 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
217 /* Check for mandatory fields */
218 if (!rp->ke_grp_len) {
219 SILC_LOG_DEBUG(("KE group not defined in payload"));
220 return SILC_SKE_STATUS_BAD_PAYLOAD;
222 if (!rp->pkcs_alg_len) {
223 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
224 return SILC_SKE_STATUS_BAD_PAYLOAD;
226 if (!rp->enc_alg_len) {
227 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
228 return SILC_SKE_STATUS_BAD_PAYLOAD;
230 if (!rp->hash_alg_len) {
231 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
232 return SILC_SKE_STATUS_BAD_PAYLOAD;
234 if (!rp->hmac_alg_len) {
235 SILC_LOG_DEBUG(("HMAC not defined in payload"));
236 return SILC_SKE_STATUS_BAD_PAYLOAD;
239 /* Allocate security properties */
240 *prop = silc_calloc(1, sizeof(**prop));
242 return SILC_SKE_STATUS_OUT_OF_MEMORY;
244 /* Allocate our reply start payload */
245 payload = silc_calloc(1, sizeof(*payload));
248 return SILC_SKE_STATUS_OUT_OF_MEMORY;
251 /* Check version string */
252 ske->remote_version = silc_memdup(rp->version, rp->version_len);
253 status = silc_ske_check_version(ske);
254 if (status != SILC_SKE_STATUS_OK) {
255 ske->status = status;
259 /* Flags are returned unchanged. */
260 (*prop)->flags = payload->flags = rp->flags;
262 /* Take cookie, we must return it to sender unmodified. */
263 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
264 if (!payload->cookie) {
265 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
268 payload->cookie_len = SILC_SKE_COOKIE_LEN;
269 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
271 /* In case IV included flag and session port is set the first 16-bits of
272 cookie will include our session port. */
273 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
274 /* Take remote port */
275 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
278 SILC_PUT16_MSB(ske->session_port, payload->cookie);
281 /* Put our version to our reply */
282 payload->version = strdup(ske->version);
283 if (!payload->version) {
284 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
287 payload->version_len = strlen(ske->version);
289 /* Get supported Key Exchange groups */
290 cp = rp->ke_grp_list;
291 if (cp && strchr(cp, ',')) {
295 len = strcspn(cp, ",");
296 item = silc_calloc(len + 1, sizeof(char));
298 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
301 memcpy(item, cp, len);
303 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
305 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
306 SILC_LOG_DEBUG(("Found KE group `%s'", item));
308 payload->ke_grp_len = len;
309 payload->ke_grp_list = item;
323 if (!payload->ke_grp_len && !payload->ke_grp_list) {
324 SILC_LOG_DEBUG(("Could not find supported KE group"));
326 return SILC_SKE_STATUS_UNKNOWN_GROUP;
329 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
330 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
332 payload->ke_grp_len = rp->ke_grp_len;
333 payload->ke_grp_list = strdup(rp->ke_grp_list);
336 /* Save group to security properties */
337 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
338 if (status != SILC_SKE_STATUS_OK) {
340 return SILC_SKE_STATUS_UNKNOWN_GROUP;
343 /* Get supported PKCS algorithms */
344 cp = rp->pkcs_alg_list;
345 if (cp && strchr(cp, ',')) {
349 len = strcspn(cp, ",");
350 item = silc_calloc(len + 1, sizeof(char));
352 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
355 memcpy(item, cp, len);
357 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
359 if (silc_pkcs_find_algorithm(item, NULL)) {
360 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
362 payload->pkcs_alg_len = len;
363 payload->pkcs_alg_list = item;
377 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
378 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
379 silc_free(payload->ke_grp_list);
381 return SILC_SKE_STATUS_UNKNOWN_PKCS;
384 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
385 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
387 payload->pkcs_alg_len = rp->pkcs_alg_len;
388 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
391 /* Get supported encryption algorithms */
392 cp = rp->enc_alg_list;
393 if (cp && strchr(cp, ',')) {
397 len = strcspn(cp, ",");
398 item = silc_calloc(len + 1, sizeof(char));
400 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
403 memcpy(item, cp, len);
405 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
407 if (silc_cipher_is_supported(item) == TRUE) {
408 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
410 payload->enc_alg_len = len;
411 payload->enc_alg_list = item;
425 if (!payload->enc_alg_len && !payload->enc_alg_list) {
426 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
427 silc_free(payload->ke_grp_list);
428 silc_free(payload->pkcs_alg_list);
430 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
433 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
436 payload->enc_alg_len = rp->enc_alg_len;
437 payload->enc_alg_list = strdup(rp->enc_alg_list);
440 /* Save selected cipher to security properties */
441 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
442 silc_free(payload->ke_grp_list);
443 silc_free(payload->pkcs_alg_list);
445 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
448 /* Get supported hash algorithms */
449 cp = rp->hash_alg_list;
450 if (cp && strchr(cp, ',')) {
454 len = strcspn(cp, ",");
455 item = silc_calloc(len + 1, sizeof(char));
457 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
460 memcpy(item, cp, len);
462 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
464 if (silc_hash_is_supported(item) == TRUE) {
465 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
467 payload->hash_alg_len = len;
468 payload->hash_alg_list = item;
482 if (!payload->hash_alg_len && !payload->hash_alg_list) {
483 SILC_LOG_DEBUG(("Could not find supported hash alg"));
484 silc_free(payload->ke_grp_list);
485 silc_free(payload->pkcs_alg_list);
486 silc_free(payload->enc_alg_list);
488 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
491 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
494 payload->hash_alg_len = rp->hash_alg_len;
495 payload->hash_alg_list = strdup(rp->hash_alg_list);
498 /* Save selected hash algorithm to security properties */
499 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
500 silc_free(payload->ke_grp_list);
501 silc_free(payload->pkcs_alg_list);
502 silc_free(payload->enc_alg_list);
504 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
507 /* Get supported HMACs */
508 cp = rp->hmac_alg_list;
509 if (cp && strchr(cp, ',')) {
513 len = strcspn(cp, ",");
514 item = silc_calloc(len + 1, sizeof(char));
516 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
519 memcpy(item, cp, len);
521 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
523 if (silc_hmac_is_supported(item) == TRUE) {
524 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
526 payload->hmac_alg_len = len;
527 payload->hmac_alg_list = item;
541 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
542 SILC_LOG_DEBUG(("Could not find supported HMAC"));
543 silc_free(payload->ke_grp_list);
544 silc_free(payload->pkcs_alg_list);
545 silc_free(payload->enc_alg_list);
546 silc_free(payload->hash_alg_list);
548 return SILC_SKE_STATUS_UNKNOWN_HMAC;
551 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
554 payload->hmac_alg_len = rp->hmac_alg_len;
555 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
558 /* Save selected HMACc to security properties */
559 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
560 silc_free(payload->ke_grp_list);
561 silc_free(payload->pkcs_alg_list);
562 silc_free(payload->enc_alg_list);
563 silc_free(payload->hash_alg_list);
565 return SILC_SKE_STATUS_UNKNOWN_HMAC;
568 /* Get supported compression algorithms */
569 cp = rp->comp_alg_list;
570 if (cp && strchr(cp, ',')) {
574 len = strcspn(cp, ",");
575 item = silc_calloc(len + 1, sizeof(char));
577 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
580 memcpy(item, cp, len);
582 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
585 if (!strcmp(item, "none")) {
586 SILC_LOG_DEBUG(("Found Compression `%s'", item));
587 payload->comp_alg_len = len;
588 payload->comp_alg_list = item;
592 if (silc_hmac_is_supported(item) == TRUE) {
593 SILC_LOG_DEBUG(("Found Compression `%s'", item));
594 payload->comp_alg_len = len;
595 payload->comp_alg_list = item;
611 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
612 2 + payload->version_len +
613 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
614 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
615 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
617 /* Save our reply payload */
618 ske->start_payload = payload;
620 return SILC_SKE_STATUS_OK;
623 /* Creates random number such that 1 < rnd < n and at most length
624 of len bits. The rnd sent as argument must be initialized. */
626 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
630 SilcSKEStatus status = SILC_SKE_STATUS_OK;
631 unsigned char *string;
635 return SILC_SKE_STATUS_ERROR;
637 SILC_LOG_DEBUG(("Creating random number"));
641 /* Get the random number as string */
642 string = silc_rng_get_rn_data(ske->rng, l);
644 return SILC_SKE_STATUS_OUT_OF_MEMORY;
646 /* Decode the string into a MP integer */
647 silc_mp_bin2mp(string, l, rnd);
648 silc_mp_mod_2exp(rnd, rnd, len);
651 if (silc_mp_cmp_ui(rnd, 1) < 0)
652 status = SILC_SKE_STATUS_ERROR;
653 if (silc_mp_cmp(rnd, n) >= 0)
654 status = SILC_SKE_STATUS_ERROR;
656 memset(string, 'F', l);
662 /* Creates a hash value HASH as defined in the SKE protocol. If the
663 `initiator' is TRUE then this function is used to create the HASH_i
664 hash value defined in the protocol. If it is FALSE then this is used
665 to create the HASH value defined by the protocol. */
667 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
668 unsigned char *return_hash,
669 SilcUInt32 *return_hash_len,
672 SilcSKEStatus status = SILC_SKE_STATUS_OK;
674 unsigned char *e, *f, *KEY;
675 SilcUInt32 e_len, f_len, KEY_len;
678 SILC_LOG_DEBUG(("Start"));
680 if (initiator == FALSE) {
681 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
682 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
683 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
685 /* Format the buffer used to compute the hash value */
686 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
687 ske->ke2_payload->pk_len +
688 ske->ke1_payload->pk_len +
689 e_len + f_len + KEY_len);
691 return SILC_SKE_STATUS_OUT_OF_MEMORY;
693 /* Initiator is not required to send its public key */
694 if (!ske->ke1_payload->pk_data) {
696 silc_buffer_format(buf,
697 SILC_STR_UI_XNSTRING(
698 ske->start_payload_copy->data,
699 silc_buffer_len(ske->start_payload_copy)),
700 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
701 ske->ke2_payload->pk_len),
702 SILC_STR_UI_XNSTRING(e, e_len),
703 SILC_STR_UI_XNSTRING(f, f_len),
704 SILC_STR_UI_XNSTRING(KEY, KEY_len),
708 silc_buffer_format(buf,
709 SILC_STR_UI_XNSTRING(
710 ske->start_payload_copy->data,
711 silc_buffer_len(ske->start_payload_copy)),
712 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
713 ske->ke2_payload->pk_len),
714 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
715 ske->ke1_payload->pk_len),
716 SILC_STR_UI_XNSTRING(e, e_len),
717 SILC_STR_UI_XNSTRING(f, f_len),
718 SILC_STR_UI_XNSTRING(KEY, KEY_len),
722 silc_buffer_free(buf);
725 memset(KEY, 0, KEY_len);
729 return SILC_SKE_STATUS_ERROR;
734 memset(KEY, 0, KEY_len);
739 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
741 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
742 ske->ke1_payload->pk_len + e_len);
744 return SILC_SKE_STATUS_OUT_OF_MEMORY;
746 /* Format the buffer used to compute the hash value */
748 silc_buffer_format(buf,
749 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
750 silc_buffer_len(ske->start_payload_copy)),
751 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
752 ske->ke1_payload->pk_len),
753 SILC_STR_UI_XNSTRING(e, e_len),
756 silc_buffer_free(buf);
759 return SILC_SKE_STATUS_ERROR;
762 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
769 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
771 *return_hash_len = silc_hash_len(ske->prop->hash);
773 if (initiator == FALSE) {
774 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
776 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
779 silc_buffer_free(buf);
784 /* Generate rekey material */
786 static SilcSKERekeyMaterial
787 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
789 SilcSKERekeyMaterial rekey;
792 /* Create rekey material */
793 rekey = silc_calloc(1, sizeof(*rekey));
798 if (ske->prop->group)
799 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
800 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
801 hash = silc_hash_get_name(ske->prop->hash);
802 rekey->hash = silc_memdup(hash, strlen(hash));
807 if (rekey->pfs == FALSE) {
808 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
809 keymat->enc_key_len / 8);
810 if (!rekey->send_enc_key) {
814 rekey->enc_key_len = keymat->enc_key_len;
820 /* Assembles security properties */
822 static SilcSKEStartPayload
823 silc_ske_assemble_security_properties(SilcSKE ske,
824 SilcSKESecurityPropertyFlag flags,
827 SilcSKEStartPayload rp;
830 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
832 rp = silc_calloc(1, sizeof(*rp));
835 rp->flags = (unsigned char)flags;
837 /* Set random cookie */
838 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
839 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
840 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
841 rp->cookie_len = SILC_SKE_COOKIE_LEN;
843 /* In case IV included flag and session port is set the first 16-bits of
844 cookie will include our session port. */
845 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
846 SILC_PUT16_MSB(ske->session_port, rp->cookie);
849 rp->version = strdup(version);
850 rp->version_len = strlen(version);
852 /* Get supported Key Exhange groups */
853 rp->ke_grp_list = silc_ske_get_supported_groups();
854 rp->ke_grp_len = strlen(rp->ke_grp_list);
856 /* Get supported PKCS algorithms */
857 rp->pkcs_alg_list = silc_pkcs_get_supported();
858 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
860 /* Get supported encryption algorithms */
861 rp->enc_alg_list = silc_cipher_get_supported();
862 rp->enc_alg_len = strlen(rp->enc_alg_list);
864 /* Get supported hash algorithms */
865 rp->hash_alg_list = silc_hash_get_supported();
866 rp->hash_alg_len = strlen(rp->hash_alg_list);
868 /* Get supported HMACs */
869 rp->hmac_alg_list = silc_hmac_get_supported();
870 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
873 /* Get supported compression algorithms */
874 rp->comp_alg_list = strdup("none");
875 rp->comp_alg_len = strlen("none");
877 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
878 2 + rp->version_len +
879 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
880 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
881 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
886 /* Packet retransmission callback. */
888 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
890 SilcSKE ske = context;
892 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
894 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
895 ske->retry_count = 0;
896 ske->retry_timer = SILC_SKE_RETRY_MIN;
897 silc_free(ske->retrans.data);
898 ske->retrans.data = NULL;
899 ske->status = SILC_SKE_STATUS_TIMEOUT;
901 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
903 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
904 silc_fsm_continue_sync(&ske->fsm);
908 SILC_LOG_DEBUG(("Retransmitting packet"));
909 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
910 ske->retrans.data, ske->retrans.data_len);
913 /* Install retransmission timer */
915 static void silc_ske_install_retransmission(SilcSKE ske)
917 if (!silc_packet_stream_is_udp(ske->stream))
920 if (ske->retrans.data) {
921 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
923 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
924 ske, ske->retry_timer, 0);
926 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
927 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
930 /* Sends SILC packet. Handles retransmissions with UDP streams. */
932 static SilcBool silc_ske_packet_send(SilcSKE ske,
934 SilcPacketFlags flags,
935 const unsigned char *data,
940 /* Send the packet */
941 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
943 if (silc_packet_stream_is_udp(ske->stream) &&
944 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
945 silc_free(ske->retrans.data);
946 ske->retrans.type = type;
947 ske->retrans.flags = flags;
948 ske->retrans.data = silc_memdup(data, data_len);
949 ske->retrans.data_len = data_len;
950 silc_ske_install_retransmission(ske);
956 /* Calls completion callback. Completion is called always in this function
957 and must not be called anywhere else. */
959 static void silc_ske_completion(SilcSKE ske)
961 /* Call the completion callback */
962 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
963 if (ske->status != SILC_SKE_STATUS_OK)
964 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
965 ske->callbacks->context);
967 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
968 ske->rekey, ske->callbacks->context);
972 /* SKE FSM destructor. */
974 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
975 void *destructor_context)
977 SilcSKE ske = fsm_context;
978 ske->running = FALSE;
983 /* Key exchange timeout task callback */
985 SILC_TASK_CALLBACK(silc_ske_timeout)
987 SilcSKE ske = context;
989 SILC_LOG_DEBUG(("Timeout"));
992 ske->status = SILC_SKE_STATUS_TIMEOUT;
994 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
996 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
998 silc_fsm_continue_sync(&ske->fsm);
1001 /******************************* Protocol API *******************************/
1003 /* Allocates new SKE object. */
1005 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1006 SilcSKR repository, SilcPublicKey public_key,
1007 SilcPrivateKey private_key, void *context)
1011 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1013 if (!rng || !schedule)
1017 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1021 ske = silc_calloc(1, sizeof(*ske));
1024 ske->status = SILC_SKE_STATUS_OK;
1026 ske->repository = repository;
1027 ske->user_data = context;
1028 ske->schedule = schedule;
1029 ske->public_key = public_key;
1030 ske->private_key = private_key;
1031 ske->retry_timer = SILC_SKE_RETRY_MIN;
1037 /* Free's SKE object. */
1039 void silc_ske_free(SilcSKE ske)
1041 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1050 /* If already aborted, destroy the session immediately */
1052 ske->status = SILC_SKE_STATUS_ERROR;
1054 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1056 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1057 silc_fsm_continue_sync(&ske->fsm);
1063 if (ske->refcnt > 0)
1066 /* Free start payload */
1067 if (ske->start_payload)
1068 silc_ske_payload_start_free(ske->start_payload);
1070 /* Free KE payload */
1071 if (ske->ke1_payload)
1072 silc_ske_payload_ke_free(ske->ke1_payload);
1073 if (ske->ke2_payload)
1074 silc_ske_payload_ke_free(ske->ke2_payload);
1075 silc_free(ske->remote_version);
1079 if (ske->prop->group)
1080 silc_ske_group_free(ske->prop->group);
1081 if (ske->prop->cipher)
1082 silc_cipher_free(ske->prop->cipher);
1083 if (ske->prop->hash)
1084 silc_hash_free(ske->prop->hash);
1085 if (ske->prop->hmac)
1086 silc_hmac_free(ske->prop->hmac);
1087 if (ske->prop->public_key)
1088 silc_pkcs_public_key_free(ske->prop->public_key);
1089 silc_free(ske->prop);
1092 silc_ske_free_key_material(ske->keymat);
1093 if (ske->start_payload_copy)
1094 silc_buffer_free(ske->start_payload_copy);
1096 silc_mp_uninit(ske->x);
1100 silc_mp_uninit(ske->KEY);
1101 silc_free(ske->KEY);
1103 silc_free(ske->retrans.data);
1104 silc_free(ske->hash);
1105 silc_free(ske->callbacks);
1107 memset(ske, 'F', sizeof(*ske));
1111 /* Return user context */
1113 void *silc_ske_get_context(SilcSKE ske)
1115 return ske->user_data;
1118 /* Sets protocol callbacks */
1120 void silc_ske_set_callbacks(SilcSKE ske,
1121 SilcSKEVerifyCb verify_key,
1122 SilcSKECompletionCb completed,
1126 silc_free(ske->callbacks);
1127 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1128 if (!ske->callbacks)
1130 ske->callbacks->verify_key = verify_key;
1131 ske->callbacks->completed = completed;
1132 ske->callbacks->context = context;
1136 /******************************** Initiator *********************************/
1138 /* Start protocol. Send our proposal */
1140 SILC_FSM_STATE(silc_ske_st_initiator_start)
1142 SilcSKE ske = fsm_context;
1143 SilcBuffer payload_buf;
1146 SILC_LOG_DEBUG(("Start"));
1150 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1151 return SILC_FSM_CONTINUE;
1154 /* Encode the payload */
1155 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1157 if (status != SILC_SKE_STATUS_OK) {
1158 /** Error encoding Start Payload */
1159 ske->status = status;
1160 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1161 return SILC_FSM_CONTINUE;
1164 /* Save the the payload buffer for future use. It is later used to
1165 compute the HASH value. */
1166 ske->start_payload_copy = payload_buf;
1168 /* Send the packet. */
1169 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1170 silc_buffer_data(payload_buf),
1171 silc_buffer_len(payload_buf))) {
1172 /** Error sending packet */
1173 SILC_LOG_DEBUG(("Error sending packet"));
1174 ske->status = SILC_SKE_STATUS_ERROR;
1175 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1176 return SILC_FSM_CONTINUE;
1179 /* Add key exchange timeout */
1180 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1181 ske, ske->timeout, 0);
1183 /** Wait for responder proposal */
1184 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1185 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1186 return SILC_FSM_WAIT;
1189 /* Phase-1. Receives responder's proposal */
1191 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1193 SilcSKE ske = fsm_context;
1194 SilcSKEStatus status;
1195 SilcSKEStartPayload payload;
1196 SilcSKESecurityProperties prop;
1197 SilcSKEDiffieHellmanGroup group = NULL;
1198 SilcBuffer packet_buf = &ske->packet->buffer;
1199 SilcUInt16 remote_port = 0;
1203 SILC_LOG_DEBUG(("Start"));
1205 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1206 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1207 silc_ske_install_retransmission(ske);
1208 silc_packet_free(ske->packet);
1210 return SILC_FSM_WAIT;
1213 /* Decode the payload */
1214 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1215 if (status != SILC_SKE_STATUS_OK) {
1216 /** Error decoding Start Payload */
1217 silc_packet_free(ske->packet);
1219 ske->status = status;
1220 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1221 return SILC_FSM_CONTINUE;
1224 /* Get remote ID and set it to stream */
1225 if (ske->packet->src_id_len) {
1226 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1227 ske->packet->src_id_type,
1228 (ske->packet->src_id_type == SILC_ID_SERVER ?
1229 (void *)&id.u.server_id : (void *)&id.u.client_id),
1230 (ske->packet->src_id_type == SILC_ID_SERVER ?
1231 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1232 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1233 (ske->packet->src_id_type == SILC_ID_SERVER ?
1234 (void *)&id.u.server_id : (void *)&id.u.client_id));
1237 silc_packet_free(ske->packet);
1240 /* Check that the cookie is returned unmodified. In case IV included
1241 flag and session port has been set, the first two bytes of cookie
1242 are the session port and we ignore them in this check. */
1243 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1244 /* Take remote port */
1245 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1248 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1249 SILC_SKE_COOKIE_LEN - coff)) {
1250 /** Invalid cookie */
1251 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1252 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1253 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1254 return SILC_FSM_CONTINUE;
1257 /* Check version string */
1258 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1259 status = silc_ske_check_version(ske);
1260 if (status != SILC_SKE_STATUS_OK) {
1261 /** Version mismatch */
1262 ske->status = status;
1263 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1264 return SILC_FSM_CONTINUE;
1267 /* Free our KE Start Payload context, we don't need it anymore. */
1268 silc_ske_payload_start_free(ske->start_payload);
1269 ske->start_payload = NULL;
1271 /* Take the selected security properties into use while doing
1272 the key exchange. This is used only while doing the key
1274 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1277 prop->flags = payload->flags;
1278 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1279 if (status != SILC_SKE_STATUS_OK)
1282 prop->group = group;
1283 prop->remote_port = remote_port;
1285 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1286 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1289 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1290 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1293 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1294 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1297 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1298 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1302 /* Save remote's KE Start Payload */
1303 ske->start_payload = payload;
1305 /** Send KE Payload */
1306 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1307 return SILC_FSM_CONTINUE;
1311 silc_ske_payload_start_free(payload);
1313 silc_ske_group_free(group);
1315 silc_cipher_free(prop->cipher);
1317 silc_hash_free(prop->hash);
1319 silc_hmac_free(prop->hmac);
1323 if (status == SILC_SKE_STATUS_OK)
1324 status = SILC_SKE_STATUS_ERROR;
1327 ske->status = status;
1328 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1329 return SILC_FSM_CONTINUE;
1332 /* Phase-2. Send KE payload */
1334 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1336 SilcSKE ske = fsm_context;
1337 SilcSKEStatus status;
1338 SilcBuffer payload_buf;
1340 SilcSKEKEPayload payload;
1343 SILC_LOG_DEBUG(("Start"));
1345 /* Create the random number x, 1 < x < q. */
1346 x = silc_calloc(1, sizeof(*x));
1348 /** Out of memory */
1349 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1350 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1351 return SILC_FSM_CONTINUE;
1355 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1356 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1358 if (status != SILC_SKE_STATUS_OK) {
1359 /** Error generating random number */
1362 ske->status = status;
1363 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1364 return SILC_FSM_CONTINUE;
1367 /* Encode the result to Key Exchange Payload. */
1369 payload = silc_calloc(1, sizeof(*payload));
1371 /** Out of memory */
1374 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1375 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1376 return SILC_FSM_CONTINUE;
1378 ske->ke1_payload = payload;
1380 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1382 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1383 silc_mp_init(&payload->x);
1384 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1385 &ske->prop->group->group);
1387 /* Get public key */
1388 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1389 if (!payload->pk_data) {
1390 /** Error encoding public key */
1393 silc_mp_uninit(&payload->x);
1395 ske->ke1_payload = NULL;
1396 ske->status = SILC_SKE_STATUS_ERROR;
1397 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1398 return SILC_FSM_CONTINUE;
1400 payload->pk_len = pk_len;
1401 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1403 /* Compute signature data if we are doing mutual authentication */
1404 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1405 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1406 SilcUInt32 hash_len, sign_len;
1408 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1409 SILC_LOG_DEBUG(("Computing HASH_i value"));
1411 /* Compute the hash value */
1412 memset(hash, 0, sizeof(hash));
1413 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1415 SILC_LOG_DEBUG(("Signing HASH_i value"));
1417 /* Sign the hash value */
1418 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1419 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1420 /** Error computing signature */
1423 silc_mp_uninit(&payload->x);
1424 silc_free(payload->pk_data);
1426 ske->ke1_payload = NULL;
1427 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1428 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1429 return SILC_FSM_CONTINUE;
1431 payload->sign_data = silc_memdup(sign, sign_len);
1432 if (payload->sign_data)
1433 payload->sign_len = sign_len;
1434 memset(sign, 0, sizeof(sign));
1437 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1438 if (status != SILC_SKE_STATUS_OK) {
1439 /** Error encoding KE payload */
1442 silc_mp_uninit(&payload->x);
1443 silc_free(payload->pk_data);
1444 silc_free(payload->sign_data);
1446 ske->ke1_payload = NULL;
1447 ske->status = status;
1448 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1449 return SILC_FSM_CONTINUE;
1454 /* Check for backwards compatibility */
1456 /* Send the packet. */
1457 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1458 silc_buffer_data(payload_buf),
1459 silc_buffer_len(payload_buf))) {
1460 /** Error sending packet */
1461 SILC_LOG_DEBUG(("Error sending packet"));
1462 ske->status = SILC_SKE_STATUS_ERROR;
1463 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1464 return SILC_FSM_CONTINUE;
1467 silc_buffer_free(payload_buf);
1469 /** Waiting responder's KE payload */
1470 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1471 return SILC_FSM_WAIT;
1474 /* Phase-3. Process responder's KE payload */
1476 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1478 SilcSKE ske = fsm_context;
1479 SilcSKEStatus status;
1480 SilcSKEKEPayload payload;
1482 SilcBuffer packet_buf = &ske->packet->buffer;
1484 SILC_LOG_DEBUG(("Start"));
1486 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1487 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1488 silc_ske_install_retransmission(ske);
1489 silc_packet_free(ske->packet);
1491 return SILC_FSM_WAIT;
1494 /* Decode the payload */
1495 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1496 if (status != SILC_SKE_STATUS_OK) {
1497 /** Error decoding KE payload */
1498 silc_packet_free(ske->packet);
1500 ske->status = status;
1501 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1502 return SILC_FSM_CONTINUE;
1504 silc_packet_free(ske->packet);
1506 ske->ke2_payload = payload;
1508 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1509 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1510 "even though we require it"));
1511 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1515 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1517 /* Compute the shared secret key */
1518 KEY = silc_calloc(1, sizeof(*KEY));
1520 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1523 /* Decode the remote's public key */
1524 if (payload->pk_data &&
1525 !silc_pkcs_public_key_alloc(payload->pk_type,
1526 payload->pk_data, payload->pk_len,
1527 &ske->prop->public_key)) {
1528 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1529 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1533 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1535 SILC_LOG_DEBUG(("Verifying public key"));
1537 /** Waiting public key verification */
1538 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1540 /* If repository is provided, verify the key from there. */
1541 if (ske->repository) {
1544 find = silc_skr_find_alloc();
1546 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1549 silc_skr_find_set_pkcs_type(find,
1550 silc_pkcs_get_type(ske->prop->public_key));
1551 silc_skr_find_set_public_key(find, ske->prop->public_key);
1552 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1554 /* Find key from repository */
1555 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1556 find, silc_ske_skr_callback, ske));
1558 /* Verify from application */
1559 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1560 ske->callbacks->context,
1561 silc_ske_pk_verified, NULL));
1566 /** Process key material */
1567 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1568 return SILC_FSM_CONTINUE;
1571 silc_ske_payload_ke_free(payload);
1572 ske->ke2_payload = NULL;
1574 silc_mp_uninit(ske->KEY);
1575 silc_free(ske->KEY);
1578 if (status == SILC_SKE_STATUS_OK)
1579 return SILC_SKE_STATUS_ERROR;
1582 ske->status = status;
1583 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1584 return SILC_FSM_CONTINUE;
1587 /* Process key material */
1589 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1591 SilcSKE ske = fsm_context;
1592 SilcSKEStatus status;
1593 SilcSKEKEPayload payload;
1594 unsigned char hash[SILC_HASH_MAXLEN];
1595 SilcUInt32 hash_len;
1596 int key_len, block_len;
1600 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1601 return SILC_FSM_CONTINUE;
1604 /* Check result of public key verification */
1605 if (ske->status != SILC_SKE_STATUS_OK) {
1606 /** Public key not verified */
1607 SILC_LOG_DEBUG(("Public key verification failed"));
1608 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1609 return SILC_FSM_CONTINUE;
1612 payload = ske->ke2_payload;
1614 if (ske->prop->public_key) {
1615 SILC_LOG_DEBUG(("Public key is authentic"));
1617 /* Compute the hash value */
1618 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1619 if (status != SILC_SKE_STATUS_OK)
1622 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1624 /* Verify signature */
1625 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1626 payload->sign_len, hash, hash_len, NULL)) {
1627 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1628 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1632 SILC_LOG_DEBUG(("Signature is Ok"));
1634 ske->hash = silc_memdup(hash, hash_len);
1635 ske->hash_len = hash_len;
1636 memset(hash, 'F', hash_len);
1639 ske->status = SILC_SKE_STATUS_OK;
1641 /* In case we are doing rekey move to finish it. */
1644 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1645 return SILC_FSM_CONTINUE;
1648 /* Process key material */
1649 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1650 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1651 hash_len = silc_hash_len(ske->prop->hash);
1652 ske->keymat = silc_ske_process_key_material(ske, block_len,
1656 SILC_LOG_ERROR(("Error processing key material"));
1657 status = SILC_SKE_STATUS_ERROR;
1661 /* Send SUCCESS packet */
1662 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1663 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1664 /** Error sending packet */
1665 SILC_LOG_DEBUG(("Error sending packet"));
1666 ske->status = SILC_SKE_STATUS_ERROR;
1667 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1668 return SILC_FSM_CONTINUE;
1671 /** Waiting completion */
1672 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1673 return SILC_FSM_WAIT;
1676 memset(hash, 'F', sizeof(hash));
1677 silc_ske_payload_ke_free(payload);
1678 ske->ke2_payload = NULL;
1680 silc_mp_uninit(ske->KEY);
1681 silc_free(ske->KEY);
1685 memset(ske->hash, 'F', hash_len);
1686 silc_free(ske->hash);
1690 if (status == SILC_SKE_STATUS_OK)
1691 status = SILC_SKE_STATUS_ERROR;
1694 ske->status = status;
1695 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1696 return SILC_FSM_CONTINUE;
1699 /* Protocol completed */
1701 SILC_FSM_STATE(silc_ske_st_initiator_end)
1703 SilcSKE ske = fsm_context;
1705 SILC_LOG_DEBUG(("Start"));
1707 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1708 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1709 silc_ske_install_retransmission(ske);
1710 silc_packet_free(ske->packet);
1712 return SILC_FSM_WAIT;
1715 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1717 silc_packet_free(ske->packet);
1719 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1720 silc_schedule_task_del_by_context(ske->schedule, ske);
1722 /* Call completion */
1723 silc_ske_completion(ske);
1725 return SILC_FSM_FINISH;
1728 /* Aborted by application */
1730 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1732 SilcSKE ske = fsm_context;
1733 unsigned char data[4];
1735 SILC_LOG_DEBUG(("Aborted by caller"));
1737 /* Send FAILURE packet */
1738 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1739 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1741 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1742 silc_schedule_task_del_by_context(ske->schedule, ske);
1744 /* Call completion */
1745 silc_ske_completion(ske);
1747 return SILC_FSM_FINISH;
1750 /* Error occurred. Send error to remote host */
1752 SILC_FSM_STATE(silc_ske_st_initiator_error)
1754 SilcSKE ske = fsm_context;
1755 SilcSKEStatus status;
1756 unsigned char data[4];
1758 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1759 silc_ske_map_status(ske->status), ske->status));
1761 status = ske->status;
1762 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1763 status = SILC_SKE_STATUS_ERROR;
1765 /* Send FAILURE packet */
1766 SILC_PUT32_MSB((SilcUInt32)status, data);
1767 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1769 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1770 silc_schedule_task_del_by_context(ske->schedule, ske);
1772 /* Call completion */
1773 silc_ske_completion(ske);
1775 return SILC_FSM_FINISH;
1778 /* Failure received from remote */
1780 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1782 SilcSKE ske = fsm_context;
1783 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1785 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1786 SILC_GET32_MSB(error, ske->packet->buffer.data);
1787 ske->status = error;
1788 silc_packet_free(ske->packet);
1792 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1793 silc_ske_map_status(ske->status), ske->status));
1795 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1796 silc_schedule_task_del_by_context(ske->schedule, ske);
1798 /* Call completion */
1799 silc_ske_completion(ske);
1801 return SILC_FSM_FINISH;
1804 /* Starts the protocol as initiator */
1806 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1807 SilcPacketStream stream,
1808 SilcSKEParams params,
1809 SilcSKEStartPayload start_payload)
1811 SILC_LOG_DEBUG(("Start SKE as initiator"));
1813 if (!ske || !stream || !params || !params->version)
1816 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1819 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1822 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1823 ske->session_port = params->session_port;
1825 /* Generate security properties if not provided */
1826 if (!start_payload) {
1827 start_payload = silc_ske_assemble_security_properties(ske,
1834 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1835 ske->start_payload = start_payload;
1836 ske->version = params->version;
1837 ske->running = TRUE;
1839 /* Link to packet stream to get key exchange packets */
1840 ske->stream = stream;
1841 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1842 SILC_PACKET_KEY_EXCHANGE,
1843 SILC_PACKET_KEY_EXCHANGE_2,
1844 SILC_PACKET_SUCCESS,
1845 SILC_PACKET_FAILURE, -1);
1847 /* Start SKE as initiator */
1848 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1853 /******************************** Responder *********************************/
1855 /* Start protocol as responder. Wait initiator's start payload */
1857 SILC_FSM_STATE(silc_ske_st_responder_start)
1859 SilcSKE ske = fsm_context;
1861 SILC_LOG_DEBUG(("Start"));
1865 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1866 return SILC_FSM_CONTINUE;
1869 /* Add key exchange timeout */
1870 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1871 ske, ske->timeout, 0);
1873 /** Wait for initiator */
1874 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1875 return SILC_FSM_WAIT;
1878 /* Decode initiator's start payload. Select the security properties from
1879 the initiator's start payload and send our reply start payload back. */
1881 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1883 SilcSKE ske = fsm_context;
1884 SilcSKEStatus status;
1885 SilcSKEStartPayload remote_payload = NULL;
1886 SilcBuffer packet_buf = &ske->packet->buffer;
1889 SILC_LOG_DEBUG(("Start"));
1891 /* Decode the payload */
1892 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1893 if (status != SILC_SKE_STATUS_OK) {
1894 /** Error decoding Start Payload */
1895 silc_packet_free(ske->packet);
1897 ske->status = status;
1898 silc_fsm_next(fsm, silc_ske_st_responder_error);
1899 return SILC_FSM_CONTINUE;
1902 /* Get remote ID and set it to stream */
1903 if (ske->packet->src_id_len) {
1904 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1905 ske->packet->src_id_type,
1906 (ske->packet->src_id_type == SILC_ID_SERVER ?
1907 (void *)&id.u.server_id : (void *)&id.u.client_id),
1908 (ske->packet->src_id_type == SILC_ID_SERVER ?
1909 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1910 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1911 (ske->packet->src_id_type == SILC_ID_SERVER ?
1912 (void *)&id.u.server_id : (void *)&id.u.client_id));
1915 /* Take a copy of the payload buffer for future use. It is used to
1916 compute the HASH value. */
1917 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1919 silc_packet_free(ske->packet);
1922 /* Force the mutual authentication flag if we want to do it. */
1923 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1924 SILC_LOG_DEBUG(("Force mutual authentication"));
1925 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1928 /* Force PFS flag if we require it */
1929 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1930 SILC_LOG_DEBUG(("Force PFS"));
1931 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1934 /* Disable IV Included flag if requested */
1935 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1936 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1937 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1938 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1941 /* Check and select security properties */
1942 status = silc_ske_select_security_properties(ske, remote_payload,
1944 if (status != SILC_SKE_STATUS_OK) {
1945 /** Error selecting proposal */
1946 silc_ske_payload_start_free(remote_payload);
1947 ske->status = status;
1948 silc_fsm_next(fsm, silc_ske_st_responder_error);
1949 return SILC_FSM_CONTINUE;
1952 silc_ske_payload_start_free(remote_payload);
1954 /* Encode our reply payload to send the selected security properties */
1955 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1957 if (status != SILC_SKE_STATUS_OK)
1960 /* Send the packet. */
1961 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1962 silc_buffer_data(packet_buf),
1963 silc_buffer_len(packet_buf)))
1966 silc_buffer_free(packet_buf);
1968 /** Waiting initiator's KE payload */
1969 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1970 return SILC_FSM_WAIT;
1973 if (ske->prop->group)
1974 silc_ske_group_free(ske->prop->group);
1975 if (ske->prop->cipher)
1976 silc_cipher_free(ske->prop->cipher);
1977 if (ske->prop->hash)
1978 silc_hash_free(ske->prop->hash);
1979 if (ske->prop->hmac)
1980 silc_hmac_free(ske->prop->hmac);
1981 silc_free(ske->prop);
1984 if (status == SILC_SKE_STATUS_OK)
1985 status = SILC_SKE_STATUS_ERROR;
1988 ske->status = status;
1989 silc_fsm_next(fsm, silc_ske_st_responder_error);
1990 return SILC_FSM_CONTINUE;
1993 /* Phase-2. Decode initiator's KE payload */
1995 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1997 SilcSKE ske = fsm_context;
1998 SilcSKEStatus status;
1999 SilcSKEKEPayload recv_payload;
2000 SilcBuffer packet_buf = &ske->packet->buffer;
2002 SILC_LOG_DEBUG(("Start"));
2004 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2005 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2006 silc_ske_install_retransmission(ske);
2007 silc_packet_free(ske->packet);
2009 return SILC_FSM_WAIT;
2012 /* Decode Key Exchange Payload */
2013 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2014 if (status != SILC_SKE_STATUS_OK) {
2015 /** Error decoding KE payload */
2016 silc_packet_free(ske->packet);
2018 ske->status = status;
2019 silc_fsm_next(fsm, silc_ske_st_responder_error);
2020 return SILC_FSM_CONTINUE;
2023 ske->ke1_payload = recv_payload;
2025 silc_packet_free(ske->packet);
2028 /* Verify the received public key and verify the signature if we are
2029 doing mutual authentication. */
2030 if (ske->start_payload &&
2031 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2033 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2035 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2037 /** Public key not provided */
2038 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2039 "certificate), even though we require it"));
2040 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2041 silc_fsm_next(fsm, silc_ske_st_responder_error);
2042 return SILC_FSM_CONTINUE;
2045 /* Decode the remote's public key */
2046 if (recv_payload->pk_data &&
2047 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2048 recv_payload->pk_data,
2049 recv_payload->pk_len,
2050 &ske->prop->public_key)) {
2051 /** Error decoding public key */
2052 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2053 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2054 silc_fsm_next(fsm, silc_ske_st_responder_error);
2055 return SILC_FSM_CONTINUE;
2058 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2060 SILC_LOG_DEBUG(("Verifying public key"));
2062 /** Waiting public key verification */
2063 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2065 /* If repository is provided, verify the key from there. */
2066 if (ske->repository) {
2069 find = silc_skr_find_alloc();
2071 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2072 silc_fsm_next(fsm, silc_ske_st_responder_error);
2073 return SILC_FSM_CONTINUE;
2075 silc_skr_find_set_pkcs_type(find,
2076 silc_pkcs_get_type(ske->prop->public_key));
2077 silc_skr_find_set_public_key(find, ske->prop->public_key);
2078 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2080 /* Find key from repository */
2081 SILC_FSM_CALL(silc_skr_find(ske->repository,
2082 silc_fsm_get_schedule(fsm), find,
2083 silc_ske_skr_callback, ske));
2085 /* Verify from application */
2086 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2087 ske->callbacks->context,
2088 silc_ske_pk_verified, NULL));
2094 /** Generate KE2 payload */
2095 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2096 return SILC_FSM_CONTINUE;
2099 /* Phase-4. Generate KE2 payload */
2101 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2103 SilcSKE ske = fsm_context;
2104 SilcSKEStatus status;
2105 SilcSKEKEPayload recv_payload, send_payload;
2110 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2111 return SILC_FSM_CONTINUE;
2114 /* Check result of public key verification */
2115 if (ske->status != SILC_SKE_STATUS_OK) {
2116 /** Public key not verified */
2117 SILC_LOG_DEBUG(("Public key verification failed"));
2118 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2119 return SILC_FSM_CONTINUE;
2122 recv_payload = ske->ke1_payload;
2124 /* The public key verification was performed only if the Mutual
2125 Authentication flag is set. */
2126 if (ske->start_payload &&
2127 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2128 unsigned char hash[SILC_HASH_MAXLEN];
2129 SilcUInt32 hash_len;
2131 SILC_LOG_DEBUG(("Public key is authentic"));
2133 /* Compute the hash value */
2134 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2135 if (status != SILC_SKE_STATUS_OK) {
2136 /** Error computing hash */
2137 ske->status = status;
2138 silc_fsm_next(fsm, silc_ske_st_responder_error);
2139 return SILC_FSM_CONTINUE;
2142 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2144 /* Verify signature */
2145 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2146 recv_payload->sign_len, hash, hash_len, NULL)) {
2147 /** Incorrect signature */
2148 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2149 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2150 silc_fsm_next(fsm, silc_ske_st_responder_error);
2151 return SILC_FSM_CONTINUE;
2154 SILC_LOG_DEBUG(("Signature is Ok"));
2156 memset(hash, 'F', hash_len);
2159 /* Create the random number x, 1 < x < q. */
2160 x = silc_calloc(1, sizeof(*x));
2163 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2164 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2166 if (status != SILC_SKE_STATUS_OK) {
2167 /** Error generating random number */
2170 ske->status = status;
2171 silc_fsm_next(fsm, silc_ske_st_responder_error);
2172 return SILC_FSM_CONTINUE;
2175 /* Save the results for later processing */
2176 send_payload = silc_calloc(1, sizeof(*send_payload));
2178 ske->ke2_payload = send_payload;
2180 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2182 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2183 silc_mp_init(&send_payload->x);
2184 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2185 &ske->prop->group->group);
2187 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2189 /* Compute the shared secret key */
2190 KEY = silc_calloc(1, sizeof(*KEY));
2192 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2193 &ske->prop->group->group);
2196 /** Send KE2 payload */
2197 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2198 return SILC_FSM_CONTINUE;
2201 /* Phase-5. Send KE2 payload */
2203 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2205 SilcSKE ske = fsm_context;
2206 SilcSKEStatus status;
2207 SilcBuffer payload_buf;
2208 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2209 SilcUInt32 hash_len, sign_len, pk_len;
2211 SILC_LOG_DEBUG(("Start"));
2213 if (ske->public_key && ske->private_key) {
2214 SILC_LOG_DEBUG(("Getting public key"));
2216 /* Get the public key */
2217 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2219 /** Error encoding public key */
2220 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2221 silc_fsm_next(fsm, silc_ske_st_responder_error);
2222 return SILC_FSM_CONTINUE;
2224 ske->ke2_payload->pk_data = pk;
2225 ske->ke2_payload->pk_len = pk_len;
2227 SILC_LOG_DEBUG(("Computing HASH value"));
2229 /* Compute the hash value */
2230 memset(hash, 0, sizeof(hash));
2231 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2232 if (status != SILC_SKE_STATUS_OK) {
2233 /** Error computing hash */
2234 ske->status = status;
2235 silc_fsm_next(fsm, silc_ske_st_responder_error);
2236 return SILC_FSM_CONTINUE;
2239 ske->hash = silc_memdup(hash, hash_len);
2240 ske->hash_len = hash_len;
2242 SILC_LOG_DEBUG(("Signing HASH value"));
2244 /* Sign the hash value */
2245 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2246 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2247 /** Error computing signature */
2248 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2249 silc_fsm_next(fsm, silc_ske_st_responder_error);
2250 return SILC_FSM_CONTINUE;
2252 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2253 ske->ke2_payload->sign_len = sign_len;
2254 memset(sign, 0, sizeof(sign));
2256 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2258 /* Encode the Key Exchange Payload */
2259 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2261 if (status != SILC_SKE_STATUS_OK) {
2262 /** Error encoding KE payload */
2263 ske->status = status;
2264 silc_fsm_next(fsm, silc_ske_st_responder_error);
2265 return SILC_FSM_CONTINUE;
2268 /* Send the packet. */
2269 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2270 payload_buf->data, silc_buffer_len(payload_buf))) {
2271 SILC_LOG_DEBUG(("Error sending packet"));
2272 ske->status = SILC_SKE_STATUS_ERROR;
2273 silc_fsm_next(fsm, silc_ske_st_responder_error);
2274 return SILC_FSM_CONTINUE;
2277 silc_buffer_free(payload_buf);
2279 /* In case we are doing rekey move to finish it. */
2282 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2283 return SILC_FSM_CONTINUE;
2286 /** Waiting completion */
2287 silc_fsm_next(fsm, silc_ske_st_responder_end);
2288 return SILC_FSM_WAIT;
2291 /* Protocol completed */
2293 SILC_FSM_STATE(silc_ske_st_responder_end)
2295 SilcSKE ske = fsm_context;
2296 unsigned char tmp[4];
2297 SilcUInt32 hash_len, key_len, block_len;
2299 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2300 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2301 silc_ske_install_retransmission(ske);
2302 silc_packet_free(ske->packet);
2304 return SILC_FSM_WAIT;
2306 silc_packet_free(ske->packet);
2309 /* Process key material */
2310 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2311 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2312 hash_len = silc_hash_len(ske->prop->hash);
2313 ske->keymat = silc_ske_process_key_material(ske, block_len,
2317 /** Error processing key material */
2318 ske->status = SILC_SKE_STATUS_ERROR;
2319 silc_fsm_next(fsm, silc_ske_st_responder_error);
2320 return SILC_FSM_CONTINUE;
2323 /* Send SUCCESS packet */
2324 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2325 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2327 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2328 silc_schedule_task_del_by_context(ske->schedule, ske);
2330 /* Call completion */
2331 silc_ske_completion(ske);
2333 return SILC_FSM_FINISH;
2336 /* Aborted by application */
2338 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2340 SilcSKE ske = fsm_context;
2341 unsigned char tmp[4];
2343 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2345 /* Send FAILURE packet */
2346 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2347 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2349 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2350 silc_schedule_task_del_by_context(ske->schedule, ske);
2352 /* Call completion */
2353 silc_ske_completion(ske);
2355 return SILC_FSM_FINISH;
2358 /* Failure received from remote */
2360 SILC_FSM_STATE(silc_ske_st_responder_failure)
2362 SilcSKE ske = fsm_context;
2363 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2365 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2367 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2368 SILC_GET32_MSB(error, ske->packet->buffer.data);
2369 ske->status = error;
2370 silc_packet_free(ske->packet);
2374 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2375 silc_schedule_task_del_by_context(ske->schedule, ske);
2377 /* Call completion */
2378 silc_ske_completion(ske);
2380 return SILC_FSM_FINISH;
2383 /* Error occurred */
2385 SILC_FSM_STATE(silc_ske_st_responder_error)
2387 SilcSKE ske = fsm_context;
2388 unsigned char tmp[4];
2390 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2391 ske->status, silc_ske_map_status(ske->status)));
2393 /* Send FAILURE packet */
2394 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2395 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2396 SILC_PUT32_MSB(ske->status, tmp);
2397 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2399 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2400 silc_schedule_task_del_by_context(ske->schedule, ske);
2402 /* Call completion */
2403 silc_ske_completion(ske);
2405 return SILC_FSM_FINISH;
2408 /* Starts the protocol as responder. */
2410 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2411 SilcPacketStream stream,
2412 SilcSKEParams params)
2414 SILC_LOG_DEBUG(("Start SKE as responder"));
2416 if (!ske || !stream || !params || !params->version)
2419 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2422 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2425 ske->responder = TRUE;
2426 ske->flags = params->flags;
2427 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2428 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2429 ske->session_port = params->session_port;
2430 ske->version = strdup(params->version);
2433 ske->running = TRUE;
2435 /* Link to packet stream to get key exchange packets */
2436 ske->stream = stream;
2437 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2438 SILC_PACKET_KEY_EXCHANGE,
2439 SILC_PACKET_KEY_EXCHANGE_1,
2440 SILC_PACKET_SUCCESS,
2441 SILC_PACKET_FAILURE, -1);
2443 /* Start SKE as responder */
2444 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2449 /***************************** Initiator Rekey ******************************/
2453 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2455 SilcSKE ske = fsm_context;
2458 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2462 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2463 return SILC_FSM_CONTINUE;
2466 /* Add rekey exchange timeout */
2467 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2470 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2473 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2474 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2475 return SILC_FSM_CONTINUE;
2478 /* Send REKEY packet to start rekey protocol */
2479 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2480 /** Error sending packet */
2481 SILC_LOG_DEBUG(("Error sending packet"));
2482 ske->status = SILC_SKE_STATUS_ERROR;
2483 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2484 return SILC_FSM_CONTINUE;
2487 /* If doing rekey without PFS, move directly to the end of the protocol. */
2488 if (!ske->rekey->pfs) {
2489 /** Rekey without PFS */
2490 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2491 return SILC_FSM_CONTINUE;
2494 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2496 if (status != SILC_SKE_STATUS_OK) {
2497 /** Unknown group */
2498 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2499 return SILC_FSM_CONTINUE;
2502 /** Rekey with PFS */
2503 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2504 return SILC_FSM_CONTINUE;
2507 /* Sends REKEY_DONE packet to finish the protocol. */
2509 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2511 SilcSKE ske = fsm_context;
2512 SilcCipher send_key;
2515 SilcUInt32 key_len, block_len, hash_len, x_len;
2516 unsigned char *pfsbuf;
2518 SILC_LOG_DEBUG(("Start"));
2520 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2521 key_len = silc_cipher_get_key_len(send_key);
2522 block_len = silc_cipher_get_block_len(send_key);
2524 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2525 /** Cannot allocate hash */
2526 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2527 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2528 return SILC_FSM_CONTINUE;
2530 hash_len = silc_hash_len(hash);
2532 /* Process key material */
2533 if (ske->rekey->pfs) {
2535 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2537 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2540 memset(pfsbuf, 0, x_len);
2546 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2547 ske->rekey->enc_key_len / 8,
2553 SILC_LOG_ERROR(("Error processing key material"));
2554 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2555 return SILC_FSM_CONTINUE;
2558 ske->prop->cipher = send_key;
2559 ske->prop->hmac = hmac_send;
2560 ske->prop->hash = hash;
2562 /* Get sending keys */
2563 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2564 &hmac_send, NULL, NULL)) {
2565 /** Cannot get keys */
2566 ske->status = SILC_SKE_STATUS_ERROR;
2567 ske->prop->cipher = NULL;
2568 ske->prop->hmac = NULL;
2569 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2570 return SILC_FSM_CONTINUE;
2573 ske->prop->cipher = NULL;
2574 ske->prop->hmac = NULL;
2576 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2577 packet sent after this call will be protected with the new keys. */
2578 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2580 /** Cannot set keys */
2581 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2582 ske->status = SILC_SKE_STATUS_ERROR;
2583 silc_cipher_free(send_key);
2584 silc_hmac_free(hmac_send);
2585 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2586 return SILC_FSM_CONTINUE;
2589 /** Wait for REKEY_DONE */
2590 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2591 return SILC_FSM_WAIT;
2594 /* Rekey protocol end */
2596 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2598 SilcSKE ske = fsm_context;
2599 SilcCipher receive_key;
2600 SilcHmac hmac_receive;
2601 SilcSKERekeyMaterial rekey;
2603 SILC_LOG_DEBUG(("Start"));
2605 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2606 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2607 silc_packet_free(ske->packet);
2609 return SILC_FSM_WAIT;
2612 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2613 ske->prop->cipher = receive_key;
2614 ske->prop->hmac = hmac_receive;
2616 /* Get receiving keys */
2617 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2618 NULL, &hmac_receive, NULL)) {
2619 /** Cannot get keys */
2620 ske->status = SILC_SKE_STATUS_ERROR;
2621 ske->prop->cipher = NULL;
2622 ske->prop->hmac = NULL;
2623 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2624 return SILC_FSM_CONTINUE;
2627 /* Set new receiving keys into use. All packets received after this will
2628 be decrypted with the new keys. */
2629 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2630 hmac_receive, FALSE)) {
2631 /** Cannot set keys */
2632 SILC_LOG_DEBUG(("Cannot set new keys"));
2633 ske->status = SILC_SKE_STATUS_ERROR;
2634 silc_cipher_free(receive_key);
2635 silc_hmac_free(hmac_receive);
2636 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2637 return SILC_FSM_CONTINUE;
2640 SILC_LOG_DEBUG(("Rekey completed successfully"));
2642 /* Generate new rekey material */
2643 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2646 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2647 ske->prop->cipher = NULL;
2648 ske->prop->hmac = NULL;
2649 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2650 return SILC_FSM_CONTINUE;
2652 rekey->pfs = ske->rekey->pfs;
2655 ske->prop->cipher = NULL;
2656 ske->prop->hmac = NULL;
2657 silc_packet_free(ske->packet);
2659 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2660 silc_schedule_task_del_by_context(ske->schedule, ske);
2662 /* Call completion */
2663 silc_ske_completion(ske);
2665 return SILC_FSM_FINISH;
2668 /* Starts rekey protocol as initiator */
2671 silc_ske_rekey_initiator(SilcSKE ske,
2672 SilcPacketStream stream,
2673 SilcSKERekeyMaterial rekey)
2675 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2677 if (!ske || !stream || !rekey)
2680 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2683 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2687 ske->responder = FALSE;
2688 ske->running = TRUE;
2689 ske->rekeying = TRUE;
2691 /* Link to packet stream to get key exchange packets */
2692 ske->stream = stream;
2693 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2695 SILC_PACKET_REKEY_DONE,
2696 SILC_PACKET_KEY_EXCHANGE_2,
2697 SILC_PACKET_SUCCESS,
2698 SILC_PACKET_FAILURE, -1);
2700 /* Start SKE rekey as initiator */
2701 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2706 /***************************** Responder Rekey ******************************/
2708 /* Wait for initiator's packet */
2710 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2712 SilcSKE ske = fsm_context;
2714 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2718 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2719 return SILC_FSM_CONTINUE;
2722 /* Add rekey exchange timeout */
2723 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2726 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2728 /* If REKEY packet already received process it directly */
2729 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2730 return SILC_FSM_CONTINUE;
2732 /* Wait for REKEY */
2733 return SILC_FSM_WAIT;
2736 /* Process initiator's REKEY packet */
2738 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2740 SilcSKE ske = fsm_context;
2741 SilcSKEStatus status;
2743 SILC_LOG_DEBUG(("Start"));
2745 if (ske->packet->type != SILC_PACKET_REKEY) {
2746 ske->status = SILC_SKE_STATUS_ERROR;
2747 silc_packet_free(ske->packet);
2749 silc_fsm_next(fsm, silc_ske_st_responder_error);
2750 return SILC_FSM_CONTINUE;
2753 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2756 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2757 silc_fsm_next(fsm, silc_ske_st_responder_error);
2758 return SILC_FSM_CONTINUE;
2761 /* If doing rekey without PFS, move directly to the end of the protocol. */
2762 if (!ske->rekey->pfs) {
2763 /** Rekey without PFS */
2764 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2765 return SILC_FSM_CONTINUE;
2768 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2770 if (status != SILC_SKE_STATUS_OK) {
2771 /** Unknown group */
2772 silc_fsm_next(fsm, silc_ske_st_responder_error);
2773 return SILC_FSM_CONTINUE;
2776 /** Rekey with PFS */
2777 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2778 return SILC_FSM_WAIT;
2781 /* Sends REKEY_DONE packet to finish the protocol. */
2783 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2785 SilcSKE ske = fsm_context;
2786 SilcCipher send_key;
2789 SilcUInt32 key_len, block_len, hash_len, x_len;
2790 unsigned char *pfsbuf;
2792 SILC_LOG_DEBUG(("Start"));
2794 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2795 key_len = silc_cipher_get_key_len(send_key);
2796 block_len = silc_cipher_get_block_len(send_key);
2798 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2799 /** Cannot allocate hash */
2800 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2801 silc_fsm_next(fsm, silc_ske_st_responder_error);
2802 return SILC_FSM_CONTINUE;
2804 hash_len = silc_hash_len(hash);
2806 /* Process key material */
2807 if (ske->rekey->pfs) {
2809 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2811 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2814 memset(pfsbuf, 0, x_len);
2820 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2821 ske->rekey->enc_key_len / 8,
2827 SILC_LOG_ERROR(("Error processing key material"));
2828 silc_fsm_next(fsm, silc_ske_st_responder_error);
2829 return SILC_FSM_CONTINUE;
2832 ske->prop->cipher = send_key;
2833 ske->prop->hmac = hmac_send;
2834 ske->prop->hash = hash;
2836 /* Get sending keys */
2837 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2838 &hmac_send, NULL, NULL)) {
2839 /** Cannot get keys */
2840 ske->status = SILC_SKE_STATUS_ERROR;
2841 ske->prop->cipher = NULL;
2842 ske->prop->hmac = NULL;
2843 silc_fsm_next(fsm, silc_ske_st_responder_error);
2844 return SILC_FSM_CONTINUE;
2847 ske->prop->cipher = NULL;
2848 ske->prop->hmac = NULL;
2850 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2851 packet sent after this call will be protected with the new keys. */
2852 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2854 /** Cannot set keys */
2855 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2856 ske->status = SILC_SKE_STATUS_ERROR;
2857 silc_cipher_free(send_key);
2858 silc_hmac_free(hmac_send);
2859 silc_fsm_next(fsm, silc_ske_st_responder_error);
2860 return SILC_FSM_CONTINUE;
2863 /** Wait for REKEY_DONE */
2864 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2865 return SILC_FSM_WAIT;
2868 /* Rekey protocol end */
2870 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2872 SilcSKE ske = fsm_context;
2873 SilcCipher receive_key;
2874 SilcHmac hmac_receive;
2875 SilcSKERekeyMaterial rekey;
2877 SILC_LOG_DEBUG(("Start"));
2879 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2880 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2881 silc_packet_free(ske->packet);
2883 return SILC_FSM_WAIT;
2886 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2887 ske->prop->cipher = receive_key;
2888 ske->prop->hmac = hmac_receive;
2890 /* Get receiving keys */
2891 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2892 NULL, &hmac_receive, NULL)) {
2893 /** Cannot get keys */
2894 ske->status = SILC_SKE_STATUS_ERROR;
2895 ske->prop->cipher = NULL;
2896 ske->prop->hmac = NULL;
2897 silc_fsm_next(fsm, silc_ske_st_responder_error);
2898 return SILC_FSM_CONTINUE;
2901 /* Set new receiving keys into use. All packets received after this will
2902 be decrypted with the new keys. */
2903 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2904 hmac_receive, FALSE)) {
2905 /** Cannot set keys */
2906 SILC_LOG_DEBUG(("Cannot set new keys"));
2907 ske->status = SILC_SKE_STATUS_ERROR;
2908 ske->prop->cipher = NULL;
2909 ske->prop->hmac = NULL;
2910 silc_cipher_free(receive_key);
2911 silc_hmac_free(hmac_receive);
2912 silc_fsm_next(fsm, silc_ske_st_responder_error);
2913 return SILC_FSM_CONTINUE;
2916 SILC_LOG_DEBUG(("Rekey completed successfully"));
2918 /* Generate new rekey material */
2919 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2922 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2923 ske->prop->cipher = NULL;
2924 ske->prop->hmac = NULL;
2925 silc_fsm_next(fsm, silc_ske_st_responder_error);
2926 return SILC_FSM_CONTINUE;
2928 rekey->pfs = ske->rekey->pfs;
2931 ske->prop->cipher = NULL;
2932 ske->prop->hmac = NULL;
2933 silc_packet_free(ske->packet);
2935 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2936 silc_schedule_task_del_by_context(ske->schedule, ske);
2938 /* Call completion */
2939 silc_ske_completion(ske);
2941 return SILC_FSM_FINISH;
2944 /* Starts rekey protocol as responder */
2947 silc_ske_rekey_responder(SilcSKE ske,
2948 SilcPacketStream stream,
2949 SilcSKERekeyMaterial rekey,
2952 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2954 if (!ske || !stream || !rekey)
2957 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2960 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2964 ske->responder = TRUE;
2965 ske->running = TRUE;
2966 ske->rekeying = TRUE;
2967 ske->packet = packet;
2969 /* Link to packet stream to get key exchange packets */
2970 ske->stream = stream;
2971 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2973 SILC_PACKET_REKEY_DONE,
2974 SILC_PACKET_KEY_EXCHANGE_1,
2975 SILC_PACKET_SUCCESS,
2976 SILC_PACKET_FAILURE, -1);
2978 /* Start SKE rekey as responder */
2979 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2984 /* Processes the provided key material `data' as the SILC protocol
2985 specification defines. */
2988 silc_ske_process_key_material_data(unsigned char *data,
2989 SilcUInt32 data_len,
2990 SilcUInt32 req_iv_len,
2991 SilcUInt32 req_enc_key_len,
2992 SilcUInt32 req_hmac_key_len,
2996 unsigned char hashd[SILC_HASH_MAXLEN];
2997 SilcUInt32 hash_len = req_hmac_key_len;
2998 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2999 SilcSKEKeyMaterial key;
3001 SILC_LOG_DEBUG(("Start"));
3003 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3006 key = silc_calloc(1, sizeof(*key));
3010 buf = silc_buffer_alloc_size(1 + data_len);
3013 silc_buffer_format(buf,
3014 SILC_STR_UI_CHAR(0),
3015 SILC_STR_UI_XNSTRING(data, data_len),
3019 memset(hashd, 0, sizeof(hashd));
3021 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3022 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3023 memcpy(key->send_iv, hashd, req_iv_len);
3024 memset(hashd, 0, sizeof(hashd));
3026 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3027 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3028 memcpy(key->receive_iv, hashd, req_iv_len);
3029 key->iv_len = req_iv_len;
3031 /* Take the encryption keys. If requested key size is more than
3032 the size of hash length we will distribute more key material
3033 as protocol defines. */
3035 if (enc_key_len > hash_len) {
3037 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3038 k3[SILC_HASH_MAXLEN];
3039 unsigned char *dtmp;
3042 if (enc_key_len > (3 * hash_len))
3045 /* Take first round */
3046 memset(k1, 0, sizeof(k1));
3047 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3049 /* Take second round */
3050 dist = silc_buffer_alloc_size(data_len + hash_len);
3053 silc_buffer_format(dist,
3054 SILC_STR_UI_XNSTRING(data, data_len),
3055 SILC_STR_UI_XNSTRING(k1, hash_len),
3057 memset(k2, 0, sizeof(k2));
3058 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3060 /* Take third round */
3061 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3062 silc_buffer_pull_tail(dist, hash_len);
3063 silc_buffer_pull(dist, data_len + hash_len);
3064 silc_buffer_format(dist,
3065 SILC_STR_UI_XNSTRING(k2, hash_len),
3067 silc_buffer_push(dist, data_len + hash_len);
3068 memset(k3, 0, sizeof(k3));
3069 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3071 /* Then, save the keys */
3072 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3073 memcpy(dtmp, k1, hash_len);
3074 memcpy(dtmp + hash_len, k2, hash_len);
3075 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3077 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3078 memcpy(key->send_enc_key, dtmp, enc_key_len);
3079 key->enc_key_len = req_enc_key_len;
3081 memset(dtmp, 0, (3 * hash_len));
3082 memset(k1, 0, sizeof(k1));
3083 memset(k2, 0, sizeof(k2));
3084 memset(k3, 0, sizeof(k3));
3086 silc_buffer_clear(dist);
3087 silc_buffer_free(dist);
3089 /* Take normal hash as key */
3090 memset(hashd, 0, sizeof(hashd));
3091 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3092 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3093 memcpy(key->send_enc_key, hashd, enc_key_len);
3094 key->enc_key_len = req_enc_key_len;
3098 if (enc_key_len > hash_len) {
3100 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3101 k3[SILC_HASH_MAXLEN];
3102 unsigned char *dtmp;
3105 if (enc_key_len > (3 * hash_len))
3108 /* Take first round */
3109 memset(k1, 0, sizeof(k1));
3110 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3112 /* Take second round */
3113 dist = silc_buffer_alloc_size(data_len + hash_len);
3116 silc_buffer_format(dist,
3117 SILC_STR_UI_XNSTRING(data, data_len),
3118 SILC_STR_UI_XNSTRING(k1, hash_len),
3120 memset(k2, 0, sizeof(k2));
3121 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3123 /* Take third round */
3124 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3125 silc_buffer_pull_tail(dist, hash_len);
3126 silc_buffer_pull(dist, data_len + hash_len);
3127 silc_buffer_format(dist,
3128 SILC_STR_UI_XNSTRING(k2, hash_len),
3130 silc_buffer_push(dist, data_len + hash_len);
3131 memset(k3, 0, sizeof(k3));
3132 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3134 /* Then, save the keys */
3135 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3136 memcpy(dtmp, k1, hash_len);
3137 memcpy(dtmp + hash_len, k2, hash_len);
3138 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3140 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3141 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3142 key->enc_key_len = req_enc_key_len;
3144 memset(dtmp, 0, (3 * hash_len));
3145 memset(k1, 0, sizeof(k1));
3146 memset(k2, 0, sizeof(k2));
3147 memset(k3, 0, sizeof(k3));
3149 silc_buffer_clear(dist);
3150 silc_buffer_free(dist);
3152 /* Take normal hash as key */
3153 memset(hashd, 0, sizeof(hashd));
3154 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3155 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3156 memcpy(key->receive_enc_key, hashd, enc_key_len);
3157 key->enc_key_len = req_enc_key_len;
3160 /* Take HMAC keys */
3161 memset(hashd, 0, sizeof(hashd));
3163 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3164 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3165 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3166 memset(hashd, 0, sizeof(hashd));
3168 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3169 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3170 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3171 key->hmac_key_len = req_hmac_key_len;
3172 memset(hashd, 0, sizeof(hashd));
3174 silc_buffer_clear(buf);
3175 silc_buffer_free(buf);
3177 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3182 /* Processes negotiated key material as protocol specifies. This returns
3183 the actual keys to be used in the SILC. */
3186 silc_ske_process_key_material(SilcSKE ske,
3187 SilcUInt32 req_iv_len,
3188 SilcUInt32 req_enc_key_len,
3189 SilcUInt32 req_hmac_key_len,
3190 SilcSKERekeyMaterial *rekey)
3193 unsigned char *tmpbuf;
3195 SilcSKEKeyMaterial key;
3197 /* Encode KEY to binary data */
3198 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3200 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3203 silc_buffer_format(buf,
3204 SILC_STR_UI_XNSTRING(tmpbuf, klen),
3205 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
3208 /* Process the key material */
3209 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3210 req_iv_len, req_enc_key_len,
3214 memset(tmpbuf, 0, klen);
3216 silc_buffer_clear(buf);
3217 silc_buffer_free(buf);
3220 *rekey = silc_ske_make_rekey_material(ske, key);
3228 /* Free key material structure */
3230 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3236 silc_free(key->send_iv);
3237 if (key->receive_iv)
3238 silc_free(key->receive_iv);
3239 if (key->send_enc_key) {
3240 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3241 silc_free(key->send_enc_key);
3243 if (key->receive_enc_key) {
3244 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3245 silc_free(key->receive_enc_key);
3247 if (key->send_hmac_key) {
3248 memset(key->send_hmac_key, 0, key->hmac_key_len);
3249 silc_free(key->send_hmac_key);
3251 if (key->receive_hmac_key) {
3252 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3253 silc_free(key->receive_hmac_key);
3258 /* Free rekey material */
3260 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3264 if (rekey->send_enc_key) {
3265 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3266 silc_free(rekey->send_enc_key);
3268 silc_free(rekey->hash);
3272 /* Set keys into use */
3274 SilcBool silc_ske_set_keys(SilcSKE ske,
3275 SilcSKEKeyMaterial keymat,
3276 SilcSKESecurityProperties prop,
3277 SilcCipher *ret_send_key,
3278 SilcCipher *ret_receive_key,
3279 SilcHmac *ret_hmac_send,
3280 SilcHmac *ret_hmac_receive,
3283 unsigned char iv[32];
3284 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3286 /* Allocate ciphers to be used in the communication */
3288 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3292 if (ret_receive_key) {
3293 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3298 /* Allocate HMACs */
3299 if (ret_hmac_send) {
3300 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3304 if (ret_hmac_receive) {
3305 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3310 /* Set key material */
3311 memset(iv, 0, sizeof(iv));
3312 if (ske->responder) {
3314 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3315 keymat->enc_key_len, TRUE);
3317 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3318 memcpy(iv, ske->hash, 4);
3319 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3320 silc_cipher_set_iv(*ret_send_key, iv);
3322 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3325 if (ret_receive_key) {
3326 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3327 keymat->enc_key_len, FALSE);
3329 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3330 memcpy(iv, ske->hash, 4);
3331 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3332 silc_cipher_set_iv(*ret_receive_key, iv);
3334 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3338 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3339 keymat->hmac_key_len);
3340 if (ret_hmac_receive)
3341 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3342 keymat->hmac_key_len);
3345 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3346 keymat->enc_key_len, TRUE);
3348 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3349 memcpy(iv, ske->hash, 4);
3350 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3351 silc_cipher_set_iv(*ret_send_key, iv);
3353 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3356 if (ret_receive_key) {
3357 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3358 keymat->enc_key_len, FALSE);
3360 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3361 memcpy(iv, ske->hash, 4);
3362 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3363 silc_cipher_set_iv(*ret_receive_key, iv);
3365 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3369 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3370 keymat->hmac_key_len);
3371 if (ret_hmac_receive)
3372 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3373 keymat->hmac_key_len);
3378 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3385 const char *silc_ske_status_string[] =
3389 "Unexpected error occurred",
3390 "Bad payload in packet",
3391 "Unsupported group",
3392 "Unsupported cipher",
3394 "Unsupported hash function",
3396 "Unsupported public key (or certificate)",
3397 "Incorrect signature",
3398 "Bad or unsupported version",
3402 "Remote did not provide public key",
3403 "Bad reserved field in packet",
3404 "Bad payload length in packet",
3405 "Error computing signature",
3406 "System out of memory",
3407 "Key exchange timeout",
3412 /* Maps status to readable string and returns the string. If string is not
3413 found and empty character string ("") is returned. */
3415 const char *silc_ske_map_status(SilcSKEStatus status)
3419 for (i = 0; silc_ske_status_string[i]; i++)
3421 return silc_ske_status_string[i];
3426 /* Parses remote host's version string. */
3428 SilcBool silc_ske_parse_version(SilcSKE ske,
3429 SilcUInt32 *protocol_version,
3430 char **protocol_version_string,
3431 SilcUInt32 *software_version,
3432 char **software_version_string,
3433 char **vendor_version)
3435 return silc_parse_version_string(ske->remote_version,
3437 protocol_version_string,
3439 software_version_string,
3443 /* Get security properties */
3445 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3450 /* Get key material */
3452 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)