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;
187 SilcBool src_set = FALSE;
189 if (!ske->remote_version || !ske->version)
190 return SILC_SKE_STATUS_BAD_VERSION;
192 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
194 &r_software_string, NULL))
195 return SILC_SKE_STATUS_BAD_VERSION;
197 /* Backwards compatibility checks */
199 /* Old server versions requires "valid" looking Source ID in the SILC
200 packets during initial key exchange. All version before 1.1.0. */
201 silc_packet_get_ids(ske->stream, &src_set, NULL, NULL, NULL);
202 if (!src_set && !ske->responder && r_software_string &&
203 r_software_version < 110) {
204 SILC_LOG_DEBUG(("Remote is old version, add dummy Source ID to packets"));
206 if (strstr(r_software_string, "server")) {
208 memset(&sid, 0, sizeof(sid));
210 silc_packet_set_ids(ske->stream, SILC_ID_SERVER, &sid, 0, NULL);
213 if (strstr(r_software_string, "client")) {
215 memset(&cid, 0, sizeof(cid));
217 silc_packet_set_ids(ske->stream, SILC_ID_CLIENT, &cid, 0, NULL);
221 return SILC_SKE_STATUS_OK;
224 /* Selects the supported security properties from the initiator's Key
225 Exchange Start Payload. A responder function. Saves our reply
226 start payload to ske->start_payload. */
229 silc_ske_select_security_properties(SilcSKE ske,
230 SilcSKEStartPayload remote_payload,
231 SilcSKESecurityProperties *prop)
233 SilcSKEStatus status;
234 SilcSKEStartPayload rp, payload;
238 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
242 /* Check for mandatory fields */
243 if (!rp->ke_grp_len) {
244 SILC_LOG_DEBUG(("KE group not defined in payload"));
245 return SILC_SKE_STATUS_BAD_PAYLOAD;
247 if (!rp->pkcs_alg_len) {
248 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
249 return SILC_SKE_STATUS_BAD_PAYLOAD;
251 if (!rp->enc_alg_len) {
252 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
253 return SILC_SKE_STATUS_BAD_PAYLOAD;
255 if (!rp->hash_alg_len) {
256 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
257 return SILC_SKE_STATUS_BAD_PAYLOAD;
259 if (!rp->hmac_alg_len) {
260 SILC_LOG_DEBUG(("HMAC not defined in payload"));
261 return SILC_SKE_STATUS_BAD_PAYLOAD;
264 /* Allocate security properties */
265 *prop = silc_calloc(1, sizeof(**prop));
267 return SILC_SKE_STATUS_OUT_OF_MEMORY;
269 /* Allocate our reply start payload */
270 payload = silc_calloc(1, sizeof(*payload));
273 return SILC_SKE_STATUS_OUT_OF_MEMORY;
276 /* Check version string */
277 ske->remote_version = silc_memdup(rp->version, rp->version_len);
278 status = silc_ske_check_version(ske);
279 if (status != SILC_SKE_STATUS_OK) {
280 ske->status = status;
284 /* Flags are returned unchanged. */
285 (*prop)->flags = payload->flags = rp->flags;
287 /* Take cookie, we must return it to sender unmodified. */
288 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
289 if (!payload->cookie) {
290 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
293 payload->cookie_len = SILC_SKE_COOKIE_LEN;
294 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
296 /* In case IV included flag and session port is set the first 16-bits of
297 cookie will include our session port. */
298 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
299 /* Take remote port */
300 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
303 SILC_PUT16_MSB(ske->session_port, payload->cookie);
306 /* Put our version to our reply */
307 payload->version = strdup(ske->version);
308 if (!payload->version) {
309 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
312 payload->version_len = strlen(ske->version);
314 /* Get supported Key Exchange groups */
315 cp = rp->ke_grp_list;
316 if (cp && strchr(cp, ',')) {
320 len = strcspn(cp, ",");
321 item = silc_calloc(len + 1, sizeof(char));
323 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
326 memcpy(item, cp, len);
328 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
330 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
331 SILC_LOG_DEBUG(("Found KE group `%s'", item));
333 payload->ke_grp_len = len;
334 payload->ke_grp_list = item;
348 if (!payload->ke_grp_len && !payload->ke_grp_list) {
349 SILC_LOG_DEBUG(("Could not find supported KE group"));
351 return SILC_SKE_STATUS_UNKNOWN_GROUP;
354 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
355 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
357 payload->ke_grp_len = rp->ke_grp_len;
358 payload->ke_grp_list = strdup(rp->ke_grp_list);
361 /* Save group to security properties */
362 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
363 if (status != SILC_SKE_STATUS_OK) {
365 return SILC_SKE_STATUS_UNKNOWN_GROUP;
368 /* Get supported PKCS algorithms */
369 cp = rp->pkcs_alg_list;
370 if (cp && strchr(cp, ',')) {
374 len = strcspn(cp, ",");
375 item = silc_calloc(len + 1, sizeof(char));
377 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
380 memcpy(item, cp, len);
382 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
384 if (silc_pkcs_find_algorithm(item, NULL)) {
385 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
387 payload->pkcs_alg_len = len;
388 payload->pkcs_alg_list = item;
402 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
403 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
404 silc_free(payload->ke_grp_list);
406 return SILC_SKE_STATUS_UNKNOWN_PKCS;
409 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
410 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
412 payload->pkcs_alg_len = rp->pkcs_alg_len;
413 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
416 /* Get supported encryption algorithms */
417 cp = rp->enc_alg_list;
418 if (cp && strchr(cp, ',')) {
422 len = strcspn(cp, ",");
423 item = silc_calloc(len + 1, sizeof(char));
425 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
428 memcpy(item, cp, len);
430 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
432 if (silc_cipher_is_supported(item) == TRUE) {
433 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
435 payload->enc_alg_len = len;
436 payload->enc_alg_list = item;
450 if (!payload->enc_alg_len && !payload->enc_alg_list) {
451 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
452 silc_free(payload->ke_grp_list);
453 silc_free(payload->pkcs_alg_list);
455 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
458 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
461 payload->enc_alg_len = rp->enc_alg_len;
462 payload->enc_alg_list = strdup(rp->enc_alg_list);
465 /* Save selected cipher to security properties */
466 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
467 silc_free(payload->ke_grp_list);
468 silc_free(payload->pkcs_alg_list);
470 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
473 /* Get supported hash algorithms */
474 cp = rp->hash_alg_list;
475 if (cp && strchr(cp, ',')) {
479 len = strcspn(cp, ",");
480 item = silc_calloc(len + 1, sizeof(char));
482 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
485 memcpy(item, cp, len);
487 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
489 if (silc_hash_is_supported(item) == TRUE) {
490 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
492 payload->hash_alg_len = len;
493 payload->hash_alg_list = item;
507 if (!payload->hash_alg_len && !payload->hash_alg_list) {
508 SILC_LOG_DEBUG(("Could not find supported hash alg"));
509 silc_free(payload->ke_grp_list);
510 silc_free(payload->pkcs_alg_list);
511 silc_free(payload->enc_alg_list);
513 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
516 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
519 payload->hash_alg_len = rp->hash_alg_len;
520 payload->hash_alg_list = strdup(rp->hash_alg_list);
523 /* Save selected hash algorithm to security properties */
524 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
525 silc_free(payload->ke_grp_list);
526 silc_free(payload->pkcs_alg_list);
527 silc_free(payload->enc_alg_list);
529 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
532 /* Get supported HMACs */
533 cp = rp->hmac_alg_list;
534 if (cp && strchr(cp, ',')) {
538 len = strcspn(cp, ",");
539 item = silc_calloc(len + 1, sizeof(char));
541 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
544 memcpy(item, cp, len);
546 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
548 if (silc_hmac_is_supported(item) == TRUE) {
549 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
551 payload->hmac_alg_len = len;
552 payload->hmac_alg_list = item;
566 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
567 SILC_LOG_DEBUG(("Could not find supported HMAC"));
568 silc_free(payload->ke_grp_list);
569 silc_free(payload->pkcs_alg_list);
570 silc_free(payload->enc_alg_list);
571 silc_free(payload->hash_alg_list);
573 return SILC_SKE_STATUS_UNKNOWN_HMAC;
576 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
579 payload->hmac_alg_len = rp->hmac_alg_len;
580 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
583 /* Save selected HMACc to security properties */
584 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
585 silc_free(payload->ke_grp_list);
586 silc_free(payload->pkcs_alg_list);
587 silc_free(payload->enc_alg_list);
588 silc_free(payload->hash_alg_list);
590 return SILC_SKE_STATUS_UNKNOWN_HMAC;
593 /* Get supported compression algorithms */
594 cp = rp->comp_alg_list;
595 if (cp && strchr(cp, ',')) {
599 len = strcspn(cp, ",");
600 item = silc_calloc(len + 1, sizeof(char));
602 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
605 memcpy(item, cp, len);
607 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
610 if (!strcmp(item, "none")) {
611 SILC_LOG_DEBUG(("Found Compression `%s'", item));
612 payload->comp_alg_len = len;
613 payload->comp_alg_list = item;
617 if (silc_hmac_is_supported(item) == TRUE) {
618 SILC_LOG_DEBUG(("Found Compression `%s'", item));
619 payload->comp_alg_len = len;
620 payload->comp_alg_list = item;
636 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
637 2 + payload->version_len +
638 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
639 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
640 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
642 /* Save our reply payload */
643 ske->start_payload = payload;
645 return SILC_SKE_STATUS_OK;
648 /* Creates random number such that 1 < rnd < n and at most length
649 of len bits. The rnd sent as argument must be initialized. */
651 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
655 SilcSKEStatus status = SILC_SKE_STATUS_OK;
656 unsigned char *string;
660 return SILC_SKE_STATUS_ERROR;
662 SILC_LOG_DEBUG(("Creating random number"));
666 /* Get the random number as string */
667 string = silc_rng_get_rn_data(ske->rng, l);
669 return SILC_SKE_STATUS_OUT_OF_MEMORY;
671 /* Decode the string into a MP integer */
672 silc_mp_bin2mp(string, l, rnd);
673 silc_mp_mod_2exp(rnd, rnd, len);
676 if (silc_mp_cmp_ui(rnd, 1) < 0)
677 status = SILC_SKE_STATUS_ERROR;
678 if (silc_mp_cmp(rnd, n) >= 0)
679 status = SILC_SKE_STATUS_ERROR;
681 memset(string, 'F', l);
687 /* Creates a hash value HASH as defined in the SKE protocol. If the
688 `initiator' is TRUE then this function is used to create the HASH_i
689 hash value defined in the protocol. If it is FALSE then this is used
690 to create the HASH value defined by the protocol. */
692 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
693 unsigned char *return_hash,
694 SilcUInt32 *return_hash_len,
697 SilcSKEStatus status = SILC_SKE_STATUS_OK;
699 unsigned char *e, *f, *KEY;
700 SilcUInt32 e_len, f_len, KEY_len;
703 SILC_LOG_DEBUG(("Start"));
705 if (initiator == FALSE) {
706 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
707 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
708 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
710 /* Format the buffer used to compute the hash value */
711 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
712 ske->ke2_payload->pk_len +
713 ske->ke1_payload->pk_len +
714 e_len + f_len + KEY_len);
716 return SILC_SKE_STATUS_OUT_OF_MEMORY;
718 /* Initiator is not required to send its public key */
719 if (!ske->ke1_payload->pk_data) {
721 silc_buffer_format(buf,
722 SILC_STR_UI_XNSTRING(
723 ske->start_payload_copy->data,
724 silc_buffer_len(ske->start_payload_copy)),
725 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
726 ske->ke2_payload->pk_len),
727 SILC_STR_UI_XNSTRING(e, e_len),
728 SILC_STR_UI_XNSTRING(f, f_len),
729 SILC_STR_UI_XNSTRING(KEY, KEY_len),
733 silc_buffer_format(buf,
734 SILC_STR_UI_XNSTRING(
735 ske->start_payload_copy->data,
736 silc_buffer_len(ske->start_payload_copy)),
737 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
738 ske->ke2_payload->pk_len),
739 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
740 ske->ke1_payload->pk_len),
741 SILC_STR_UI_XNSTRING(e, e_len),
742 SILC_STR_UI_XNSTRING(f, f_len),
743 SILC_STR_UI_XNSTRING(KEY, KEY_len),
747 silc_buffer_free(buf);
750 memset(KEY, 0, KEY_len);
754 return SILC_SKE_STATUS_ERROR;
759 memset(KEY, 0, KEY_len);
764 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
766 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
767 ske->ke1_payload->pk_len + e_len);
769 return SILC_SKE_STATUS_OUT_OF_MEMORY;
771 /* Format the buffer used to compute the hash value */
773 silc_buffer_format(buf,
774 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
775 silc_buffer_len(ske->start_payload_copy)),
776 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
777 ske->ke1_payload->pk_len),
778 SILC_STR_UI_XNSTRING(e, e_len),
781 silc_buffer_free(buf);
784 return SILC_SKE_STATUS_ERROR;
787 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
794 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
796 *return_hash_len = silc_hash_len(ske->prop->hash);
798 if (initiator == FALSE) {
799 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
801 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
804 silc_buffer_free(buf);
809 /* Generate rekey material */
811 static SilcSKERekeyMaterial
812 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
814 SilcSKERekeyMaterial rekey;
817 /* Create rekey material */
818 rekey = silc_calloc(1, sizeof(*rekey));
823 if (ske->prop->group)
824 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
825 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
826 hash = silc_hash_get_name(ske->prop->hash);
827 rekey->hash = silc_memdup(hash, strlen(hash));
832 if (rekey->pfs == FALSE) {
833 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
834 keymat->enc_key_len / 8);
835 if (!rekey->send_enc_key) {
839 rekey->enc_key_len = keymat->enc_key_len;
845 /* Assembles security properties */
847 static SilcSKEStartPayload
848 silc_ske_assemble_security_properties(SilcSKE ske,
849 SilcSKESecurityPropertyFlag flags,
852 SilcSKEStartPayload rp;
855 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
857 rp = silc_calloc(1, sizeof(*rp));
860 rp->flags = (unsigned char)flags;
862 /* Set random cookie */
863 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
864 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
865 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
866 rp->cookie_len = SILC_SKE_COOKIE_LEN;
868 /* In case IV included flag and session port is set the first 16-bits of
869 cookie will include our session port. */
870 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
871 SILC_PUT16_MSB(ske->session_port, rp->cookie);
874 rp->version = strdup(version);
875 rp->version_len = strlen(version);
877 /* Get supported Key Exhange groups */
878 rp->ke_grp_list = silc_ske_get_supported_groups();
879 rp->ke_grp_len = strlen(rp->ke_grp_list);
881 /* Get supported PKCS algorithms */
882 rp->pkcs_alg_list = silc_pkcs_get_supported();
883 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
885 /* Get supported encryption algorithms */
886 rp->enc_alg_list = silc_cipher_get_supported();
887 rp->enc_alg_len = strlen(rp->enc_alg_list);
889 /* Get supported hash algorithms */
890 rp->hash_alg_list = silc_hash_get_supported();
891 rp->hash_alg_len = strlen(rp->hash_alg_list);
893 /* Get supported HMACs */
894 rp->hmac_alg_list = silc_hmac_get_supported();
895 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
898 /* Get supported compression algorithms */
899 rp->comp_alg_list = strdup("none");
900 rp->comp_alg_len = strlen("none");
902 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
903 2 + rp->version_len +
904 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
905 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
906 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
911 /* Packet retransmission callback. */
913 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
915 SilcSKE ske = context;
917 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
919 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
920 ske->retry_count = 0;
921 ske->retry_timer = SILC_SKE_RETRY_MIN;
922 silc_free(ske->retrans.data);
923 ske->retrans.data = NULL;
924 ske->status = SILC_SKE_STATUS_TIMEOUT;
926 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
928 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
929 silc_fsm_continue_sync(&ske->fsm);
933 SILC_LOG_DEBUG(("Retransmitting packet"));
934 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
935 ske->retrans.data, ske->retrans.data_len);
938 /* Install retransmission timer */
940 static void silc_ske_install_retransmission(SilcSKE ske)
942 if (!silc_packet_stream_is_udp(ske->stream))
945 if (ske->retrans.data) {
946 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
948 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
949 ske, ske->retry_timer, 0);
951 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
952 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
955 /* Sends SILC packet. Handles retransmissions with UDP streams. */
957 static SilcBool silc_ske_packet_send(SilcSKE ske,
959 SilcPacketFlags flags,
960 const unsigned char *data,
965 /* Send the packet */
966 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
968 if (silc_packet_stream_is_udp(ske->stream) &&
969 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
970 silc_free(ske->retrans.data);
971 ske->retrans.type = type;
972 ske->retrans.flags = flags;
973 ske->retrans.data = silc_memdup(data, data_len);
974 ske->retrans.data_len = data_len;
975 silc_ske_install_retransmission(ske);
981 /* Calls completion callback. Completion is called always in this function
982 and must not be called anywhere else. */
984 static void silc_ske_completion(SilcSKE ske)
986 /* Call the completion callback */
987 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
988 if (ske->status != SILC_SKE_STATUS_OK)
989 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
990 ske->callbacks->context);
992 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
993 ske->rekey, ske->callbacks->context);
997 /* SKE FSM destructor. */
999 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
1000 void *destructor_context)
1002 SilcSKE ske = fsm_context;
1003 ske->running = FALSE;
1008 /* Key exchange timeout task callback */
1010 SILC_TASK_CALLBACK(silc_ske_timeout)
1012 SilcSKE ske = context;
1014 SILC_LOG_DEBUG(("Timeout"));
1017 ske->status = SILC_SKE_STATUS_TIMEOUT;
1019 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1021 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1023 silc_fsm_continue_sync(&ske->fsm);
1026 /******************************* Protocol API *******************************/
1028 /* Allocates new SKE object. */
1030 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1031 SilcSKR repository, SilcPublicKey public_key,
1032 SilcPrivateKey private_key, void *context)
1036 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1038 if (!rng || !schedule)
1042 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1046 ske = silc_calloc(1, sizeof(*ske));
1049 ske->status = SILC_SKE_STATUS_OK;
1051 ske->repository = repository;
1052 ske->user_data = context;
1053 ske->schedule = schedule;
1054 ske->public_key = public_key;
1055 ske->private_key = private_key;
1056 ske->retry_timer = SILC_SKE_RETRY_MIN;
1062 /* Free's SKE object. */
1064 void silc_ske_free(SilcSKE ske)
1066 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1075 /* If already aborted, destroy the session immediately */
1077 ske->status = SILC_SKE_STATUS_ERROR;
1079 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1081 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1082 silc_fsm_continue_sync(&ske->fsm);
1088 if (ske->refcnt > 0)
1091 /* Free start payload */
1092 if (ske->start_payload)
1093 silc_ske_payload_start_free(ske->start_payload);
1095 /* Free KE payload */
1096 if (ske->ke1_payload)
1097 silc_ske_payload_ke_free(ske->ke1_payload);
1098 if (ske->ke2_payload)
1099 silc_ske_payload_ke_free(ske->ke2_payload);
1100 silc_free(ske->remote_version);
1104 if (ske->prop->group)
1105 silc_ske_group_free(ske->prop->group);
1106 if (ske->prop->cipher)
1107 silc_cipher_free(ske->prop->cipher);
1108 if (ske->prop->hash)
1109 silc_hash_free(ske->prop->hash);
1110 if (ske->prop->hmac)
1111 silc_hmac_free(ske->prop->hmac);
1112 if (ske->prop->public_key)
1113 silc_pkcs_public_key_free(ske->prop->public_key);
1114 silc_free(ske->prop);
1117 silc_ske_free_key_material(ske->keymat);
1118 if (ske->start_payload_copy)
1119 silc_buffer_free(ske->start_payload_copy);
1121 silc_mp_uninit(ske->x);
1125 silc_mp_uninit(ske->KEY);
1126 silc_free(ske->KEY);
1128 silc_free(ske->retrans.data);
1129 silc_free(ske->hash);
1130 silc_free(ske->callbacks);
1132 memset(ske, 'F', sizeof(*ske));
1136 /* Return user context */
1138 void *silc_ske_get_context(SilcSKE ske)
1140 return ske->user_data;
1143 /* Sets protocol callbacks */
1145 void silc_ske_set_callbacks(SilcSKE ske,
1146 SilcSKEVerifyCb verify_key,
1147 SilcSKECompletionCb completed,
1151 silc_free(ske->callbacks);
1152 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1153 if (!ske->callbacks)
1155 ske->callbacks->verify_key = verify_key;
1156 ske->callbacks->completed = completed;
1157 ske->callbacks->context = context;
1161 /******************************** Initiator *********************************/
1163 /* Start protocol. Send our proposal */
1165 SILC_FSM_STATE(silc_ske_st_initiator_start)
1167 SilcSKE ske = fsm_context;
1168 SilcBuffer payload_buf;
1171 SILC_LOG_DEBUG(("Start"));
1175 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1176 return SILC_FSM_CONTINUE;
1179 /* Encode the payload */
1180 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1182 if (status != SILC_SKE_STATUS_OK) {
1183 /** Error encoding Start Payload */
1184 ske->status = status;
1185 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1186 return SILC_FSM_CONTINUE;
1189 /* Save the the payload buffer for future use. It is later used to
1190 compute the HASH value. */
1191 ske->start_payload_copy = payload_buf;
1193 /* Send the packet. */
1194 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1195 silc_buffer_data(payload_buf),
1196 silc_buffer_len(payload_buf))) {
1197 /** Error sending packet */
1198 SILC_LOG_DEBUG(("Error sending packet"));
1199 ske->status = SILC_SKE_STATUS_ERROR;
1200 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1201 return SILC_FSM_CONTINUE;
1204 /* Add key exchange timeout */
1205 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1206 ske, ske->timeout, 0);
1208 /** Wait for responder proposal */
1209 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1210 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1211 return SILC_FSM_WAIT;
1214 /* Phase-1. Receives responder's proposal */
1216 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1218 SilcSKE ske = fsm_context;
1219 SilcSKEStatus status;
1220 SilcSKEStartPayload payload;
1221 SilcSKESecurityProperties prop;
1222 SilcSKEDiffieHellmanGroup group = NULL;
1223 SilcBuffer packet_buf = &ske->packet->buffer;
1224 SilcUInt16 remote_port = 0;
1228 SILC_LOG_DEBUG(("Start"));
1230 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1231 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1232 silc_ske_install_retransmission(ske);
1233 silc_packet_free(ske->packet);
1235 return SILC_FSM_WAIT;
1238 /* Decode the payload */
1239 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1240 if (status != SILC_SKE_STATUS_OK) {
1241 /** Error decoding Start Payload */
1242 silc_packet_free(ske->packet);
1244 ske->status = status;
1245 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1246 return SILC_FSM_CONTINUE;
1249 /* Get remote ID and set it to stream */
1250 if (ske->packet->src_id_len) {
1251 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1252 ske->packet->src_id_type,
1253 (ske->packet->src_id_type == SILC_ID_SERVER ?
1254 (void *)&id.u.server_id : (void *)&id.u.client_id),
1255 (ske->packet->src_id_type == SILC_ID_SERVER ?
1256 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1257 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1258 (ske->packet->src_id_type == SILC_ID_SERVER ?
1259 (void *)&id.u.server_id : (void *)&id.u.client_id));
1262 silc_packet_free(ske->packet);
1265 /* Check that the cookie is returned unmodified. In case IV included
1266 flag and session port has been set, the first two bytes of cookie
1267 are the session port and we ignore them in this check. */
1268 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1269 /* Take remote port */
1270 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1273 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1274 SILC_SKE_COOKIE_LEN - coff)) {
1275 /** Invalid cookie */
1276 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1277 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1278 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1279 return SILC_FSM_CONTINUE;
1282 /* Check version string */
1283 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1284 status = silc_ske_check_version(ske);
1285 if (status != SILC_SKE_STATUS_OK) {
1286 /** Version mismatch */
1287 ske->status = status;
1288 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1289 return SILC_FSM_CONTINUE;
1292 /* Free our KE Start Payload context, we don't need it anymore. */
1293 silc_ske_payload_start_free(ske->start_payload);
1294 ske->start_payload = NULL;
1296 /* Take the selected security properties into use while doing
1297 the key exchange. This is used only while doing the key
1299 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1302 prop->flags = payload->flags;
1303 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1304 if (status != SILC_SKE_STATUS_OK)
1307 prop->group = group;
1308 prop->remote_port = remote_port;
1310 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1311 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1314 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1315 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1318 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1319 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1322 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1323 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1327 /* Save remote's KE Start Payload */
1328 ske->start_payload = payload;
1330 /** Send KE Payload */
1331 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1332 return SILC_FSM_CONTINUE;
1336 silc_ske_payload_start_free(payload);
1338 silc_ske_group_free(group);
1340 silc_cipher_free(prop->cipher);
1342 silc_hash_free(prop->hash);
1344 silc_hmac_free(prop->hmac);
1348 if (status == SILC_SKE_STATUS_OK)
1349 status = SILC_SKE_STATUS_ERROR;
1352 ske->status = status;
1353 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1354 return SILC_FSM_CONTINUE;
1357 /* Phase-2. Send KE payload */
1359 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1361 SilcSKE ske = fsm_context;
1362 SilcSKEStatus status;
1363 SilcBuffer payload_buf;
1365 SilcSKEKEPayload payload;
1368 SILC_LOG_DEBUG(("Start"));
1370 /* Create the random number x, 1 < x < q. */
1371 x = silc_calloc(1, sizeof(*x));
1373 /** 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;
1380 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1381 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1383 if (status != SILC_SKE_STATUS_OK) {
1384 /** Error generating random number */
1387 ske->status = status;
1388 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1389 return SILC_FSM_CONTINUE;
1392 /* Encode the result to Key Exchange Payload. */
1394 payload = silc_calloc(1, sizeof(*payload));
1396 /** Out of memory */
1399 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1400 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1401 return SILC_FSM_CONTINUE;
1403 ske->ke1_payload = payload;
1405 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1407 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1408 silc_mp_init(&payload->x);
1409 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1410 &ske->prop->group->group);
1412 /* Get public key */
1413 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1414 if (!payload->pk_data) {
1415 /** Error encoding public key */
1418 silc_mp_uninit(&payload->x);
1420 ske->ke1_payload = NULL;
1421 ske->status = SILC_SKE_STATUS_ERROR;
1422 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1423 return SILC_FSM_CONTINUE;
1425 payload->pk_len = pk_len;
1426 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1428 /* Compute signature data if we are doing mutual authentication */
1429 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1430 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1431 SilcUInt32 hash_len, sign_len;
1433 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1434 SILC_LOG_DEBUG(("Computing HASH_i value"));
1436 /* Compute the hash value */
1437 memset(hash, 0, sizeof(hash));
1438 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1440 SILC_LOG_DEBUG(("Signing HASH_i value"));
1442 /* Sign the hash value */
1443 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1444 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1445 /** Error computing signature */
1448 silc_mp_uninit(&payload->x);
1449 silc_free(payload->pk_data);
1451 ske->ke1_payload = NULL;
1452 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1453 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1454 return SILC_FSM_CONTINUE;
1456 payload->sign_data = silc_memdup(sign, sign_len);
1457 if (payload->sign_data)
1458 payload->sign_len = sign_len;
1459 memset(sign, 0, sizeof(sign));
1462 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1463 if (status != SILC_SKE_STATUS_OK) {
1464 /** Error encoding KE payload */
1467 silc_mp_uninit(&payload->x);
1468 silc_free(payload->pk_data);
1469 silc_free(payload->sign_data);
1471 ske->ke1_payload = NULL;
1472 ske->status = status;
1473 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1474 return SILC_FSM_CONTINUE;
1479 /* Check for backwards compatibility */
1481 /* Send the packet. */
1482 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1483 silc_buffer_data(payload_buf),
1484 silc_buffer_len(payload_buf))) {
1485 /** Error sending packet */
1486 SILC_LOG_DEBUG(("Error sending packet"));
1487 ske->status = SILC_SKE_STATUS_ERROR;
1488 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1489 return SILC_FSM_CONTINUE;
1492 silc_buffer_free(payload_buf);
1494 /** Waiting responder's KE payload */
1495 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1496 return SILC_FSM_WAIT;
1499 /* Phase-3. Process responder's KE payload */
1501 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1503 SilcSKE ske = fsm_context;
1504 SilcSKEStatus status;
1505 SilcSKEKEPayload payload;
1507 SilcBuffer packet_buf = &ske->packet->buffer;
1509 SILC_LOG_DEBUG(("Start"));
1511 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1512 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1513 silc_ske_install_retransmission(ske);
1514 silc_packet_free(ske->packet);
1516 return SILC_FSM_WAIT;
1519 /* Decode the payload */
1520 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1521 if (status != SILC_SKE_STATUS_OK) {
1522 /** Error decoding KE payload */
1523 silc_packet_free(ske->packet);
1525 ske->status = status;
1526 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1527 return SILC_FSM_CONTINUE;
1529 silc_packet_free(ske->packet);
1531 ske->ke2_payload = payload;
1533 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1534 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1535 "even though we require it"));
1536 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1540 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1542 /* Compute the shared secret key */
1543 KEY = silc_calloc(1, sizeof(*KEY));
1545 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1548 /* Decode the remote's public key */
1549 if (payload->pk_data &&
1550 !silc_pkcs_public_key_alloc(payload->pk_type,
1551 payload->pk_data, payload->pk_len,
1552 &ske->prop->public_key)) {
1553 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1554 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1558 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1560 SILC_LOG_DEBUG(("Verifying public key"));
1562 /** Waiting public key verification */
1563 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1565 /* If repository is provided, verify the key from there. */
1566 if (ske->repository) {
1569 find = silc_skr_find_alloc();
1571 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1574 silc_skr_find_set_pkcs_type(find,
1575 silc_pkcs_get_type(ske->prop->public_key));
1576 silc_skr_find_set_public_key(find, ske->prop->public_key);
1577 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1579 /* Find key from repository */
1580 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1581 find, silc_ske_skr_callback, ske));
1583 /* Verify from application */
1584 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1585 ske->callbacks->context,
1586 silc_ske_pk_verified, NULL));
1591 /** Process key material */
1592 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1593 return SILC_FSM_CONTINUE;
1596 silc_ske_payload_ke_free(payload);
1597 ske->ke2_payload = NULL;
1599 silc_mp_uninit(ske->KEY);
1600 silc_free(ske->KEY);
1603 if (status == SILC_SKE_STATUS_OK)
1604 return SILC_SKE_STATUS_ERROR;
1607 ske->status = status;
1608 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1609 return SILC_FSM_CONTINUE;
1612 /* Process key material */
1614 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1616 SilcSKE ske = fsm_context;
1617 SilcSKEStatus status;
1618 SilcSKEKEPayload payload;
1619 unsigned char hash[SILC_HASH_MAXLEN];
1620 SilcUInt32 hash_len;
1621 int key_len, block_len;
1625 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1626 return SILC_FSM_CONTINUE;
1629 /* Check result of public key verification */
1630 if (ske->status != SILC_SKE_STATUS_OK) {
1631 /** Public key not verified */
1632 SILC_LOG_DEBUG(("Public key verification failed"));
1633 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1634 return SILC_FSM_CONTINUE;
1637 payload = ske->ke2_payload;
1639 if (ske->prop->public_key) {
1640 SILC_LOG_DEBUG(("Public key is authentic"));
1642 /* Compute the hash value */
1643 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1644 if (status != SILC_SKE_STATUS_OK)
1647 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1649 /* Verify signature */
1650 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1651 payload->sign_len, hash, hash_len, NULL)) {
1652 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1653 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1657 SILC_LOG_DEBUG(("Signature is Ok"));
1659 ske->hash = silc_memdup(hash, hash_len);
1660 ske->hash_len = hash_len;
1661 memset(hash, 'F', hash_len);
1664 ske->status = SILC_SKE_STATUS_OK;
1666 /* In case we are doing rekey move to finish it. */
1669 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1670 return SILC_FSM_CONTINUE;
1673 /* Process key material */
1674 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1675 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1676 hash_len = silc_hash_len(ske->prop->hash);
1677 ske->keymat = silc_ske_process_key_material(ske, block_len,
1681 SILC_LOG_ERROR(("Error processing key material"));
1682 status = SILC_SKE_STATUS_ERROR;
1686 /* Send SUCCESS packet */
1687 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1688 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1689 /** Error sending packet */
1690 SILC_LOG_DEBUG(("Error sending packet"));
1691 ske->status = SILC_SKE_STATUS_ERROR;
1692 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1693 return SILC_FSM_CONTINUE;
1696 /** Waiting completion */
1697 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1698 return SILC_FSM_WAIT;
1701 memset(hash, 'F', sizeof(hash));
1702 silc_ske_payload_ke_free(payload);
1703 ske->ke2_payload = NULL;
1705 silc_mp_uninit(ske->KEY);
1706 silc_free(ske->KEY);
1710 memset(ske->hash, 'F', hash_len);
1711 silc_free(ske->hash);
1715 if (status == SILC_SKE_STATUS_OK)
1716 status = SILC_SKE_STATUS_ERROR;
1719 ske->status = status;
1720 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1721 return SILC_FSM_CONTINUE;
1724 /* Protocol completed */
1726 SILC_FSM_STATE(silc_ske_st_initiator_end)
1728 SilcSKE ske = fsm_context;
1730 SILC_LOG_DEBUG(("Start"));
1732 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1733 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1734 silc_ske_install_retransmission(ske);
1735 silc_packet_free(ske->packet);
1737 return SILC_FSM_WAIT;
1740 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1742 silc_packet_free(ske->packet);
1744 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1745 silc_schedule_task_del_by_context(ske->schedule, ske);
1747 /* Call completion */
1748 silc_ske_completion(ske);
1750 return SILC_FSM_FINISH;
1753 /* Aborted by application */
1755 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1757 SilcSKE ske = fsm_context;
1758 unsigned char data[4];
1760 SILC_LOG_DEBUG(("Aborted by caller"));
1762 /* Send FAILURE packet */
1763 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1764 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1766 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1767 silc_schedule_task_del_by_context(ske->schedule, ske);
1769 /* Call completion */
1770 silc_ske_completion(ske);
1772 return SILC_FSM_FINISH;
1775 /* Error occurred. Send error to remote host */
1777 SILC_FSM_STATE(silc_ske_st_initiator_error)
1779 SilcSKE ske = fsm_context;
1780 SilcSKEStatus status;
1781 unsigned char data[4];
1783 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1784 silc_ske_map_status(ske->status), ske->status));
1786 status = ske->status;
1787 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1788 status = SILC_SKE_STATUS_ERROR;
1790 /* Send FAILURE packet */
1791 SILC_PUT32_MSB((SilcUInt32)status, data);
1792 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1794 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1795 silc_schedule_task_del_by_context(ske->schedule, ske);
1797 /* Call completion */
1798 silc_ske_completion(ske);
1800 return SILC_FSM_FINISH;
1803 /* Failure received from remote */
1805 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1807 SilcSKE ske = fsm_context;
1808 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1810 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1811 silc_ske_map_status(ske->status), ske->status));
1813 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1814 SILC_GET32_MSB(error, ske->packet->buffer.data);
1815 ske->status = error;
1816 silc_packet_free(ske->packet);
1820 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1821 silc_schedule_task_del_by_context(ske->schedule, ske);
1823 /* Call completion */
1824 silc_ske_completion(ske);
1826 return SILC_FSM_FINISH;
1829 /* Starts the protocol as initiator */
1831 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1832 SilcPacketStream stream,
1833 SilcSKEParams params,
1834 SilcSKEStartPayload start_payload)
1836 SILC_LOG_DEBUG(("Start SKE as initiator"));
1838 if (!ske || !stream || !params || !params->version)
1841 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1844 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1847 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1848 ske->session_port = params->session_port;
1850 /* Generate security properties if not provided */
1851 if (!start_payload) {
1852 start_payload = silc_ske_assemble_security_properties(ske,
1859 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1860 ske->start_payload = start_payload;
1861 ske->version = params->version;
1862 ske->running = TRUE;
1864 /* Link to packet stream to get key exchange packets */
1865 ske->stream = stream;
1866 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1867 SILC_PACKET_KEY_EXCHANGE,
1868 SILC_PACKET_KEY_EXCHANGE_2,
1869 SILC_PACKET_SUCCESS,
1870 SILC_PACKET_FAILURE, -1);
1872 /* Start SKE as initiator */
1873 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1878 /******************************** Responder *********************************/
1880 /* Start protocol as responder. Wait initiator's start payload */
1882 SILC_FSM_STATE(silc_ske_st_responder_start)
1884 SilcSKE ske = fsm_context;
1886 SILC_LOG_DEBUG(("Start"));
1890 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1891 return SILC_FSM_CONTINUE;
1894 /* Add key exchange timeout */
1895 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1896 ske, ske->timeout, 0);
1898 /** Wait for initiator */
1899 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1900 return SILC_FSM_WAIT;
1903 /* Decode initiator's start payload. Select the security properties from
1904 the initiator's start payload and send our reply start payload back. */
1906 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1908 SilcSKE ske = fsm_context;
1909 SilcSKEStatus status;
1910 SilcSKEStartPayload remote_payload = NULL;
1911 SilcBuffer packet_buf = &ske->packet->buffer;
1913 SILC_LOG_DEBUG(("Start"));
1915 /* Decode the payload */
1916 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1917 if (status != SILC_SKE_STATUS_OK) {
1918 /** Error decoding Start Payload */
1919 silc_packet_free(ske->packet);
1921 ske->status = status;
1922 silc_fsm_next(fsm, silc_ske_st_responder_error);
1923 return SILC_FSM_CONTINUE;
1926 /* Take a copy of the payload buffer for future use. It is used to
1927 compute the HASH value. */
1928 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1930 silc_packet_free(ske->packet);
1933 /* Force the mutual authentication flag if we want to do it. */
1934 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1935 SILC_LOG_DEBUG(("Force mutual authentication"));
1936 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1939 /* Force PFS flag if we require it */
1940 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1941 SILC_LOG_DEBUG(("Force PFS"));
1942 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1945 /* Disable IV Included flag if requested */
1946 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1947 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1948 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1949 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1952 /* Check and select security properties */
1953 status = silc_ske_select_security_properties(ske, remote_payload,
1955 if (status != SILC_SKE_STATUS_OK) {
1956 /** Error selecting proposal */
1957 silc_ske_payload_start_free(remote_payload);
1958 ske->status = status;
1959 silc_fsm_next(fsm, silc_ske_st_responder_error);
1960 return SILC_FSM_CONTINUE;
1963 silc_ske_payload_start_free(remote_payload);
1965 /* Encode our reply payload to send the selected security properties */
1966 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1968 if (status != SILC_SKE_STATUS_OK)
1971 /* Send the packet. */
1972 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1973 silc_buffer_data(packet_buf),
1974 silc_buffer_len(packet_buf)))
1977 silc_buffer_free(packet_buf);
1979 /** Waiting initiator's KE payload */
1980 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1981 return SILC_FSM_WAIT;
1984 if (ske->prop->group)
1985 silc_ske_group_free(ske->prop->group);
1986 if (ske->prop->cipher)
1987 silc_cipher_free(ske->prop->cipher);
1988 if (ske->prop->hash)
1989 silc_hash_free(ske->prop->hash);
1990 if (ske->prop->hmac)
1991 silc_hmac_free(ske->prop->hmac);
1992 silc_free(ske->prop);
1995 if (status == SILC_SKE_STATUS_OK)
1996 status = SILC_SKE_STATUS_ERROR;
1999 ske->status = status;
2000 silc_fsm_next(fsm, silc_ske_st_responder_error);
2001 return SILC_FSM_CONTINUE;
2004 /* Phase-2. Decode initiator's KE payload */
2006 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2008 SilcSKE ske = fsm_context;
2009 SilcSKEStatus status;
2010 SilcSKEKEPayload recv_payload;
2011 SilcBuffer packet_buf = &ske->packet->buffer;
2013 SILC_LOG_DEBUG(("Start"));
2015 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2016 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2017 silc_ske_install_retransmission(ske);
2018 silc_packet_free(ske->packet);
2020 return SILC_FSM_WAIT;
2023 /* Decode Key Exchange Payload */
2024 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2025 if (status != SILC_SKE_STATUS_OK) {
2026 /** Error decoding KE payload */
2027 silc_packet_free(ske->packet);
2029 ske->status = status;
2030 silc_fsm_next(fsm, silc_ske_st_responder_error);
2031 return SILC_FSM_CONTINUE;
2034 ske->ke1_payload = recv_payload;
2036 silc_packet_free(ske->packet);
2039 /* Verify the received public key and verify the signature if we are
2040 doing mutual authentication. */
2041 if (ske->start_payload &&
2042 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2044 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2046 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2048 /** Public key not provided */
2049 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2050 "certificate), even though we require it"));
2051 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2052 silc_fsm_next(fsm, silc_ske_st_responder_error);
2053 return SILC_FSM_CONTINUE;
2056 /* Decode the remote's public key */
2057 if (recv_payload->pk_data &&
2058 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2059 recv_payload->pk_data,
2060 recv_payload->pk_len,
2061 &ske->prop->public_key)) {
2062 /** Error decoding public key */
2063 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2064 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2065 silc_fsm_next(fsm, silc_ske_st_responder_error);
2066 return SILC_FSM_CONTINUE;
2069 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2071 SILC_LOG_DEBUG(("Verifying public key"));
2073 /** Waiting public key verification */
2074 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2076 /* If repository is provided, verify the key from there. */
2077 if (ske->repository) {
2080 find = silc_skr_find_alloc();
2082 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2083 silc_fsm_next(fsm, silc_ske_st_responder_error);
2084 return SILC_FSM_CONTINUE;
2086 silc_skr_find_set_pkcs_type(find,
2087 silc_pkcs_get_type(ske->prop->public_key));
2088 silc_skr_find_set_public_key(find, ske->prop->public_key);
2089 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2091 /* Find key from repository */
2092 SILC_FSM_CALL(silc_skr_find(ske->repository,
2093 silc_fsm_get_schedule(fsm), find,
2094 silc_ske_skr_callback, ske));
2096 /* Verify from application */
2097 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2098 ske->callbacks->context,
2099 silc_ske_pk_verified, NULL));
2105 /** Generate KE2 payload */
2106 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2107 return SILC_FSM_CONTINUE;
2110 /* Phase-4. Generate KE2 payload */
2112 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2114 SilcSKE ske = fsm_context;
2115 SilcSKEStatus status;
2116 SilcSKEKEPayload recv_payload, send_payload;
2121 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2122 return SILC_FSM_CONTINUE;
2125 /* Check result of public key verification */
2126 if (ske->status != SILC_SKE_STATUS_OK) {
2127 /** Public key not verified */
2128 SILC_LOG_DEBUG(("Public key verification failed"));
2129 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2130 return SILC_FSM_CONTINUE;
2133 recv_payload = ske->ke1_payload;
2135 /* The public key verification was performed only if the Mutual
2136 Authentication flag is set. */
2137 if (ske->start_payload &&
2138 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2139 unsigned char hash[SILC_HASH_MAXLEN];
2140 SilcUInt32 hash_len;
2142 SILC_LOG_DEBUG(("Public key is authentic"));
2144 /* Compute the hash value */
2145 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2146 if (status != SILC_SKE_STATUS_OK) {
2147 /** Error computing hash */
2148 ske->status = status;
2149 silc_fsm_next(fsm, silc_ske_st_responder_error);
2150 return SILC_FSM_CONTINUE;
2153 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2155 /* Verify signature */
2156 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2157 recv_payload->sign_len, hash, hash_len, NULL)) {
2158 /** Incorrect signature */
2159 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2160 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2161 silc_fsm_next(fsm, silc_ske_st_responder_error);
2162 return SILC_FSM_CONTINUE;
2165 SILC_LOG_DEBUG(("Signature is Ok"));
2167 memset(hash, 'F', hash_len);
2170 /* Create the random number x, 1 < x < q. */
2171 x = silc_calloc(1, sizeof(*x));
2174 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2175 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2177 if (status != SILC_SKE_STATUS_OK) {
2178 /** Error generating random number */
2181 ske->status = status;
2182 silc_fsm_next(fsm, silc_ske_st_responder_error);
2183 return SILC_FSM_CONTINUE;
2186 /* Save the results for later processing */
2187 send_payload = silc_calloc(1, sizeof(*send_payload));
2189 ske->ke2_payload = send_payload;
2191 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2193 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2194 silc_mp_init(&send_payload->x);
2195 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2196 &ske->prop->group->group);
2198 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2200 /* Compute the shared secret key */
2201 KEY = silc_calloc(1, sizeof(*KEY));
2203 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2204 &ske->prop->group->group);
2207 /** Send KE2 payload */
2208 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2209 return SILC_FSM_CONTINUE;
2212 /* Phase-5. Send KE2 payload */
2214 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2216 SilcSKE ske = fsm_context;
2217 SilcSKEStatus status;
2218 SilcBuffer payload_buf;
2219 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2220 SilcUInt32 hash_len, sign_len, pk_len;
2222 SILC_LOG_DEBUG(("Start"));
2224 if (ske->public_key && ske->private_key) {
2225 SILC_LOG_DEBUG(("Getting public key"));
2227 /* Get the public key */
2228 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2230 /** Error encoding public key */
2231 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2232 silc_fsm_next(fsm, silc_ske_st_responder_error);
2233 return SILC_FSM_CONTINUE;
2235 ske->ke2_payload->pk_data = pk;
2236 ske->ke2_payload->pk_len = pk_len;
2238 SILC_LOG_DEBUG(("Computing HASH value"));
2240 /* Compute the hash value */
2241 memset(hash, 0, sizeof(hash));
2242 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2243 if (status != SILC_SKE_STATUS_OK) {
2244 /** Error computing hash */
2245 ske->status = status;
2246 silc_fsm_next(fsm, silc_ske_st_responder_error);
2247 return SILC_FSM_CONTINUE;
2250 ske->hash = silc_memdup(hash, hash_len);
2251 ske->hash_len = hash_len;
2253 SILC_LOG_DEBUG(("Signing HASH value"));
2255 /* Sign the hash value */
2256 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2257 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2258 /** Error computing signature */
2259 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2260 silc_fsm_next(fsm, silc_ske_st_responder_error);
2261 return SILC_FSM_CONTINUE;
2263 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2264 ske->ke2_payload->sign_len = sign_len;
2265 memset(sign, 0, sizeof(sign));
2267 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2269 /* Encode the Key Exchange Payload */
2270 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2272 if (status != SILC_SKE_STATUS_OK) {
2273 /** Error encoding KE payload */
2274 ske->status = status;
2275 silc_fsm_next(fsm, silc_ske_st_responder_error);
2276 return SILC_FSM_CONTINUE;
2279 /* Send the packet. */
2280 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2281 payload_buf->data, silc_buffer_len(payload_buf))) {
2282 SILC_LOG_DEBUG(("Error sending packet"));
2283 ske->status = SILC_SKE_STATUS_ERROR;
2284 silc_fsm_next(fsm, silc_ske_st_responder_error);
2285 return SILC_FSM_CONTINUE;
2288 silc_buffer_free(payload_buf);
2290 /* In case we are doing rekey move to finish it. */
2293 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2294 return SILC_FSM_CONTINUE;
2297 /** Waiting completion */
2298 silc_fsm_next(fsm, silc_ske_st_responder_end);
2299 return SILC_FSM_WAIT;
2302 /* Protocol completed */
2304 SILC_FSM_STATE(silc_ske_st_responder_end)
2306 SilcSKE ske = fsm_context;
2307 unsigned char tmp[4];
2308 SilcUInt32 hash_len, key_len, block_len;
2310 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2311 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2312 silc_ske_install_retransmission(ske);
2313 silc_packet_free(ske->packet);
2315 return SILC_FSM_WAIT;
2317 silc_packet_free(ske->packet);
2320 /* Process key material */
2321 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2322 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2323 hash_len = silc_hash_len(ske->prop->hash);
2324 ske->keymat = silc_ske_process_key_material(ske, block_len,
2328 /** Error processing key material */
2329 ske->status = SILC_SKE_STATUS_ERROR;
2330 silc_fsm_next(fsm, silc_ske_st_responder_error);
2331 return SILC_FSM_CONTINUE;
2334 /* Send SUCCESS packet */
2335 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2336 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2338 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2339 silc_schedule_task_del_by_context(ske->schedule, ske);
2341 /* Call completion */
2342 silc_ske_completion(ske);
2344 return SILC_FSM_FINISH;
2347 /* Aborted by application */
2349 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2351 SilcSKE ske = fsm_context;
2352 unsigned char tmp[4];
2354 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2356 /* Send FAILURE packet */
2357 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2358 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
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 /* Failure received from remote */
2371 SILC_FSM_STATE(silc_ske_st_responder_failure)
2373 SilcSKE ske = fsm_context;
2374 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2376 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2378 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2379 SILC_GET32_MSB(error, ske->packet->buffer.data);
2380 ske->status = error;
2381 silc_packet_free(ske->packet);
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 /* Error occurred */
2396 SILC_FSM_STATE(silc_ske_st_responder_error)
2398 SilcSKE ske = fsm_context;
2399 unsigned char tmp[4];
2401 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2402 ske->status, silc_ske_map_status(ske->status)));
2404 /* Send FAILURE packet */
2405 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2406 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2407 SILC_PUT32_MSB(ske->status, tmp);
2408 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2410 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2411 silc_schedule_task_del_by_context(ske->schedule, ske);
2413 /* Call completion */
2414 silc_ske_completion(ske);
2416 return SILC_FSM_FINISH;
2419 /* Starts the protocol as responder. */
2421 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2422 SilcPacketStream stream,
2423 SilcSKEParams params)
2425 SILC_LOG_DEBUG(("Start SKE as responder"));
2427 if (!ske || !stream || !params || !params->version)
2430 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2433 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2436 ske->responder = TRUE;
2437 ske->flags = params->flags;
2438 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2439 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2440 ske->session_port = params->session_port;
2441 ske->version = strdup(params->version);
2444 ske->running = TRUE;
2446 /* Link to packet stream to get key exchange packets */
2447 ske->stream = stream;
2448 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2449 SILC_PACKET_KEY_EXCHANGE,
2450 SILC_PACKET_KEY_EXCHANGE_1,
2451 SILC_PACKET_SUCCESS,
2452 SILC_PACKET_FAILURE, -1);
2454 /* Start SKE as responder */
2455 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2460 /***************************** Initiator Rekey ******************************/
2464 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2466 SilcSKE ske = fsm_context;
2469 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2473 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2474 return SILC_FSM_CONTINUE;
2477 /* Add rekey exchange timeout */
2478 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2481 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2484 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2485 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2486 return SILC_FSM_CONTINUE;
2489 /* Send REKEY packet to start rekey protocol */
2490 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2491 /** Error sending packet */
2492 SILC_LOG_DEBUG(("Error sending packet"));
2493 ske->status = SILC_SKE_STATUS_ERROR;
2494 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2495 return SILC_FSM_CONTINUE;
2498 /* If doing rekey without PFS, move directly to the end of the protocol. */
2499 if (!ske->rekey->pfs) {
2500 /** Rekey without PFS */
2501 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2502 return SILC_FSM_CONTINUE;
2505 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2507 if (status != SILC_SKE_STATUS_OK) {
2508 /** Unknown group */
2509 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2510 return SILC_FSM_CONTINUE;
2513 /** Rekey with PFS */
2514 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2515 return SILC_FSM_CONTINUE;
2518 /* Sends REKEY_DONE packet to finish the protocol. */
2520 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2522 SilcSKE ske = fsm_context;
2523 SilcCipher send_key;
2526 SilcUInt32 key_len, block_len, hash_len, x_len;
2527 unsigned char *pfsbuf;
2529 SILC_LOG_DEBUG(("Start"));
2531 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2532 key_len = silc_cipher_get_key_len(send_key);
2533 block_len = silc_cipher_get_block_len(send_key);
2535 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2536 /** Cannot allocate hash */
2537 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2538 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2539 return SILC_FSM_CONTINUE;
2541 hash_len = silc_hash_len(hash);
2543 /* Process key material */
2544 if (ske->rekey->pfs) {
2546 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2548 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2551 memset(pfsbuf, 0, x_len);
2557 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2558 ske->rekey->enc_key_len / 8,
2564 SILC_LOG_ERROR(("Error processing key material"));
2565 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2566 return SILC_FSM_CONTINUE;
2569 ske->prop->cipher = send_key;
2570 ske->prop->hmac = hmac_send;
2571 ske->prop->hash = hash;
2573 /* Get sending keys */
2574 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2575 &hmac_send, NULL, NULL)) {
2576 /** Cannot get keys */
2577 ske->status = SILC_SKE_STATUS_ERROR;
2578 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2579 return SILC_FSM_CONTINUE;
2582 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2583 packet sent after this call will be protected with the new keys. */
2584 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2586 /** Cannot set keys */
2587 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2588 ske->status = SILC_SKE_STATUS_ERROR;
2589 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2590 return SILC_FSM_CONTINUE;
2593 /** Wait for REKEY_DONE */
2594 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2595 return SILC_FSM_WAIT;
2598 /* Rekey protocol end */
2600 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2602 SilcSKE ske = fsm_context;
2603 SilcCipher receive_key;
2604 SilcHmac hmac_receive;
2605 SilcSKERekeyMaterial rekey;
2607 SILC_LOG_DEBUG(("Start"));
2609 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2610 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2611 silc_packet_free(ske->packet);
2613 return SILC_FSM_WAIT;
2616 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2617 ske->prop->cipher = receive_key;
2618 ske->prop->hmac = hmac_receive;
2620 /* Get receiving keys */
2621 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2622 NULL, &hmac_receive, NULL)) {
2623 /** Cannot get keys */
2624 ske->status = SILC_SKE_STATUS_ERROR;
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_fsm_next(fsm, silc_ske_st_initiator_error);
2637 return SILC_FSM_CONTINUE;
2640 SILC_LOG_DEBUG(("Rekey completed successfully"));
2642 /* Generate new rekey material */
2643 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2646 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2647 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2648 return SILC_FSM_CONTINUE;
2650 rekey->pfs = ske->rekey->pfs;
2653 ske->prop->cipher = NULL;
2654 ske->prop->hmac = NULL;
2655 silc_packet_free(ske->packet);
2657 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2658 silc_schedule_task_del_by_context(ske->schedule, ske);
2660 /* Call completion */
2661 silc_ske_completion(ske);
2663 return SILC_FSM_FINISH;
2666 /* Starts rekey protocol as initiator */
2669 silc_ske_rekey_initiator(SilcSKE ske,
2670 SilcPacketStream stream,
2671 SilcSKERekeyMaterial rekey)
2673 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2675 if (!ske || !stream || !rekey)
2678 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2681 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2685 ske->responder = FALSE;
2686 ske->running = TRUE;
2687 ske->rekeying = TRUE;
2689 /* Link to packet stream to get key exchange packets */
2690 ske->stream = stream;
2691 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2693 SILC_PACKET_REKEY_DONE,
2694 SILC_PACKET_KEY_EXCHANGE_2,
2695 SILC_PACKET_SUCCESS,
2696 SILC_PACKET_FAILURE, -1);
2698 /* Start SKE rekey as initiator */
2699 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2704 /***************************** Responder Rekey ******************************/
2706 /* Wait for initiator's packet */
2708 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2710 SilcSKE ske = fsm_context;
2712 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2716 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2717 return SILC_FSM_CONTINUE;
2720 /* Add rekey exchange timeout */
2721 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2725 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2727 /* If REKEY packet already received process it directly */
2728 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2729 return SILC_FSM_CONTINUE;
2731 /* Wait for REKEY */
2732 return SILC_FSM_WAIT;
2735 /* Process initiator's REKEY packet */
2737 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2739 SilcSKE ske = fsm_context;
2740 SilcSKEStatus status;
2742 SILC_LOG_DEBUG(("Start"));
2744 if (ske->packet->type != SILC_PACKET_REKEY) {
2745 ske->status = SILC_SKE_STATUS_ERROR;
2746 silc_packet_free(ske->packet);
2748 silc_fsm_next(fsm, silc_ske_st_responder_error);
2749 return SILC_FSM_CONTINUE;
2752 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2755 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2756 silc_fsm_next(fsm, silc_ske_st_responder_error);
2757 return SILC_FSM_CONTINUE;
2760 /* If doing rekey without PFS, move directly to the end of the protocol. */
2761 if (!ske->rekey->pfs) {
2762 /** Rekey without PFS */
2763 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2764 return SILC_FSM_CONTINUE;
2767 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2769 if (status != SILC_SKE_STATUS_OK) {
2770 /** Unknown group */
2771 silc_fsm_next(fsm, silc_ske_st_responder_error);
2772 return SILC_FSM_CONTINUE;
2775 /** Rekey with PFS */
2776 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2777 return SILC_FSM_WAIT;
2780 /* Sends REKEY_DONE packet to finish the protocol. */
2782 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2784 SilcSKE ske = fsm_context;
2785 SilcCipher send_key;
2788 SilcUInt32 key_len, block_len, hash_len, x_len;
2789 unsigned char *pfsbuf;
2791 SILC_LOG_DEBUG(("Start"));
2793 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2794 key_len = silc_cipher_get_key_len(send_key);
2795 block_len = silc_cipher_get_block_len(send_key);
2797 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2798 /** Cannot allocate hash */
2799 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2800 silc_fsm_next(fsm, silc_ske_st_responder_error);
2801 return SILC_FSM_CONTINUE;
2803 hash_len = silc_hash_len(hash);
2805 /* Process key material */
2806 if (ske->rekey->pfs) {
2808 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2810 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2813 memset(pfsbuf, 0, x_len);
2819 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2820 ske->rekey->enc_key_len / 8,
2826 SILC_LOG_ERROR(("Error processing key material"));
2827 silc_fsm_next(fsm, silc_ske_st_responder_error);
2828 return SILC_FSM_CONTINUE;
2831 ske->prop->cipher = send_key;
2832 ske->prop->hmac = hmac_send;
2833 ske->prop->hash = hash;
2835 /* Get sending keys */
2836 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2837 &hmac_send, NULL, NULL)) {
2838 /** Cannot get keys */
2839 ske->status = SILC_SKE_STATUS_ERROR;
2840 silc_fsm_next(fsm, silc_ske_st_responder_error);
2841 return SILC_FSM_CONTINUE;
2844 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2845 packet sent after this call will be protected with the new keys. */
2846 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2848 /** Cannot set keys */
2849 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2850 ske->status = SILC_SKE_STATUS_ERROR;
2851 silc_fsm_next(fsm, silc_ske_st_responder_error);
2852 return SILC_FSM_CONTINUE;
2855 /** Wait for REKEY_DONE */
2856 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2857 return SILC_FSM_WAIT;
2860 /* Rekey protocol end */
2862 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2864 SilcSKE ske = fsm_context;
2865 SilcCipher receive_key;
2866 SilcHmac hmac_receive;
2867 SilcSKERekeyMaterial rekey;
2869 SILC_LOG_DEBUG(("Start"));
2871 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2872 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2873 silc_packet_free(ske->packet);
2875 return SILC_FSM_WAIT;
2878 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2879 ske->prop->cipher = receive_key;
2880 ske->prop->hmac = hmac_receive;
2882 /* Get receiving keys */
2883 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2884 NULL, &hmac_receive, NULL)) {
2885 /** Cannot get keys */
2886 ske->status = SILC_SKE_STATUS_ERROR;
2887 silc_fsm_next(fsm, silc_ske_st_responder_error);
2888 return SILC_FSM_CONTINUE;
2891 /* Set new receiving keys into use. All packets received after this will
2892 be decrypted with the new keys. */
2893 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2894 hmac_receive, FALSE)) {
2895 /** Cannot set keys */
2896 SILC_LOG_DEBUG(("Cannot set new keys"));
2897 ske->status = SILC_SKE_STATUS_ERROR;
2898 silc_fsm_next(fsm, silc_ske_st_responder_error);
2899 return SILC_FSM_CONTINUE;
2902 SILC_LOG_DEBUG(("Rekey completed successfully"));
2904 /* Generate new rekey material */
2905 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2908 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2909 silc_fsm_next(fsm, silc_ske_st_responder_error);
2910 return SILC_FSM_CONTINUE;
2912 rekey->pfs = ske->rekey->pfs;
2915 ske->prop->cipher = NULL;
2916 ske->prop->hmac = NULL;
2917 silc_packet_free(ske->packet);
2919 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2920 silc_schedule_task_del_by_context(ske->schedule, ske);
2922 /* Call completion */
2923 silc_ske_completion(ske);
2925 return SILC_FSM_FINISH;
2928 /* Starts rekey protocol as responder */
2931 silc_ske_rekey_responder(SilcSKE ske,
2932 SilcPacketStream stream,
2933 SilcSKERekeyMaterial rekey,
2936 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2938 if (!ske || !stream || !rekey)
2941 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2944 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2948 ske->responder = TRUE;
2949 ske->running = TRUE;
2950 ske->rekeying = TRUE;
2951 ske->packet = packet;
2953 /* Link to packet stream to get key exchange packets */
2954 ske->stream = stream;
2955 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2957 SILC_PACKET_REKEY_DONE,
2958 SILC_PACKET_KEY_EXCHANGE_1,
2959 SILC_PACKET_SUCCESS,
2960 SILC_PACKET_FAILURE, -1);
2962 /* Start SKE rekey as responder */
2963 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2968 /* Processes the provided key material `data' as the SILC protocol
2969 specification defines. */
2972 silc_ske_process_key_material_data(unsigned char *data,
2973 SilcUInt32 data_len,
2974 SilcUInt32 req_iv_len,
2975 SilcUInt32 req_enc_key_len,
2976 SilcUInt32 req_hmac_key_len,
2980 unsigned char hashd[SILC_HASH_MAXLEN];
2981 SilcUInt32 hash_len = req_hmac_key_len;
2982 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2983 SilcSKEKeyMaterial key;
2985 SILC_LOG_DEBUG(("Start"));
2987 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2990 key = silc_calloc(1, sizeof(*key));
2994 buf = silc_buffer_alloc_size(1 + data_len);
2997 silc_buffer_format(buf,
2998 SILC_STR_UI_CHAR(0),
2999 SILC_STR_UI_XNSTRING(data, data_len),
3003 memset(hashd, 0, sizeof(hashd));
3005 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3006 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3007 memcpy(key->send_iv, hashd, req_iv_len);
3008 memset(hashd, 0, sizeof(hashd));
3010 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3011 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3012 memcpy(key->receive_iv, hashd, req_iv_len);
3013 key->iv_len = req_iv_len;
3015 /* Take the encryption keys. If requested key size is more than
3016 the size of hash length we will distribute more key material
3017 as protocol defines. */
3019 if (enc_key_len > hash_len) {
3021 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3022 k3[SILC_HASH_MAXLEN];
3023 unsigned char *dtmp;
3026 if (enc_key_len > (3 * hash_len))
3029 /* Take first round */
3030 memset(k1, 0, sizeof(k1));
3031 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3033 /* Take second round */
3034 dist = silc_buffer_alloc_size(data_len + hash_len);
3037 silc_buffer_format(dist,
3038 SILC_STR_UI_XNSTRING(data, data_len),
3039 SILC_STR_UI_XNSTRING(k1, hash_len),
3041 memset(k2, 0, sizeof(k2));
3042 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3044 /* Take third round */
3045 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3046 silc_buffer_pull_tail(dist, hash_len);
3047 silc_buffer_pull(dist, data_len + hash_len);
3048 silc_buffer_format(dist,
3049 SILC_STR_UI_XNSTRING(k2, hash_len),
3051 silc_buffer_push(dist, data_len + hash_len);
3052 memset(k3, 0, sizeof(k3));
3053 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3055 /* Then, save the keys */
3056 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3057 memcpy(dtmp, k1, hash_len);
3058 memcpy(dtmp + hash_len, k2, hash_len);
3059 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3061 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3062 memcpy(key->send_enc_key, dtmp, enc_key_len);
3063 key->enc_key_len = req_enc_key_len;
3065 memset(dtmp, 0, (3 * hash_len));
3066 memset(k1, 0, sizeof(k1));
3067 memset(k2, 0, sizeof(k2));
3068 memset(k3, 0, sizeof(k3));
3070 silc_buffer_clear(dist);
3071 silc_buffer_free(dist);
3073 /* Take normal hash as key */
3074 memset(hashd, 0, sizeof(hashd));
3075 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3076 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3077 memcpy(key->send_enc_key, hashd, enc_key_len);
3078 key->enc_key_len = req_enc_key_len;
3082 if (enc_key_len > hash_len) {
3084 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3085 k3[SILC_HASH_MAXLEN];
3086 unsigned char *dtmp;
3089 if (enc_key_len > (3 * hash_len))
3092 /* Take first round */
3093 memset(k1, 0, sizeof(k1));
3094 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3096 /* Take second round */
3097 dist = silc_buffer_alloc_size(data_len + hash_len);
3100 silc_buffer_format(dist,
3101 SILC_STR_UI_XNSTRING(data, data_len),
3102 SILC_STR_UI_XNSTRING(k1, hash_len),
3104 memset(k2, 0, sizeof(k2));
3105 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3107 /* Take third round */
3108 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3109 silc_buffer_pull_tail(dist, hash_len);
3110 silc_buffer_pull(dist, data_len + hash_len);
3111 silc_buffer_format(dist,
3112 SILC_STR_UI_XNSTRING(k2, hash_len),
3114 silc_buffer_push(dist, data_len + hash_len);
3115 memset(k3, 0, sizeof(k3));
3116 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3118 /* Then, save the keys */
3119 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3120 memcpy(dtmp, k1, hash_len);
3121 memcpy(dtmp + hash_len, k2, hash_len);
3122 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3124 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3125 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3126 key->enc_key_len = req_enc_key_len;
3128 memset(dtmp, 0, (3 * hash_len));
3129 memset(k1, 0, sizeof(k1));
3130 memset(k2, 0, sizeof(k2));
3131 memset(k3, 0, sizeof(k3));
3133 silc_buffer_clear(dist);
3134 silc_buffer_free(dist);
3136 /* Take normal hash as key */
3137 memset(hashd, 0, sizeof(hashd));
3138 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3139 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3140 memcpy(key->receive_enc_key, hashd, enc_key_len);
3141 key->enc_key_len = req_enc_key_len;
3144 /* Take HMAC keys */
3145 memset(hashd, 0, sizeof(hashd));
3147 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3148 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3149 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3150 memset(hashd, 0, sizeof(hashd));
3152 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3153 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3154 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3155 key->hmac_key_len = req_hmac_key_len;
3156 memset(hashd, 0, sizeof(hashd));
3158 silc_buffer_clear(buf);
3159 silc_buffer_free(buf);
3161 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3166 /* Processes negotiated key material as protocol specifies. This returns
3167 the actual keys to be used in the SILC. */
3170 silc_ske_process_key_material(SilcSKE ske,
3171 SilcUInt32 req_iv_len,
3172 SilcUInt32 req_enc_key_len,
3173 SilcUInt32 req_hmac_key_len,
3174 SilcSKERekeyMaterial *rekey)
3177 unsigned char *tmpbuf;
3179 SilcSKEKeyMaterial key;
3181 /* Encode KEY to binary data */
3182 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3184 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3187 silc_buffer_format(buf,
3188 SILC_STR_UI_XNSTRING(tmpbuf, klen),
3189 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
3192 /* Process the key material */
3193 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3194 req_iv_len, req_enc_key_len,
3198 memset(tmpbuf, 0, klen);
3200 silc_buffer_clear(buf);
3201 silc_buffer_free(buf);
3204 *rekey = silc_ske_make_rekey_material(ske, key);
3212 /* Free key material structure */
3214 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3220 silc_free(key->send_iv);
3221 if (key->receive_iv)
3222 silc_free(key->receive_iv);
3223 if (key->send_enc_key) {
3224 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3225 silc_free(key->send_enc_key);
3227 if (key->receive_enc_key) {
3228 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3229 silc_free(key->receive_enc_key);
3231 if (key->send_hmac_key) {
3232 memset(key->send_hmac_key, 0, key->hmac_key_len);
3233 silc_free(key->send_hmac_key);
3235 if (key->receive_hmac_key) {
3236 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3237 silc_free(key->receive_hmac_key);
3242 /* Free rekey material */
3244 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3248 if (rekey->send_enc_key) {
3249 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3250 silc_free(rekey->send_enc_key);
3252 silc_free(rekey->hash);
3256 /* Set keys into use */
3258 SilcBool silc_ske_set_keys(SilcSKE ske,
3259 SilcSKEKeyMaterial keymat,
3260 SilcSKESecurityProperties prop,
3261 SilcCipher *ret_send_key,
3262 SilcCipher *ret_receive_key,
3263 SilcHmac *ret_hmac_send,
3264 SilcHmac *ret_hmac_receive,
3267 unsigned char iv[32];
3268 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3270 /* Allocate ciphers to be used in the communication */
3272 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3276 if (ret_receive_key) {
3277 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3282 /* Allocate HMACs */
3283 if (ret_hmac_send) {
3284 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3288 if (ret_hmac_receive) {
3289 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3294 /* Set key material */
3295 memset(iv, 0, sizeof(iv));
3296 if (ske->responder) {
3298 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3299 keymat->enc_key_len, TRUE);
3301 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3302 memcpy(iv, ske->hash, 4);
3303 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3304 silc_cipher_set_iv(*ret_send_key, iv);
3306 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3309 if (ret_receive_key) {
3310 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3311 keymat->enc_key_len, FALSE);
3313 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3314 memcpy(iv, ske->hash, 4);
3315 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3316 silc_cipher_set_iv(*ret_receive_key, iv);
3318 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3322 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3323 keymat->hmac_key_len);
3324 if (ret_hmac_receive)
3325 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3326 keymat->hmac_key_len);
3329 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3330 keymat->enc_key_len, TRUE);
3332 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3333 memcpy(iv, ske->hash, 4);
3334 memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
3335 silc_cipher_set_iv(*ret_send_key, iv);
3337 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3340 if (ret_receive_key) {
3341 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3342 keymat->enc_key_len, FALSE);
3344 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3345 memcpy(iv, ske->hash, 4);
3346 memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
3347 silc_cipher_set_iv(*ret_receive_key, iv);
3349 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3353 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3354 keymat->hmac_key_len);
3355 if (ret_hmac_receive)
3356 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3357 keymat->hmac_key_len);
3362 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3369 const char *silc_ske_status_string[] =
3373 "Unexpected error occurred",
3374 "Bad payload in packet",
3375 "Unsupported group",
3376 "Unsupported cipher",
3378 "Unsupported hash function",
3380 "Unsupported public key (or certificate)",
3381 "Incorrect signature",
3382 "Bad or unsupported version",
3386 "Remote did not provide public key",
3387 "Bad reserved field in packet",
3388 "Bad payload length in packet",
3389 "Error computing signature",
3390 "System out of memory",
3391 "Key exchange timeout",
3396 /* Maps status to readable string and returns the string. If string is not
3397 found and empty character string ("") is returned. */
3399 const char *silc_ske_map_status(SilcSKEStatus status)
3403 for (i = 0; silc_ske_status_string[i]; i++)
3405 return silc_ske_status_string[i];
3410 /* Parses remote host's version string. */
3412 SilcBool silc_ske_parse_version(SilcSKE ske,
3413 SilcUInt32 *protocol_version,
3414 char **protocol_version_string,
3415 SilcUInt32 *software_version,
3416 char **software_version_string,
3417 char **vendor_version)
3419 return silc_parse_version_string(ske->remote_version,
3421 protocol_version_string,
3423 software_version_string,
3427 /* Get security properties */
3429 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3434 /* Get key material */
3436 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)