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, *s_data;
675 SilcUInt32 e_len, f_len, KEY_len, s_len;
678 SILC_LOG_DEBUG(("Start"));
680 if (initiator == FALSE) {
681 s_data = (ske->start_payload_copy ?
682 silc_buffer_data(ske->start_payload_copy) : NULL);
683 s_len = (ske->start_payload_copy ?
684 silc_buffer_len(ske->start_payload_copy) : 0);
685 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
686 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
687 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
689 /* Format the buffer used to compute the hash value */
690 buf = silc_buffer_alloc_size(s_len +
691 ske->ke2_payload->pk_len +
692 ske->ke1_payload->pk_len +
693 e_len + f_len + KEY_len);
695 return SILC_SKE_STATUS_OUT_OF_MEMORY;
697 /* Initiator is not required to send its public key */
698 if (!ske->ke1_payload->pk_data) {
700 silc_buffer_format(buf,
701 SILC_STR_DATA(s_data, s_len),
702 SILC_STR_DATA(ske->ke2_payload->pk_data,
703 ske->ke2_payload->pk_len),
704 SILC_STR_DATA(e, e_len),
705 SILC_STR_DATA(f, f_len),
706 SILC_STR_DATA(KEY, KEY_len),
710 silc_buffer_format(buf,
711 SILC_STR_DATA(s_data, s_len),
712 SILC_STR_DATA(ske->ke2_payload->pk_data,
713 ske->ke2_payload->pk_len),
714 SILC_STR_DATA(ske->ke1_payload->pk_data,
715 ske->ke1_payload->pk_len),
716 SILC_STR_DATA(e, e_len),
717 SILC_STR_DATA(f, f_len),
718 SILC_STR_DATA(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 s_data = (ske->start_payload_copy ?
740 silc_buffer_data(ske->start_payload_copy) : NULL);
741 s_len = (ske->start_payload_copy ?
742 silc_buffer_len(ske->start_payload_copy) : 0);
743 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
745 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
747 return SILC_SKE_STATUS_OUT_OF_MEMORY;
749 /* Format the buffer used to compute the hash value */
751 silc_buffer_format(buf,
752 SILC_STR_DATA(s_data, s_len),
753 SILC_STR_DATA(ske->ke1_payload->pk_data,
754 ske->ke1_payload->pk_len),
755 SILC_STR_DATA(e, e_len),
758 silc_buffer_free(buf);
761 return SILC_SKE_STATUS_ERROR;
764 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
771 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
773 *return_hash_len = silc_hash_len(ske->prop->hash);
775 if (initiator == FALSE) {
776 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
778 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
781 silc_buffer_free(buf);
786 /* Generate rekey material */
788 static SilcSKERekeyMaterial
789 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
791 SilcSKERekeyMaterial rekey;
794 /* Create rekey material */
795 rekey = silc_calloc(1, sizeof(*rekey));
800 if (ske->prop->group)
801 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
802 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
803 hash = silc_hash_get_name(ske->prop->hash);
804 rekey->hash = silc_memdup(hash, strlen(hash));
809 if (rekey->pfs == FALSE) {
810 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
811 keymat->enc_key_len / 8);
812 if (!rekey->send_enc_key) {
816 rekey->enc_key_len = keymat->enc_key_len;
822 /* Assembles security properties */
824 static SilcSKEStartPayload
825 silc_ske_assemble_security_properties(SilcSKE ske,
826 SilcSKESecurityPropertyFlag flags,
829 SilcSKEStartPayload rp;
832 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
834 rp = silc_calloc(1, sizeof(*rp));
837 rp->flags = (unsigned char)flags;
839 /* Set random cookie */
840 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
841 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
842 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
843 rp->cookie_len = SILC_SKE_COOKIE_LEN;
845 /* In case IV included flag and session port is set the first 16-bits of
846 cookie will include our session port. */
847 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
848 SILC_PUT16_MSB(ske->session_port, rp->cookie);
851 rp->version = strdup(version);
852 rp->version_len = strlen(version);
854 /* Get supported Key Exhange groups */
855 rp->ke_grp_list = silc_ske_get_supported_groups();
856 rp->ke_grp_len = strlen(rp->ke_grp_list);
858 /* Get supported PKCS algorithms */
859 rp->pkcs_alg_list = silc_pkcs_get_supported();
860 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
862 /* Get supported encryption algorithms */
863 rp->enc_alg_list = silc_cipher_get_supported();
864 rp->enc_alg_len = strlen(rp->enc_alg_list);
866 /* Get supported hash algorithms */
867 rp->hash_alg_list = silc_hash_get_supported();
868 rp->hash_alg_len = strlen(rp->hash_alg_list);
870 /* Get supported HMACs */
871 rp->hmac_alg_list = silc_hmac_get_supported();
872 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
875 /* Get supported compression algorithms */
876 rp->comp_alg_list = strdup("none");
877 rp->comp_alg_len = strlen("none");
879 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
880 2 + rp->version_len +
881 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
882 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
883 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
888 /* Packet retransmission callback. */
890 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
892 SilcSKE ske = context;
894 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
896 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
897 ske->retry_count = 0;
898 ske->retry_timer = SILC_SKE_RETRY_MIN;
899 silc_free(ske->retrans.data);
900 ske->retrans.data = NULL;
901 ske->status = SILC_SKE_STATUS_TIMEOUT;
903 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
905 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
906 silc_fsm_continue_sync(&ske->fsm);
910 SILC_LOG_DEBUG(("Retransmitting packet"));
911 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
912 ske->retrans.data, ske->retrans.data_len);
915 /* Install retransmission timer */
917 static void silc_ske_install_retransmission(SilcSKE ske)
919 if (!silc_packet_stream_is_udp(ske->stream))
922 if (ske->retrans.data) {
923 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
925 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
926 ske, ske->retry_timer, 0);
928 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
929 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
932 /* Sends SILC packet. Handles retransmissions with UDP streams. */
934 static SilcBool silc_ske_packet_send(SilcSKE ske,
936 SilcPacketFlags flags,
937 const unsigned char *data,
942 /* Send the packet */
943 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
945 if (silc_packet_stream_is_udp(ske->stream) &&
946 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
947 silc_free(ske->retrans.data);
948 ske->retrans.type = type;
949 ske->retrans.flags = flags;
950 ske->retrans.data = silc_memdup(data, data_len);
951 ske->retrans.data_len = data_len;
952 silc_ske_install_retransmission(ske);
958 /* Calls completion callback. Completion is called always in this function
959 and must not be called anywhere else. */
961 static void silc_ske_completion(SilcSKE ske)
963 /* Call the completion callback */
964 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
965 if (ske->status != SILC_SKE_STATUS_OK)
966 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
967 ske->callbacks->context);
969 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
970 ske->rekey, ske->callbacks->context);
974 /* SKE FSM destructor. */
976 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
977 void *destructor_context)
979 SilcSKE ske = fsm_context;
980 ske->running = FALSE;
985 /* Key exchange timeout task callback */
987 SILC_TASK_CALLBACK(silc_ske_timeout)
989 SilcSKE ske = context;
991 SILC_LOG_DEBUG(("Timeout"));
994 ske->status = SILC_SKE_STATUS_TIMEOUT;
996 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
998 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1000 silc_fsm_continue_sync(&ske->fsm);
1003 /******************************* Protocol API *******************************/
1005 /* Allocates new SKE object. */
1007 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1008 SilcSKR repository, SilcPublicKey public_key,
1009 SilcPrivateKey private_key, void *context)
1013 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1015 if (!rng || !schedule)
1019 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1023 ske = silc_calloc(1, sizeof(*ske));
1026 ske->status = SILC_SKE_STATUS_OK;
1028 ske->repository = repository;
1029 ske->user_data = context;
1030 ske->schedule = schedule;
1031 ske->public_key = public_key;
1032 ske->private_key = private_key;
1033 ske->retry_timer = SILC_SKE_RETRY_MIN;
1039 /* Free's SKE object. */
1041 void silc_ske_free(SilcSKE ske)
1043 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1052 /* If already aborted, destroy the session immediately */
1054 ske->status = SILC_SKE_STATUS_ERROR;
1056 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1058 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1059 silc_fsm_continue_sync(&ske->fsm);
1065 if (ske->refcnt > 0)
1068 /* Free start payload */
1069 if (ske->start_payload)
1070 silc_ske_payload_start_free(ske->start_payload);
1072 /* Free KE payload */
1073 if (ske->ke1_payload)
1074 silc_ske_payload_ke_free(ske->ke1_payload);
1075 if (ske->ke2_payload)
1076 silc_ske_payload_ke_free(ske->ke2_payload);
1077 silc_free(ske->remote_version);
1081 if (ske->prop->group)
1082 silc_ske_group_free(ske->prop->group);
1083 if (ske->prop->cipher)
1084 silc_cipher_free(ske->prop->cipher);
1085 if (ske->prop->hash)
1086 silc_hash_free(ske->prop->hash);
1087 if (ske->prop->hmac)
1088 silc_hmac_free(ske->prop->hmac);
1089 if (ske->prop->public_key)
1090 silc_pkcs_public_key_free(ske->prop->public_key);
1091 silc_free(ske->prop);
1094 silc_ske_free_key_material(ske->keymat);
1095 if (ske->start_payload_copy)
1096 silc_buffer_free(ske->start_payload_copy);
1098 silc_mp_uninit(ske->x);
1102 silc_mp_uninit(ske->KEY);
1103 silc_free(ske->KEY);
1105 silc_free(ske->retrans.data);
1106 silc_free(ske->hash);
1107 silc_free(ske->callbacks);
1109 memset(ske, 'F', sizeof(*ske));
1113 /* Return user context */
1115 void *silc_ske_get_context(SilcSKE ske)
1117 return ske->user_data;
1120 /* Sets protocol callbacks */
1122 void silc_ske_set_callbacks(SilcSKE ske,
1123 SilcSKEVerifyCb verify_key,
1124 SilcSKECompletionCb completed,
1128 silc_free(ske->callbacks);
1129 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1130 if (!ske->callbacks)
1132 ske->callbacks->verify_key = verify_key;
1133 ske->callbacks->completed = completed;
1134 ske->callbacks->context = context;
1138 /******************************** Initiator *********************************/
1140 /* Start protocol. Send our proposal */
1142 SILC_FSM_STATE(silc_ske_st_initiator_start)
1144 SilcSKE ske = fsm_context;
1145 SilcBuffer payload_buf;
1148 SILC_LOG_DEBUG(("Start"));
1152 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1153 return SILC_FSM_CONTINUE;
1156 /* Encode the payload */
1157 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1159 if (status != SILC_SKE_STATUS_OK) {
1160 /** Error encoding Start Payload */
1161 ske->status = status;
1162 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1163 return SILC_FSM_CONTINUE;
1166 /* Save the the payload buffer for future use. It is later used to
1167 compute the HASH value. */
1168 ske->start_payload_copy = payload_buf;
1170 /* Send the packet. */
1171 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1172 silc_buffer_data(payload_buf),
1173 silc_buffer_len(payload_buf))) {
1174 /** Error sending packet */
1175 SILC_LOG_DEBUG(("Error sending packet"));
1176 ske->status = SILC_SKE_STATUS_ERROR;
1177 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1178 return SILC_FSM_CONTINUE;
1181 /* Add key exchange timeout */
1182 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1183 ske, ske->timeout, 0);
1185 /** Wait for responder proposal */
1186 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1187 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1188 return SILC_FSM_WAIT;
1191 /* Phase-1. Receives responder's proposal */
1193 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1195 SilcSKE ske = fsm_context;
1196 SilcSKEStatus status;
1197 SilcSKEStartPayload payload;
1198 SilcSKESecurityProperties prop;
1199 SilcSKEDiffieHellmanGroup group = NULL;
1200 SilcBuffer packet_buf = &ske->packet->buffer;
1201 SilcUInt16 remote_port = 0;
1205 SILC_LOG_DEBUG(("Start"));
1207 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1208 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1209 silc_ske_install_retransmission(ske);
1210 silc_packet_free(ske->packet);
1212 return SILC_FSM_WAIT;
1215 /* Decode the payload */
1216 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1217 if (status != SILC_SKE_STATUS_OK) {
1218 /** Error decoding Start Payload */
1219 silc_packet_free(ske->packet);
1221 ske->status = status;
1222 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1223 return SILC_FSM_CONTINUE;
1226 /* Get remote ID and set it to stream */
1227 if (ske->packet->src_id_len) {
1228 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1229 ske->packet->src_id_type,
1230 (ske->packet->src_id_type == SILC_ID_SERVER ?
1231 (void *)&id.u.server_id : (void *)&id.u.client_id),
1232 (ske->packet->src_id_type == SILC_ID_SERVER ?
1233 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1234 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1235 (ske->packet->src_id_type == SILC_ID_SERVER ?
1236 (void *)&id.u.server_id : (void *)&id.u.client_id));
1239 silc_packet_free(ske->packet);
1242 /* Check that the cookie is returned unmodified. In case IV included
1243 flag and session port has been set, the first two bytes of cookie
1244 are the session port and we ignore them in this check. */
1245 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1246 /* Take remote port */
1247 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1250 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1251 SILC_SKE_COOKIE_LEN - coff)) {
1252 /** Invalid cookie */
1253 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1254 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1255 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1256 return SILC_FSM_CONTINUE;
1259 /* Check version string */
1260 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1261 status = silc_ske_check_version(ske);
1262 if (status != SILC_SKE_STATUS_OK) {
1263 /** Version mismatch */
1264 ske->status = status;
1265 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1266 return SILC_FSM_CONTINUE;
1269 /* Free our KE Start Payload context, we don't need it anymore. */
1270 silc_ske_payload_start_free(ske->start_payload);
1271 ske->start_payload = NULL;
1273 /* Take the selected security properties into use while doing
1274 the key exchange. This is used only while doing the key
1276 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1279 prop->flags = payload->flags;
1280 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1281 if (status != SILC_SKE_STATUS_OK)
1284 prop->group = group;
1285 prop->remote_port = remote_port;
1287 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1288 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1291 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1292 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1295 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1296 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1299 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1300 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1304 /* Save remote's KE Start Payload */
1305 ske->start_payload = payload;
1307 /** Send KE Payload */
1308 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1309 return SILC_FSM_CONTINUE;
1313 silc_ske_payload_start_free(payload);
1315 silc_ske_group_free(group);
1317 silc_cipher_free(prop->cipher);
1319 silc_hash_free(prop->hash);
1321 silc_hmac_free(prop->hmac);
1325 if (status == SILC_SKE_STATUS_OK)
1326 status = SILC_SKE_STATUS_ERROR;
1329 ske->status = status;
1330 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1331 return SILC_FSM_CONTINUE;
1334 /* Phase-2. Send KE payload */
1336 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1338 SilcSKE ske = fsm_context;
1339 SilcSKEStatus status;
1340 SilcBuffer payload_buf;
1342 SilcSKEKEPayload payload;
1345 SILC_LOG_DEBUG(("Start"));
1347 /* Create the random number x, 1 < x < q. */
1348 x = silc_calloc(1, sizeof(*x));
1350 /** Out of memory */
1351 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1352 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1353 return SILC_FSM_CONTINUE;
1357 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1358 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1360 if (status != SILC_SKE_STATUS_OK) {
1361 /** Error generating random number */
1364 ske->status = status;
1365 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1366 return SILC_FSM_CONTINUE;
1369 /* Encode the result to Key Exchange Payload. */
1371 payload = silc_calloc(1, sizeof(*payload));
1373 /** Out of memory */
1376 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1377 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1378 return SILC_FSM_CONTINUE;
1380 ske->ke1_payload = payload;
1382 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1384 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1385 silc_mp_init(&payload->x);
1386 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1387 &ske->prop->group->group);
1389 /* Get public key */
1390 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1391 if (!payload->pk_data) {
1392 /** Error encoding public key */
1395 silc_mp_uninit(&payload->x);
1397 ske->ke1_payload = NULL;
1398 ske->status = SILC_SKE_STATUS_ERROR;
1399 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1400 return SILC_FSM_CONTINUE;
1402 payload->pk_len = pk_len;
1403 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1405 /* Compute signature data if we are doing mutual authentication */
1406 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1407 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1408 SilcUInt32 hash_len, sign_len;
1410 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1411 SILC_LOG_DEBUG(("Computing HASH_i value"));
1413 /* Compute the hash value */
1414 memset(hash, 0, sizeof(hash));
1415 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1417 SILC_LOG_DEBUG(("Signing HASH_i value"));
1419 /* Sign the hash value */
1420 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1421 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1422 /** Error computing signature */
1425 silc_mp_uninit(&payload->x);
1426 silc_free(payload->pk_data);
1428 ske->ke1_payload = NULL;
1429 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1430 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1431 return SILC_FSM_CONTINUE;
1433 payload->sign_data = silc_memdup(sign, sign_len);
1434 if (payload->sign_data)
1435 payload->sign_len = sign_len;
1436 memset(sign, 0, sizeof(sign));
1439 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1440 if (status != SILC_SKE_STATUS_OK) {
1441 /** Error encoding KE payload */
1444 silc_mp_uninit(&payload->x);
1445 silc_free(payload->pk_data);
1446 silc_free(payload->sign_data);
1448 ske->ke1_payload = NULL;
1449 ske->status = status;
1450 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1451 return SILC_FSM_CONTINUE;
1456 /* Check for backwards compatibility */
1458 /* Send the packet. */
1459 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1460 silc_buffer_data(payload_buf),
1461 silc_buffer_len(payload_buf))) {
1462 /** Error sending packet */
1463 SILC_LOG_DEBUG(("Error sending packet"));
1464 ske->status = SILC_SKE_STATUS_ERROR;
1465 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1466 return SILC_FSM_CONTINUE;
1469 silc_buffer_free(payload_buf);
1471 /** Waiting responder's KE payload */
1472 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1473 return SILC_FSM_WAIT;
1476 /* Phase-3. Process responder's KE payload */
1478 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1480 SilcSKE ske = fsm_context;
1481 SilcSKEStatus status;
1482 SilcSKEKEPayload payload;
1484 SilcBuffer packet_buf = &ske->packet->buffer;
1486 SILC_LOG_DEBUG(("Start"));
1488 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1489 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1490 silc_ske_install_retransmission(ske);
1491 silc_packet_free(ske->packet);
1493 return SILC_FSM_WAIT;
1496 /* Decode the payload */
1497 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1498 if (status != SILC_SKE_STATUS_OK) {
1499 /** Error decoding KE payload */
1500 silc_packet_free(ske->packet);
1502 ske->status = status;
1503 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1504 return SILC_FSM_CONTINUE;
1506 silc_packet_free(ske->packet);
1508 ske->ke2_payload = payload;
1510 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1511 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1512 "even though we require it"));
1513 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1517 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1519 /* Compute the shared secret key */
1520 KEY = silc_calloc(1, sizeof(*KEY));
1522 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1525 /* Decode the remote's public key */
1526 if (payload->pk_data &&
1527 !silc_pkcs_public_key_alloc(payload->pk_type,
1528 payload->pk_data, payload->pk_len,
1529 &ske->prop->public_key)) {
1530 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1531 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1535 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1537 SILC_LOG_DEBUG(("Verifying public key"));
1539 /** Waiting public key verification */
1540 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1542 /* If repository is provided, verify the key from there. */
1543 if (ske->repository) {
1546 find = silc_skr_find_alloc();
1548 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1551 silc_skr_find_set_pkcs_type(find,
1552 silc_pkcs_get_type(ske->prop->public_key));
1553 silc_skr_find_set_public_key(find, ske->prop->public_key);
1554 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1556 /* Find key from repository */
1557 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1558 find, silc_ske_skr_callback, ske));
1560 /* Verify from application */
1561 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1562 ske->callbacks->context,
1563 silc_ske_pk_verified, NULL));
1568 /** Process key material */
1569 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1570 return SILC_FSM_CONTINUE;
1573 silc_ske_payload_ke_free(payload);
1574 ske->ke2_payload = NULL;
1576 silc_mp_uninit(ske->KEY);
1577 silc_free(ske->KEY);
1580 if (status == SILC_SKE_STATUS_OK)
1581 return SILC_SKE_STATUS_ERROR;
1584 ske->status = status;
1585 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1586 return SILC_FSM_CONTINUE;
1589 /* Process key material */
1591 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1593 SilcSKE ske = fsm_context;
1594 SilcSKEStatus status;
1595 SilcSKEKEPayload payload;
1596 unsigned char hash[SILC_HASH_MAXLEN];
1597 SilcUInt32 hash_len;
1598 int key_len, block_len;
1602 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1603 return SILC_FSM_CONTINUE;
1606 /* Check result of public key verification */
1607 if (ske->status != SILC_SKE_STATUS_OK) {
1608 /** Public key not verified */
1609 SILC_LOG_DEBUG(("Public key verification failed"));
1610 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1611 return SILC_FSM_CONTINUE;
1614 payload = ske->ke2_payload;
1616 /* Compute the HASH value */
1617 SILC_LOG_DEBUG(("Computing HASH value"));
1618 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1619 if (status != SILC_SKE_STATUS_OK)
1621 ske->hash = silc_memdup(hash, hash_len);
1622 ske->hash_len = hash_len;
1624 if (ske->prop->public_key) {
1625 SILC_LOG_DEBUG(("Public key is authentic"));
1626 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1628 /* Verify signature */
1629 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1630 payload->sign_len, hash, hash_len, NULL)) {
1631 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1632 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1636 SILC_LOG_DEBUG(("Signature is Ok"));
1637 memset(hash, 'F', hash_len);
1640 ske->status = SILC_SKE_STATUS_OK;
1642 /* In case we are doing rekey move to finish it. */
1645 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1646 return SILC_FSM_CONTINUE;
1649 /* Process key material */
1650 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1651 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1652 hash_len = silc_hash_len(ske->prop->hash);
1653 ske->keymat = silc_ske_process_key_material(ske, block_len,
1657 SILC_LOG_ERROR(("Error processing key material"));
1658 status = SILC_SKE_STATUS_ERROR;
1662 /* Send SUCCESS packet */
1663 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1664 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1665 /** Error sending packet */
1666 SILC_LOG_DEBUG(("Error sending packet"));
1667 ske->status = SILC_SKE_STATUS_ERROR;
1668 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1669 return SILC_FSM_CONTINUE;
1672 /** Waiting completion */
1673 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1674 return SILC_FSM_WAIT;
1677 memset(hash, 'F', sizeof(hash));
1678 silc_ske_payload_ke_free(payload);
1679 ske->ke2_payload = NULL;
1681 silc_mp_uninit(ske->KEY);
1682 silc_free(ske->KEY);
1686 memset(ske->hash, 'F', hash_len);
1687 silc_free(ske->hash);
1691 if (status == SILC_SKE_STATUS_OK)
1692 status = SILC_SKE_STATUS_ERROR;
1695 ske->status = status;
1696 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1697 return SILC_FSM_CONTINUE;
1700 /* Protocol completed */
1702 SILC_FSM_STATE(silc_ske_st_initiator_end)
1704 SilcSKE ske = fsm_context;
1706 SILC_LOG_DEBUG(("Start"));
1708 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1709 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1710 silc_ske_install_retransmission(ske);
1711 silc_packet_free(ske->packet);
1713 return SILC_FSM_WAIT;
1716 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1718 silc_packet_free(ske->packet);
1720 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1721 silc_schedule_task_del_by_context(ske->schedule, ske);
1723 /* Call completion */
1724 silc_ske_completion(ske);
1726 return SILC_FSM_FINISH;
1729 /* Aborted by application */
1731 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1733 SilcSKE ske = fsm_context;
1734 unsigned char data[4];
1736 SILC_LOG_DEBUG(("Aborted by caller"));
1738 /* Send FAILURE packet */
1739 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1740 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1742 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1743 silc_schedule_task_del_by_context(ske->schedule, ske);
1745 /* Call completion */
1746 silc_ske_completion(ske);
1748 return SILC_FSM_FINISH;
1751 /* Error occurred. Send error to remote host */
1753 SILC_FSM_STATE(silc_ske_st_initiator_error)
1755 SilcSKE ske = fsm_context;
1756 SilcSKEStatus status;
1757 unsigned char data[4];
1759 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1760 silc_ske_map_status(ske->status), ske->status));
1762 status = ske->status;
1763 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1764 status = SILC_SKE_STATUS_ERROR;
1766 /* Send FAILURE packet */
1767 SILC_PUT32_MSB((SilcUInt32)status, data);
1768 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1770 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1771 silc_schedule_task_del_by_context(ske->schedule, ske);
1773 /* Call completion */
1774 silc_ske_completion(ske);
1776 return SILC_FSM_FINISH;
1779 /* Failure received from remote */
1781 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1783 SilcSKE ske = fsm_context;
1784 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1786 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1787 SILC_GET32_MSB(error, ske->packet->buffer.data);
1788 ske->status = error;
1789 silc_packet_free(ske->packet);
1793 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1794 silc_ske_map_status(ske->status), ske->status));
1796 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1797 silc_schedule_task_del_by_context(ske->schedule, ske);
1799 /* Call completion */
1800 silc_ske_completion(ske);
1802 return SILC_FSM_FINISH;
1805 /* Starts the protocol as initiator */
1807 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1808 SilcPacketStream stream,
1809 SilcSKEParams params,
1810 SilcSKEStartPayload start_payload)
1812 SILC_LOG_DEBUG(("Start SKE as initiator"));
1814 if (!ske || !stream || !params || !params->version)
1817 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1820 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1823 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1824 ske->session_port = params->session_port;
1826 /* Generate security properties if not provided */
1827 if (!start_payload) {
1828 start_payload = silc_ske_assemble_security_properties(ske,
1835 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1836 ske->start_payload = start_payload;
1837 ske->version = params->version;
1838 ske->running = TRUE;
1840 /* Link to packet stream to get key exchange packets */
1841 ske->stream = stream;
1842 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1843 SILC_PACKET_KEY_EXCHANGE,
1844 SILC_PACKET_KEY_EXCHANGE_2,
1845 SILC_PACKET_SUCCESS,
1846 SILC_PACKET_FAILURE, -1);
1848 /* Start SKE as initiator */
1849 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1854 /******************************** Responder *********************************/
1856 /* Start protocol as responder. Wait initiator's start payload */
1858 SILC_FSM_STATE(silc_ske_st_responder_start)
1860 SilcSKE ske = fsm_context;
1862 SILC_LOG_DEBUG(("Start"));
1866 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1867 return SILC_FSM_CONTINUE;
1870 /* Add key exchange timeout */
1871 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1872 ske, ske->timeout, 0);
1874 /** Wait for initiator */
1875 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1876 return SILC_FSM_WAIT;
1879 /* Decode initiator's start payload. Select the security properties from
1880 the initiator's start payload and send our reply start payload back. */
1882 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1884 SilcSKE ske = fsm_context;
1885 SilcSKEStatus status;
1886 SilcSKEStartPayload remote_payload = NULL;
1887 SilcBuffer packet_buf = &ske->packet->buffer;
1890 SILC_LOG_DEBUG(("Start"));
1892 /* Decode the payload */
1893 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1894 if (status != SILC_SKE_STATUS_OK) {
1895 /** Error decoding Start Payload */
1896 silc_packet_free(ske->packet);
1898 ske->status = status;
1899 silc_fsm_next(fsm, silc_ske_st_responder_error);
1900 return SILC_FSM_CONTINUE;
1903 /* Get remote ID and set it to stream */
1904 if (ske->packet->src_id_len) {
1905 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1906 ske->packet->src_id_type,
1907 (ske->packet->src_id_type == SILC_ID_SERVER ?
1908 (void *)&id.u.server_id : (void *)&id.u.client_id),
1909 (ske->packet->src_id_type == SILC_ID_SERVER ?
1910 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1911 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1912 (ske->packet->src_id_type == SILC_ID_SERVER ?
1913 (void *)&id.u.server_id : (void *)&id.u.client_id));
1916 /* Take a copy of the payload buffer for future use. It is used to
1917 compute the HASH value. */
1918 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1920 silc_packet_free(ske->packet);
1923 /* Force the mutual authentication flag if we want to do it. */
1924 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1925 SILC_LOG_DEBUG(("Force mutual authentication"));
1926 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1929 /* Force PFS flag if we require it */
1930 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1931 SILC_LOG_DEBUG(("Force PFS"));
1932 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1935 /* Disable IV Included flag if requested */
1936 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1937 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1938 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1939 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1942 /* Check and select security properties */
1943 status = silc_ske_select_security_properties(ske, remote_payload,
1945 if (status != SILC_SKE_STATUS_OK) {
1946 /** Error selecting proposal */
1947 silc_ske_payload_start_free(remote_payload);
1948 ske->status = status;
1949 silc_fsm_next(fsm, silc_ske_st_responder_error);
1950 return SILC_FSM_CONTINUE;
1953 silc_ske_payload_start_free(remote_payload);
1955 /* Encode our reply payload to send the selected security properties */
1956 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1958 if (status != SILC_SKE_STATUS_OK)
1961 /* Send the packet. */
1962 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1963 silc_buffer_data(packet_buf),
1964 silc_buffer_len(packet_buf)))
1967 silc_buffer_free(packet_buf);
1969 /** Waiting initiator's KE payload */
1970 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1971 return SILC_FSM_WAIT;
1974 if (ske->prop->group)
1975 silc_ske_group_free(ske->prop->group);
1976 if (ske->prop->cipher)
1977 silc_cipher_free(ske->prop->cipher);
1978 if (ske->prop->hash)
1979 silc_hash_free(ske->prop->hash);
1980 if (ske->prop->hmac)
1981 silc_hmac_free(ske->prop->hmac);
1982 silc_free(ske->prop);
1985 if (status == SILC_SKE_STATUS_OK)
1986 status = SILC_SKE_STATUS_ERROR;
1989 ske->status = status;
1990 silc_fsm_next(fsm, silc_ske_st_responder_error);
1991 return SILC_FSM_CONTINUE;
1994 /* Phase-2. Decode initiator's KE payload */
1996 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1998 SilcSKE ske = fsm_context;
1999 SilcSKEStatus status;
2000 SilcSKEKEPayload recv_payload;
2001 SilcBuffer packet_buf = &ske->packet->buffer;
2003 SILC_LOG_DEBUG(("Start"));
2005 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2006 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2007 silc_ske_install_retransmission(ske);
2008 silc_packet_free(ske->packet);
2010 return SILC_FSM_WAIT;
2013 /* Decode Key Exchange Payload */
2014 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2015 if (status != SILC_SKE_STATUS_OK) {
2016 /** Error decoding KE payload */
2017 silc_packet_free(ske->packet);
2019 ske->status = status;
2020 silc_fsm_next(fsm, silc_ske_st_responder_error);
2021 return SILC_FSM_CONTINUE;
2024 ske->ke1_payload = recv_payload;
2026 silc_packet_free(ske->packet);
2029 /* Verify the received public key and verify the signature if we are
2030 doing mutual authentication. */
2031 if (ske->start_payload &&
2032 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2034 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2036 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2038 /** Public key not provided */
2039 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2040 "certificate), even though we require it"));
2041 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2042 silc_fsm_next(fsm, silc_ske_st_responder_error);
2043 return SILC_FSM_CONTINUE;
2046 /* Decode the remote's public key */
2047 if (recv_payload->pk_data &&
2048 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2049 recv_payload->pk_data,
2050 recv_payload->pk_len,
2051 &ske->prop->public_key)) {
2052 /** Error decoding public key */
2053 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2054 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2055 silc_fsm_next(fsm, silc_ske_st_responder_error);
2056 return SILC_FSM_CONTINUE;
2059 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2061 SILC_LOG_DEBUG(("Verifying public key"));
2063 /** Waiting public key verification */
2064 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2066 /* If repository is provided, verify the key from there. */
2067 if (ske->repository) {
2070 find = silc_skr_find_alloc();
2072 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2073 silc_fsm_next(fsm, silc_ske_st_responder_error);
2074 return SILC_FSM_CONTINUE;
2076 silc_skr_find_set_pkcs_type(find,
2077 silc_pkcs_get_type(ske->prop->public_key));
2078 silc_skr_find_set_public_key(find, ske->prop->public_key);
2079 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2081 /* Find key from repository */
2082 SILC_FSM_CALL(silc_skr_find(ske->repository,
2083 silc_fsm_get_schedule(fsm), find,
2084 silc_ske_skr_callback, ske));
2086 /* Verify from application */
2087 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2088 ske->callbacks->context,
2089 silc_ske_pk_verified, NULL));
2095 /** Generate KE2 payload */
2096 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2097 return SILC_FSM_CONTINUE;
2100 /* Phase-4. Generate KE2 payload */
2102 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2104 SilcSKE ske = fsm_context;
2105 SilcSKEStatus status;
2106 SilcSKEKEPayload recv_payload, send_payload;
2111 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2112 return SILC_FSM_CONTINUE;
2115 /* Check result of public key verification */
2116 if (ske->status != SILC_SKE_STATUS_OK) {
2117 /** Public key not verified */
2118 SILC_LOG_DEBUG(("Public key verification failed"));
2119 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2120 return SILC_FSM_CONTINUE;
2123 recv_payload = ske->ke1_payload;
2125 /* The public key verification was performed only if the Mutual
2126 Authentication flag is set. */
2127 if (ske->start_payload &&
2128 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2129 unsigned char hash[SILC_HASH_MAXLEN];
2130 SilcUInt32 hash_len;
2132 SILC_LOG_DEBUG(("Public key is authentic"));
2134 /* Compute the hash value */
2135 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2136 if (status != SILC_SKE_STATUS_OK) {
2137 /** Error computing hash */
2138 ske->status = status;
2139 silc_fsm_next(fsm, silc_ske_st_responder_error);
2140 return SILC_FSM_CONTINUE;
2143 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2145 /* Verify signature */
2146 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2147 recv_payload->sign_len, hash, hash_len, NULL)) {
2148 /** Incorrect signature */
2149 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2150 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2151 silc_fsm_next(fsm, silc_ske_st_responder_error);
2152 return SILC_FSM_CONTINUE;
2155 SILC_LOG_DEBUG(("Signature is Ok"));
2157 memset(hash, 'F', hash_len);
2160 /* Create the random number x, 1 < x < q. */
2161 x = silc_calloc(1, sizeof(*x));
2164 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2165 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2167 if (status != SILC_SKE_STATUS_OK) {
2168 /** Error generating random number */
2171 ske->status = status;
2172 silc_fsm_next(fsm, silc_ske_st_responder_error);
2173 return SILC_FSM_CONTINUE;
2176 /* Save the results for later processing */
2177 send_payload = silc_calloc(1, sizeof(*send_payload));
2179 ske->ke2_payload = send_payload;
2181 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2183 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2184 silc_mp_init(&send_payload->x);
2185 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2186 &ske->prop->group->group);
2188 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2190 /* Compute the shared secret key */
2191 KEY = silc_calloc(1, sizeof(*KEY));
2193 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2194 &ske->prop->group->group);
2197 /** Send KE2 payload */
2198 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2199 return SILC_FSM_CONTINUE;
2202 /* Phase-5. Send KE2 payload */
2204 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2206 SilcSKE ske = fsm_context;
2207 SilcSKEStatus status;
2208 SilcBuffer payload_buf;
2209 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2210 SilcUInt32 hash_len, sign_len, pk_len;
2212 SILC_LOG_DEBUG(("Start"));
2214 if (ske->public_key && ske->private_key) {
2215 SILC_LOG_DEBUG(("Getting public key"));
2217 /* Get the public key */
2218 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2220 /** Error encoding public key */
2221 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2222 silc_fsm_next(fsm, silc_ske_st_responder_error);
2223 return SILC_FSM_CONTINUE;
2225 ske->ke2_payload->pk_data = pk;
2226 ske->ke2_payload->pk_len = pk_len;
2229 SILC_LOG_DEBUG(("Computing HASH value"));
2231 /* Compute the hash value */
2232 memset(hash, 0, sizeof(hash));
2233 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2234 if (status != SILC_SKE_STATUS_OK) {
2235 /** Error computing hash */
2236 ske->status = status;
2237 silc_fsm_next(fsm, silc_ske_st_responder_error);
2238 return SILC_FSM_CONTINUE;
2240 ske->hash = silc_memdup(hash, hash_len);
2241 ske->hash_len = hash_len;
2243 if (ske->public_key && ske->private_key) {
2244 SILC_LOG_DEBUG(("Signing HASH value"));
2246 /* Sign the hash value */
2247 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2248 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2249 /** Error computing signature */
2250 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2251 silc_fsm_next(fsm, silc_ske_st_responder_error);
2252 return SILC_FSM_CONTINUE;
2254 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2255 ske->ke2_payload->sign_len = sign_len;
2256 memset(sign, 0, sizeof(sign));
2258 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2260 /* Encode the Key Exchange Payload */
2261 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2263 if (status != SILC_SKE_STATUS_OK) {
2264 /** Error encoding KE payload */
2265 ske->status = status;
2266 silc_fsm_next(fsm, silc_ske_st_responder_error);
2267 return SILC_FSM_CONTINUE;
2270 /* Send the packet. */
2271 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2272 payload_buf->data, silc_buffer_len(payload_buf))) {
2273 SILC_LOG_DEBUG(("Error sending packet"));
2274 ske->status = SILC_SKE_STATUS_ERROR;
2275 silc_fsm_next(fsm, silc_ske_st_responder_error);
2276 return SILC_FSM_CONTINUE;
2279 silc_buffer_free(payload_buf);
2281 /* In case we are doing rekey move to finish it. */
2284 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2285 return SILC_FSM_CONTINUE;
2288 /** Waiting completion */
2289 silc_fsm_next(fsm, silc_ske_st_responder_end);
2290 return SILC_FSM_WAIT;
2293 /* Protocol completed */
2295 SILC_FSM_STATE(silc_ske_st_responder_end)
2297 SilcSKE ske = fsm_context;
2298 unsigned char tmp[4];
2299 SilcUInt32 hash_len, key_len, block_len;
2301 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2302 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2303 silc_ske_install_retransmission(ske);
2304 silc_packet_free(ske->packet);
2306 return SILC_FSM_WAIT;
2308 silc_packet_free(ske->packet);
2311 /* Process key material */
2312 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2313 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2314 hash_len = silc_hash_len(ske->prop->hash);
2315 ske->keymat = silc_ske_process_key_material(ske, block_len,
2319 /** Error processing key material */
2320 ske->status = SILC_SKE_STATUS_ERROR;
2321 silc_fsm_next(fsm, silc_ske_st_responder_error);
2322 return SILC_FSM_CONTINUE;
2325 /* Send SUCCESS packet */
2326 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2327 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2329 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2330 silc_schedule_task_del_by_context(ske->schedule, ske);
2332 /* Call completion */
2333 silc_ske_completion(ske);
2335 return SILC_FSM_FINISH;
2338 /* Aborted by application */
2340 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2342 SilcSKE ske = fsm_context;
2343 unsigned char tmp[4];
2345 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2347 /* Send FAILURE packet */
2348 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2349 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2351 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2352 silc_schedule_task_del_by_context(ske->schedule, ske);
2354 /* Call completion */
2355 silc_ske_completion(ske);
2357 return SILC_FSM_FINISH;
2360 /* Failure received from remote */
2362 SILC_FSM_STATE(silc_ske_st_responder_failure)
2364 SilcSKE ske = fsm_context;
2365 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2367 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2369 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2370 SILC_GET32_MSB(error, ske->packet->buffer.data);
2371 ske->status = error;
2372 silc_packet_free(ske->packet);
2376 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2377 silc_schedule_task_del_by_context(ske->schedule, ske);
2379 /* Call completion */
2380 silc_ske_completion(ske);
2382 return SILC_FSM_FINISH;
2385 /* Error occurred */
2387 SILC_FSM_STATE(silc_ske_st_responder_error)
2389 SilcSKE ske = fsm_context;
2390 unsigned char tmp[4];
2392 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2393 ske->status, silc_ske_map_status(ske->status)));
2395 /* Send FAILURE packet */
2396 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2397 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2398 SILC_PUT32_MSB(ske->status, tmp);
2399 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2401 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2402 silc_schedule_task_del_by_context(ske->schedule, ske);
2404 /* Call completion */
2405 silc_ske_completion(ske);
2407 return SILC_FSM_FINISH;
2410 /* Starts the protocol as responder. */
2412 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2413 SilcPacketStream stream,
2414 SilcSKEParams params)
2416 SILC_LOG_DEBUG(("Start SKE as responder"));
2418 if (!ske || !stream || !params || !params->version)
2421 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2424 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2427 ske->responder = TRUE;
2428 ske->flags = params->flags;
2429 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2430 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2431 ske->session_port = params->session_port;
2432 ske->version = strdup(params->version);
2435 ske->running = TRUE;
2437 /* Link to packet stream to get key exchange packets */
2438 ske->stream = stream;
2439 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2440 SILC_PACKET_KEY_EXCHANGE,
2441 SILC_PACKET_KEY_EXCHANGE_1,
2442 SILC_PACKET_SUCCESS,
2443 SILC_PACKET_FAILURE, -1);
2445 /* Start SKE as responder */
2446 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2451 /***************************** Initiator Rekey ******************************/
2455 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2457 SilcSKE ske = fsm_context;
2460 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2464 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2465 return SILC_FSM_CONTINUE;
2468 /* Add rekey exchange timeout */
2469 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2472 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2475 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2476 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2477 return SILC_FSM_CONTINUE;
2480 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2481 /** Cannot allocate hash */
2482 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2483 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2484 return SILC_FSM_CONTINUE;
2487 /* Send REKEY packet to start rekey protocol */
2488 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2489 /** Error sending packet */
2490 SILC_LOG_DEBUG(("Error sending packet"));
2491 ske->status = SILC_SKE_STATUS_ERROR;
2492 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2493 return SILC_FSM_CONTINUE;
2496 /* If doing rekey without PFS, move directly to the end of the protocol. */
2497 if (!ske->rekey->pfs) {
2498 /** Rekey without PFS */
2499 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2500 return SILC_FSM_CONTINUE;
2503 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2505 if (status != SILC_SKE_STATUS_OK) {
2506 /** Unknown group */
2507 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2508 return SILC_FSM_CONTINUE;
2511 /** Rekey with PFS */
2512 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2513 return SILC_FSM_CONTINUE;
2516 /* Sends REKEY_DONE packet to finish the protocol. */
2518 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2520 SilcSKE ske = fsm_context;
2521 SilcCipher send_key;
2524 SilcUInt32 key_len, block_len, hash_len, x_len;
2525 unsigned char *pfsbuf;
2527 SILC_LOG_DEBUG(("Start"));
2529 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2530 key_len = silc_cipher_get_key_len(send_key);
2531 block_len = silc_cipher_get_block_len(send_key);
2532 hash = ske->prop->hash;
2533 hash_len = silc_hash_len(hash);
2535 /* Process key material */
2536 if (ske->rekey->pfs) {
2538 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2540 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2543 memset(pfsbuf, 0, x_len);
2549 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2550 ske->rekey->enc_key_len / 8,
2556 SILC_LOG_ERROR(("Error processing key material"));
2557 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2558 return SILC_FSM_CONTINUE;
2561 ske->prop->cipher = send_key;
2562 ske->prop->hmac = hmac_send;
2564 /* Get sending keys */
2565 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2566 &hmac_send, NULL, NULL)) {
2567 /** Cannot get keys */
2568 ske->status = SILC_SKE_STATUS_ERROR;
2569 ske->prop->cipher = NULL;
2570 ske->prop->hmac = NULL;
2571 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2572 return SILC_FSM_CONTINUE;
2575 ske->prop->cipher = NULL;
2576 ske->prop->hmac = NULL;
2578 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2579 packet sent after this call will be protected with the new keys. */
2580 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2582 /** Cannot set keys */
2583 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2584 ske->status = SILC_SKE_STATUS_ERROR;
2585 silc_cipher_free(send_key);
2586 silc_hmac_free(hmac_send);
2587 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2588 return SILC_FSM_CONTINUE;
2591 /** Wait for REKEY_DONE */
2592 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2593 return SILC_FSM_WAIT;
2596 /* Rekey protocol end */
2598 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2600 SilcSKE ske = fsm_context;
2601 SilcCipher receive_key;
2602 SilcHmac hmac_receive;
2603 SilcSKERekeyMaterial rekey;
2605 SILC_LOG_DEBUG(("Start"));
2607 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2608 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2609 silc_packet_free(ske->packet);
2611 return SILC_FSM_WAIT;
2614 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2615 ske->prop->cipher = receive_key;
2616 ske->prop->hmac = hmac_receive;
2618 /* Get receiving keys */
2619 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2620 NULL, &hmac_receive, NULL)) {
2621 /** Cannot get keys */
2622 ske->status = SILC_SKE_STATUS_ERROR;
2623 ske->prop->cipher = NULL;
2624 ske->prop->hmac = NULL;
2625 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2626 return SILC_FSM_CONTINUE;
2629 /* Set new receiving keys into use. All packets received after this will
2630 be decrypted with the new keys. */
2631 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2632 hmac_receive, FALSE)) {
2633 /** Cannot set keys */
2634 SILC_LOG_DEBUG(("Cannot set new keys"));
2635 ske->status = SILC_SKE_STATUS_ERROR;
2636 silc_cipher_free(receive_key);
2637 silc_hmac_free(hmac_receive);
2638 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2639 return SILC_FSM_CONTINUE;
2642 SILC_LOG_DEBUG(("Rekey completed successfully"));
2644 /* Generate new rekey material */
2645 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2648 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2649 ske->prop->cipher = NULL;
2650 ske->prop->hmac = NULL;
2651 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2652 return SILC_FSM_CONTINUE;
2654 rekey->pfs = ske->rekey->pfs;
2657 ske->prop->cipher = NULL;
2658 ske->prop->hmac = NULL;
2659 silc_packet_free(ske->packet);
2661 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2662 silc_schedule_task_del_by_context(ske->schedule, ske);
2664 /* Call completion */
2665 silc_ske_completion(ske);
2667 return SILC_FSM_FINISH;
2670 /* Starts rekey protocol as initiator */
2673 silc_ske_rekey_initiator(SilcSKE ske,
2674 SilcPacketStream stream,
2675 SilcSKERekeyMaterial rekey)
2677 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2679 if (!ske || !stream || !rekey) {
2680 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2685 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2688 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2692 ske->responder = FALSE;
2693 ske->running = TRUE;
2694 ske->rekeying = TRUE;
2696 /* Link to packet stream to get key exchange packets */
2697 ske->stream = stream;
2698 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2700 SILC_PACKET_REKEY_DONE,
2701 SILC_PACKET_KEY_EXCHANGE_2,
2702 SILC_PACKET_SUCCESS,
2703 SILC_PACKET_FAILURE, -1);
2705 /* Start SKE rekey as initiator */
2706 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2711 /***************************** Responder Rekey ******************************/
2713 /* Wait for initiator's packet */
2715 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2717 SilcSKE ske = fsm_context;
2719 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2723 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2724 return SILC_FSM_CONTINUE;
2727 /* Add rekey exchange timeout */
2728 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2731 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2733 /* If REKEY packet already received process it directly */
2734 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2735 return SILC_FSM_CONTINUE;
2737 /* Wait for REKEY */
2738 return SILC_FSM_WAIT;
2741 /* Process initiator's REKEY packet */
2743 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2745 SilcSKE ske = fsm_context;
2746 SilcSKEStatus status;
2748 SILC_LOG_DEBUG(("Start"));
2750 if (ske->packet->type != SILC_PACKET_REKEY) {
2751 ske->status = SILC_SKE_STATUS_ERROR;
2752 silc_packet_free(ske->packet);
2754 silc_fsm_next(fsm, silc_ske_st_responder_error);
2755 return SILC_FSM_CONTINUE;
2758 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2761 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2762 silc_fsm_next(fsm, silc_ske_st_responder_error);
2763 return SILC_FSM_CONTINUE;
2766 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2767 /** Cannot allocate hash */
2768 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2769 silc_fsm_next(fsm, silc_ske_st_responder_error);
2770 return SILC_FSM_CONTINUE;
2773 /* If doing rekey without PFS, move directly to the end of the protocol. */
2774 if (!ske->rekey->pfs) {
2775 /** Rekey without PFS */
2776 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2777 return SILC_FSM_CONTINUE;
2780 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2782 if (status != SILC_SKE_STATUS_OK) {
2783 /** Unknown group */
2784 silc_fsm_next(fsm, silc_ske_st_responder_error);
2785 return SILC_FSM_CONTINUE;
2788 /** Rekey with PFS */
2789 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2790 return SILC_FSM_WAIT;
2793 /* Sends REKEY_DONE packet to finish the protocol. */
2795 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2797 SilcSKE ske = fsm_context;
2798 SilcCipher send_key;
2801 SilcUInt32 key_len, block_len, hash_len, x_len;
2802 unsigned char *pfsbuf;
2804 SILC_LOG_DEBUG(("Start"));
2806 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2807 key_len = silc_cipher_get_key_len(send_key);
2808 block_len = silc_cipher_get_block_len(send_key);
2809 hash = ske->prop->hash;
2810 hash_len = silc_hash_len(hash);
2812 /* Process key material */
2813 if (ske->rekey->pfs) {
2815 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2817 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2820 memset(pfsbuf, 0, x_len);
2826 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2827 ske->rekey->enc_key_len / 8,
2833 SILC_LOG_ERROR(("Error processing key material"));
2834 silc_fsm_next(fsm, silc_ske_st_responder_error);
2835 return SILC_FSM_CONTINUE;
2838 ske->prop->cipher = send_key;
2839 ske->prop->hmac = hmac_send;
2841 /* Get sending keys */
2842 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2843 &hmac_send, NULL, NULL)) {
2844 /** Cannot get keys */
2845 ske->status = SILC_SKE_STATUS_ERROR;
2846 ske->prop->cipher = NULL;
2847 ske->prop->hmac = NULL;
2848 silc_fsm_next(fsm, silc_ske_st_responder_error);
2849 return SILC_FSM_CONTINUE;
2852 ske->prop->cipher = NULL;
2853 ske->prop->hmac = NULL;
2855 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2856 packet sent after this call will be protected with the new keys. */
2857 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2859 /** Cannot set keys */
2860 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2861 ske->status = SILC_SKE_STATUS_ERROR;
2862 silc_cipher_free(send_key);
2863 silc_hmac_free(hmac_send);
2864 silc_fsm_next(fsm, silc_ske_st_responder_error);
2865 return SILC_FSM_CONTINUE;
2868 /** Wait for REKEY_DONE */
2869 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2870 return SILC_FSM_WAIT;
2873 /* Rekey protocol end */
2875 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2877 SilcSKE ske = fsm_context;
2878 SilcCipher receive_key;
2879 SilcHmac hmac_receive;
2880 SilcSKERekeyMaterial rekey;
2882 SILC_LOG_DEBUG(("Start"));
2884 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2885 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2886 silc_packet_free(ske->packet);
2888 return SILC_FSM_WAIT;
2891 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2892 ske->prop->cipher = receive_key;
2893 ske->prop->hmac = hmac_receive;
2895 /* Get receiving keys */
2896 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2897 NULL, &hmac_receive, NULL)) {
2898 /** Cannot get keys */
2899 ske->status = SILC_SKE_STATUS_ERROR;
2900 ske->prop->cipher = NULL;
2901 ske->prop->hmac = NULL;
2902 silc_fsm_next(fsm, silc_ske_st_responder_error);
2903 return SILC_FSM_CONTINUE;
2906 /* Set new receiving keys into use. All packets received after this will
2907 be decrypted with the new keys. */
2908 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2909 hmac_receive, FALSE)) {
2910 /** Cannot set keys */
2911 SILC_LOG_DEBUG(("Cannot set new keys"));
2912 ske->status = SILC_SKE_STATUS_ERROR;
2913 ske->prop->cipher = NULL;
2914 ske->prop->hmac = NULL;
2915 silc_cipher_free(receive_key);
2916 silc_hmac_free(hmac_receive);
2917 silc_fsm_next(fsm, silc_ske_st_responder_error);
2918 return SILC_FSM_CONTINUE;
2921 SILC_LOG_DEBUG(("Rekey completed successfully"));
2923 /* Generate new rekey material */
2924 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2927 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2928 ske->prop->cipher = NULL;
2929 ske->prop->hmac = NULL;
2930 silc_fsm_next(fsm, silc_ske_st_responder_error);
2931 return SILC_FSM_CONTINUE;
2933 rekey->pfs = ske->rekey->pfs;
2936 ske->prop->cipher = NULL;
2937 ske->prop->hmac = NULL;
2938 silc_packet_free(ske->packet);
2940 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2941 silc_schedule_task_del_by_context(ske->schedule, ske);
2943 /* Call completion */
2944 silc_ske_completion(ske);
2946 return SILC_FSM_FINISH;
2949 /* Starts rekey protocol as responder */
2952 silc_ske_rekey_responder(SilcSKE ske,
2953 SilcPacketStream stream,
2954 SilcSKERekeyMaterial rekey,
2957 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2959 if (!ske || !stream || !rekey)
2962 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2965 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2969 ske->responder = TRUE;
2970 ske->running = TRUE;
2971 ske->rekeying = TRUE;
2972 ske->packet = packet;
2974 /* Link to packet stream to get key exchange packets */
2975 ske->stream = stream;
2976 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2978 SILC_PACKET_REKEY_DONE,
2979 SILC_PACKET_KEY_EXCHANGE_1,
2980 SILC_PACKET_SUCCESS,
2981 SILC_PACKET_FAILURE, -1);
2983 /* Start SKE rekey as responder */
2984 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2989 /* Processes the provided key material `data' as the SILC protocol
2990 specification defines. */
2993 silc_ske_process_key_material_data(unsigned char *data,
2994 SilcUInt32 data_len,
2995 SilcUInt32 req_iv_len,
2996 SilcUInt32 req_enc_key_len,
2997 SilcUInt32 req_hmac_key_len,
3001 unsigned char hashd[SILC_HASH_MAXLEN];
3002 SilcUInt32 hash_len = req_hmac_key_len;
3003 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3004 SilcSKEKeyMaterial key;
3006 SILC_LOG_DEBUG(("Start"));
3008 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3011 key = silc_calloc(1, sizeof(*key));
3015 buf = silc_buffer_alloc_size(1 + data_len);
3018 silc_buffer_format(buf,
3019 SILC_STR_UI_CHAR(0),
3020 SILC_STR_DATA(data, data_len),
3024 memset(hashd, 0, sizeof(hashd));
3026 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3027 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3028 memcpy(key->send_iv, hashd, req_iv_len);
3029 memset(hashd, 0, sizeof(hashd));
3031 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3032 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3033 memcpy(key->receive_iv, hashd, req_iv_len);
3034 key->iv_len = req_iv_len;
3036 /* Take the encryption keys. If requested key size is more than
3037 the size of hash length we will distribute more key material
3038 as protocol defines. */
3040 if (enc_key_len > hash_len) {
3042 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3043 k3[SILC_HASH_MAXLEN];
3044 unsigned char *dtmp;
3047 if (enc_key_len > (3 * hash_len))
3050 /* Take first round */
3051 memset(k1, 0, sizeof(k1));
3052 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3054 /* Take second round */
3055 dist = silc_buffer_alloc_size(data_len + hash_len);
3058 silc_buffer_format(dist,
3059 SILC_STR_DATA(data, data_len),
3060 SILC_STR_DATA(k1, hash_len),
3062 memset(k2, 0, sizeof(k2));
3063 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3065 /* Take third round */
3066 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3067 silc_buffer_pull_tail(dist, hash_len);
3068 silc_buffer_pull(dist, data_len + hash_len);
3069 silc_buffer_format(dist,
3070 SILC_STR_DATA(k2, hash_len),
3072 silc_buffer_push(dist, data_len + hash_len);
3073 memset(k3, 0, sizeof(k3));
3074 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3076 /* Then, save the keys */
3077 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3078 memcpy(dtmp, k1, hash_len);
3079 memcpy(dtmp + hash_len, k2, hash_len);
3080 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3082 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3083 memcpy(key->send_enc_key, dtmp, enc_key_len);
3084 key->enc_key_len = req_enc_key_len;
3086 memset(dtmp, 0, (3 * hash_len));
3087 memset(k1, 0, sizeof(k1));
3088 memset(k2, 0, sizeof(k2));
3089 memset(k3, 0, sizeof(k3));
3091 silc_buffer_clear(dist);
3092 silc_buffer_free(dist);
3094 /* Take normal hash as key */
3095 memset(hashd, 0, sizeof(hashd));
3096 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3097 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3098 memcpy(key->send_enc_key, hashd, enc_key_len);
3099 key->enc_key_len = req_enc_key_len;
3103 if (enc_key_len > hash_len) {
3105 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3106 k3[SILC_HASH_MAXLEN];
3107 unsigned char *dtmp;
3110 if (enc_key_len > (3 * hash_len))
3113 /* Take first round */
3114 memset(k1, 0, sizeof(k1));
3115 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3117 /* Take second round */
3118 dist = silc_buffer_alloc_size(data_len + hash_len);
3121 silc_buffer_format(dist,
3122 SILC_STR_DATA(data, data_len),
3123 SILC_STR_DATA(k1, hash_len),
3125 memset(k2, 0, sizeof(k2));
3126 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3128 /* Take third round */
3129 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3130 silc_buffer_pull_tail(dist, hash_len);
3131 silc_buffer_pull(dist, data_len + hash_len);
3132 silc_buffer_format(dist,
3133 SILC_STR_DATA(k2, hash_len),
3135 silc_buffer_push(dist, data_len + hash_len);
3136 memset(k3, 0, sizeof(k3));
3137 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3139 /* Then, save the keys */
3140 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3141 memcpy(dtmp, k1, hash_len);
3142 memcpy(dtmp + hash_len, k2, hash_len);
3143 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3145 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3146 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3147 key->enc_key_len = req_enc_key_len;
3149 memset(dtmp, 0, (3 * hash_len));
3150 memset(k1, 0, sizeof(k1));
3151 memset(k2, 0, sizeof(k2));
3152 memset(k3, 0, sizeof(k3));
3154 silc_buffer_clear(dist);
3155 silc_buffer_free(dist);
3157 /* Take normal hash as key */
3158 memset(hashd, 0, sizeof(hashd));
3159 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3160 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3161 memcpy(key->receive_enc_key, hashd, enc_key_len);
3162 key->enc_key_len = req_enc_key_len;
3165 /* Take HMAC keys */
3166 memset(hashd, 0, sizeof(hashd));
3168 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3169 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3170 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3171 memset(hashd, 0, sizeof(hashd));
3173 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3174 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3175 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3176 key->hmac_key_len = req_hmac_key_len;
3177 memset(hashd, 0, sizeof(hashd));
3179 silc_buffer_clear(buf);
3180 silc_buffer_free(buf);
3182 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3187 /* Processes negotiated key material as protocol specifies. This returns
3188 the actual keys to be used in the SILC. */
3191 silc_ske_process_key_material(SilcSKE ske,
3192 SilcUInt32 req_iv_len,
3193 SilcUInt32 req_enc_key_len,
3194 SilcUInt32 req_hmac_key_len,
3195 SilcSKERekeyMaterial *rekey)
3198 unsigned char *tmpbuf;
3200 SilcSKEKeyMaterial key;
3202 /* Encode KEY to binary data */
3203 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3205 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3208 silc_buffer_format(buf,
3209 SILC_STR_DATA(tmpbuf, klen),
3210 SILC_STR_DATA(ske->hash, ske->hash_len),
3213 /* Process the key material */
3214 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3215 req_iv_len, req_enc_key_len,
3219 memset(tmpbuf, 0, klen);
3221 silc_buffer_clear(buf);
3222 silc_buffer_free(buf);
3225 *rekey = silc_ske_make_rekey_material(ske, key);
3233 /* Free key material structure */
3235 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3241 silc_free(key->send_iv);
3242 if (key->receive_iv)
3243 silc_free(key->receive_iv);
3244 if (key->send_enc_key) {
3245 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3246 silc_free(key->send_enc_key);
3248 if (key->receive_enc_key) {
3249 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3250 silc_free(key->receive_enc_key);
3252 if (key->send_hmac_key) {
3253 memset(key->send_hmac_key, 0, key->hmac_key_len);
3254 silc_free(key->send_hmac_key);
3256 if (key->receive_hmac_key) {
3257 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3258 silc_free(key->receive_hmac_key);
3263 /* Free rekey material */
3265 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3269 if (rekey->send_enc_key) {
3270 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3271 silc_free(rekey->send_enc_key);
3273 silc_free(rekey->hash);
3277 /* Set keys into use */
3279 SilcBool silc_ske_set_keys(SilcSKE ske,
3280 SilcSKEKeyMaterial keymat,
3281 SilcSKESecurityProperties prop,
3282 SilcCipher *ret_send_key,
3283 SilcCipher *ret_receive_key,
3284 SilcHmac *ret_hmac_send,
3285 SilcHmac *ret_hmac_receive,
3288 unsigned char iv[SILC_HASH_MAXLEN];
3289 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3291 /* Allocate ciphers to be used in the communication */
3293 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3297 if (ret_receive_key) {
3298 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3303 /* Allocate HMACs */
3304 if (ret_hmac_send) {
3305 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3309 if (ret_hmac_receive) {
3310 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3317 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3321 /* Set key material */
3322 memset(iv, 0, sizeof(iv));
3323 if (ske->responder) {
3325 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3326 keymat->enc_key_len, TRUE);
3328 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3330 if (!ske->rekeying) {
3332 memcpy(iv, ske->hash, 4);
3334 memcpy(iv + 4, keymat->receive_iv, 8);
3336 /* Rekey, recompute the truncated hash value. */
3337 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3339 memcpy(iv + 4, keymat->receive_iv, 8);
3341 memset(iv + 4, 0, 12);
3344 silc_cipher_set_iv(*ret_send_key, iv);
3347 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3350 if (ret_receive_key) {
3351 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3352 keymat->enc_key_len, FALSE);
3354 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3356 if (!ske->rekeying) {
3358 memcpy(iv, ske->hash, 4);
3360 memcpy(iv + 4, keymat->send_iv, 8);
3362 /* Rekey, recompute the truncated hash value. */
3363 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3365 memcpy(iv + 4, keymat->send_iv, 8);
3367 memset(iv + 4, 0, 12);
3370 silc_cipher_set_iv(*ret_receive_key, iv);
3373 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3377 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3378 keymat->hmac_key_len);
3379 if (ret_hmac_receive)
3380 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3381 keymat->hmac_key_len);
3384 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3385 keymat->enc_key_len, TRUE);
3387 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3389 if (!ske->rekeying) {
3391 memcpy(iv, ske->hash, 4);
3393 memcpy(iv + 4, keymat->send_iv, 8);
3395 /* Rekey, recompute the truncated hash value. */
3396 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3398 memcpy(iv + 4, keymat->send_iv, 8);
3400 memset(iv + 4, 0, 12);
3403 silc_cipher_set_iv(*ret_send_key, iv);
3406 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3409 if (ret_receive_key) {
3410 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3411 keymat->enc_key_len, FALSE);
3413 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3415 if (!ske->rekeying) {
3416 /* Set IV. If IV Included flag was negotiated we only set the
3417 truncated hash value. */
3418 memcpy(iv, ske->hash, 4);
3420 memcpy(iv + 4, keymat->receive_iv, 8);
3422 /* Rekey, recompute the truncated hash value. */
3423 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3425 memcpy(iv + 4, keymat->receive_iv, 8);
3427 memset(iv + 4, 0, 12);
3430 silc_cipher_set_iv(*ret_receive_key, iv);
3433 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3437 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3438 keymat->hmac_key_len);
3439 if (ret_hmac_receive)
3440 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3441 keymat->hmac_key_len);
3447 const char *silc_ske_status_string[] =
3451 "Unexpected error occurred",
3452 "Bad payload in packet",
3453 "Unsupported group",
3454 "Unsupported cipher",
3456 "Unsupported hash function",
3458 "Unsupported public key (or certificate)",
3459 "Incorrect signature",
3460 "Bad or unsupported version",
3464 "Remote did not provide public key",
3465 "Bad reserved field in packet",
3466 "Bad payload length in packet",
3467 "Error computing signature",
3468 "System out of memory",
3469 "Key exchange timeout",
3474 /* Maps status to readable string and returns the string. If string is not
3475 found and empty character string ("") is returned. */
3477 const char *silc_ske_map_status(SilcSKEStatus status)
3481 for (i = 0; silc_ske_status_string[i]; i++)
3483 return silc_ske_status_string[i];
3488 /* Parses remote host's version string. */
3490 SilcBool silc_ske_parse_version(SilcSKE ske,
3491 SilcUInt32 *protocol_version,
3492 char **protocol_version_string,
3493 SilcUInt32 *software_version,
3494 char **software_version_string,
3495 char **vendor_version)
3497 return silc_parse_version_string(ske->remote_version,
3499 protocol_version_string,
3501 software_version_string,
3505 /* Get security properties */
3507 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3512 /* Get key material */
3514 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)