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 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2554 return SILC_FSM_CONTINUE;
2557 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2558 packet sent after this call will be protected with the new keys. */
2559 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2561 /** Cannot set keys */
2562 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2563 ske->status = SILC_SKE_STATUS_ERROR;
2564 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2565 return SILC_FSM_CONTINUE;
2568 /** Wait for REKEY_DONE */
2569 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2570 return SILC_FSM_WAIT;
2573 /* Rekey protocol end */
2575 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2577 SilcSKE ske = fsm_context;
2578 SilcCipher receive_key;
2579 SilcHmac hmac_receive;
2580 SilcSKERekeyMaterial rekey;
2582 SILC_LOG_DEBUG(("Start"));
2584 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2585 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2586 silc_packet_free(ske->packet);
2588 return SILC_FSM_WAIT;
2591 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2592 ske->prop->cipher = receive_key;
2593 ske->prop->hmac = hmac_receive;
2595 /* Get receiving keys */
2596 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2597 NULL, &hmac_receive, NULL)) {
2598 /** Cannot get keys */
2599 ske->status = SILC_SKE_STATUS_ERROR;
2600 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2601 return SILC_FSM_CONTINUE;
2604 /* Set new receiving keys into use. All packets received after this will
2605 be decrypted with the new keys. */
2606 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2607 hmac_receive, FALSE)) {
2608 /** Cannot set keys */
2609 SILC_LOG_DEBUG(("Cannot set new keys"));
2610 ske->status = SILC_SKE_STATUS_ERROR;
2611 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2612 return SILC_FSM_CONTINUE;
2615 SILC_LOG_DEBUG(("Rekey completed successfully"));
2617 /* Generate new rekey material */
2618 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2621 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2622 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2623 return SILC_FSM_CONTINUE;
2625 rekey->pfs = ske->rekey->pfs;
2628 ske->prop->cipher = NULL;
2629 ske->prop->hmac = NULL;
2630 silc_packet_free(ske->packet);
2632 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2633 silc_schedule_task_del_by_context(ske->schedule, ske);
2635 /* Call completion */
2636 silc_ske_completion(ske);
2638 return SILC_FSM_FINISH;
2641 /* Starts rekey protocol as initiator */
2644 silc_ske_rekey_initiator(SilcSKE ske,
2645 SilcPacketStream stream,
2646 SilcSKERekeyMaterial rekey)
2648 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2650 if (!ske || !stream || !rekey)
2653 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2656 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2660 ske->responder = FALSE;
2661 ske->running = TRUE;
2662 ske->rekeying = TRUE;
2664 /* Link to packet stream to get key exchange packets */
2665 ske->stream = stream;
2666 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2668 SILC_PACKET_REKEY_DONE,
2669 SILC_PACKET_KEY_EXCHANGE_2,
2670 SILC_PACKET_SUCCESS,
2671 SILC_PACKET_FAILURE, -1);
2673 /* Start SKE rekey as initiator */
2674 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2679 /***************************** Responder Rekey ******************************/
2681 /* Wait for initiator's packet */
2683 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2685 SilcSKE ske = fsm_context;
2687 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2691 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2692 return SILC_FSM_CONTINUE;
2695 /* Add rekey exchange timeout */
2696 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2700 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2702 /* If REKEY packet already received process it directly */
2703 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2704 return SILC_FSM_CONTINUE;
2706 /* Wait for REKEY */
2707 return SILC_FSM_WAIT;
2710 /* Process initiator's REKEY packet */
2712 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2714 SilcSKE ske = fsm_context;
2715 SilcSKEStatus status;
2717 SILC_LOG_DEBUG(("Start"));
2719 if (ske->packet->type != SILC_PACKET_REKEY) {
2720 ske->status = SILC_SKE_STATUS_ERROR;
2721 silc_packet_free(ske->packet);
2723 silc_fsm_next(fsm, silc_ske_st_responder_error);
2724 return SILC_FSM_CONTINUE;
2727 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2730 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2731 silc_fsm_next(fsm, silc_ske_st_responder_error);
2732 return SILC_FSM_CONTINUE;
2735 /* If doing rekey without PFS, move directly to the end of the protocol. */
2736 if (!ske->rekey->pfs) {
2737 /** Rekey without PFS */
2738 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2739 return SILC_FSM_CONTINUE;
2742 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2744 if (status != SILC_SKE_STATUS_OK) {
2745 /** Unknown group */
2746 silc_fsm_next(fsm, silc_ske_st_responder_error);
2747 return SILC_FSM_CONTINUE;
2750 /** Rekey with PFS */
2751 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2752 return SILC_FSM_WAIT;
2755 /* Sends REKEY_DONE packet to finish the protocol. */
2757 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2759 SilcSKE ske = fsm_context;
2760 SilcCipher send_key;
2763 SilcUInt32 key_len, block_len, hash_len, x_len;
2764 unsigned char *pfsbuf;
2766 SILC_LOG_DEBUG(("Start"));
2768 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2769 key_len = silc_cipher_get_key_len(send_key);
2770 block_len = silc_cipher_get_block_len(send_key);
2772 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2773 /** Cannot allocate hash */
2774 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2775 silc_fsm_next(fsm, silc_ske_st_responder_error);
2776 return SILC_FSM_CONTINUE;
2778 hash_len = silc_hash_len(hash);
2780 /* Process key material */
2781 if (ske->rekey->pfs) {
2783 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2785 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2788 memset(pfsbuf, 0, x_len);
2794 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2795 ske->rekey->enc_key_len / 8,
2801 SILC_LOG_ERROR(("Error processing key material"));
2802 silc_fsm_next(fsm, silc_ske_st_responder_error);
2803 return SILC_FSM_CONTINUE;
2806 ske->prop->cipher = send_key;
2807 ske->prop->hmac = hmac_send;
2808 ske->prop->hash = hash;
2810 /* Get sending keys */
2811 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2812 &hmac_send, NULL, NULL)) {
2813 /** Cannot get keys */
2814 ske->status = SILC_SKE_STATUS_ERROR;
2815 silc_fsm_next(fsm, silc_ske_st_responder_error);
2816 return SILC_FSM_CONTINUE;
2819 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2820 packet sent after this call will be protected with the new keys. */
2821 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2823 /** Cannot set keys */
2824 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2825 ske->status = SILC_SKE_STATUS_ERROR;
2826 silc_fsm_next(fsm, silc_ske_st_responder_error);
2827 return SILC_FSM_CONTINUE;
2830 /** Wait for REKEY_DONE */
2831 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2832 return SILC_FSM_WAIT;
2835 /* Rekey protocol end */
2837 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2839 SilcSKE ske = fsm_context;
2840 SilcCipher receive_key;
2841 SilcHmac hmac_receive;
2842 SilcSKERekeyMaterial rekey;
2844 SILC_LOG_DEBUG(("Start"));
2846 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2847 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2848 silc_packet_free(ske->packet);
2850 return SILC_FSM_WAIT;
2853 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2854 ske->prop->cipher = receive_key;
2855 ske->prop->hmac = hmac_receive;
2857 /* Get receiving keys */
2858 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2859 NULL, &hmac_receive, NULL)) {
2860 /** Cannot get keys */
2861 ske->status = SILC_SKE_STATUS_ERROR;
2862 silc_fsm_next(fsm, silc_ske_st_responder_error);
2863 return SILC_FSM_CONTINUE;
2866 /* Set new receiving keys into use. All packets received after this will
2867 be decrypted with the new keys. */
2868 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2869 hmac_receive, FALSE)) {
2870 /** Cannot set keys */
2871 SILC_LOG_DEBUG(("Cannot set new keys"));
2872 ske->status = SILC_SKE_STATUS_ERROR;
2873 silc_fsm_next(fsm, silc_ske_st_responder_error);
2874 return SILC_FSM_CONTINUE;
2877 SILC_LOG_DEBUG(("Rekey completed successfully"));
2879 /* Generate new rekey material */
2880 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2883 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2884 silc_fsm_next(fsm, silc_ske_st_responder_error);
2885 return SILC_FSM_CONTINUE;
2887 rekey->pfs = ske->rekey->pfs;
2890 ske->prop->cipher = NULL;
2891 ske->prop->hmac = NULL;
2892 silc_packet_free(ske->packet);
2894 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2895 silc_schedule_task_del_by_context(ske->schedule, ske);
2897 /* Call completion */
2898 silc_ske_completion(ske);
2900 return SILC_FSM_FINISH;
2903 /* Starts rekey protocol as responder */
2906 silc_ske_rekey_responder(SilcSKE ske,
2907 SilcPacketStream stream,
2908 SilcSKERekeyMaterial rekey,
2911 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2913 if (!ske || !stream || !rekey)
2916 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2919 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2923 ske->responder = TRUE;
2924 ske->running = TRUE;
2925 ske->rekeying = TRUE;
2926 ske->packet = packet;
2928 /* Link to packet stream to get key exchange packets */
2929 ske->stream = stream;
2930 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2932 SILC_PACKET_REKEY_DONE,
2933 SILC_PACKET_KEY_EXCHANGE_1,
2934 SILC_PACKET_SUCCESS,
2935 SILC_PACKET_FAILURE, -1);
2937 /* Start SKE rekey as responder */
2938 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2943 /* Processes the provided key material `data' as the SILC protocol
2944 specification defines. */
2947 silc_ske_process_key_material_data(unsigned char *data,
2948 SilcUInt32 data_len,
2949 SilcUInt32 req_iv_len,
2950 SilcUInt32 req_enc_key_len,
2951 SilcUInt32 req_hmac_key_len,
2955 unsigned char hashd[SILC_HASH_MAXLEN];
2956 SilcUInt32 hash_len = req_hmac_key_len;
2957 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2958 SilcSKEKeyMaterial key;
2960 SILC_LOG_DEBUG(("Start"));
2962 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2965 key = silc_calloc(1, sizeof(*key));
2969 buf = silc_buffer_alloc_size(1 + data_len);
2972 silc_buffer_format(buf,
2973 SILC_STR_UI_CHAR(0),
2974 SILC_STR_UI_XNSTRING(data, data_len),
2978 memset(hashd, 0, sizeof(hashd));
2980 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2981 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2982 memcpy(key->send_iv, hashd, req_iv_len);
2983 memset(hashd, 0, sizeof(hashd));
2985 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2986 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2987 memcpy(key->receive_iv, hashd, req_iv_len);
2988 key->iv_len = req_iv_len;
2990 /* Take the encryption keys. If requested key size is more than
2991 the size of hash length we will distribute more key material
2992 as protocol defines. */
2994 if (enc_key_len > hash_len) {
2996 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2997 k3[SILC_HASH_MAXLEN];
2998 unsigned char *dtmp;
3001 if (enc_key_len > (3 * hash_len))
3004 /* Take first round */
3005 memset(k1, 0, sizeof(k1));
3006 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3008 /* Take second round */
3009 dist = silc_buffer_alloc_size(data_len + hash_len);
3012 silc_buffer_format(dist,
3013 SILC_STR_UI_XNSTRING(data, data_len),
3014 SILC_STR_UI_XNSTRING(k1, hash_len),
3016 memset(k2, 0, sizeof(k2));
3017 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3019 /* Take third round */
3020 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3021 silc_buffer_pull_tail(dist, hash_len);
3022 silc_buffer_pull(dist, data_len + hash_len);
3023 silc_buffer_format(dist,
3024 SILC_STR_UI_XNSTRING(k2, hash_len),
3026 silc_buffer_push(dist, data_len + hash_len);
3027 memset(k3, 0, sizeof(k3));
3028 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3030 /* Then, save the keys */
3031 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3032 memcpy(dtmp, k1, hash_len);
3033 memcpy(dtmp + hash_len, k2, hash_len);
3034 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3036 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3037 memcpy(key->send_enc_key, dtmp, enc_key_len);
3038 key->enc_key_len = req_enc_key_len;
3040 memset(dtmp, 0, (3 * hash_len));
3041 memset(k1, 0, sizeof(k1));
3042 memset(k2, 0, sizeof(k2));
3043 memset(k3, 0, sizeof(k3));
3045 silc_buffer_clear(dist);
3046 silc_buffer_free(dist);
3048 /* Take normal hash as key */
3049 memset(hashd, 0, sizeof(hashd));
3050 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3051 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3052 memcpy(key->send_enc_key, hashd, enc_key_len);
3053 key->enc_key_len = req_enc_key_len;
3057 if (enc_key_len > hash_len) {
3059 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3060 k3[SILC_HASH_MAXLEN];
3061 unsigned char *dtmp;
3064 if (enc_key_len > (3 * hash_len))
3067 /* Take first round */
3068 memset(k1, 0, sizeof(k1));
3069 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3071 /* Take second round */
3072 dist = silc_buffer_alloc_size(data_len + hash_len);
3075 silc_buffer_format(dist,
3076 SILC_STR_UI_XNSTRING(data, data_len),
3077 SILC_STR_UI_XNSTRING(k1, hash_len),
3079 memset(k2, 0, sizeof(k2));
3080 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3082 /* Take third round */
3083 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3084 silc_buffer_pull_tail(dist, hash_len);
3085 silc_buffer_pull(dist, data_len + hash_len);
3086 silc_buffer_format(dist,
3087 SILC_STR_UI_XNSTRING(k2, hash_len),
3089 silc_buffer_push(dist, data_len + hash_len);
3090 memset(k3, 0, sizeof(k3));
3091 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3093 /* Then, save the keys */
3094 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3095 memcpy(dtmp, k1, hash_len);
3096 memcpy(dtmp + hash_len, k2, hash_len);
3097 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3099 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3100 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3101 key->enc_key_len = req_enc_key_len;
3103 memset(dtmp, 0, (3 * hash_len));
3104 memset(k1, 0, sizeof(k1));
3105 memset(k2, 0, sizeof(k2));
3106 memset(k3, 0, sizeof(k3));
3108 silc_buffer_clear(dist);
3109 silc_buffer_free(dist);
3111 /* Take normal hash as key */
3112 memset(hashd, 0, sizeof(hashd));
3113 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3114 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3115 memcpy(key->receive_enc_key, hashd, enc_key_len);
3116 key->enc_key_len = req_enc_key_len;
3119 /* Take HMAC keys */
3120 memset(hashd, 0, sizeof(hashd));
3122 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3123 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3124 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3125 memset(hashd, 0, sizeof(hashd));
3127 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3128 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3129 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3130 key->hmac_key_len = req_hmac_key_len;
3131 memset(hashd, 0, sizeof(hashd));
3133 silc_buffer_clear(buf);
3134 silc_buffer_free(buf);
3136 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3141 /* Processes negotiated key material as protocol specifies. This returns
3142 the actual keys to be used in the SILC. */
3145 silc_ske_process_key_material(SilcSKE ske,
3146 SilcUInt32 req_iv_len,
3147 SilcUInt32 req_enc_key_len,
3148 SilcUInt32 req_hmac_key_len,
3149 SilcSKERekeyMaterial *rekey)
3152 unsigned char *tmpbuf;
3154 SilcSKEKeyMaterial key;
3156 /* Encode KEY to binary data */
3157 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3159 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3162 silc_buffer_format(buf,
3163 SILC_STR_UI_XNSTRING(tmpbuf, klen),
3164 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
3167 /* Process the key material */
3168 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3169 req_iv_len, req_enc_key_len,
3173 memset(tmpbuf, 0, klen);
3175 silc_buffer_clear(buf);
3176 silc_buffer_free(buf);
3179 *rekey = silc_ske_make_rekey_material(ske, key);
3187 /* Free key material structure */
3189 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3195 silc_free(key->send_iv);
3196 if (key->receive_iv)
3197 silc_free(key->receive_iv);
3198 if (key->send_enc_key) {
3199 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3200 silc_free(key->send_enc_key);
3202 if (key->receive_enc_key) {
3203 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3204 silc_free(key->receive_enc_key);
3206 if (key->send_hmac_key) {
3207 memset(key->send_hmac_key, 0, key->hmac_key_len);
3208 silc_free(key->send_hmac_key);
3210 if (key->receive_hmac_key) {
3211 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3212 silc_free(key->receive_hmac_key);
3217 /* Free rekey material */
3219 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3223 if (rekey->send_enc_key) {
3224 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3225 silc_free(rekey->send_enc_key);
3227 silc_free(rekey->hash);
3231 /* Set keys into use */
3233 SilcBool silc_ske_set_keys(SilcSKE ske,
3234 SilcSKEKeyMaterial keymat,
3235 SilcSKESecurityProperties prop,
3236 SilcCipher *ret_send_key,
3237 SilcCipher *ret_receive_key,
3238 SilcHmac *ret_hmac_send,
3239 SilcHmac *ret_hmac_receive,
3242 unsigned char iv[32];
3243 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3245 /* Allocate ciphers to be used in the communication */
3247 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3251 if (ret_receive_key) {
3252 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3257 /* Allocate HMACs */
3258 if (ret_hmac_send) {
3259 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3263 if (ret_hmac_receive) {
3264 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3269 /* Set key material */
3270 memset(iv, 0, sizeof(iv));
3271 if (ske->responder) {
3273 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3274 keymat->enc_key_len, TRUE);
3276 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3277 memcpy(iv, ske->hash, 4);
3278 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3279 silc_cipher_set_iv(*ret_send_key, iv);
3281 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3284 if (ret_receive_key) {
3285 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3286 keymat->enc_key_len, FALSE);
3288 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3289 memcpy(iv, ske->hash, 4);
3290 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3291 silc_cipher_set_iv(*ret_receive_key, iv);
3293 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3297 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3298 keymat->hmac_key_len);
3299 if (ret_hmac_receive)
3300 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3301 keymat->hmac_key_len);
3304 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3305 keymat->enc_key_len, TRUE);
3307 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3308 memcpy(iv, ske->hash, 4);
3309 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3310 silc_cipher_set_iv(*ret_send_key, iv);
3312 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3315 if (ret_receive_key) {
3316 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3317 keymat->enc_key_len, FALSE);
3319 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3320 memcpy(iv, ske->hash, 4);
3321 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3322 silc_cipher_set_iv(*ret_receive_key, iv);
3324 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3328 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3329 keymat->hmac_key_len);
3330 if (ret_hmac_receive)
3331 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3332 keymat->hmac_key_len);
3337 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3344 const char *silc_ske_status_string[] =
3348 "Unexpected error occurred",
3349 "Bad payload in packet",
3350 "Unsupported group",
3351 "Unsupported cipher",
3353 "Unsupported hash function",
3355 "Unsupported public key (or certificate)",
3356 "Incorrect signature",
3357 "Bad or unsupported version",
3361 "Remote did not provide public key",
3362 "Bad reserved field in packet",
3363 "Bad payload length in packet",
3364 "Error computing signature",
3365 "System out of memory",
3366 "Key exchange timeout",
3371 /* Maps status to readable string and returns the string. If string is not
3372 found and empty character string ("") is returned. */
3374 const char *silc_ske_map_status(SilcSKEStatus status)
3378 for (i = 0; silc_ske_status_string[i]; i++)
3380 return silc_ske_status_string[i];
3385 /* Parses remote host's version string. */
3387 SilcBool silc_ske_parse_version(SilcSKE ske,
3388 SilcUInt32 *protocol_version,
3389 char **protocol_version_string,
3390 SilcUInt32 *software_version,
3391 char **software_version_string,
3392 char **vendor_version)
3394 return silc_parse_version_string(ske->remote_version,
3396 protocol_version_string,
3398 software_version_string,
3402 /* Get security properties */
3404 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3409 /* Get key material */
3411 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)