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;
1888 SILC_LOG_DEBUG(("Start"));
1890 /* Decode the payload */
1891 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1892 if (status != SILC_SKE_STATUS_OK) {
1893 /** Error decoding Start Payload */
1894 silc_packet_free(ske->packet);
1896 ske->status = status;
1897 silc_fsm_next(fsm, silc_ske_st_responder_error);
1898 return SILC_FSM_CONTINUE;
1901 /* Take a copy of the payload buffer for future use. It is used to
1902 compute the HASH value. */
1903 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1905 silc_packet_free(ske->packet);
1908 /* Force the mutual authentication flag if we want to do it. */
1909 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1910 SILC_LOG_DEBUG(("Force mutual authentication"));
1911 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1914 /* Force PFS flag if we require it */
1915 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1916 SILC_LOG_DEBUG(("Force PFS"));
1917 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1920 /* Disable IV Included flag if requested */
1921 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1922 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1923 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1924 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1927 /* Check and select security properties */
1928 status = silc_ske_select_security_properties(ske, remote_payload,
1930 if (status != SILC_SKE_STATUS_OK) {
1931 /** Error selecting proposal */
1932 silc_ske_payload_start_free(remote_payload);
1933 ske->status = status;
1934 silc_fsm_next(fsm, silc_ske_st_responder_error);
1935 return SILC_FSM_CONTINUE;
1938 silc_ske_payload_start_free(remote_payload);
1940 /* Encode our reply payload to send the selected security properties */
1941 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1943 if (status != SILC_SKE_STATUS_OK)
1946 /* Send the packet. */
1947 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1948 silc_buffer_data(packet_buf),
1949 silc_buffer_len(packet_buf)))
1952 silc_buffer_free(packet_buf);
1954 /** Waiting initiator's KE payload */
1955 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1956 return SILC_FSM_WAIT;
1959 if (ske->prop->group)
1960 silc_ske_group_free(ske->prop->group);
1961 if (ske->prop->cipher)
1962 silc_cipher_free(ske->prop->cipher);
1963 if (ske->prop->hash)
1964 silc_hash_free(ske->prop->hash);
1965 if (ske->prop->hmac)
1966 silc_hmac_free(ske->prop->hmac);
1967 silc_free(ske->prop);
1970 if (status == SILC_SKE_STATUS_OK)
1971 status = SILC_SKE_STATUS_ERROR;
1974 ske->status = status;
1975 silc_fsm_next(fsm, silc_ske_st_responder_error);
1976 return SILC_FSM_CONTINUE;
1979 /* Phase-2. Decode initiator's KE payload */
1981 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1983 SilcSKE ske = fsm_context;
1984 SilcSKEStatus status;
1985 SilcSKEKEPayload recv_payload;
1986 SilcBuffer packet_buf = &ske->packet->buffer;
1988 SILC_LOG_DEBUG(("Start"));
1990 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1991 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1992 silc_ske_install_retransmission(ske);
1993 silc_packet_free(ske->packet);
1995 return SILC_FSM_WAIT;
1998 /* Decode Key Exchange Payload */
1999 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2000 if (status != SILC_SKE_STATUS_OK) {
2001 /** Error decoding KE payload */
2002 silc_packet_free(ske->packet);
2004 ske->status = status;
2005 silc_fsm_next(fsm, silc_ske_st_responder_error);
2006 return SILC_FSM_CONTINUE;
2009 ske->ke1_payload = recv_payload;
2011 silc_packet_free(ske->packet);
2014 /* Verify the received public key and verify the signature if we are
2015 doing mutual authentication. */
2016 if (ske->start_payload &&
2017 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2019 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2021 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2023 /** Public key not provided */
2024 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2025 "certificate), even though we require it"));
2026 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2027 silc_fsm_next(fsm, silc_ske_st_responder_error);
2028 return SILC_FSM_CONTINUE;
2031 /* Decode the remote's public key */
2032 if (recv_payload->pk_data &&
2033 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2034 recv_payload->pk_data,
2035 recv_payload->pk_len,
2036 &ske->prop->public_key)) {
2037 /** Error decoding public key */
2038 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2039 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2040 silc_fsm_next(fsm, silc_ske_st_responder_error);
2041 return SILC_FSM_CONTINUE;
2044 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2046 SILC_LOG_DEBUG(("Verifying public key"));
2048 /** Waiting public key verification */
2049 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2051 /* If repository is provided, verify the key from there. */
2052 if (ske->repository) {
2055 find = silc_skr_find_alloc();
2057 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2058 silc_fsm_next(fsm, silc_ske_st_responder_error);
2059 return SILC_FSM_CONTINUE;
2061 silc_skr_find_set_pkcs_type(find,
2062 silc_pkcs_get_type(ske->prop->public_key));
2063 silc_skr_find_set_public_key(find, ske->prop->public_key);
2064 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2066 /* Find key from repository */
2067 SILC_FSM_CALL(silc_skr_find(ske->repository,
2068 silc_fsm_get_schedule(fsm), find,
2069 silc_ske_skr_callback, ske));
2071 /* Verify from application */
2072 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2073 ske->callbacks->context,
2074 silc_ske_pk_verified, NULL));
2080 /** Generate KE2 payload */
2081 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2082 return SILC_FSM_CONTINUE;
2085 /* Phase-4. Generate KE2 payload */
2087 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2089 SilcSKE ske = fsm_context;
2090 SilcSKEStatus status;
2091 SilcSKEKEPayload recv_payload, send_payload;
2096 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2097 return SILC_FSM_CONTINUE;
2100 /* Check result of public key verification */
2101 if (ske->status != SILC_SKE_STATUS_OK) {
2102 /** Public key not verified */
2103 SILC_LOG_DEBUG(("Public key verification failed"));
2104 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2105 return SILC_FSM_CONTINUE;
2108 recv_payload = ske->ke1_payload;
2110 /* The public key verification was performed only if the Mutual
2111 Authentication flag is set. */
2112 if (ske->start_payload &&
2113 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2114 unsigned char hash[SILC_HASH_MAXLEN];
2115 SilcUInt32 hash_len;
2117 SILC_LOG_DEBUG(("Public key is authentic"));
2119 /* Compute the hash value */
2120 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2121 if (status != SILC_SKE_STATUS_OK) {
2122 /** Error computing hash */
2123 ske->status = status;
2124 silc_fsm_next(fsm, silc_ske_st_responder_error);
2125 return SILC_FSM_CONTINUE;
2128 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2130 /* Verify signature */
2131 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2132 recv_payload->sign_len, hash, hash_len, NULL)) {
2133 /** Incorrect signature */
2134 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2135 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2136 silc_fsm_next(fsm, silc_ske_st_responder_error);
2137 return SILC_FSM_CONTINUE;
2140 SILC_LOG_DEBUG(("Signature is Ok"));
2142 memset(hash, 'F', hash_len);
2145 /* Create the random number x, 1 < x < q. */
2146 x = silc_calloc(1, sizeof(*x));
2149 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2150 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2152 if (status != SILC_SKE_STATUS_OK) {
2153 /** Error generating random number */
2156 ske->status = status;
2157 silc_fsm_next(fsm, silc_ske_st_responder_error);
2158 return SILC_FSM_CONTINUE;
2161 /* Save the results for later processing */
2162 send_payload = silc_calloc(1, sizeof(*send_payload));
2164 ske->ke2_payload = send_payload;
2166 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2168 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2169 silc_mp_init(&send_payload->x);
2170 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2171 &ske->prop->group->group);
2173 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2175 /* Compute the shared secret key */
2176 KEY = silc_calloc(1, sizeof(*KEY));
2178 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2179 &ske->prop->group->group);
2182 /** Send KE2 payload */
2183 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2184 return SILC_FSM_CONTINUE;
2187 /* Phase-5. Send KE2 payload */
2189 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2191 SilcSKE ske = fsm_context;
2192 SilcSKEStatus status;
2193 SilcBuffer payload_buf;
2194 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2195 SilcUInt32 hash_len, sign_len, pk_len;
2197 SILC_LOG_DEBUG(("Start"));
2199 if (ske->public_key && ske->private_key) {
2200 SILC_LOG_DEBUG(("Getting public key"));
2202 /* Get the public key */
2203 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2205 /** Error encoding public key */
2206 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2207 silc_fsm_next(fsm, silc_ske_st_responder_error);
2208 return SILC_FSM_CONTINUE;
2210 ske->ke2_payload->pk_data = pk;
2211 ske->ke2_payload->pk_len = pk_len;
2213 SILC_LOG_DEBUG(("Computing HASH value"));
2215 /* Compute the hash value */
2216 memset(hash, 0, sizeof(hash));
2217 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2218 if (status != SILC_SKE_STATUS_OK) {
2219 /** Error computing hash */
2220 ske->status = status;
2221 silc_fsm_next(fsm, silc_ske_st_responder_error);
2222 return SILC_FSM_CONTINUE;
2225 ske->hash = silc_memdup(hash, hash_len);
2226 ske->hash_len = hash_len;
2228 SILC_LOG_DEBUG(("Signing HASH value"));
2230 /* Sign the hash value */
2231 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2232 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2233 /** Error computing signature */
2234 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2235 silc_fsm_next(fsm, silc_ske_st_responder_error);
2236 return SILC_FSM_CONTINUE;
2238 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2239 ske->ke2_payload->sign_len = sign_len;
2240 memset(sign, 0, sizeof(sign));
2242 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2244 /* Encode the Key Exchange Payload */
2245 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2247 if (status != SILC_SKE_STATUS_OK) {
2248 /** Error encoding KE payload */
2249 ske->status = status;
2250 silc_fsm_next(fsm, silc_ske_st_responder_error);
2251 return SILC_FSM_CONTINUE;
2254 /* Send the packet. */
2255 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2256 payload_buf->data, silc_buffer_len(payload_buf))) {
2257 SILC_LOG_DEBUG(("Error sending packet"));
2258 ske->status = SILC_SKE_STATUS_ERROR;
2259 silc_fsm_next(fsm, silc_ske_st_responder_error);
2260 return SILC_FSM_CONTINUE;
2263 silc_buffer_free(payload_buf);
2265 /* In case we are doing rekey move to finish it. */
2268 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2269 return SILC_FSM_CONTINUE;
2272 /** Waiting completion */
2273 silc_fsm_next(fsm, silc_ske_st_responder_end);
2274 return SILC_FSM_WAIT;
2277 /* Protocol completed */
2279 SILC_FSM_STATE(silc_ske_st_responder_end)
2281 SilcSKE ske = fsm_context;
2282 unsigned char tmp[4];
2283 SilcUInt32 hash_len, key_len, block_len;
2285 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2286 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2287 silc_ske_install_retransmission(ske);
2288 silc_packet_free(ske->packet);
2290 return SILC_FSM_WAIT;
2292 silc_packet_free(ske->packet);
2295 /* Process key material */
2296 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2297 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2298 hash_len = silc_hash_len(ske->prop->hash);
2299 ske->keymat = silc_ske_process_key_material(ske, block_len,
2303 /** Error processing key material */
2304 ske->status = SILC_SKE_STATUS_ERROR;
2305 silc_fsm_next(fsm, silc_ske_st_responder_error);
2306 return SILC_FSM_CONTINUE;
2309 /* Send SUCCESS packet */
2310 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2311 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2313 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2314 silc_schedule_task_del_by_context(ske->schedule, ske);
2316 /* Call completion */
2317 silc_ske_completion(ske);
2319 return SILC_FSM_FINISH;
2322 /* Aborted by application */
2324 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2326 SilcSKE ske = fsm_context;
2327 unsigned char tmp[4];
2329 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2331 /* Send FAILURE packet */
2332 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2333 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2335 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2336 silc_schedule_task_del_by_context(ske->schedule, ske);
2338 /* Call completion */
2339 silc_ske_completion(ske);
2341 return SILC_FSM_FINISH;
2344 /* Failure received from remote */
2346 SILC_FSM_STATE(silc_ske_st_responder_failure)
2348 SilcSKE ske = fsm_context;
2349 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2351 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2353 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2354 SILC_GET32_MSB(error, ske->packet->buffer.data);
2355 ske->status = error;
2356 silc_packet_free(ske->packet);
2360 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2361 silc_schedule_task_del_by_context(ske->schedule, ske);
2363 /* Call completion */
2364 silc_ske_completion(ske);
2366 return SILC_FSM_FINISH;
2369 /* Error occurred */
2371 SILC_FSM_STATE(silc_ske_st_responder_error)
2373 SilcSKE ske = fsm_context;
2374 unsigned char tmp[4];
2376 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2377 ske->status, silc_ske_map_status(ske->status)));
2379 /* Send FAILURE packet */
2380 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2381 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2382 SILC_PUT32_MSB(ske->status, tmp);
2383 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2385 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2386 silc_schedule_task_del_by_context(ske->schedule, ske);
2388 /* Call completion */
2389 silc_ske_completion(ske);
2391 return SILC_FSM_FINISH;
2394 /* Starts the protocol as responder. */
2396 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2397 SilcPacketStream stream,
2398 SilcSKEParams params)
2400 SILC_LOG_DEBUG(("Start SKE as responder"));
2402 if (!ske || !stream || !params || !params->version)
2405 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2408 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2411 ske->responder = TRUE;
2412 ske->flags = params->flags;
2413 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2414 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2415 ske->session_port = params->session_port;
2416 ske->version = strdup(params->version);
2419 ske->running = TRUE;
2421 /* Link to packet stream to get key exchange packets */
2422 ske->stream = stream;
2423 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2424 SILC_PACKET_KEY_EXCHANGE,
2425 SILC_PACKET_KEY_EXCHANGE_1,
2426 SILC_PACKET_SUCCESS,
2427 SILC_PACKET_FAILURE, -1);
2429 /* Start SKE as responder */
2430 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2435 /***************************** Initiator Rekey ******************************/
2439 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2441 SilcSKE ske = fsm_context;
2444 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2448 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2449 return SILC_FSM_CONTINUE;
2452 /* Add rekey exchange timeout */
2453 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2456 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2459 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2460 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2461 return SILC_FSM_CONTINUE;
2464 /* Send REKEY packet to start rekey protocol */
2465 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2466 /** Error sending packet */
2467 SILC_LOG_DEBUG(("Error sending packet"));
2468 ske->status = SILC_SKE_STATUS_ERROR;
2469 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2470 return SILC_FSM_CONTINUE;
2473 /* If doing rekey without PFS, move directly to the end of the protocol. */
2474 if (!ske->rekey->pfs) {
2475 /** Rekey without PFS */
2476 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2477 return SILC_FSM_CONTINUE;
2480 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2482 if (status != SILC_SKE_STATUS_OK) {
2483 /** Unknown group */
2484 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2485 return SILC_FSM_CONTINUE;
2488 /** Rekey with PFS */
2489 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2490 return SILC_FSM_CONTINUE;
2493 /* Sends REKEY_DONE packet to finish the protocol. */
2495 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2497 SilcSKE ske = fsm_context;
2498 SilcCipher send_key;
2501 SilcUInt32 key_len, block_len, hash_len, x_len;
2502 unsigned char *pfsbuf;
2504 SILC_LOG_DEBUG(("Start"));
2506 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2507 key_len = silc_cipher_get_key_len(send_key);
2508 block_len = silc_cipher_get_block_len(send_key);
2510 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2511 /** Cannot allocate hash */
2512 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2513 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2514 return SILC_FSM_CONTINUE;
2516 hash_len = silc_hash_len(hash);
2518 /* Process key material */
2519 if (ske->rekey->pfs) {
2521 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2523 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2526 memset(pfsbuf, 0, x_len);
2532 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2533 ske->rekey->enc_key_len / 8,
2539 SILC_LOG_ERROR(("Error processing key material"));
2540 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2541 return SILC_FSM_CONTINUE;
2544 ske->prop->cipher = send_key;
2545 ske->prop->hmac = hmac_send;
2546 ske->prop->hash = hash;
2548 /* Get sending keys */
2549 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2550 &hmac_send, NULL, NULL)) {
2551 /** Cannot get keys */
2552 ske->status = SILC_SKE_STATUS_ERROR;
2553 ske->prop->cipher = NULL;
2554 ske->prop->hmac = NULL;
2555 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2556 return SILC_FSM_CONTINUE;
2559 ske->prop->cipher = NULL;
2560 ske->prop->hmac = NULL;
2562 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2563 packet sent after this call will be protected with the new keys. */
2564 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2566 /** Cannot set keys */
2567 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2568 ske->status = SILC_SKE_STATUS_ERROR;
2569 silc_cipher_free(send_key);
2570 silc_hmac_free(hmac_send);
2571 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2572 return SILC_FSM_CONTINUE;
2575 /** Wait for REKEY_DONE */
2576 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2577 return SILC_FSM_WAIT;
2580 /* Rekey protocol end */
2582 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2584 SilcSKE ske = fsm_context;
2585 SilcCipher receive_key;
2586 SilcHmac hmac_receive;
2587 SilcSKERekeyMaterial rekey;
2589 SILC_LOG_DEBUG(("Start"));
2591 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2592 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2593 silc_packet_free(ske->packet);
2595 return SILC_FSM_WAIT;
2598 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2599 ske->prop->cipher = receive_key;
2600 ske->prop->hmac = hmac_receive;
2602 /* Get receiving keys */
2603 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2604 NULL, &hmac_receive, NULL)) {
2605 /** Cannot get keys */
2606 ske->status = SILC_SKE_STATUS_ERROR;
2607 ske->prop->cipher = NULL;
2608 ske->prop->hmac = NULL;
2609 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2610 return SILC_FSM_CONTINUE;
2613 /* Set new receiving keys into use. All packets received after this will
2614 be decrypted with the new keys. */
2615 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2616 hmac_receive, FALSE)) {
2617 /** Cannot set keys */
2618 SILC_LOG_DEBUG(("Cannot set new keys"));
2619 ske->status = SILC_SKE_STATUS_ERROR;
2620 silc_cipher_free(receive_key);
2621 silc_hmac_free(hmac_receive);
2622 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2623 return SILC_FSM_CONTINUE;
2626 SILC_LOG_DEBUG(("Rekey completed successfully"));
2628 /* Generate new rekey material */
2629 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2632 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2633 ske->prop->cipher = NULL;
2634 ske->prop->hmac = NULL;
2635 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2636 return SILC_FSM_CONTINUE;
2638 rekey->pfs = ske->rekey->pfs;
2641 ske->prop->cipher = NULL;
2642 ske->prop->hmac = NULL;
2643 silc_packet_free(ske->packet);
2645 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2646 silc_schedule_task_del_by_context(ske->schedule, ske);
2648 /* Call completion */
2649 silc_ske_completion(ske);
2651 return SILC_FSM_FINISH;
2654 /* Starts rekey protocol as initiator */
2657 silc_ske_rekey_initiator(SilcSKE ske,
2658 SilcPacketStream stream,
2659 SilcSKERekeyMaterial rekey)
2661 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2663 if (!ske || !stream || !rekey)
2666 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2669 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2673 ske->responder = FALSE;
2674 ske->running = TRUE;
2675 ske->rekeying = TRUE;
2677 /* Link to packet stream to get key exchange packets */
2678 ske->stream = stream;
2679 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2681 SILC_PACKET_REKEY_DONE,
2682 SILC_PACKET_KEY_EXCHANGE_2,
2683 SILC_PACKET_SUCCESS,
2684 SILC_PACKET_FAILURE, -1);
2686 /* Start SKE rekey as initiator */
2687 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2692 /***************************** Responder Rekey ******************************/
2694 /* Wait for initiator's packet */
2696 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2698 SilcSKE ske = fsm_context;
2700 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2704 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2705 return SILC_FSM_CONTINUE;
2708 /* Add rekey exchange timeout */
2709 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2712 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2714 /* If REKEY packet already received process it directly */
2715 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2716 return SILC_FSM_CONTINUE;
2718 /* Wait for REKEY */
2719 return SILC_FSM_WAIT;
2722 /* Process initiator's REKEY packet */
2724 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2726 SilcSKE ske = fsm_context;
2727 SilcSKEStatus status;
2729 SILC_LOG_DEBUG(("Start"));
2731 if (ske->packet->type != SILC_PACKET_REKEY) {
2732 ske->status = SILC_SKE_STATUS_ERROR;
2733 silc_packet_free(ske->packet);
2735 silc_fsm_next(fsm, silc_ske_st_responder_error);
2736 return SILC_FSM_CONTINUE;
2739 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2742 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2743 silc_fsm_next(fsm, silc_ske_st_responder_error);
2744 return SILC_FSM_CONTINUE;
2747 /* If doing rekey without PFS, move directly to the end of the protocol. */
2748 if (!ske->rekey->pfs) {
2749 /** Rekey without PFS */
2750 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2751 return SILC_FSM_CONTINUE;
2754 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2756 if (status != SILC_SKE_STATUS_OK) {
2757 /** Unknown group */
2758 silc_fsm_next(fsm, silc_ske_st_responder_error);
2759 return SILC_FSM_CONTINUE;
2762 /** Rekey with PFS */
2763 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2764 return SILC_FSM_WAIT;
2767 /* Sends REKEY_DONE packet to finish the protocol. */
2769 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2771 SilcSKE ske = fsm_context;
2772 SilcCipher send_key;
2775 SilcUInt32 key_len, block_len, hash_len, x_len;
2776 unsigned char *pfsbuf;
2778 SILC_LOG_DEBUG(("Start"));
2780 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2781 key_len = silc_cipher_get_key_len(send_key);
2782 block_len = silc_cipher_get_block_len(send_key);
2784 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2785 /** Cannot allocate hash */
2786 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2787 silc_fsm_next(fsm, silc_ske_st_responder_error);
2788 return SILC_FSM_CONTINUE;
2790 hash_len = silc_hash_len(hash);
2792 /* Process key material */
2793 if (ske->rekey->pfs) {
2795 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2797 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2800 memset(pfsbuf, 0, x_len);
2806 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2807 ske->rekey->enc_key_len / 8,
2813 SILC_LOG_ERROR(("Error processing key material"));
2814 silc_fsm_next(fsm, silc_ske_st_responder_error);
2815 return SILC_FSM_CONTINUE;
2818 ske->prop->cipher = send_key;
2819 ske->prop->hmac = hmac_send;
2820 ske->prop->hash = hash;
2822 /* Get sending keys */
2823 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2824 &hmac_send, NULL, NULL)) {
2825 /** Cannot get keys */
2826 ske->status = SILC_SKE_STATUS_ERROR;
2827 ske->prop->cipher = NULL;
2828 ske->prop->hmac = NULL;
2829 silc_fsm_next(fsm, silc_ske_st_responder_error);
2830 return SILC_FSM_CONTINUE;
2833 ske->prop->cipher = NULL;
2834 ske->prop->hmac = NULL;
2836 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2837 packet sent after this call will be protected with the new keys. */
2838 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2840 /** Cannot set keys */
2841 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2842 ske->status = SILC_SKE_STATUS_ERROR;
2843 silc_cipher_free(send_key);
2844 silc_hmac_free(hmac_send);
2845 silc_fsm_next(fsm, silc_ske_st_responder_error);
2846 return SILC_FSM_CONTINUE;
2849 /** Wait for REKEY_DONE */
2850 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2851 return SILC_FSM_WAIT;
2854 /* Rekey protocol end */
2856 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2858 SilcSKE ske = fsm_context;
2859 SilcCipher receive_key;
2860 SilcHmac hmac_receive;
2861 SilcSKERekeyMaterial rekey;
2863 SILC_LOG_DEBUG(("Start"));
2865 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2866 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2867 silc_packet_free(ske->packet);
2869 return SILC_FSM_WAIT;
2872 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2873 ske->prop->cipher = receive_key;
2874 ske->prop->hmac = hmac_receive;
2876 /* Get receiving keys */
2877 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2878 NULL, &hmac_receive, NULL)) {
2879 /** Cannot get keys */
2880 ske->status = SILC_SKE_STATUS_ERROR;
2881 ske->prop->cipher = NULL;
2882 ske->prop->hmac = NULL;
2883 silc_fsm_next(fsm, silc_ske_st_responder_error);
2884 return SILC_FSM_CONTINUE;
2887 /* Set new receiving keys into use. All packets received after this will
2888 be decrypted with the new keys. */
2889 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2890 hmac_receive, FALSE)) {
2891 /** Cannot set keys */
2892 SILC_LOG_DEBUG(("Cannot set new keys"));
2893 ske->status = SILC_SKE_STATUS_ERROR;
2894 ske->prop->cipher = NULL;
2895 ske->prop->hmac = NULL;
2896 silc_cipher_free(receive_key);
2897 silc_hmac_free(hmac_receive);
2898 silc_fsm_next(fsm, silc_ske_st_responder_error);
2899 return SILC_FSM_CONTINUE;
2902 SILC_LOG_DEBUG(("Rekey completed successfully"));
2904 /* Generate new rekey material */
2905 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2908 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2909 ske->prop->cipher = NULL;
2910 ske->prop->hmac = NULL;
2911 silc_fsm_next(fsm, silc_ske_st_responder_error);
2912 return SILC_FSM_CONTINUE;
2914 rekey->pfs = ske->rekey->pfs;
2917 ske->prop->cipher = NULL;
2918 ske->prop->hmac = NULL;
2919 silc_packet_free(ske->packet);
2921 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2922 silc_schedule_task_del_by_context(ske->schedule, ske);
2924 /* Call completion */
2925 silc_ske_completion(ske);
2927 return SILC_FSM_FINISH;
2930 /* Starts rekey protocol as responder */
2933 silc_ske_rekey_responder(SilcSKE ske,
2934 SilcPacketStream stream,
2935 SilcSKERekeyMaterial rekey,
2938 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2940 if (!ske || !stream || !rekey)
2943 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2946 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2950 ske->responder = TRUE;
2951 ske->running = TRUE;
2952 ske->rekeying = TRUE;
2953 ske->packet = packet;
2955 /* Link to packet stream to get key exchange packets */
2956 ske->stream = stream;
2957 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2959 SILC_PACKET_REKEY_DONE,
2960 SILC_PACKET_KEY_EXCHANGE_1,
2961 SILC_PACKET_SUCCESS,
2962 SILC_PACKET_FAILURE, -1);
2964 /* Start SKE rekey as responder */
2965 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2970 /* Processes the provided key material `data' as the SILC protocol
2971 specification defines. */
2974 silc_ske_process_key_material_data(unsigned char *data,
2975 SilcUInt32 data_len,
2976 SilcUInt32 req_iv_len,
2977 SilcUInt32 req_enc_key_len,
2978 SilcUInt32 req_hmac_key_len,
2982 unsigned char hashd[SILC_HASH_MAXLEN];
2983 SilcUInt32 hash_len = req_hmac_key_len;
2984 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2985 SilcSKEKeyMaterial key;
2987 SILC_LOG_DEBUG(("Start"));
2989 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2992 key = silc_calloc(1, sizeof(*key));
2996 buf = silc_buffer_alloc_size(1 + data_len);
2999 silc_buffer_format(buf,
3000 SILC_STR_UI_CHAR(0),
3001 SILC_STR_UI_XNSTRING(data, data_len),
3005 memset(hashd, 0, sizeof(hashd));
3007 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3008 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3009 memcpy(key->send_iv, hashd, req_iv_len);
3010 memset(hashd, 0, sizeof(hashd));
3012 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3013 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3014 memcpy(key->receive_iv, hashd, req_iv_len);
3015 key->iv_len = req_iv_len;
3017 /* Take the encryption keys. If requested key size is more than
3018 the size of hash length we will distribute more key material
3019 as protocol defines. */
3021 if (enc_key_len > hash_len) {
3023 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3024 k3[SILC_HASH_MAXLEN];
3025 unsigned char *dtmp;
3028 if (enc_key_len > (3 * hash_len))
3031 /* Take first round */
3032 memset(k1, 0, sizeof(k1));
3033 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3035 /* Take second round */
3036 dist = silc_buffer_alloc_size(data_len + hash_len);
3039 silc_buffer_format(dist,
3040 SILC_STR_UI_XNSTRING(data, data_len),
3041 SILC_STR_UI_XNSTRING(k1, hash_len),
3043 memset(k2, 0, sizeof(k2));
3044 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3046 /* Take third round */
3047 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3048 silc_buffer_pull_tail(dist, hash_len);
3049 silc_buffer_pull(dist, data_len + hash_len);
3050 silc_buffer_format(dist,
3051 SILC_STR_UI_XNSTRING(k2, hash_len),
3053 silc_buffer_push(dist, data_len + hash_len);
3054 memset(k3, 0, sizeof(k3));
3055 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3057 /* Then, save the keys */
3058 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3059 memcpy(dtmp, k1, hash_len);
3060 memcpy(dtmp + hash_len, k2, hash_len);
3061 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3063 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3064 memcpy(key->send_enc_key, dtmp, enc_key_len);
3065 key->enc_key_len = req_enc_key_len;
3067 memset(dtmp, 0, (3 * hash_len));
3068 memset(k1, 0, sizeof(k1));
3069 memset(k2, 0, sizeof(k2));
3070 memset(k3, 0, sizeof(k3));
3072 silc_buffer_clear(dist);
3073 silc_buffer_free(dist);
3075 /* Take normal hash as key */
3076 memset(hashd, 0, sizeof(hashd));
3077 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3078 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3079 memcpy(key->send_enc_key, hashd, enc_key_len);
3080 key->enc_key_len = req_enc_key_len;
3084 if (enc_key_len > hash_len) {
3086 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3087 k3[SILC_HASH_MAXLEN];
3088 unsigned char *dtmp;
3091 if (enc_key_len > (3 * hash_len))
3094 /* Take first round */
3095 memset(k1, 0, sizeof(k1));
3096 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3098 /* Take second round */
3099 dist = silc_buffer_alloc_size(data_len + hash_len);
3102 silc_buffer_format(dist,
3103 SILC_STR_UI_XNSTRING(data, data_len),
3104 SILC_STR_UI_XNSTRING(k1, hash_len),
3106 memset(k2, 0, sizeof(k2));
3107 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3109 /* Take third round */
3110 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3111 silc_buffer_pull_tail(dist, hash_len);
3112 silc_buffer_pull(dist, data_len + hash_len);
3113 silc_buffer_format(dist,
3114 SILC_STR_UI_XNSTRING(k2, hash_len),
3116 silc_buffer_push(dist, data_len + hash_len);
3117 memset(k3, 0, sizeof(k3));
3118 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3120 /* Then, save the keys */
3121 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3122 memcpy(dtmp, k1, hash_len);
3123 memcpy(dtmp + hash_len, k2, hash_len);
3124 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3126 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3127 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3128 key->enc_key_len = req_enc_key_len;
3130 memset(dtmp, 0, (3 * hash_len));
3131 memset(k1, 0, sizeof(k1));
3132 memset(k2, 0, sizeof(k2));
3133 memset(k3, 0, sizeof(k3));
3135 silc_buffer_clear(dist);
3136 silc_buffer_free(dist);
3138 /* Take normal hash as key */
3139 memset(hashd, 0, sizeof(hashd));
3140 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3141 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3142 memcpy(key->receive_enc_key, hashd, enc_key_len);
3143 key->enc_key_len = req_enc_key_len;
3146 /* Take HMAC keys */
3147 memset(hashd, 0, sizeof(hashd));
3149 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3150 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3151 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3152 memset(hashd, 0, sizeof(hashd));
3154 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3155 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3156 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3157 key->hmac_key_len = req_hmac_key_len;
3158 memset(hashd, 0, sizeof(hashd));
3160 silc_buffer_clear(buf);
3161 silc_buffer_free(buf);
3163 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3168 /* Processes negotiated key material as protocol specifies. This returns
3169 the actual keys to be used in the SILC. */
3172 silc_ske_process_key_material(SilcSKE ske,
3173 SilcUInt32 req_iv_len,
3174 SilcUInt32 req_enc_key_len,
3175 SilcUInt32 req_hmac_key_len,
3176 SilcSKERekeyMaterial *rekey)
3179 unsigned char *tmpbuf;
3181 SilcSKEKeyMaterial key;
3183 /* Encode KEY to binary data */
3184 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3186 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3189 silc_buffer_format(buf,
3190 SILC_STR_UI_XNSTRING(tmpbuf, klen),
3191 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
3194 /* Process the key material */
3195 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3196 req_iv_len, req_enc_key_len,
3200 memset(tmpbuf, 0, klen);
3202 silc_buffer_clear(buf);
3203 silc_buffer_free(buf);
3206 *rekey = silc_ske_make_rekey_material(ske, key);
3214 /* Free key material structure */
3216 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3222 silc_free(key->send_iv);
3223 if (key->receive_iv)
3224 silc_free(key->receive_iv);
3225 if (key->send_enc_key) {
3226 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3227 silc_free(key->send_enc_key);
3229 if (key->receive_enc_key) {
3230 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3231 silc_free(key->receive_enc_key);
3233 if (key->send_hmac_key) {
3234 memset(key->send_hmac_key, 0, key->hmac_key_len);
3235 silc_free(key->send_hmac_key);
3237 if (key->receive_hmac_key) {
3238 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3239 silc_free(key->receive_hmac_key);
3244 /* Free rekey material */
3246 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3250 if (rekey->send_enc_key) {
3251 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3252 silc_free(rekey->send_enc_key);
3254 silc_free(rekey->hash);
3258 /* Set keys into use */
3260 SilcBool silc_ske_set_keys(SilcSKE ske,
3261 SilcSKEKeyMaterial keymat,
3262 SilcSKESecurityProperties prop,
3263 SilcCipher *ret_send_key,
3264 SilcCipher *ret_receive_key,
3265 SilcHmac *ret_hmac_send,
3266 SilcHmac *ret_hmac_receive,
3269 unsigned char iv[32];
3270 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3272 /* Allocate ciphers to be used in the communication */
3274 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3278 if (ret_receive_key) {
3279 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3284 /* Allocate HMACs */
3285 if (ret_hmac_send) {
3286 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3290 if (ret_hmac_receive) {
3291 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3296 /* Set key material */
3297 memset(iv, 0, sizeof(iv));
3298 if (ske->responder) {
3300 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3301 keymat->enc_key_len, TRUE);
3303 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3304 memcpy(iv, ske->hash, 4);
3305 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3306 silc_cipher_set_iv(*ret_send_key, iv);
3308 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3311 if (ret_receive_key) {
3312 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3313 keymat->enc_key_len, FALSE);
3315 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3316 memcpy(iv, ske->hash, 4);
3317 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3318 silc_cipher_set_iv(*ret_receive_key, iv);
3320 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3324 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3325 keymat->hmac_key_len);
3326 if (ret_hmac_receive)
3327 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3328 keymat->hmac_key_len);
3331 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3332 keymat->enc_key_len, TRUE);
3334 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3335 memcpy(iv, ske->hash, 4);
3336 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3337 silc_cipher_set_iv(*ret_send_key, iv);
3339 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3342 if (ret_receive_key) {
3343 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3344 keymat->enc_key_len, FALSE);
3346 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3347 memcpy(iv, ske->hash, 4);
3348 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3349 silc_cipher_set_iv(*ret_receive_key, iv);
3351 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3355 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3356 keymat->hmac_key_len);
3357 if (ret_hmac_receive)
3358 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3359 keymat->hmac_key_len);
3364 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3371 const char *silc_ske_status_string[] =
3375 "Unexpected error occurred",
3376 "Bad payload in packet",
3377 "Unsupported group",
3378 "Unsupported cipher",
3380 "Unsupported hash function",
3382 "Unsupported public key (or certificate)",
3383 "Incorrect signature",
3384 "Bad or unsupported version",
3388 "Remote did not provide public key",
3389 "Bad reserved field in packet",
3390 "Bad payload length in packet",
3391 "Error computing signature",
3392 "System out of memory",
3393 "Key exchange timeout",
3398 /* Maps status to readable string and returns the string. If string is not
3399 found and empty character string ("") is returned. */
3401 const char *silc_ske_map_status(SilcSKEStatus status)
3405 for (i = 0; silc_ske_status_string[i]; i++)
3407 return silc_ske_status_string[i];
3412 /* Parses remote host's version string. */
3414 SilcBool silc_ske_parse_version(SilcSKE ske,
3415 SilcUInt32 *protocol_version,
3416 char **protocol_version_string,
3417 SilcUInt32 *software_version,
3418 char **software_version_string,
3419 char **vendor_version)
3421 return silc_parse_version_string(ske->remote_version,
3423 protocol_version_string,
3425 software_version_string,
3429 /* Get security properties */
3431 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3436 /* Get key material */
3438 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)