5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2008 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 if (!ske->remote_version || !ske->version)
186 return SILC_SKE_STATUS_BAD_VERSION;
188 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
190 return SILC_SKE_STATUS_BAD_VERSION;
192 return SILC_SKE_STATUS_OK;
195 /* Selects the supported security properties from the initiator's Key
196 Exchange Start Payload. A responder function. Saves our reply
197 start payload to ske->start_payload. */
200 silc_ske_select_security_properties(SilcSKE ske,
201 SilcSKEStartPayload remote_payload,
202 SilcSKESecurityProperties *prop)
204 SilcSKEStatus status;
205 SilcSKEStartPayload rp, payload;
209 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
213 /* Check for mandatory fields */
214 if (!rp->ke_grp_len) {
215 SILC_LOG_DEBUG(("KE group not defined in payload"));
216 return SILC_SKE_STATUS_BAD_PAYLOAD;
218 if (!rp->pkcs_alg_len) {
219 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
220 return SILC_SKE_STATUS_BAD_PAYLOAD;
222 if (!rp->enc_alg_len) {
223 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
224 return SILC_SKE_STATUS_BAD_PAYLOAD;
226 if (!rp->hash_alg_len) {
227 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
228 return SILC_SKE_STATUS_BAD_PAYLOAD;
230 if (!rp->hmac_alg_len) {
231 SILC_LOG_DEBUG(("HMAC not defined in payload"));
232 return SILC_SKE_STATUS_BAD_PAYLOAD;
235 /* Allocate security properties */
236 *prop = silc_calloc(1, sizeof(**prop));
238 return SILC_SKE_STATUS_OUT_OF_MEMORY;
240 /* Allocate our reply start payload */
241 payload = silc_calloc(1, sizeof(*payload));
244 return SILC_SKE_STATUS_OUT_OF_MEMORY;
247 /* Check version string */
248 ske->remote_version = silc_memdup(rp->version, rp->version_len);
249 status = silc_ske_check_version(ske);
250 if (status != SILC_SKE_STATUS_OK) {
251 ske->status = status;
255 /* Flags are returned unchanged. */
256 (*prop)->flags = payload->flags = rp->flags;
258 /* Take cookie, we must return it to sender unmodified. */
259 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
260 if (!payload->cookie) {
261 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
264 payload->cookie_len = SILC_SKE_COOKIE_LEN;
265 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
267 /* In case IV included flag and session port is set the first 16-bits of
268 cookie will include our session port. */
269 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
270 /* Take remote port */
271 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
274 SILC_PUT16_MSB(ske->session_port, payload->cookie);
277 /* Put our version to our reply */
278 payload->version = strdup(ske->version);
279 if (!payload->version) {
280 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
283 payload->version_len = strlen(ske->version);
285 /* Get supported Key Exchange groups */
286 cp = rp->ke_grp_list;
287 if (cp && strchr(cp, ',')) {
291 len = strcspn(cp, ",");
292 item = silc_calloc(len + 1, sizeof(char));
294 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
297 memcpy(item, cp, len);
299 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
301 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
302 SILC_LOG_DEBUG(("Found KE group `%s'", item));
304 payload->ke_grp_len = len;
305 payload->ke_grp_list = item;
319 if (!payload->ke_grp_len && !payload->ke_grp_list) {
320 SILC_LOG_DEBUG(("Could not find supported KE group"));
322 return SILC_SKE_STATUS_UNKNOWN_GROUP;
325 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
326 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
328 payload->ke_grp_len = rp->ke_grp_len;
329 payload->ke_grp_list = strdup(rp->ke_grp_list);
332 /* Save group to security properties */
333 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
334 if (status != SILC_SKE_STATUS_OK) {
336 return SILC_SKE_STATUS_UNKNOWN_GROUP;
339 /* Get supported PKCS algorithms */
340 cp = rp->pkcs_alg_list;
341 if (cp && strchr(cp, ',')) {
345 len = strcspn(cp, ",");
346 item = silc_calloc(len + 1, sizeof(char));
348 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
351 memcpy(item, cp, len);
353 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
355 if (silc_pkcs_find_algorithm(item, NULL)) {
356 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
358 payload->pkcs_alg_len = len;
359 payload->pkcs_alg_list = item;
373 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
374 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
375 silc_free(payload->ke_grp_list);
377 return SILC_SKE_STATUS_UNKNOWN_PKCS;
380 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
381 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
383 payload->pkcs_alg_len = rp->pkcs_alg_len;
384 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
387 /* Get supported encryption algorithms */
388 cp = rp->enc_alg_list;
389 if (cp && strchr(cp, ',')) {
393 len = strcspn(cp, ",");
394 item = silc_calloc(len + 1, sizeof(char));
396 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
399 memcpy(item, cp, len);
401 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
403 if (silc_cipher_is_supported(item) == TRUE) {
404 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
406 payload->enc_alg_len = len;
407 payload->enc_alg_list = item;
421 if (!payload->enc_alg_len && !payload->enc_alg_list) {
422 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
423 silc_free(payload->ke_grp_list);
424 silc_free(payload->pkcs_alg_list);
426 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
429 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
432 payload->enc_alg_len = rp->enc_alg_len;
433 payload->enc_alg_list = strdup(rp->enc_alg_list);
436 /* Save selected cipher to security properties */
437 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
438 silc_free(payload->ke_grp_list);
439 silc_free(payload->pkcs_alg_list);
441 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
444 /* Get supported hash algorithms */
445 cp = rp->hash_alg_list;
446 if (cp && strchr(cp, ',')) {
450 len = strcspn(cp, ",");
451 item = silc_calloc(len + 1, sizeof(char));
453 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
456 memcpy(item, cp, len);
458 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
460 if (silc_hash_is_supported(item) == TRUE) {
461 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
463 payload->hash_alg_len = len;
464 payload->hash_alg_list = item;
478 if (!payload->hash_alg_len && !payload->hash_alg_list) {
479 SILC_LOG_DEBUG(("Could not find supported hash alg"));
480 silc_free(payload->ke_grp_list);
481 silc_free(payload->pkcs_alg_list);
482 silc_free(payload->enc_alg_list);
484 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
487 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
490 payload->hash_alg_len = rp->hash_alg_len;
491 payload->hash_alg_list = strdup(rp->hash_alg_list);
494 /* Save selected hash algorithm to security properties */
495 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
496 silc_free(payload->ke_grp_list);
497 silc_free(payload->pkcs_alg_list);
498 silc_free(payload->enc_alg_list);
500 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
503 /* Get supported HMACs */
504 cp = rp->hmac_alg_list;
505 if (cp && strchr(cp, ',')) {
509 len = strcspn(cp, ",");
510 item = silc_calloc(len + 1, sizeof(char));
512 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
515 memcpy(item, cp, len);
517 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
519 if (silc_hmac_is_supported(item) == TRUE) {
520 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
522 payload->hmac_alg_len = len;
523 payload->hmac_alg_list = item;
537 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
538 SILC_LOG_DEBUG(("Could not find supported HMAC"));
539 silc_free(payload->ke_grp_list);
540 silc_free(payload->pkcs_alg_list);
541 silc_free(payload->enc_alg_list);
542 silc_free(payload->hash_alg_list);
544 return SILC_SKE_STATUS_UNKNOWN_HMAC;
547 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
550 payload->hmac_alg_len = rp->hmac_alg_len;
551 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
554 /* Save selected HMACc to security properties */
555 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
556 silc_free(payload->ke_grp_list);
557 silc_free(payload->pkcs_alg_list);
558 silc_free(payload->enc_alg_list);
559 silc_free(payload->hash_alg_list);
561 return SILC_SKE_STATUS_UNKNOWN_HMAC;
564 /* Get supported compression algorithms */
565 cp = rp->comp_alg_list;
566 if (cp && strchr(cp, ',')) {
570 len = strcspn(cp, ",");
571 item = silc_calloc(len + 1, sizeof(char));
573 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
576 memcpy(item, cp, len);
578 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
581 if (!strcmp(item, "none")) {
582 SILC_LOG_DEBUG(("Found Compression `%s'", item));
583 payload->comp_alg_len = len;
584 payload->comp_alg_list = item;
588 if (silc_hmac_is_supported(item) == TRUE) {
589 SILC_LOG_DEBUG(("Found Compression `%s'", item));
590 payload->comp_alg_len = len;
591 payload->comp_alg_list = item;
607 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
608 2 + payload->version_len +
609 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
610 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
611 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
613 /* Save our reply payload */
614 ske->start_payload = payload;
616 return SILC_SKE_STATUS_OK;
619 /* Creates random number such that 1 < rnd < n and at most length
620 of len bits. The rnd sent as argument must be initialized. */
622 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
626 SilcSKEStatus status = SILC_SKE_STATUS_OK;
627 unsigned char *string;
631 return SILC_SKE_STATUS_ERROR;
633 SILC_LOG_DEBUG(("Creating random number"));
637 /* Get the random number as string */
638 string = silc_rng_get_rn_data(ske->rng, l);
640 return SILC_SKE_STATUS_OUT_OF_MEMORY;
642 /* Decode the string into a MP integer */
643 silc_mp_bin2mp(string, l, rnd);
644 silc_mp_mod_2exp(rnd, rnd, len);
647 if (silc_mp_cmp_ui(rnd, 1) < 0)
648 status = SILC_SKE_STATUS_ERROR;
649 if (silc_mp_cmp(rnd, n) >= 0)
650 status = SILC_SKE_STATUS_ERROR;
652 memset(string, 'F', l);
658 /* Creates a hash value HASH as defined in the SKE protocol. If the
659 `initiator' is TRUE then this function is used to create the HASH_i
660 hash value defined in the protocol. If it is FALSE then this is used
661 to create the HASH value defined by the protocol. */
663 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
664 unsigned char *return_hash,
665 SilcUInt32 *return_hash_len,
668 SilcSKEStatus status = SILC_SKE_STATUS_OK;
670 unsigned char *e, *f, *KEY, *s_data;
671 SilcUInt32 e_len, f_len, KEY_len, s_len;
674 SILC_LOG_DEBUG(("Start"));
676 if (initiator == FALSE) {
677 s_data = (ske->start_payload_copy ?
678 silc_buffer_data(ske->start_payload_copy) : NULL);
679 s_len = (ske->start_payload_copy ?
680 silc_buffer_len(ske->start_payload_copy) : 0);
681 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
682 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
683 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
685 /* Format the buffer used to compute the hash value */
686 buf = silc_buffer_alloc_size(s_len +
687 ske->ke2_payload->pk_len +
688 ske->ke1_payload->pk_len +
689 e_len + f_len + KEY_len);
691 return SILC_SKE_STATUS_OUT_OF_MEMORY;
693 /* Initiator is not required to send its public key */
694 if (!ske->ke1_payload->pk_data) {
696 silc_buffer_format(buf,
697 SILC_STR_DATA(s_data, s_len),
698 SILC_STR_DATA(ske->ke2_payload->pk_data,
699 ske->ke2_payload->pk_len),
700 SILC_STR_DATA(e, e_len),
701 SILC_STR_DATA(f, f_len),
702 SILC_STR_DATA(KEY, KEY_len),
706 silc_buffer_format(buf,
707 SILC_STR_DATA(s_data, s_len),
708 SILC_STR_DATA(ske->ke2_payload->pk_data,
709 ske->ke2_payload->pk_len),
710 SILC_STR_DATA(ske->ke1_payload->pk_data,
711 ske->ke1_payload->pk_len),
712 SILC_STR_DATA(e, e_len),
713 SILC_STR_DATA(f, f_len),
714 SILC_STR_DATA(KEY, KEY_len),
718 silc_buffer_free(buf);
721 memset(KEY, 0, KEY_len);
725 return SILC_SKE_STATUS_ERROR;
730 memset(KEY, 0, KEY_len);
735 s_data = (ske->start_payload_copy ?
736 silc_buffer_data(ske->start_payload_copy) : NULL);
737 s_len = (ske->start_payload_copy ?
738 silc_buffer_len(ske->start_payload_copy) : 0);
739 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
741 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
743 return SILC_SKE_STATUS_OUT_OF_MEMORY;
745 /* Format the buffer used to compute the hash value */
747 silc_buffer_format(buf,
748 SILC_STR_DATA(s_data, s_len),
749 SILC_STR_DATA(ske->ke1_payload->pk_data,
750 ske->ke1_payload->pk_len),
751 SILC_STR_DATA(e, e_len),
754 silc_buffer_free(buf);
757 return SILC_SKE_STATUS_ERROR;
760 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
767 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
769 *return_hash_len = silc_hash_len(ske->prop->hash);
771 if (initiator == FALSE) {
772 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
774 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
777 silc_buffer_free(buf);
782 /* Generate rekey material */
784 static SilcSKERekeyMaterial
785 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
787 SilcSKERekeyMaterial rekey;
790 /* Create rekey material */
791 rekey = silc_calloc(1, sizeof(*rekey));
796 if (ske->prop->group)
797 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
798 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
799 hash = silc_hash_get_name(ske->prop->hash);
800 rekey->hash = silc_memdup(hash, strlen(hash));
805 if (rekey->pfs == FALSE) {
806 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
807 keymat->enc_key_len / 8);
808 if (!rekey->send_enc_key) {
812 rekey->enc_key_len = keymat->enc_key_len;
818 /* Assembles security properties */
820 static SilcSKEStartPayload
821 silc_ske_assemble_security_properties(SilcSKE ske,
822 SilcSKESecurityPropertyFlag flags,
825 SilcSKEStartPayload rp;
828 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
830 rp = silc_calloc(1, sizeof(*rp));
833 rp->flags = (unsigned char)flags;
835 /* Set random cookie */
836 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
837 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
838 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
839 rp->cookie_len = SILC_SKE_COOKIE_LEN;
841 /* In case IV included flag and session port is set the first 16-bits of
842 cookie will include our session port. */
843 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
844 SILC_PUT16_MSB(ske->session_port, rp->cookie);
847 rp->version = strdup(version);
848 rp->version_len = strlen(version);
850 /* Get supported Key Exhange groups */
851 rp->ke_grp_list = silc_ske_get_supported_groups();
852 rp->ke_grp_len = strlen(rp->ke_grp_list);
854 /* Get supported PKCS algorithms */
855 rp->pkcs_alg_list = silc_pkcs_get_supported();
856 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
858 /* Get supported encryption algorithms */
859 rp->enc_alg_list = silc_cipher_get_supported();
860 rp->enc_alg_len = strlen(rp->enc_alg_list);
862 /* Get supported hash algorithms */
863 rp->hash_alg_list = silc_hash_get_supported();
864 rp->hash_alg_len = strlen(rp->hash_alg_list);
866 /* Get supported HMACs */
867 rp->hmac_alg_list = silc_hmac_get_supported();
868 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
871 /* Get supported compression algorithms */
872 rp->comp_alg_list = strdup("none");
873 rp->comp_alg_len = strlen("none");
875 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
876 2 + rp->version_len +
877 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
878 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
879 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
884 /* Packet retransmission callback. */
886 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
888 SilcSKE ske = context;
890 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
892 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
893 ske->retry_count = 0;
894 ske->retry_timer = SILC_SKE_RETRY_MIN;
895 silc_free(ske->retrans.data);
896 ske->retrans.data = NULL;
897 ske->status = SILC_SKE_STATUS_TIMEOUT;
899 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
901 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
902 silc_fsm_continue_sync(&ske->fsm);
906 SILC_LOG_DEBUG(("Retransmitting packet"));
907 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
908 ske->retrans.data, ske->retrans.data_len);
911 /* Install retransmission timer */
913 static void silc_ske_install_retransmission(SilcSKE ske)
915 if (!silc_packet_stream_is_udp(ske->stream))
918 if (ske->retrans.data) {
919 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
921 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
922 ske, ske->retry_timer, 0);
924 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
925 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
928 /* Sends SILC packet. Handles retransmissions with UDP streams. */
930 static SilcBool silc_ske_packet_send(SilcSKE ske,
932 SilcPacketFlags flags,
933 const unsigned char *data,
938 /* Send the packet */
939 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
941 if (silc_packet_stream_is_udp(ske->stream) &&
942 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
943 silc_free(ske->retrans.data);
944 ske->retrans.type = type;
945 ske->retrans.flags = flags;
946 ske->retrans.data = silc_memdup(data, data_len);
947 ske->retrans.data_len = data_len;
948 silc_ske_install_retransmission(ske);
954 /* Calls completion callback. Completion is called always in this function
955 and must not be called anywhere else. */
957 static void silc_ske_completion(SilcSKE ske)
959 /* Call the completion callback */
960 if (!ske->aborted && ske->callbacks->completed) {
961 if (ske->status != SILC_SKE_STATUS_OK)
962 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
963 ske->callbacks->context);
965 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
966 ske->rekey, ske->callbacks->context);
970 /* SKE FSM destructor. */
972 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
973 void *destructor_context)
975 SilcSKE ske = fsm_context;
979 /* Key exchange timeout task callback */
981 SILC_TASK_CALLBACK(silc_ske_timeout)
983 SilcSKE ske = context;
985 SILC_LOG_DEBUG(("Timeout"));
988 ske->status = SILC_SKE_STATUS_TIMEOUT;
990 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
992 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
994 silc_fsm_continue_sync(&ske->fsm);
997 /******************************* Protocol API *******************************/
999 /* Allocates new SKE object. */
1001 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1002 SilcSKR repository, SilcPublicKey public_key,
1003 SilcPrivateKey private_key, void *context)
1007 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1009 if (!rng || !schedule)
1013 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1017 ske = silc_calloc(1, sizeof(*ske));
1020 ske->status = SILC_SKE_STATUS_OK;
1022 ske->repository = repository;
1023 ske->user_data = context;
1024 ske->schedule = schedule;
1025 ske->public_key = public_key;
1026 ske->private_key = private_key;
1027 ske->retry_timer = SILC_SKE_RETRY_MIN;
1033 /* Free's SKE object. */
1035 void silc_ske_free(SilcSKE ske)
1040 SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu", ske, ske->aborted, ske->refcnt));
1043 /* If already aborted, destroy the session immediately */
1045 ske->status = SILC_SKE_STATUS_ERROR;
1047 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1049 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1050 silc_fsm_continue_sync(&ske->fsm);
1054 if (ske->refcnt > 0)
1057 /* Free start payload */
1058 if (ske->start_payload)
1059 silc_ske_payload_start_free(ske->start_payload);
1061 /* Free KE payload */
1062 if (ske->ke1_payload)
1063 silc_ske_payload_ke_free(ske->ke1_payload);
1064 if (ske->ke2_payload)
1065 silc_ske_payload_ke_free(ske->ke2_payload);
1066 silc_free(ske->remote_version);
1070 if (ske->prop->group)
1071 silc_ske_group_free(ske->prop->group);
1072 if (ske->prop->cipher)
1073 silc_cipher_free(ske->prop->cipher);
1074 if (ske->prop->hash)
1075 silc_hash_free(ske->prop->hash);
1076 if (ske->prop->hmac)
1077 silc_hmac_free(ske->prop->hmac);
1078 if (ske->prop->public_key)
1079 silc_pkcs_public_key_free(ske->prop->public_key);
1080 silc_free(ske->prop);
1083 silc_ske_free_key_material(ske->keymat);
1084 if (ske->start_payload_copy)
1085 silc_buffer_free(ske->start_payload_copy);
1087 silc_mp_uninit(ske->x);
1091 silc_mp_uninit(ske->KEY);
1092 silc_free(ske->KEY);
1094 silc_free(ske->retrans.data);
1095 silc_free(ske->hash);
1096 silc_free(ske->callbacks);
1098 memset(ske, 0xdd, sizeof(*ske));
1102 /* Return user context */
1104 void *silc_ske_get_context(SilcSKE ske)
1106 return ske->user_data;
1109 /* Sets protocol callbacks */
1111 void silc_ske_set_callbacks(SilcSKE ske,
1112 SilcSKEVerifyCb verify_key,
1113 SilcSKECompletionCb completed,
1117 silc_free(ske->callbacks);
1118 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1119 if (!ske->callbacks)
1121 ske->callbacks->verify_key = verify_key;
1122 ske->callbacks->completed = completed;
1123 ske->callbacks->context = context;
1127 /******************************** Initiator *********************************/
1129 /* Start protocol. Send our proposal */
1131 SILC_FSM_STATE(silc_ske_st_initiator_start)
1133 SilcSKE ske = fsm_context;
1134 SilcBuffer payload_buf;
1137 SILC_LOG_DEBUG(("Start"));
1141 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1142 return SILC_FSM_CONTINUE;
1145 /* Encode the payload */
1146 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1148 if (status != SILC_SKE_STATUS_OK) {
1149 /** Error encoding Start Payload */
1150 ske->status = status;
1151 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1152 return SILC_FSM_CONTINUE;
1155 /* Save the the payload buffer for future use. It is later used to
1156 compute the HASH value. */
1157 ske->start_payload_copy = payload_buf;
1159 /* Send the packet. */
1160 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1161 silc_buffer_data(payload_buf),
1162 silc_buffer_len(payload_buf))) {
1163 /** Error sending packet */
1164 SILC_LOG_DEBUG(("Error sending packet"));
1165 ske->status = SILC_SKE_STATUS_ERROR;
1166 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1167 return SILC_FSM_CONTINUE;
1170 /* Add key exchange timeout */
1171 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1172 ske, ske->timeout, 0);
1174 /** Wait for responder proposal */
1175 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1176 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1177 return SILC_FSM_WAIT;
1180 /* Phase-1. Receives responder's proposal */
1182 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1184 SilcSKE ske = fsm_context;
1185 SilcSKEStatus status;
1186 SilcSKEStartPayload payload;
1187 SilcSKESecurityProperties prop;
1188 SilcSKEDiffieHellmanGroup group = NULL;
1189 SilcBuffer packet_buf = &ske->packet->buffer;
1190 SilcUInt16 remote_port = 0;
1194 SILC_LOG_DEBUG(("Start"));
1196 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1197 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1198 silc_ske_install_retransmission(ske);
1199 silc_packet_free(ske->packet);
1201 return SILC_FSM_WAIT;
1204 /* Decode the payload */
1205 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1206 if (status != SILC_SKE_STATUS_OK) {
1207 /** Error decoding Start Payload */
1208 silc_packet_free(ske->packet);
1210 ske->status = status;
1211 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1212 return SILC_FSM_CONTINUE;
1215 /* Get remote ID and set it to stream */
1216 if (ske->packet->src_id_len) {
1217 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1218 ske->packet->src_id_type,
1219 (ske->packet->src_id_type == SILC_ID_SERVER ?
1220 (void *)&id.u.server_id : (void *)&id.u.client_id),
1221 (ske->packet->src_id_type == SILC_ID_SERVER ?
1222 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1223 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1224 (ske->packet->src_id_type == SILC_ID_SERVER ?
1225 (void *)&id.u.server_id : (void *)&id.u.client_id));
1228 silc_packet_free(ske->packet);
1231 /* Check that the cookie is returned unmodified. In case IV included
1232 flag and session port has been set, the first two bytes of cookie
1233 are the session port and we ignore them in this check. */
1234 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1235 /* Take remote port */
1236 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1239 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1240 SILC_SKE_COOKIE_LEN - coff)) {
1241 /** Invalid cookie */
1242 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1243 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1244 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1245 return SILC_FSM_CONTINUE;
1248 /* Check version string */
1249 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1250 status = silc_ske_check_version(ske);
1251 if (status != SILC_SKE_STATUS_OK) {
1252 /** Version mismatch */
1253 ske->status = status;
1254 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1255 return SILC_FSM_CONTINUE;
1258 /* Free our KE Start Payload context, we don't need it anymore. */
1259 silc_ske_payload_start_free(ske->start_payload);
1260 ske->start_payload = NULL;
1262 /* Take the selected security properties into use while doing
1263 the key exchange. This is used only while doing the key
1265 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1268 prop->flags = payload->flags;
1269 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1270 if (status != SILC_SKE_STATUS_OK)
1273 prop->group = group;
1274 prop->remote_port = remote_port;
1276 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1277 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1280 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1281 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1284 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1285 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1288 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1289 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1293 /* Save remote's KE Start Payload */
1294 ske->start_payload = payload;
1296 /** Send KE Payload */
1297 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1298 return SILC_FSM_CONTINUE;
1302 silc_ske_payload_start_free(payload);
1304 silc_ske_group_free(group);
1306 silc_cipher_free(prop->cipher);
1308 silc_hash_free(prop->hash);
1310 silc_hmac_free(prop->hmac);
1314 if (status == SILC_SKE_STATUS_OK)
1315 status = SILC_SKE_STATUS_ERROR;
1318 ske->status = status;
1319 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1320 return SILC_FSM_CONTINUE;
1323 /* Phase-2. Send KE payload */
1325 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1327 SilcSKE ske = fsm_context;
1328 SilcSKEStatus status;
1329 SilcBuffer payload_buf;
1331 SilcSKEKEPayload payload;
1334 SILC_LOG_DEBUG(("Start"));
1336 /* Create the random number x, 1 < x < q. */
1337 x = silc_calloc(1, sizeof(*x));
1339 /** Out of memory */
1340 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1341 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1342 return SILC_FSM_CONTINUE;
1346 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1347 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1349 if (status != SILC_SKE_STATUS_OK) {
1350 /** Error generating random number */
1353 ske->status = status;
1354 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1355 return SILC_FSM_CONTINUE;
1358 /* Encode the result to Key Exchange Payload. */
1360 payload = silc_calloc(1, sizeof(*payload));
1362 /** Out of memory */
1365 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1366 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1367 return SILC_FSM_CONTINUE;
1369 ske->ke1_payload = payload;
1371 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1373 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1374 silc_mp_init(&payload->x);
1375 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1376 &ske->prop->group->group);
1378 /* Get public key */
1379 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1380 if (!payload->pk_data) {
1381 /** Error encoding public key */
1384 silc_mp_uninit(&payload->x);
1386 ske->ke1_payload = NULL;
1387 ske->status = SILC_SKE_STATUS_ERROR;
1388 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1389 return SILC_FSM_CONTINUE;
1391 payload->pk_len = pk_len;
1392 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1394 /* Compute signature data if we are doing mutual authentication */
1395 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1396 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1397 SilcUInt32 hash_len, sign_len;
1399 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1400 SILC_LOG_DEBUG(("Computing HASH_i value"));
1402 /* Compute the hash value */
1403 memset(hash, 0, sizeof(hash));
1404 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1406 SILC_LOG_DEBUG(("Signing HASH_i value"));
1408 /* Sign the hash value */
1409 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1410 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1411 /** Error computing signature */
1414 silc_mp_uninit(&payload->x);
1415 silc_free(payload->pk_data);
1417 ske->ke1_payload = NULL;
1418 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1419 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1420 return SILC_FSM_CONTINUE;
1422 payload->sign_data = silc_memdup(sign, sign_len);
1423 if (payload->sign_data)
1424 payload->sign_len = sign_len;
1425 memset(sign, 0, sizeof(sign));
1428 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1429 if (status != SILC_SKE_STATUS_OK) {
1430 /** Error encoding KE payload */
1433 silc_mp_uninit(&payload->x);
1434 silc_free(payload->pk_data);
1435 silc_free(payload->sign_data);
1437 ske->ke1_payload = NULL;
1438 ske->status = status;
1439 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1440 return SILC_FSM_CONTINUE;
1445 /* Check for backwards compatibility */
1447 /* Send the packet. */
1448 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1449 silc_buffer_data(payload_buf),
1450 silc_buffer_len(payload_buf))) {
1451 /** Error sending packet */
1452 SILC_LOG_DEBUG(("Error sending packet"));
1453 ske->status = SILC_SKE_STATUS_ERROR;
1454 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1455 return SILC_FSM_CONTINUE;
1458 silc_buffer_free(payload_buf);
1460 /** Waiting responder's KE payload */
1461 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1462 return SILC_FSM_WAIT;
1465 /* Phase-3. Process responder's KE payload */
1467 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1469 SilcSKE ske = fsm_context;
1470 SilcSKEStatus status;
1471 SilcSKEKEPayload payload;
1473 SilcBuffer packet_buf = &ske->packet->buffer;
1475 SILC_LOG_DEBUG(("Start"));
1477 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1478 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1479 silc_ske_install_retransmission(ske);
1480 silc_packet_free(ske->packet);
1482 return SILC_FSM_WAIT;
1485 /* Decode the payload */
1486 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1487 if (status != SILC_SKE_STATUS_OK) {
1488 /** Error decoding KE payload */
1489 silc_packet_free(ske->packet);
1491 ske->status = status;
1492 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1493 return SILC_FSM_CONTINUE;
1495 silc_packet_free(ske->packet);
1497 ske->ke2_payload = payload;
1499 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1500 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1501 "even though we require it"));
1502 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1506 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1508 /* Compute the shared secret key */
1509 KEY = silc_calloc(1, sizeof(*KEY));
1511 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1514 /* Decode the remote's public key */
1515 if (payload->pk_data &&
1516 !silc_pkcs_public_key_alloc(payload->pk_type,
1517 payload->pk_data, payload->pk_len,
1518 &ske->prop->public_key)) {
1519 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1520 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1524 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1526 SILC_LOG_DEBUG(("Verifying public key"));
1528 /** Waiting public key verification */
1529 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1531 /* If repository is provided, verify the key from there. */
1532 if (ske->repository) {
1535 find = silc_skr_find_alloc();
1537 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1540 silc_skr_find_set_pkcs_type(find,
1541 silc_pkcs_get_type(ske->prop->public_key));
1542 silc_skr_find_set_public_key(find, ske->prop->public_key);
1543 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1545 /* Find key from repository */
1546 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1547 find, silc_ske_skr_callback, ske));
1549 /* Verify from application */
1550 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1551 ske->callbacks->context,
1552 silc_ske_pk_verified, NULL));
1557 /** Process key material */
1558 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1559 return SILC_FSM_CONTINUE;
1562 silc_ske_payload_ke_free(payload);
1563 ske->ke2_payload = NULL;
1565 silc_mp_uninit(ske->KEY);
1566 silc_free(ske->KEY);
1569 if (status == SILC_SKE_STATUS_OK)
1570 return SILC_SKE_STATUS_ERROR;
1573 ske->status = status;
1574 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1575 return SILC_FSM_CONTINUE;
1578 /* Process key material */
1580 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1582 SilcSKE ske = fsm_context;
1583 SilcSKEStatus status;
1584 SilcSKEKEPayload payload;
1585 unsigned char hash[SILC_HASH_MAXLEN];
1586 SilcUInt32 hash_len;
1587 int key_len, block_len;
1591 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1592 return SILC_FSM_CONTINUE;
1595 /* Check result of public key verification */
1596 if (ske->status != SILC_SKE_STATUS_OK) {
1597 /** Public key not verified */
1598 SILC_LOG_DEBUG(("Public key verification failed"));
1599 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1600 return SILC_FSM_CONTINUE;
1603 payload = ske->ke2_payload;
1605 /* Compute the HASH value */
1606 SILC_LOG_DEBUG(("Computing HASH value"));
1607 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1608 if (status != SILC_SKE_STATUS_OK)
1610 ske->hash = silc_memdup(hash, hash_len);
1611 ske->hash_len = hash_len;
1613 if (ske->prop->public_key) {
1614 SILC_LOG_DEBUG(("Public key is authentic"));
1615 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1617 /* Verify signature */
1618 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1619 payload->sign_len, hash, hash_len, NULL)) {
1620 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1621 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1625 SILC_LOG_DEBUG(("Signature is Ok"));
1626 memset(hash, 'F', hash_len);
1629 ske->status = SILC_SKE_STATUS_OK;
1631 /* In case we are doing rekey move to finish it. */
1634 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1635 return SILC_FSM_CONTINUE;
1638 /* Process key material */
1639 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1640 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1641 hash_len = silc_hash_len(ske->prop->hash);
1642 ske->keymat = silc_ske_process_key_material(ske, block_len,
1646 SILC_LOG_ERROR(("Error processing key material"));
1647 status = SILC_SKE_STATUS_ERROR;
1651 /* Send SUCCESS packet */
1652 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1653 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1654 /** Error sending packet */
1655 SILC_LOG_DEBUG(("Error sending packet"));
1656 ske->status = SILC_SKE_STATUS_ERROR;
1657 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1658 return SILC_FSM_CONTINUE;
1661 /** Waiting completion */
1662 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1663 return SILC_FSM_WAIT;
1666 memset(hash, 'F', sizeof(hash));
1667 silc_ske_payload_ke_free(payload);
1668 ske->ke2_payload = NULL;
1670 silc_mp_uninit(ske->KEY);
1671 silc_free(ske->KEY);
1675 memset(ske->hash, 'F', hash_len);
1676 silc_free(ske->hash);
1680 if (status == SILC_SKE_STATUS_OK)
1681 status = SILC_SKE_STATUS_ERROR;
1684 ske->status = status;
1685 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1686 return SILC_FSM_CONTINUE;
1689 /* Protocol completed */
1691 SILC_FSM_STATE(silc_ske_st_initiator_end)
1693 SilcSKE ske = fsm_context;
1695 SILC_LOG_DEBUG(("Start"));
1697 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1698 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1699 silc_ske_install_retransmission(ske);
1700 silc_packet_free(ske->packet);
1702 return SILC_FSM_WAIT;
1705 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1707 silc_packet_free(ske->packet);
1709 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1710 silc_schedule_task_del_by_context(ske->schedule, ske);
1712 /* Call completion */
1713 silc_ske_completion(ske);
1715 return SILC_FSM_FINISH;
1718 /* Aborted by application */
1720 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1722 SilcSKE ske = fsm_context;
1723 unsigned char data[4];
1725 SILC_LOG_DEBUG(("Aborted by caller"));
1727 /* Send FAILURE packet */
1728 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1729 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1731 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1732 silc_schedule_task_del_by_context(ske->schedule, ske);
1734 /* Call completion */
1735 silc_ske_completion(ske);
1737 return SILC_FSM_FINISH;
1740 /* Error occurred. Send error to remote host */
1742 SILC_FSM_STATE(silc_ske_st_initiator_error)
1744 SilcSKE ske = fsm_context;
1745 SilcSKEStatus status;
1746 unsigned char data[4];
1748 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1749 silc_ske_map_status(ske->status), ske->status));
1751 status = ske->status;
1752 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1753 status = SILC_SKE_STATUS_ERROR;
1755 /* Send FAILURE packet */
1756 SILC_PUT32_MSB((SilcUInt32)status, data);
1757 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1759 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1760 silc_schedule_task_del_by_context(ske->schedule, ske);
1762 /* Call completion */
1763 silc_ske_completion(ske);
1765 return SILC_FSM_FINISH;
1768 /* Failure received from remote */
1770 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1772 SilcSKE ske = fsm_context;
1773 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1775 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1776 SILC_GET32_MSB(error, ske->packet->buffer.data);
1777 ske->status = error;
1778 silc_packet_free(ske->packet);
1782 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1783 silc_ske_map_status(ske->status), ske->status));
1785 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1786 silc_schedule_task_del_by_context(ske->schedule, ske);
1788 /* Call completion */
1789 silc_ske_completion(ske);
1791 return SILC_FSM_FINISH;
1794 /* Starts the protocol as initiator */
1796 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1797 SilcPacketStream stream,
1798 SilcSKEParams params,
1799 SilcSKEStartPayload start_payload)
1801 SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; start_payload=%p", ske, stream, params, start_payload));
1803 if (!ske || !stream || !params || !params->version)
1806 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1809 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1812 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1813 ske->session_port = params->session_port;
1815 /* Generate security properties if not provided */
1816 if (!start_payload) {
1817 start_payload = silc_ske_assemble_security_properties(ske,
1824 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1825 ske->start_payload = start_payload;
1826 ske->version = params->version;
1829 /* Link to packet stream to get key exchange packets */
1830 ske->stream = stream;
1831 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1832 SILC_PACKET_KEY_EXCHANGE,
1833 SILC_PACKET_KEY_EXCHANGE_2,
1834 SILC_PACKET_SUCCESS,
1835 SILC_PACKET_FAILURE, -1);
1837 /* Start SKE as initiator */
1838 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1843 /******************************** Responder *********************************/
1845 /* Start protocol as responder. Wait initiator's start payload */
1847 SILC_FSM_STATE(silc_ske_st_responder_start)
1849 SilcSKE ske = fsm_context;
1851 SILC_LOG_DEBUG(("Start"));
1855 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1856 return SILC_FSM_CONTINUE;
1859 /* Add key exchange timeout */
1860 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1861 ske, ske->timeout, 0);
1863 /** Wait for initiator */
1864 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1865 return SILC_FSM_WAIT;
1868 /* Decode initiator's start payload. Select the security properties from
1869 the initiator's start payload and send our reply start payload back. */
1871 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1873 SilcSKE ske = fsm_context;
1874 SilcSKEStatus status;
1875 SilcSKEStartPayload remote_payload = NULL;
1876 SilcBuffer packet_buf = &ske->packet->buffer;
1879 SILC_LOG_DEBUG(("Start"));
1881 /* Decode the payload */
1882 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1883 if (status != SILC_SKE_STATUS_OK) {
1884 /** Error decoding Start Payload */
1885 silc_packet_free(ske->packet);
1887 ske->status = status;
1888 silc_fsm_next(fsm, silc_ske_st_responder_error);
1889 return SILC_FSM_CONTINUE;
1892 /* Get remote ID and set it to stream */
1893 if (ske->packet->src_id_len) {
1894 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1895 ske->packet->src_id_type,
1896 (ske->packet->src_id_type == SILC_ID_SERVER ?
1897 (void *)&id.u.server_id : (void *)&id.u.client_id),
1898 (ske->packet->src_id_type == SILC_ID_SERVER ?
1899 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1900 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1901 (ske->packet->src_id_type == SILC_ID_SERVER ?
1902 (void *)&id.u.server_id : (void *)&id.u.client_id));
1905 /* Take a copy of the payload buffer for future use. It is used to
1906 compute the HASH value. */
1907 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1909 silc_packet_free(ske->packet);
1912 /* Force the mutual authentication flag if we want to do it. */
1913 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1914 SILC_LOG_DEBUG(("Force mutual authentication"));
1915 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1918 /* Force PFS flag if we require it */
1919 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1920 SILC_LOG_DEBUG(("Force PFS"));
1921 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1924 /* Disable IV Included flag if requested */
1925 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1926 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1927 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1928 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1931 /* Check and select security properties */
1932 status = silc_ske_select_security_properties(ske, remote_payload,
1934 if (status != SILC_SKE_STATUS_OK) {
1935 /** Error selecting proposal */
1936 silc_ske_payload_start_free(remote_payload);
1937 ske->status = status;
1938 silc_fsm_next(fsm, silc_ske_st_responder_error);
1939 return SILC_FSM_CONTINUE;
1942 silc_ske_payload_start_free(remote_payload);
1944 /* Encode our reply payload to send the selected security properties */
1945 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1947 if (status != SILC_SKE_STATUS_OK)
1950 /* Send the packet. */
1951 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1952 silc_buffer_data(packet_buf),
1953 silc_buffer_len(packet_buf)))
1956 silc_buffer_free(packet_buf);
1958 /** Waiting initiator's KE payload */
1959 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1960 return SILC_FSM_WAIT;
1963 if (ske->prop->group)
1964 silc_ske_group_free(ske->prop->group);
1965 if (ske->prop->cipher)
1966 silc_cipher_free(ske->prop->cipher);
1967 if (ske->prop->hash)
1968 silc_hash_free(ske->prop->hash);
1969 if (ske->prop->hmac)
1970 silc_hmac_free(ske->prop->hmac);
1971 silc_free(ske->prop);
1974 if (status == SILC_SKE_STATUS_OK)
1975 status = SILC_SKE_STATUS_ERROR;
1978 ske->status = status;
1979 silc_fsm_next(fsm, silc_ske_st_responder_error);
1980 return SILC_FSM_CONTINUE;
1983 /* Phase-2. Decode initiator's KE payload */
1985 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1987 SilcSKE ske = fsm_context;
1988 SilcSKEStatus status;
1989 SilcSKEKEPayload recv_payload;
1990 SilcBuffer packet_buf = &ske->packet->buffer;
1992 SILC_LOG_DEBUG(("Start"));
1994 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1995 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1996 silc_ske_install_retransmission(ske);
1997 silc_packet_free(ske->packet);
1999 return SILC_FSM_WAIT;
2002 /* Decode Key Exchange Payload */
2003 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2004 if (status != SILC_SKE_STATUS_OK) {
2005 /** Error decoding KE payload */
2006 silc_packet_free(ske->packet);
2008 ske->status = status;
2009 silc_fsm_next(fsm, silc_ske_st_responder_error);
2010 return SILC_FSM_CONTINUE;
2013 ske->ke1_payload = recv_payload;
2015 silc_packet_free(ske->packet);
2018 /* Verify public key, except in rekey, when it is not sent */
2020 if (!recv_payload->pk_data) {
2021 /** Public key not provided */
2022 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2023 "certificate), even though we require it"));
2024 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2025 silc_fsm_next(fsm, silc_ske_st_responder_error);
2026 return SILC_FSM_CONTINUE;
2029 /* Decode the remote's public key */
2030 if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2031 recv_payload->pk_data,
2032 recv_payload->pk_len,
2033 &ske->prop->public_key)) {
2034 /** Error decoding public key */
2035 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2036 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2037 silc_fsm_next(fsm, silc_ske_st_responder_error);
2038 return SILC_FSM_CONTINUE;
2041 SILC_LOG_DEBUG(("Verifying public key"));
2043 /** Waiting public key verification */
2044 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2046 /* If repository is provided, verify the key from there. */
2047 if (ske->repository) {
2050 find = silc_skr_find_alloc();
2052 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2053 silc_fsm_next(fsm, silc_ske_st_responder_error);
2054 return SILC_FSM_CONTINUE;
2056 silc_skr_find_set_pkcs_type(find,
2057 silc_pkcs_get_type(ske->prop->public_key));
2058 silc_skr_find_set_public_key(find, ske->prop->public_key);
2059 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2061 /* Find key from repository */
2062 SILC_FSM_CALL(silc_skr_find(ske->repository,
2063 silc_fsm_get_schedule(fsm), find,
2064 silc_ske_skr_callback, ske));
2066 /* Verify from application */
2067 if (ske->callbacks->verify_key)
2068 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2069 ske->callbacks->context,
2070 silc_ske_pk_verified, NULL));
2074 /** Generate KE2 payload */
2075 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2076 return SILC_FSM_CONTINUE;
2079 /* Phase-4. Generate KE2 payload */
2081 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2083 SilcSKE ske = fsm_context;
2084 SilcSKEStatus status;
2085 SilcSKEKEPayload recv_payload, send_payload;
2090 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2091 return SILC_FSM_CONTINUE;
2094 /* Check result of public key verification */
2095 if (ske->status != SILC_SKE_STATUS_OK) {
2096 /** Public key not verified */
2097 SILC_LOG_DEBUG(("Public key verification failed"));
2098 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2099 return SILC_FSM_CONTINUE;
2102 recv_payload = ske->ke1_payload;
2104 /* The public key verification was performed only if the Mutual
2105 Authentication flag is set. */
2106 if (ske->start_payload &&
2107 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2108 unsigned char hash[SILC_HASH_MAXLEN];
2109 SilcUInt32 hash_len;
2111 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2113 /* Compute the hash value */
2114 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2115 if (status != SILC_SKE_STATUS_OK) {
2116 /** Error computing hash */
2117 ske->status = status;
2118 silc_fsm_next(fsm, silc_ske_st_responder_error);
2119 return SILC_FSM_CONTINUE;
2122 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2124 /* Verify signature */
2125 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2126 recv_payload->sign_len, hash, hash_len, NULL)) {
2127 /** Incorrect signature */
2128 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2129 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2130 silc_fsm_next(fsm, silc_ske_st_responder_error);
2131 return SILC_FSM_CONTINUE;
2134 SILC_LOG_DEBUG(("Signature is Ok"));
2136 memset(hash, 'F', hash_len);
2139 /* Create the random number x, 1 < x < q. */
2140 x = silc_calloc(1, sizeof(*x));
2143 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2144 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2146 if (status != SILC_SKE_STATUS_OK) {
2147 /** Error generating random number */
2150 ske->status = status;
2151 silc_fsm_next(fsm, silc_ske_st_responder_error);
2152 return SILC_FSM_CONTINUE;
2155 /* Save the results for later processing */
2156 send_payload = silc_calloc(1, sizeof(*send_payload));
2158 ske->ke2_payload = send_payload;
2160 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2162 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2163 silc_mp_init(&send_payload->x);
2164 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2165 &ske->prop->group->group);
2167 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2169 /* Compute the shared secret key */
2170 KEY = silc_calloc(1, sizeof(*KEY));
2172 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2173 &ske->prop->group->group);
2176 /** Send KE2 payload */
2177 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2178 return SILC_FSM_CONTINUE;
2181 /* Phase-5. Send KE2 payload */
2183 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2185 SilcSKE ske = fsm_context;
2186 SilcSKEStatus status;
2187 SilcBuffer payload_buf;
2188 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2189 SilcUInt32 hash_len, sign_len, pk_len;
2191 SILC_LOG_DEBUG(("Start"));
2193 if (ske->public_key && ske->private_key) {
2194 SILC_LOG_DEBUG(("Getting public key"));
2196 /* Get the public key */
2197 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2199 /** Error encoding public key */
2200 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2201 silc_fsm_next(fsm, silc_ske_st_responder_error);
2202 return SILC_FSM_CONTINUE;
2204 ske->ke2_payload->pk_data = pk;
2205 ske->ke2_payload->pk_len = pk_len;
2208 SILC_LOG_DEBUG(("Computing HASH value"));
2210 /* Compute the hash value */
2211 memset(hash, 0, sizeof(hash));
2212 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2213 if (status != SILC_SKE_STATUS_OK) {
2214 /** Error computing hash */
2215 ske->status = status;
2216 silc_fsm_next(fsm, silc_ske_st_responder_error);
2217 return SILC_FSM_CONTINUE;
2219 ske->hash = silc_memdup(hash, hash_len);
2220 ske->hash_len = hash_len;
2222 if (ske->public_key && ske->private_key) {
2223 SILC_LOG_DEBUG(("Signing HASH value"));
2225 /* Sign the hash value */
2226 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2227 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2228 /** Error computing signature */
2229 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2230 silc_fsm_next(fsm, silc_ske_st_responder_error);
2231 return SILC_FSM_CONTINUE;
2233 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2234 ske->ke2_payload->sign_len = sign_len;
2235 memset(sign, 0, sizeof(sign));
2237 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2239 /* Encode the Key Exchange Payload */
2240 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2242 if (status != SILC_SKE_STATUS_OK) {
2243 /** Error encoding KE payload */
2244 ske->status = status;
2245 silc_fsm_next(fsm, silc_ske_st_responder_error);
2246 return SILC_FSM_CONTINUE;
2249 /* Send the packet. */
2250 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2251 payload_buf->data, silc_buffer_len(payload_buf))) {
2252 SILC_LOG_DEBUG(("Error sending packet"));
2253 ske->status = SILC_SKE_STATUS_ERROR;
2254 silc_fsm_next(fsm, silc_ske_st_responder_error);
2255 return SILC_FSM_CONTINUE;
2258 silc_buffer_free(payload_buf);
2260 /* In case we are doing rekey move to finish it. */
2263 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2264 return SILC_FSM_CONTINUE;
2267 /** Waiting completion */
2268 silc_fsm_next(fsm, silc_ske_st_responder_end);
2269 return SILC_FSM_WAIT;
2272 /* Protocol completed */
2274 SILC_FSM_STATE(silc_ske_st_responder_end)
2276 SilcSKE ske = fsm_context;
2277 unsigned char tmp[4];
2278 SilcUInt32 hash_len, key_len, block_len;
2280 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2281 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2282 silc_ske_install_retransmission(ske);
2283 silc_packet_free(ske->packet);
2285 return SILC_FSM_WAIT;
2287 silc_packet_free(ske->packet);
2290 /* Process key material */
2291 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2292 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2293 hash_len = silc_hash_len(ske->prop->hash);
2294 ske->keymat = silc_ske_process_key_material(ske, block_len,
2298 /** Error processing key material */
2299 ske->status = SILC_SKE_STATUS_ERROR;
2300 silc_fsm_next(fsm, silc_ske_st_responder_error);
2301 return SILC_FSM_CONTINUE;
2304 /* Send SUCCESS packet */
2305 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2306 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2308 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2309 silc_schedule_task_del_by_context(ske->schedule, ske);
2311 /* Call completion */
2312 silc_ske_completion(ske);
2314 return SILC_FSM_FINISH;
2317 /* Aborted by application */
2319 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2321 SilcSKE ske = fsm_context;
2322 unsigned char tmp[4];
2324 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2326 /* Send FAILURE packet */
2327 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2328 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2330 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2331 silc_schedule_task_del_by_context(ske->schedule, ske);
2333 /* Call completion */
2334 silc_ske_completion(ske);
2336 return SILC_FSM_FINISH;
2339 /* Failure received from remote */
2341 SILC_FSM_STATE(silc_ske_st_responder_failure)
2343 SilcSKE ske = fsm_context;
2344 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2346 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2348 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2349 SILC_GET32_MSB(error, ske->packet->buffer.data);
2350 ske->status = error;
2351 silc_packet_free(ske->packet);
2355 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2356 silc_schedule_task_del_by_context(ske->schedule, ske);
2358 /* Call completion */
2359 silc_ske_completion(ske);
2361 return SILC_FSM_FINISH;
2364 /* Error occurred */
2366 SILC_FSM_STATE(silc_ske_st_responder_error)
2368 SilcSKE ske = fsm_context;
2369 unsigned char tmp[4];
2371 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2372 ske->status, silc_ske_map_status(ske->status)));
2374 /* Send FAILURE packet */
2375 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2376 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2377 SILC_PUT32_MSB(ske->status, tmp);
2378 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2380 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2381 silc_schedule_task_del_by_context(ske->schedule, ske);
2383 /* Call completion */
2384 silc_ske_completion(ske);
2386 return SILC_FSM_FINISH;
2389 /* Starts the protocol as responder. */
2391 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2392 SilcPacketStream stream,
2393 SilcSKEParams params)
2395 SILC_LOG_DEBUG(("Start SKE as responder"));
2397 if (!ske || !stream || !params || !params->version)
2400 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2403 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2406 ske->responder = TRUE;
2407 ske->flags = params->flags;
2408 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2409 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2410 ske->session_port = params->session_port;
2411 ske->version = params->version;
2416 /* Link to packet stream to get key exchange packets */
2417 ske->stream = stream;
2418 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2419 SILC_PACKET_KEY_EXCHANGE,
2420 SILC_PACKET_KEY_EXCHANGE_1,
2421 SILC_PACKET_SUCCESS,
2422 SILC_PACKET_FAILURE, -1);
2424 /* Start SKE as responder */
2425 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2430 /***************************** Initiator Rekey ******************************/
2434 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2436 SilcSKE ske = fsm_context;
2439 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2443 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2444 return SILC_FSM_CONTINUE;
2447 /* Add rekey exchange timeout */
2448 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2451 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2454 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2455 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2456 return SILC_FSM_CONTINUE;
2459 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2460 /** Cannot allocate hash */
2461 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2462 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2463 return SILC_FSM_CONTINUE;
2466 /* Send REKEY packet to start rekey protocol */
2467 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2468 /** Error sending packet */
2469 SILC_LOG_DEBUG(("Error sending packet"));
2470 ske->status = SILC_SKE_STATUS_ERROR;
2471 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2472 return SILC_FSM_CONTINUE;
2475 /* If doing rekey without PFS, move directly to the end of the protocol. */
2476 if (!ske->rekey->pfs) {
2477 /** Rekey without PFS */
2478 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2479 return SILC_FSM_CONTINUE;
2482 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2484 if (status != SILC_SKE_STATUS_OK) {
2485 /** Unknown group */
2486 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2487 return SILC_FSM_CONTINUE;
2490 /** Rekey with PFS */
2491 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2492 return SILC_FSM_CONTINUE;
2495 /* Sends REKEY_DONE packet to finish the protocol. */
2497 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2499 SilcSKE ske = fsm_context;
2500 SilcCipher send_key;
2503 SilcUInt32 key_len, block_len, hash_len, x_len;
2504 unsigned char *pfsbuf;
2506 SILC_LOG_DEBUG(("Start"));
2508 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2509 key_len = silc_cipher_get_key_len(send_key);
2510 block_len = silc_cipher_get_block_len(send_key);
2511 hash = ske->prop->hash;
2512 hash_len = silc_hash_len(hash);
2514 /* Process key material */
2515 if (ske->rekey->pfs) {
2517 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2519 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2522 memset(pfsbuf, 0, x_len);
2528 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2529 ske->rekey->enc_key_len / 8,
2535 SILC_LOG_ERROR(("Error processing key material"));
2536 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2537 return SILC_FSM_CONTINUE;
2540 ske->prop->cipher = send_key;
2541 ske->prop->hmac = hmac_send;
2543 /* Get sending keys */
2544 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2545 &hmac_send, NULL, NULL)) {
2546 /** Cannot get keys */
2547 ske->status = SILC_SKE_STATUS_ERROR;
2548 ske->prop->cipher = NULL;
2549 ske->prop->hmac = NULL;
2550 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2551 return SILC_FSM_CONTINUE;
2554 ske->prop->cipher = NULL;
2555 ske->prop->hmac = NULL;
2557 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2558 packet sent after this call will be protected with the new keys. */
2559 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2561 /** Cannot set keys */
2562 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2563 ske->status = SILC_SKE_STATUS_ERROR;
2564 silc_cipher_free(send_key);
2565 silc_hmac_free(hmac_send);
2566 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2567 return SILC_FSM_CONTINUE;
2570 /** Wait for REKEY_DONE */
2571 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2572 return SILC_FSM_WAIT;
2575 /* Rekey protocol end */
2577 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2579 SilcSKE ske = fsm_context;
2580 SilcCipher receive_key;
2581 SilcHmac hmac_receive;
2582 SilcSKERekeyMaterial rekey;
2584 SILC_LOG_DEBUG(("Start"));
2586 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2587 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2588 silc_packet_free(ske->packet);
2590 return SILC_FSM_WAIT;
2593 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2594 ske->prop->cipher = receive_key;
2595 ske->prop->hmac = hmac_receive;
2597 /* Get receiving keys */
2598 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2599 NULL, &hmac_receive, NULL)) {
2600 /** Cannot get keys */
2601 ske->status = SILC_SKE_STATUS_ERROR;
2602 ske->prop->cipher = NULL;
2603 ske->prop->hmac = NULL;
2604 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2605 return SILC_FSM_CONTINUE;
2608 /* Set new receiving keys into use. All packets received after this will
2609 be decrypted with the new keys. */
2610 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2611 hmac_receive, FALSE)) {
2612 /** Cannot set keys */
2613 SILC_LOG_DEBUG(("Cannot set new keys"));
2614 ske->status = SILC_SKE_STATUS_ERROR;
2615 silc_cipher_free(receive_key);
2616 silc_hmac_free(hmac_receive);
2617 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2618 return SILC_FSM_CONTINUE;
2621 SILC_LOG_DEBUG(("Rekey completed successfully"));
2623 /* Generate new rekey material */
2624 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2627 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2628 ske->prop->cipher = NULL;
2629 ske->prop->hmac = NULL;
2630 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2631 return SILC_FSM_CONTINUE;
2633 rekey->pfs = ske->rekey->pfs;
2636 ske->prop->cipher = NULL;
2637 ske->prop->hmac = NULL;
2638 silc_packet_free(ske->packet);
2640 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2641 silc_schedule_task_del_by_context(ske->schedule, ske);
2643 /* Call completion */
2644 silc_ske_completion(ske);
2646 return SILC_FSM_FINISH;
2649 /* Starts rekey protocol as initiator */
2652 silc_ske_rekey_initiator(SilcSKE ske,
2653 SilcPacketStream stream,
2654 SilcSKERekeyMaterial rekey)
2656 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2658 if (!ske || !stream || !rekey) {
2659 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2664 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2667 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2671 ske->responder = FALSE;
2672 ske->rekeying = TRUE;
2675 /* Link to packet stream to get key exchange packets */
2676 ske->stream = stream;
2677 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2679 SILC_PACKET_REKEY_DONE,
2680 SILC_PACKET_KEY_EXCHANGE_2,
2681 SILC_PACKET_SUCCESS,
2682 SILC_PACKET_FAILURE, -1);
2684 /* Start SKE rekey as initiator */
2685 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2690 /***************************** Responder Rekey ******************************/
2692 /* Wait for initiator's packet */
2694 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2696 SilcSKE ske = fsm_context;
2698 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2702 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2703 return SILC_FSM_CONTINUE;
2706 /* Add rekey exchange timeout */
2707 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2710 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2712 /* If REKEY packet already received process it directly */
2713 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2714 return SILC_FSM_CONTINUE;
2716 /* Wait for REKEY */
2717 return SILC_FSM_WAIT;
2720 /* Process initiator's REKEY packet */
2722 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2724 SilcSKE ske = fsm_context;
2725 SilcSKEStatus status;
2727 SILC_LOG_DEBUG(("Start"));
2729 if (ske->packet->type != SILC_PACKET_REKEY) {
2730 ske->status = SILC_SKE_STATUS_ERROR;
2731 silc_packet_free(ske->packet);
2733 silc_fsm_next(fsm, silc_ske_st_responder_error);
2734 return SILC_FSM_CONTINUE;
2737 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2740 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2741 silc_fsm_next(fsm, silc_ske_st_responder_error);
2742 return SILC_FSM_CONTINUE;
2745 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2746 /** Cannot allocate hash */
2747 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2748 silc_fsm_next(fsm, silc_ske_st_responder_error);
2749 return SILC_FSM_CONTINUE;
2752 /* If doing rekey without PFS, move directly to the end of the protocol. */
2753 if (!ske->rekey->pfs) {
2754 /** Rekey without PFS */
2755 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2756 return SILC_FSM_CONTINUE;
2759 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2761 if (status != SILC_SKE_STATUS_OK) {
2762 /** Unknown group */
2763 silc_fsm_next(fsm, silc_ske_st_responder_error);
2764 return SILC_FSM_CONTINUE;
2767 /** Rekey with PFS */
2768 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2769 return SILC_FSM_WAIT;
2772 /* Sends REKEY_DONE packet to finish the protocol. */
2774 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2776 SilcSKE ske = fsm_context;
2777 SilcCipher send_key;
2780 SilcUInt32 key_len, block_len, hash_len, x_len;
2781 unsigned char *pfsbuf;
2783 SILC_LOG_DEBUG(("Start"));
2785 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2786 key_len = silc_cipher_get_key_len(send_key);
2787 block_len = silc_cipher_get_block_len(send_key);
2788 hash = ske->prop->hash;
2789 hash_len = silc_hash_len(hash);
2791 /* Process key material */
2792 if (ske->rekey->pfs) {
2794 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2796 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2799 memset(pfsbuf, 0, x_len);
2805 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2806 ske->rekey->enc_key_len / 8,
2812 SILC_LOG_ERROR(("Error processing key material"));
2813 silc_fsm_next(fsm, silc_ske_st_responder_error);
2814 return SILC_FSM_CONTINUE;
2817 ske->prop->cipher = send_key;
2818 ske->prop->hmac = hmac_send;
2820 /* Get sending keys */
2821 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2822 &hmac_send, NULL, NULL)) {
2823 /** Cannot get keys */
2824 ske->status = SILC_SKE_STATUS_ERROR;
2825 ske->prop->cipher = NULL;
2826 ske->prop->hmac = NULL;
2827 silc_fsm_next(fsm, silc_ske_st_responder_error);
2828 return SILC_FSM_CONTINUE;
2831 ske->prop->cipher = NULL;
2832 ske->prop->hmac = NULL;
2834 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2835 packet sent after this call will be protected with the new keys. */
2836 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2838 /** Cannot set keys */
2839 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2840 ske->status = SILC_SKE_STATUS_ERROR;
2841 silc_cipher_free(send_key);
2842 silc_hmac_free(hmac_send);
2843 silc_fsm_next(fsm, silc_ske_st_responder_error);
2844 return SILC_FSM_CONTINUE;
2847 /** Wait for REKEY_DONE */
2848 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2849 return SILC_FSM_WAIT;
2852 /* Rekey protocol end */
2854 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2856 SilcSKE ske = fsm_context;
2857 SilcCipher receive_key;
2858 SilcHmac hmac_receive;
2859 SilcSKERekeyMaterial rekey;
2861 SILC_LOG_DEBUG(("Start"));
2863 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2864 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2865 silc_packet_free(ske->packet);
2867 return SILC_FSM_WAIT;
2870 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2871 ske->prop->cipher = receive_key;
2872 ske->prop->hmac = hmac_receive;
2874 /* Get receiving keys */
2875 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2876 NULL, &hmac_receive, NULL)) {
2877 /** Cannot get keys */
2878 ske->status = SILC_SKE_STATUS_ERROR;
2879 ske->prop->cipher = NULL;
2880 ske->prop->hmac = NULL;
2881 silc_fsm_next(fsm, silc_ske_st_responder_error);
2882 return SILC_FSM_CONTINUE;
2885 /* Set new receiving keys into use. All packets received after this will
2886 be decrypted with the new keys. */
2887 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2888 hmac_receive, FALSE)) {
2889 /** Cannot set keys */
2890 SILC_LOG_DEBUG(("Cannot set new keys"));
2891 ske->status = SILC_SKE_STATUS_ERROR;
2892 ske->prop->cipher = NULL;
2893 ske->prop->hmac = NULL;
2894 silc_cipher_free(receive_key);
2895 silc_hmac_free(hmac_receive);
2896 silc_fsm_next(fsm, silc_ske_st_responder_error);
2897 return SILC_FSM_CONTINUE;
2900 SILC_LOG_DEBUG(("Rekey completed successfully"));
2902 /* Generate new rekey material */
2903 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2906 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2907 ske->prop->cipher = NULL;
2908 ske->prop->hmac = NULL;
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->rekeying = TRUE;
2950 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_DATA(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_DATA(data, data_len),
3039 SILC_STR_DATA(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_DATA(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_DATA(data, data_len),
3102 SILC_STR_DATA(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_DATA(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_DATA(tmpbuf, klen),
3189 SILC_STR_DATA(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[SILC_HASH_MAXLEN];
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,
3296 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3300 /* Set key material */
3301 memset(iv, 0, sizeof(iv));
3302 if (ske->responder) {
3304 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3305 keymat->enc_key_len, TRUE);
3307 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3309 if (!ske->rekeying) {
3311 memcpy(iv, ske->hash, 4);
3313 memcpy(iv + 4, keymat->receive_iv, 8);
3315 /* Rekey, recompute the truncated hash value. */
3316 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3318 memcpy(iv + 4, keymat->receive_iv, 8);
3320 memset(iv + 4, 0, 12);
3323 silc_cipher_set_iv(*ret_send_key, iv);
3326 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3329 if (ret_receive_key) {
3330 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3331 keymat->enc_key_len, FALSE);
3333 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3335 if (!ske->rekeying) {
3337 memcpy(iv, ske->hash, 4);
3339 memcpy(iv + 4, keymat->send_iv, 8);
3341 /* Rekey, recompute the truncated hash value. */
3342 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3344 memcpy(iv + 4, keymat->send_iv, 8);
3346 memset(iv + 4, 0, 12);
3349 silc_cipher_set_iv(*ret_receive_key, iv);
3352 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3356 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3357 keymat->hmac_key_len);
3358 if (ret_hmac_receive)
3359 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3360 keymat->hmac_key_len);
3363 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3364 keymat->enc_key_len, TRUE);
3366 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3368 if (!ske->rekeying) {
3370 memcpy(iv, ske->hash, 4);
3372 memcpy(iv + 4, keymat->send_iv, 8);
3374 /* Rekey, recompute the truncated hash value. */
3375 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3377 memcpy(iv + 4, keymat->send_iv, 8);
3379 memset(iv + 4, 0, 12);
3382 silc_cipher_set_iv(*ret_send_key, iv);
3385 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3388 if (ret_receive_key) {
3389 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3390 keymat->enc_key_len, FALSE);
3392 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3394 if (!ske->rekeying) {
3395 /* Set IV. If IV Included flag was negotiated we only set the
3396 truncated hash value. */
3397 memcpy(iv, ske->hash, 4);
3399 memcpy(iv + 4, keymat->receive_iv, 8);
3401 /* Rekey, recompute the truncated hash value. */
3402 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3404 memcpy(iv + 4, keymat->receive_iv, 8);
3406 memset(iv + 4, 0, 12);
3409 silc_cipher_set_iv(*ret_receive_key, iv);
3412 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3416 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3417 keymat->hmac_key_len);
3418 if (ret_hmac_receive)
3419 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3420 keymat->hmac_key_len);
3426 const char *silc_ske_status_string[] =
3430 "Unexpected error occurred",
3431 "Bad payload in packet",
3432 "Unsupported group",
3433 "Unsupported cipher",
3435 "Unsupported hash function",
3437 "Unsupported public key (or certificate)",
3438 "Incorrect signature",
3439 "Bad or unsupported version",
3443 "Remote did not provide public key",
3444 "Bad reserved field in packet",
3445 "Bad payload length in packet",
3446 "Error computing signature",
3447 "System out of memory",
3448 "Key exchange timeout",
3453 /* Maps status to readable string and returns the string. If string is not
3454 found and empty character string ("") is returned. */
3456 const char *silc_ske_map_status(SilcSKEStatus status)
3460 for (i = 0; silc_ske_status_string[i]; i++)
3462 return silc_ske_status_string[i];
3467 /* Parses remote host's version string. */
3469 SilcBool silc_ske_parse_version(SilcSKE ske,
3470 SilcUInt32 *protocol_version,
3471 char **protocol_version_string,
3472 SilcUInt32 *software_version,
3473 char **software_version_string,
3474 char **vendor_version)
3476 return silc_parse_version_string(ske->remote_version,
3478 protocol_version_string,
3480 software_version_string,
3484 /* Get security properties */
3486 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3491 /* Get key material */
3493 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)