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->freed && !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;
976 ske->running = FALSE;
981 /* Key exchange timeout task callback */
983 SILC_TASK_CALLBACK(silc_ske_timeout)
985 SilcSKE ske = context;
987 SILC_LOG_DEBUG(("Timeout"));
990 ske->status = SILC_SKE_STATUS_TIMEOUT;
992 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
994 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
996 silc_fsm_continue_sync(&ske->fsm);
999 /******************************* Protocol API *******************************/
1001 /* Allocates new SKE object. */
1003 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1004 SilcSKR repository, SilcPublicKey public_key,
1005 SilcPrivateKey private_key, void *context)
1009 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1011 if (!rng || !schedule)
1015 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1019 ske = silc_calloc(1, sizeof(*ske));
1022 ske->status = SILC_SKE_STATUS_OK;
1024 ske->repository = repository;
1025 ske->user_data = context;
1026 ske->schedule = schedule;
1027 ske->public_key = public_key;
1028 ske->private_key = private_key;
1029 ske->retry_timer = SILC_SKE_RETRY_MIN;
1035 /* Free's SKE object. */
1037 void silc_ske_free(SilcSKE ske)
1039 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1048 /* If already aborted, destroy the session immediately */
1050 ske->status = SILC_SKE_STATUS_ERROR;
1052 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1054 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1055 silc_fsm_continue_sync(&ske->fsm);
1061 if (ske->refcnt > 0)
1064 /* Free start payload */
1065 if (ske->start_payload)
1066 silc_ske_payload_start_free(ske->start_payload);
1068 /* Free KE payload */
1069 if (ske->ke1_payload)
1070 silc_ske_payload_ke_free(ske->ke1_payload);
1071 if (ske->ke2_payload)
1072 silc_ske_payload_ke_free(ske->ke2_payload);
1073 silc_free(ske->remote_version);
1077 if (ske->prop->group)
1078 silc_ske_group_free(ske->prop->group);
1079 if (ske->prop->cipher)
1080 silc_cipher_free(ske->prop->cipher);
1081 if (ske->prop->hash)
1082 silc_hash_free(ske->prop->hash);
1083 if (ske->prop->hmac)
1084 silc_hmac_free(ske->prop->hmac);
1085 if (ske->prop->public_key)
1086 silc_pkcs_public_key_free(ske->prop->public_key);
1087 silc_free(ske->prop);
1090 silc_ske_free_key_material(ske->keymat);
1091 if (ske->start_payload_copy)
1092 silc_buffer_free(ske->start_payload_copy);
1094 silc_mp_uninit(ske->x);
1098 silc_mp_uninit(ske->KEY);
1099 silc_free(ske->KEY);
1101 silc_free(ske->retrans.data);
1102 silc_free(ske->hash);
1103 silc_free(ske->callbacks);
1105 memset(ske, 'F', sizeof(*ske));
1109 /* Return user context */
1111 void *silc_ske_get_context(SilcSKE ske)
1113 return ske->user_data;
1116 /* Sets protocol callbacks */
1118 void silc_ske_set_callbacks(SilcSKE ske,
1119 SilcSKEVerifyCb verify_key,
1120 SilcSKECompletionCb completed,
1124 silc_free(ske->callbacks);
1125 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1126 if (!ske->callbacks)
1128 ske->callbacks->verify_key = verify_key;
1129 ske->callbacks->completed = completed;
1130 ske->callbacks->context = context;
1134 /******************************** Initiator *********************************/
1136 /* Start protocol. Send our proposal */
1138 SILC_FSM_STATE(silc_ske_st_initiator_start)
1140 SilcSKE ske = fsm_context;
1141 SilcBuffer payload_buf;
1144 SILC_LOG_DEBUG(("Start"));
1148 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1149 return SILC_FSM_CONTINUE;
1152 /* Encode the payload */
1153 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1155 if (status != SILC_SKE_STATUS_OK) {
1156 /** Error encoding Start Payload */
1157 ske->status = status;
1158 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1159 return SILC_FSM_CONTINUE;
1162 /* Save the the payload buffer for future use. It is later used to
1163 compute the HASH value. */
1164 ske->start_payload_copy = payload_buf;
1166 /* Send the packet. */
1167 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1168 silc_buffer_data(payload_buf),
1169 silc_buffer_len(payload_buf))) {
1170 /** Error sending packet */
1171 SILC_LOG_DEBUG(("Error sending packet"));
1172 ske->status = SILC_SKE_STATUS_ERROR;
1173 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1174 return SILC_FSM_CONTINUE;
1177 /* Add key exchange timeout */
1178 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1179 ske, ske->timeout, 0);
1181 /** Wait for responder proposal */
1182 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1183 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1184 return SILC_FSM_WAIT;
1187 /* Phase-1. Receives responder's proposal */
1189 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1191 SilcSKE ske = fsm_context;
1192 SilcSKEStatus status;
1193 SilcSKEStartPayload payload;
1194 SilcSKESecurityProperties prop;
1195 SilcSKEDiffieHellmanGroup group = NULL;
1196 SilcBuffer packet_buf = &ske->packet->buffer;
1197 SilcUInt16 remote_port = 0;
1201 SILC_LOG_DEBUG(("Start"));
1203 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1204 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1205 silc_ske_install_retransmission(ske);
1206 silc_packet_free(ske->packet);
1208 return SILC_FSM_WAIT;
1211 /* Decode the payload */
1212 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1213 if (status != SILC_SKE_STATUS_OK) {
1214 /** Error decoding Start Payload */
1215 silc_packet_free(ske->packet);
1217 ske->status = status;
1218 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1219 return SILC_FSM_CONTINUE;
1222 /* Get remote ID and set it to stream */
1223 if (ske->packet->src_id_len) {
1224 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1225 ske->packet->src_id_type,
1226 (ske->packet->src_id_type == SILC_ID_SERVER ?
1227 (void *)&id.u.server_id : (void *)&id.u.client_id),
1228 (ske->packet->src_id_type == SILC_ID_SERVER ?
1229 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1230 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1231 (ske->packet->src_id_type == SILC_ID_SERVER ?
1232 (void *)&id.u.server_id : (void *)&id.u.client_id));
1235 silc_packet_free(ske->packet);
1238 /* Check that the cookie is returned unmodified. In case IV included
1239 flag and session port has been set, the first two bytes of cookie
1240 are the session port and we ignore them in this check. */
1241 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1242 /* Take remote port */
1243 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1246 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1247 SILC_SKE_COOKIE_LEN - coff)) {
1248 /** Invalid cookie */
1249 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1250 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1251 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1252 return SILC_FSM_CONTINUE;
1255 /* Check version string */
1256 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1257 status = silc_ske_check_version(ske);
1258 if (status != SILC_SKE_STATUS_OK) {
1259 /** Version mismatch */
1260 ske->status = status;
1261 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1262 return SILC_FSM_CONTINUE;
1265 /* Free our KE Start Payload context, we don't need it anymore. */
1266 silc_ske_payload_start_free(ske->start_payload);
1267 ske->start_payload = NULL;
1269 /* Take the selected security properties into use while doing
1270 the key exchange. This is used only while doing the key
1272 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1275 prop->flags = payload->flags;
1276 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1277 if (status != SILC_SKE_STATUS_OK)
1280 prop->group = group;
1281 prop->remote_port = remote_port;
1283 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1284 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1287 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1288 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1291 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1292 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1295 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1296 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1300 /* Save remote's KE Start Payload */
1301 ske->start_payload = payload;
1303 /** Send KE Payload */
1304 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1305 return SILC_FSM_CONTINUE;
1309 silc_ske_payload_start_free(payload);
1311 silc_ske_group_free(group);
1313 silc_cipher_free(prop->cipher);
1315 silc_hash_free(prop->hash);
1317 silc_hmac_free(prop->hmac);
1321 if (status == SILC_SKE_STATUS_OK)
1322 status = SILC_SKE_STATUS_ERROR;
1325 ske->status = status;
1326 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1327 return SILC_FSM_CONTINUE;
1330 /* Phase-2. Send KE payload */
1332 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1334 SilcSKE ske = fsm_context;
1335 SilcSKEStatus status;
1336 SilcBuffer payload_buf;
1338 SilcSKEKEPayload payload;
1341 SILC_LOG_DEBUG(("Start"));
1343 /* Create the random number x, 1 < x < q. */
1344 x = silc_calloc(1, sizeof(*x));
1346 /** Out of memory */
1347 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1348 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1349 return SILC_FSM_CONTINUE;
1353 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1354 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1356 if (status != SILC_SKE_STATUS_OK) {
1357 /** Error generating random number */
1360 ske->status = status;
1361 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1362 return SILC_FSM_CONTINUE;
1365 /* Encode the result to Key Exchange Payload. */
1367 payload = silc_calloc(1, sizeof(*payload));
1369 /** Out of memory */
1372 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1373 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1374 return SILC_FSM_CONTINUE;
1376 ske->ke1_payload = payload;
1378 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1380 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1381 silc_mp_init(&payload->x);
1382 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1383 &ske->prop->group->group);
1385 /* Get public key */
1386 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1387 if (!payload->pk_data) {
1388 /** Error encoding public key */
1391 silc_mp_uninit(&payload->x);
1393 ske->ke1_payload = NULL;
1394 ske->status = SILC_SKE_STATUS_ERROR;
1395 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1396 return SILC_FSM_CONTINUE;
1398 payload->pk_len = pk_len;
1399 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1401 /* Compute signature data if we are doing mutual authentication */
1402 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1403 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1404 SilcUInt32 hash_len, sign_len;
1406 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1407 SILC_LOG_DEBUG(("Computing HASH_i value"));
1409 /* Compute the hash value */
1410 memset(hash, 0, sizeof(hash));
1411 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1413 SILC_LOG_DEBUG(("Signing HASH_i value"));
1415 /* Sign the hash value */
1416 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1417 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1418 /** Error computing signature */
1421 silc_mp_uninit(&payload->x);
1422 silc_free(payload->pk_data);
1424 ske->ke1_payload = NULL;
1425 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1426 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1427 return SILC_FSM_CONTINUE;
1429 payload->sign_data = silc_memdup(sign, sign_len);
1430 if (payload->sign_data)
1431 payload->sign_len = sign_len;
1432 memset(sign, 0, sizeof(sign));
1435 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1436 if (status != SILC_SKE_STATUS_OK) {
1437 /** Error encoding KE payload */
1440 silc_mp_uninit(&payload->x);
1441 silc_free(payload->pk_data);
1442 silc_free(payload->sign_data);
1444 ske->ke1_payload = NULL;
1445 ske->status = status;
1446 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1447 return SILC_FSM_CONTINUE;
1452 /* Check for backwards compatibility */
1454 /* Send the packet. */
1455 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1456 silc_buffer_data(payload_buf),
1457 silc_buffer_len(payload_buf))) {
1458 /** Error sending packet */
1459 SILC_LOG_DEBUG(("Error sending packet"));
1460 ske->status = SILC_SKE_STATUS_ERROR;
1461 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1462 return SILC_FSM_CONTINUE;
1465 silc_buffer_free(payload_buf);
1467 /** Waiting responder's KE payload */
1468 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1469 return SILC_FSM_WAIT;
1472 /* Phase-3. Process responder's KE payload */
1474 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1476 SilcSKE ske = fsm_context;
1477 SilcSKEStatus status;
1478 SilcSKEKEPayload payload;
1480 SilcBuffer packet_buf = &ske->packet->buffer;
1482 SILC_LOG_DEBUG(("Start"));
1484 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1485 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1486 silc_ske_install_retransmission(ske);
1487 silc_packet_free(ske->packet);
1489 return SILC_FSM_WAIT;
1492 /* Decode the payload */
1493 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1494 if (status != SILC_SKE_STATUS_OK) {
1495 /** Error decoding KE payload */
1496 silc_packet_free(ske->packet);
1498 ske->status = status;
1499 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1500 return SILC_FSM_CONTINUE;
1502 silc_packet_free(ske->packet);
1504 ske->ke2_payload = payload;
1506 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1507 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1508 "even though we require it"));
1509 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1513 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1515 /* Compute the shared secret key */
1516 KEY = silc_calloc(1, sizeof(*KEY));
1518 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1521 /* Decode the remote's public key */
1522 if (payload->pk_data &&
1523 !silc_pkcs_public_key_alloc(payload->pk_type,
1524 payload->pk_data, payload->pk_len,
1525 &ske->prop->public_key)) {
1526 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1527 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1531 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1533 SILC_LOG_DEBUG(("Verifying public key"));
1535 /** Waiting public key verification */
1536 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1538 /* If repository is provided, verify the key from there. */
1539 if (ske->repository) {
1542 find = silc_skr_find_alloc();
1544 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1547 silc_skr_find_set_pkcs_type(find,
1548 silc_pkcs_get_type(ske->prop->public_key));
1549 silc_skr_find_set_public_key(find, ske->prop->public_key);
1550 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1552 /* Find key from repository */
1553 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1554 find, silc_ske_skr_callback, ske));
1556 /* Verify from application */
1557 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1558 ske->callbacks->context,
1559 silc_ske_pk_verified, NULL));
1564 /** Process key material */
1565 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1566 return SILC_FSM_CONTINUE;
1569 silc_ske_payload_ke_free(payload);
1570 ske->ke2_payload = NULL;
1572 silc_mp_uninit(ske->KEY);
1573 silc_free(ske->KEY);
1576 if (status == SILC_SKE_STATUS_OK)
1577 return SILC_SKE_STATUS_ERROR;
1580 ske->status = status;
1581 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1582 return SILC_FSM_CONTINUE;
1585 /* Process key material */
1587 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1589 SilcSKE ske = fsm_context;
1590 SilcSKEStatus status;
1591 SilcSKEKEPayload payload;
1592 unsigned char hash[SILC_HASH_MAXLEN];
1593 SilcUInt32 hash_len;
1594 int key_len, block_len;
1598 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1599 return SILC_FSM_CONTINUE;
1602 /* Check result of public key verification */
1603 if (ske->status != SILC_SKE_STATUS_OK) {
1604 /** Public key not verified */
1605 SILC_LOG_DEBUG(("Public key verification failed"));
1606 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1607 return SILC_FSM_CONTINUE;
1610 payload = ske->ke2_payload;
1612 /* Compute the HASH value */
1613 SILC_LOG_DEBUG(("Computing HASH value"));
1614 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1615 if (status != SILC_SKE_STATUS_OK)
1617 ske->hash = silc_memdup(hash, hash_len);
1618 ske->hash_len = hash_len;
1620 if (ske->prop->public_key) {
1621 SILC_LOG_DEBUG(("Public key is authentic"));
1622 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1624 /* Verify signature */
1625 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1626 payload->sign_len, hash, hash_len, NULL)) {
1627 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1628 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1632 SILC_LOG_DEBUG(("Signature is Ok"));
1633 memset(hash, 'F', hash_len);
1636 ske->status = SILC_SKE_STATUS_OK;
1638 /* In case we are doing rekey move to finish it. */
1641 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1642 return SILC_FSM_CONTINUE;
1645 /* Process key material */
1646 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1647 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1648 hash_len = silc_hash_len(ske->prop->hash);
1649 ske->keymat = silc_ske_process_key_material(ske, block_len,
1653 SILC_LOG_ERROR(("Error processing key material"));
1654 status = SILC_SKE_STATUS_ERROR;
1658 /* Send SUCCESS packet */
1659 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1660 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1661 /** Error sending packet */
1662 SILC_LOG_DEBUG(("Error sending packet"));
1663 ske->status = SILC_SKE_STATUS_ERROR;
1664 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1665 return SILC_FSM_CONTINUE;
1668 /** Waiting completion */
1669 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1670 return SILC_FSM_WAIT;
1673 memset(hash, 'F', sizeof(hash));
1674 silc_ske_payload_ke_free(payload);
1675 ske->ke2_payload = NULL;
1677 silc_mp_uninit(ske->KEY);
1678 silc_free(ske->KEY);
1682 memset(ske->hash, 'F', hash_len);
1683 silc_free(ske->hash);
1687 if (status == SILC_SKE_STATUS_OK)
1688 status = SILC_SKE_STATUS_ERROR;
1691 ske->status = status;
1692 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1693 return SILC_FSM_CONTINUE;
1696 /* Protocol completed */
1698 SILC_FSM_STATE(silc_ske_st_initiator_end)
1700 SilcSKE ske = fsm_context;
1702 SILC_LOG_DEBUG(("Start"));
1704 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1705 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1706 silc_ske_install_retransmission(ske);
1707 silc_packet_free(ske->packet);
1709 return SILC_FSM_WAIT;
1712 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1714 silc_packet_free(ske->packet);
1716 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1717 silc_schedule_task_del_by_context(ske->schedule, ske);
1719 /* Call completion */
1720 silc_ske_completion(ske);
1722 return SILC_FSM_FINISH;
1725 /* Aborted by application */
1727 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1729 SilcSKE ske = fsm_context;
1730 unsigned char data[4];
1732 SILC_LOG_DEBUG(("Aborted by caller"));
1734 /* Send FAILURE packet */
1735 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1736 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1738 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1739 silc_schedule_task_del_by_context(ske->schedule, ske);
1741 /* Call completion */
1742 silc_ske_completion(ske);
1744 return SILC_FSM_FINISH;
1747 /* Error occurred. Send error to remote host */
1749 SILC_FSM_STATE(silc_ske_st_initiator_error)
1751 SilcSKE ske = fsm_context;
1752 SilcSKEStatus status;
1753 unsigned char data[4];
1755 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1756 silc_ske_map_status(ske->status), ske->status));
1758 status = ske->status;
1759 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1760 status = SILC_SKE_STATUS_ERROR;
1762 /* Send FAILURE packet */
1763 SILC_PUT32_MSB((SilcUInt32)status, 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 /* Failure received from remote */
1777 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1779 SilcSKE ske = fsm_context;
1780 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1782 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1783 SILC_GET32_MSB(error, ske->packet->buffer.data);
1784 ske->status = error;
1785 silc_packet_free(ske->packet);
1789 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1790 silc_ske_map_status(ske->status), ske->status));
1792 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1793 silc_schedule_task_del_by_context(ske->schedule, ske);
1795 /* Call completion */
1796 silc_ske_completion(ske);
1798 return SILC_FSM_FINISH;
1801 /* Starts the protocol as initiator */
1803 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1804 SilcPacketStream stream,
1805 SilcSKEParams params,
1806 SilcSKEStartPayload start_payload)
1808 SILC_LOG_DEBUG(("Start SKE as initiator"));
1810 if (!ske || !stream || !params || !params->version)
1813 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1816 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1819 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1820 ske->session_port = params->session_port;
1822 /* Generate security properties if not provided */
1823 if (!start_payload) {
1824 start_payload = silc_ske_assemble_security_properties(ske,
1831 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1832 ske->start_payload = start_payload;
1833 ske->version = params->version;
1834 ske->running = TRUE;
1836 /* Link to packet stream to get key exchange packets */
1837 ske->stream = stream;
1838 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1839 SILC_PACKET_KEY_EXCHANGE,
1840 SILC_PACKET_KEY_EXCHANGE_2,
1841 SILC_PACKET_SUCCESS,
1842 SILC_PACKET_FAILURE, -1);
1844 /* Start SKE as initiator */
1845 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1850 /******************************** Responder *********************************/
1852 /* Start protocol as responder. Wait initiator's start payload */
1854 SILC_FSM_STATE(silc_ske_st_responder_start)
1856 SilcSKE ske = fsm_context;
1858 SILC_LOG_DEBUG(("Start"));
1862 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1863 return SILC_FSM_CONTINUE;
1866 /* Add key exchange timeout */
1867 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1868 ske, ske->timeout, 0);
1870 /** Wait for initiator */
1871 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1872 return SILC_FSM_WAIT;
1875 /* Decode initiator's start payload. Select the security properties from
1876 the initiator's start payload and send our reply start payload back. */
1878 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1880 SilcSKE ske = fsm_context;
1881 SilcSKEStatus status;
1882 SilcSKEStartPayload remote_payload = NULL;
1883 SilcBuffer packet_buf = &ske->packet->buffer;
1886 SILC_LOG_DEBUG(("Start"));
1888 /* Decode the payload */
1889 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1890 if (status != SILC_SKE_STATUS_OK) {
1891 /** Error decoding Start Payload */
1892 silc_packet_free(ske->packet);
1894 ske->status = status;
1895 silc_fsm_next(fsm, silc_ske_st_responder_error);
1896 return SILC_FSM_CONTINUE;
1899 /* Get remote ID and set it to stream */
1900 if (ske->packet->src_id_len) {
1901 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1902 ske->packet->src_id_type,
1903 (ske->packet->src_id_type == SILC_ID_SERVER ?
1904 (void *)&id.u.server_id : (void *)&id.u.client_id),
1905 (ske->packet->src_id_type == SILC_ID_SERVER ?
1906 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1907 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1908 (ske->packet->src_id_type == SILC_ID_SERVER ?
1909 (void *)&id.u.server_id : (void *)&id.u.client_id));
1912 /* Take a copy of the payload buffer for future use. It is used to
1913 compute the HASH value. */
1914 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1916 silc_packet_free(ske->packet);
1919 /* Force the mutual authentication flag if we want to do it. */
1920 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1921 SILC_LOG_DEBUG(("Force mutual authentication"));
1922 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1925 /* Force PFS flag if we require it */
1926 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1927 SILC_LOG_DEBUG(("Force PFS"));
1928 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1931 /* Disable IV Included flag if requested */
1932 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1933 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1934 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1935 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1938 /* Check and select security properties */
1939 status = silc_ske_select_security_properties(ske, remote_payload,
1941 if (status != SILC_SKE_STATUS_OK) {
1942 /** Error selecting proposal */
1943 silc_ske_payload_start_free(remote_payload);
1944 ske->status = status;
1945 silc_fsm_next(fsm, silc_ske_st_responder_error);
1946 return SILC_FSM_CONTINUE;
1949 silc_ske_payload_start_free(remote_payload);
1951 /* Encode our reply payload to send the selected security properties */
1952 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1954 if (status != SILC_SKE_STATUS_OK)
1957 /* Send the packet. */
1958 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1959 silc_buffer_data(packet_buf),
1960 silc_buffer_len(packet_buf)))
1963 silc_buffer_free(packet_buf);
1965 /** Waiting initiator's KE payload */
1966 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1967 return SILC_FSM_WAIT;
1970 if (ske->prop->group)
1971 silc_ske_group_free(ske->prop->group);
1972 if (ske->prop->cipher)
1973 silc_cipher_free(ske->prop->cipher);
1974 if (ske->prop->hash)
1975 silc_hash_free(ske->prop->hash);
1976 if (ske->prop->hmac)
1977 silc_hmac_free(ske->prop->hmac);
1978 silc_free(ske->prop);
1981 if (status == SILC_SKE_STATUS_OK)
1982 status = SILC_SKE_STATUS_ERROR;
1985 ske->status = status;
1986 silc_fsm_next(fsm, silc_ske_st_responder_error);
1987 return SILC_FSM_CONTINUE;
1990 /* Phase-2. Decode initiator's KE payload */
1992 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1994 SilcSKE ske = fsm_context;
1995 SilcSKEStatus status;
1996 SilcSKEKEPayload recv_payload;
1997 SilcBuffer packet_buf = &ske->packet->buffer;
1999 SILC_LOG_DEBUG(("Start"));
2001 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2002 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2003 silc_ske_install_retransmission(ske);
2004 silc_packet_free(ske->packet);
2006 return SILC_FSM_WAIT;
2009 /* Decode Key Exchange Payload */
2010 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2011 if (status != SILC_SKE_STATUS_OK) {
2012 /** Error decoding KE payload */
2013 silc_packet_free(ske->packet);
2015 ske->status = status;
2016 silc_fsm_next(fsm, silc_ske_st_responder_error);
2017 return SILC_FSM_CONTINUE;
2020 ske->ke1_payload = recv_payload;
2022 silc_packet_free(ske->packet);
2025 /* Verify public key, except in rekey, when it is not sent */
2027 if (!recv_payload->pk_data) {
2028 /** Public key not provided */
2029 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2030 "certificate), even though we require it"));
2031 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2032 silc_fsm_next(fsm, silc_ske_st_responder_error);
2033 return SILC_FSM_CONTINUE;
2036 /* Decode the remote's public key */
2037 if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2038 recv_payload->pk_data,
2039 recv_payload->pk_len,
2040 &ske->prop->public_key)) {
2041 /** Error decoding public key */
2042 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2043 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2044 silc_fsm_next(fsm, silc_ske_st_responder_error);
2045 return SILC_FSM_CONTINUE;
2048 SILC_LOG_DEBUG(("Verifying public key"));
2050 /** Waiting public key verification */
2051 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2053 /* If repository is provided, verify the key from there. */
2054 if (ske->repository) {
2057 find = silc_skr_find_alloc();
2059 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2060 silc_fsm_next(fsm, silc_ske_st_responder_error);
2061 return SILC_FSM_CONTINUE;
2063 silc_skr_find_set_pkcs_type(find,
2064 silc_pkcs_get_type(ske->prop->public_key));
2065 silc_skr_find_set_public_key(find, ske->prop->public_key);
2066 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2068 /* Find key from repository */
2069 SILC_FSM_CALL(silc_skr_find(ske->repository,
2070 silc_fsm_get_schedule(fsm), find,
2071 silc_ske_skr_callback, ske));
2073 /* Verify from application */
2074 if (ske->callbacks->verify_key)
2075 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2076 ske->callbacks->context,
2077 silc_ske_pk_verified, NULL));
2081 /** Generate KE2 payload */
2082 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2083 return SILC_FSM_CONTINUE;
2086 /* Phase-4. Generate KE2 payload */
2088 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2090 SilcSKE ske = fsm_context;
2091 SilcSKEStatus status;
2092 SilcSKEKEPayload recv_payload, send_payload;
2097 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2098 return SILC_FSM_CONTINUE;
2101 /* Check result of public key verification */
2102 if (ske->status != SILC_SKE_STATUS_OK) {
2103 /** Public key not verified */
2104 SILC_LOG_DEBUG(("Public key verification failed"));
2105 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2106 return SILC_FSM_CONTINUE;
2109 recv_payload = ske->ke1_payload;
2111 /* The public key verification was performed only if the Mutual
2112 Authentication flag is set. */
2113 if (ske->start_payload &&
2114 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2115 unsigned char hash[SILC_HASH_MAXLEN];
2116 SilcUInt32 hash_len;
2118 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2120 /* Compute the hash value */
2121 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2122 if (status != SILC_SKE_STATUS_OK) {
2123 /** Error computing hash */
2124 ske->status = status;
2125 silc_fsm_next(fsm, silc_ske_st_responder_error);
2126 return SILC_FSM_CONTINUE;
2129 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2131 /* Verify signature */
2132 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2133 recv_payload->sign_len, hash, hash_len, NULL)) {
2134 /** Incorrect signature */
2135 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2136 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2137 silc_fsm_next(fsm, silc_ske_st_responder_error);
2138 return SILC_FSM_CONTINUE;
2141 SILC_LOG_DEBUG(("Signature is Ok"));
2143 memset(hash, 'F', hash_len);
2146 /* Create the random number x, 1 < x < q. */
2147 x = silc_calloc(1, sizeof(*x));
2150 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2151 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2153 if (status != SILC_SKE_STATUS_OK) {
2154 /** Error generating random number */
2157 ske->status = status;
2158 silc_fsm_next(fsm, silc_ske_st_responder_error);
2159 return SILC_FSM_CONTINUE;
2162 /* Save the results for later processing */
2163 send_payload = silc_calloc(1, sizeof(*send_payload));
2165 ske->ke2_payload = send_payload;
2167 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2169 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2170 silc_mp_init(&send_payload->x);
2171 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2172 &ske->prop->group->group);
2174 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2176 /* Compute the shared secret key */
2177 KEY = silc_calloc(1, sizeof(*KEY));
2179 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2180 &ske->prop->group->group);
2183 /** Send KE2 payload */
2184 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2185 return SILC_FSM_CONTINUE;
2188 /* Phase-5. Send KE2 payload */
2190 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2192 SilcSKE ske = fsm_context;
2193 SilcSKEStatus status;
2194 SilcBuffer payload_buf;
2195 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2196 SilcUInt32 hash_len, sign_len, pk_len;
2198 SILC_LOG_DEBUG(("Start"));
2200 if (ske->public_key && ske->private_key) {
2201 SILC_LOG_DEBUG(("Getting public key"));
2203 /* Get the public key */
2204 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2206 /** Error encoding public key */
2207 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2208 silc_fsm_next(fsm, silc_ske_st_responder_error);
2209 return SILC_FSM_CONTINUE;
2211 ske->ke2_payload->pk_data = pk;
2212 ske->ke2_payload->pk_len = pk_len;
2215 SILC_LOG_DEBUG(("Computing HASH value"));
2217 /* Compute the hash value */
2218 memset(hash, 0, sizeof(hash));
2219 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2220 if (status != SILC_SKE_STATUS_OK) {
2221 /** Error computing hash */
2222 ske->status = status;
2223 silc_fsm_next(fsm, silc_ske_st_responder_error);
2224 return SILC_FSM_CONTINUE;
2226 ske->hash = silc_memdup(hash, hash_len);
2227 ske->hash_len = hash_len;
2229 if (ske->public_key && ske->private_key) {
2230 SILC_LOG_DEBUG(("Signing HASH value"));
2232 /* Sign the hash value */
2233 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2234 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2235 /** Error computing signature */
2236 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2237 silc_fsm_next(fsm, silc_ske_st_responder_error);
2238 return SILC_FSM_CONTINUE;
2240 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2241 ske->ke2_payload->sign_len = sign_len;
2242 memset(sign, 0, sizeof(sign));
2244 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2246 /* Encode the Key Exchange Payload */
2247 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2249 if (status != SILC_SKE_STATUS_OK) {
2250 /** Error encoding KE payload */
2251 ske->status = status;
2252 silc_fsm_next(fsm, silc_ske_st_responder_error);
2253 return SILC_FSM_CONTINUE;
2256 /* Send the packet. */
2257 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2258 payload_buf->data, silc_buffer_len(payload_buf))) {
2259 SILC_LOG_DEBUG(("Error sending packet"));
2260 ske->status = SILC_SKE_STATUS_ERROR;
2261 silc_fsm_next(fsm, silc_ske_st_responder_error);
2262 return SILC_FSM_CONTINUE;
2265 silc_buffer_free(payload_buf);
2267 /* In case we are doing rekey move to finish it. */
2270 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2271 return SILC_FSM_CONTINUE;
2274 /** Waiting completion */
2275 silc_fsm_next(fsm, silc_ske_st_responder_end);
2276 return SILC_FSM_WAIT;
2279 /* Protocol completed */
2281 SILC_FSM_STATE(silc_ske_st_responder_end)
2283 SilcSKE ske = fsm_context;
2284 unsigned char tmp[4];
2285 SilcUInt32 hash_len, key_len, block_len;
2287 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2288 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2289 silc_ske_install_retransmission(ske);
2290 silc_packet_free(ske->packet);
2292 return SILC_FSM_WAIT;
2294 silc_packet_free(ske->packet);
2297 /* Process key material */
2298 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2299 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2300 hash_len = silc_hash_len(ske->prop->hash);
2301 ske->keymat = silc_ske_process_key_material(ske, block_len,
2305 /** Error processing key material */
2306 ske->status = SILC_SKE_STATUS_ERROR;
2307 silc_fsm_next(fsm, silc_ske_st_responder_error);
2308 return SILC_FSM_CONTINUE;
2311 /* Send SUCCESS packet */
2312 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2313 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2315 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2316 silc_schedule_task_del_by_context(ske->schedule, ske);
2318 /* Call completion */
2319 silc_ske_completion(ske);
2321 return SILC_FSM_FINISH;
2324 /* Aborted by application */
2326 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2328 SilcSKE ske = fsm_context;
2329 unsigned char tmp[4];
2331 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2333 /* Send FAILURE packet */
2334 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2335 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2337 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2338 silc_schedule_task_del_by_context(ske->schedule, ske);
2340 /* Call completion */
2341 silc_ske_completion(ske);
2343 return SILC_FSM_FINISH;
2346 /* Failure received from remote */
2348 SILC_FSM_STATE(silc_ske_st_responder_failure)
2350 SilcSKE ske = fsm_context;
2351 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2353 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2355 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2356 SILC_GET32_MSB(error, ske->packet->buffer.data);
2357 ske->status = error;
2358 silc_packet_free(ske->packet);
2362 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2363 silc_schedule_task_del_by_context(ske->schedule, ske);
2365 /* Call completion */
2366 silc_ske_completion(ske);
2368 return SILC_FSM_FINISH;
2371 /* Error occurred */
2373 SILC_FSM_STATE(silc_ske_st_responder_error)
2375 SilcSKE ske = fsm_context;
2376 unsigned char tmp[4];
2378 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2379 ske->status, silc_ske_map_status(ske->status)));
2381 /* Send FAILURE packet */
2382 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2383 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2384 SILC_PUT32_MSB(ske->status, tmp);
2385 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2387 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2388 silc_schedule_task_del_by_context(ske->schedule, ske);
2390 /* Call completion */
2391 silc_ske_completion(ske);
2393 return SILC_FSM_FINISH;
2396 /* Starts the protocol as responder. */
2398 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2399 SilcPacketStream stream,
2400 SilcSKEParams params)
2402 SILC_LOG_DEBUG(("Start SKE as responder"));
2404 if (!ske || !stream || !params || !params->version)
2407 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2410 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2413 ske->responder = TRUE;
2414 ske->flags = params->flags;
2415 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2416 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2417 ske->session_port = params->session_port;
2418 ske->version = params->version;
2421 ske->running = TRUE;
2423 /* Link to packet stream to get key exchange packets */
2424 ske->stream = stream;
2425 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2426 SILC_PACKET_KEY_EXCHANGE,
2427 SILC_PACKET_KEY_EXCHANGE_1,
2428 SILC_PACKET_SUCCESS,
2429 SILC_PACKET_FAILURE, -1);
2431 /* Start SKE as responder */
2432 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2437 /***************************** Initiator Rekey ******************************/
2441 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2443 SilcSKE ske = fsm_context;
2446 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2450 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2451 return SILC_FSM_CONTINUE;
2454 /* Add rekey exchange timeout */
2455 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2458 ske->prop = silc_calloc(1, sizeof(*ske->prop));
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 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2467 /** Cannot allocate hash */
2468 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2469 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2470 return SILC_FSM_CONTINUE;
2473 /* Send REKEY packet to start rekey protocol */
2474 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2475 /** Error sending packet */
2476 SILC_LOG_DEBUG(("Error sending packet"));
2477 ske->status = SILC_SKE_STATUS_ERROR;
2478 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2479 return SILC_FSM_CONTINUE;
2482 /* If doing rekey without PFS, move directly to the end of the protocol. */
2483 if (!ske->rekey->pfs) {
2484 /** Rekey without PFS */
2485 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2486 return SILC_FSM_CONTINUE;
2489 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2491 if (status != SILC_SKE_STATUS_OK) {
2492 /** Unknown group */
2493 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2494 return SILC_FSM_CONTINUE;
2497 /** Rekey with PFS */
2498 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2499 return SILC_FSM_CONTINUE;
2502 /* Sends REKEY_DONE packet to finish the protocol. */
2504 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2506 SilcSKE ske = fsm_context;
2507 SilcCipher send_key;
2510 SilcUInt32 key_len, block_len, hash_len, x_len;
2511 unsigned char *pfsbuf;
2513 SILC_LOG_DEBUG(("Start"));
2515 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2516 key_len = silc_cipher_get_key_len(send_key);
2517 block_len = silc_cipher_get_block_len(send_key);
2518 hash = ske->prop->hash;
2519 hash_len = silc_hash_len(hash);
2521 /* Process key material */
2522 if (ske->rekey->pfs) {
2524 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2526 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2529 memset(pfsbuf, 0, x_len);
2535 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2536 ske->rekey->enc_key_len / 8,
2542 SILC_LOG_ERROR(("Error processing key material"));
2543 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2544 return SILC_FSM_CONTINUE;
2547 ske->prop->cipher = send_key;
2548 ske->prop->hmac = hmac_send;
2550 /* Get sending keys */
2551 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2552 &hmac_send, NULL, NULL)) {
2553 /** Cannot get keys */
2554 ske->status = SILC_SKE_STATUS_ERROR;
2555 ske->prop->cipher = NULL;
2556 ske->prop->hmac = NULL;
2557 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2558 return SILC_FSM_CONTINUE;
2561 ske->prop->cipher = NULL;
2562 ske->prop->hmac = NULL;
2564 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2565 packet sent after this call will be protected with the new keys. */
2566 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2568 /** Cannot set keys */
2569 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2570 ske->status = SILC_SKE_STATUS_ERROR;
2571 silc_cipher_free(send_key);
2572 silc_hmac_free(hmac_send);
2573 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2574 return SILC_FSM_CONTINUE;
2577 /** Wait for REKEY_DONE */
2578 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2579 return SILC_FSM_WAIT;
2582 /* Rekey protocol end */
2584 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2586 SilcSKE ske = fsm_context;
2587 SilcCipher receive_key;
2588 SilcHmac hmac_receive;
2589 SilcSKERekeyMaterial rekey;
2591 SILC_LOG_DEBUG(("Start"));
2593 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2594 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2595 silc_packet_free(ske->packet);
2597 return SILC_FSM_WAIT;
2600 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2601 ske->prop->cipher = receive_key;
2602 ske->prop->hmac = hmac_receive;
2604 /* Get receiving keys */
2605 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2606 NULL, &hmac_receive, NULL)) {
2607 /** Cannot get keys */
2608 ske->status = SILC_SKE_STATUS_ERROR;
2609 ske->prop->cipher = NULL;
2610 ske->prop->hmac = NULL;
2611 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2612 return SILC_FSM_CONTINUE;
2615 /* Set new receiving keys into use. All packets received after this will
2616 be decrypted with the new keys. */
2617 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2618 hmac_receive, FALSE)) {
2619 /** Cannot set keys */
2620 SILC_LOG_DEBUG(("Cannot set new keys"));
2621 ske->status = SILC_SKE_STATUS_ERROR;
2622 silc_cipher_free(receive_key);
2623 silc_hmac_free(hmac_receive);
2624 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2625 return SILC_FSM_CONTINUE;
2628 SILC_LOG_DEBUG(("Rekey completed successfully"));
2630 /* Generate new rekey material */
2631 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2634 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2635 ske->prop->cipher = NULL;
2636 ske->prop->hmac = NULL;
2637 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2638 return SILC_FSM_CONTINUE;
2640 rekey->pfs = ske->rekey->pfs;
2643 ske->prop->cipher = NULL;
2644 ske->prop->hmac = NULL;
2645 silc_packet_free(ske->packet);
2647 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2648 silc_schedule_task_del_by_context(ske->schedule, ske);
2650 /* Call completion */
2651 silc_ske_completion(ske);
2653 return SILC_FSM_FINISH;
2656 /* Starts rekey protocol as initiator */
2659 silc_ske_rekey_initiator(SilcSKE ske,
2660 SilcPacketStream stream,
2661 SilcSKERekeyMaterial rekey)
2663 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2665 if (!ske || !stream || !rekey) {
2666 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2671 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2674 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2678 ske->responder = FALSE;
2679 ske->running = TRUE;
2680 ske->rekeying = TRUE;
2682 /* Link to packet stream to get key exchange packets */
2683 ske->stream = stream;
2684 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2686 SILC_PACKET_REKEY_DONE,
2687 SILC_PACKET_KEY_EXCHANGE_2,
2688 SILC_PACKET_SUCCESS,
2689 SILC_PACKET_FAILURE, -1);
2691 /* Start SKE rekey as initiator */
2692 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2697 /***************************** Responder Rekey ******************************/
2699 /* Wait for initiator's packet */
2701 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2703 SilcSKE ske = fsm_context;
2705 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2709 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2710 return SILC_FSM_CONTINUE;
2713 /* Add rekey exchange timeout */
2714 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2717 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2719 /* If REKEY packet already received process it directly */
2720 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2721 return SILC_FSM_CONTINUE;
2723 /* Wait for REKEY */
2724 return SILC_FSM_WAIT;
2727 /* Process initiator's REKEY packet */
2729 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2731 SilcSKE ske = fsm_context;
2732 SilcSKEStatus status;
2734 SILC_LOG_DEBUG(("Start"));
2736 if (ske->packet->type != SILC_PACKET_REKEY) {
2737 ske->status = SILC_SKE_STATUS_ERROR;
2738 silc_packet_free(ske->packet);
2740 silc_fsm_next(fsm, silc_ske_st_responder_error);
2741 return SILC_FSM_CONTINUE;
2744 ske->prop = silc_calloc(1, sizeof(*ske->prop));
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 (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2753 /** Cannot allocate hash */
2754 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2755 silc_fsm_next(fsm, silc_ske_st_responder_error);
2756 return SILC_FSM_CONTINUE;
2759 /* If doing rekey without PFS, move directly to the end of the protocol. */
2760 if (!ske->rekey->pfs) {
2761 /** Rekey without PFS */
2762 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2763 return SILC_FSM_CONTINUE;
2766 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2768 if (status != SILC_SKE_STATUS_OK) {
2769 /** Unknown group */
2770 silc_fsm_next(fsm, silc_ske_st_responder_error);
2771 return SILC_FSM_CONTINUE;
2774 /** Rekey with PFS */
2775 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2776 return SILC_FSM_WAIT;
2779 /* Sends REKEY_DONE packet to finish the protocol. */
2781 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2783 SilcSKE ske = fsm_context;
2784 SilcCipher send_key;
2787 SilcUInt32 key_len, block_len, hash_len, x_len;
2788 unsigned char *pfsbuf;
2790 SILC_LOG_DEBUG(("Start"));
2792 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2793 key_len = silc_cipher_get_key_len(send_key);
2794 block_len = silc_cipher_get_block_len(send_key);
2795 hash = ske->prop->hash;
2796 hash_len = silc_hash_len(hash);
2798 /* Process key material */
2799 if (ske->rekey->pfs) {
2801 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2803 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2806 memset(pfsbuf, 0, x_len);
2812 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2813 ske->rekey->enc_key_len / 8,
2819 SILC_LOG_ERROR(("Error processing key material"));
2820 silc_fsm_next(fsm, silc_ske_st_responder_error);
2821 return SILC_FSM_CONTINUE;
2824 ske->prop->cipher = send_key;
2825 ske->prop->hmac = hmac_send;
2827 /* Get sending keys */
2828 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2829 &hmac_send, NULL, NULL)) {
2830 /** Cannot get keys */
2831 ske->status = SILC_SKE_STATUS_ERROR;
2832 ske->prop->cipher = NULL;
2833 ske->prop->hmac = NULL;
2834 silc_fsm_next(fsm, silc_ske_st_responder_error);
2835 return SILC_FSM_CONTINUE;
2838 ske->prop->cipher = NULL;
2839 ske->prop->hmac = NULL;
2841 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2842 packet sent after this call will be protected with the new keys. */
2843 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2845 /** Cannot set keys */
2846 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2847 ske->status = SILC_SKE_STATUS_ERROR;
2848 silc_cipher_free(send_key);
2849 silc_hmac_free(hmac_send);
2850 silc_fsm_next(fsm, silc_ske_st_responder_error);
2851 return SILC_FSM_CONTINUE;
2854 /** Wait for REKEY_DONE */
2855 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2856 return SILC_FSM_WAIT;
2859 /* Rekey protocol end */
2861 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2863 SilcSKE ske = fsm_context;
2864 SilcCipher receive_key;
2865 SilcHmac hmac_receive;
2866 SilcSKERekeyMaterial rekey;
2868 SILC_LOG_DEBUG(("Start"));
2870 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2871 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2872 silc_packet_free(ske->packet);
2874 return SILC_FSM_WAIT;
2877 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2878 ske->prop->cipher = receive_key;
2879 ske->prop->hmac = hmac_receive;
2881 /* Get receiving keys */
2882 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2883 NULL, &hmac_receive, NULL)) {
2884 /** Cannot get keys */
2885 ske->status = SILC_SKE_STATUS_ERROR;
2886 ske->prop->cipher = NULL;
2887 ske->prop->hmac = NULL;
2888 silc_fsm_next(fsm, silc_ske_st_responder_error);
2889 return SILC_FSM_CONTINUE;
2892 /* Set new receiving keys into use. All packets received after this will
2893 be decrypted with the new keys. */
2894 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2895 hmac_receive, FALSE)) {
2896 /** Cannot set keys */
2897 SILC_LOG_DEBUG(("Cannot set new keys"));
2898 ske->status = SILC_SKE_STATUS_ERROR;
2899 ske->prop->cipher = NULL;
2900 ske->prop->hmac = NULL;
2901 silc_cipher_free(receive_key);
2902 silc_hmac_free(hmac_receive);
2903 silc_fsm_next(fsm, silc_ske_st_responder_error);
2904 return SILC_FSM_CONTINUE;
2907 SILC_LOG_DEBUG(("Rekey completed successfully"));
2909 /* Generate new rekey material */
2910 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2913 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2914 ske->prop->cipher = NULL;
2915 ske->prop->hmac = NULL;
2916 silc_fsm_next(fsm, silc_ske_st_responder_error);
2917 return SILC_FSM_CONTINUE;
2919 rekey->pfs = ske->rekey->pfs;
2922 ske->prop->cipher = NULL;
2923 ske->prop->hmac = NULL;
2924 silc_packet_free(ske->packet);
2926 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2927 silc_schedule_task_del_by_context(ske->schedule, ske);
2929 /* Call completion */
2930 silc_ske_completion(ske);
2932 return SILC_FSM_FINISH;
2935 /* Starts rekey protocol as responder */
2938 silc_ske_rekey_responder(SilcSKE ske,
2939 SilcPacketStream stream,
2940 SilcSKERekeyMaterial rekey,
2943 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2945 if (!ske || !stream || !rekey)
2948 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2951 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2955 ske->responder = TRUE;
2956 ske->running = TRUE;
2957 ske->rekeying = TRUE;
2958 ske->packet = packet;
2960 /* Link to packet stream to get key exchange packets */
2961 ske->stream = stream;
2962 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2964 SILC_PACKET_REKEY_DONE,
2965 SILC_PACKET_KEY_EXCHANGE_1,
2966 SILC_PACKET_SUCCESS,
2967 SILC_PACKET_FAILURE, -1);
2969 /* Start SKE rekey as responder */
2970 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2975 /* Processes the provided key material `data' as the SILC protocol
2976 specification defines. */
2979 silc_ske_process_key_material_data(unsigned char *data,
2980 SilcUInt32 data_len,
2981 SilcUInt32 req_iv_len,
2982 SilcUInt32 req_enc_key_len,
2983 SilcUInt32 req_hmac_key_len,
2987 unsigned char hashd[SILC_HASH_MAXLEN];
2988 SilcUInt32 hash_len = req_hmac_key_len;
2989 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2990 SilcSKEKeyMaterial key;
2992 SILC_LOG_DEBUG(("Start"));
2994 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2997 key = silc_calloc(1, sizeof(*key));
3001 buf = silc_buffer_alloc_size(1 + data_len);
3004 silc_buffer_format(buf,
3005 SILC_STR_UI_CHAR(0),
3006 SILC_STR_DATA(data, data_len),
3010 memset(hashd, 0, sizeof(hashd));
3012 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3013 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3014 memcpy(key->send_iv, hashd, req_iv_len);
3015 memset(hashd, 0, sizeof(hashd));
3017 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3018 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3019 memcpy(key->receive_iv, hashd, req_iv_len);
3020 key->iv_len = req_iv_len;
3022 /* Take the encryption keys. If requested key size is more than
3023 the size of hash length we will distribute more key material
3024 as protocol defines. */
3026 if (enc_key_len > hash_len) {
3028 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3029 k3[SILC_HASH_MAXLEN];
3030 unsigned char *dtmp;
3033 if (enc_key_len > (3 * hash_len))
3036 /* Take first round */
3037 memset(k1, 0, sizeof(k1));
3038 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3040 /* Take second round */
3041 dist = silc_buffer_alloc_size(data_len + hash_len);
3044 silc_buffer_format(dist,
3045 SILC_STR_DATA(data, data_len),
3046 SILC_STR_DATA(k1, hash_len),
3048 memset(k2, 0, sizeof(k2));
3049 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3051 /* Take third round */
3052 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3053 silc_buffer_pull_tail(dist, hash_len);
3054 silc_buffer_pull(dist, data_len + hash_len);
3055 silc_buffer_format(dist,
3056 SILC_STR_DATA(k2, hash_len),
3058 silc_buffer_push(dist, data_len + hash_len);
3059 memset(k3, 0, sizeof(k3));
3060 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3062 /* Then, save the keys */
3063 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3064 memcpy(dtmp, k1, hash_len);
3065 memcpy(dtmp + hash_len, k2, hash_len);
3066 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3068 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3069 memcpy(key->send_enc_key, dtmp, enc_key_len);
3070 key->enc_key_len = req_enc_key_len;
3072 memset(dtmp, 0, (3 * hash_len));
3073 memset(k1, 0, sizeof(k1));
3074 memset(k2, 0, sizeof(k2));
3075 memset(k3, 0, sizeof(k3));
3077 silc_buffer_clear(dist);
3078 silc_buffer_free(dist);
3080 /* Take normal hash as key */
3081 memset(hashd, 0, sizeof(hashd));
3082 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3083 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3084 memcpy(key->send_enc_key, hashd, enc_key_len);
3085 key->enc_key_len = req_enc_key_len;
3089 if (enc_key_len > hash_len) {
3091 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3092 k3[SILC_HASH_MAXLEN];
3093 unsigned char *dtmp;
3096 if (enc_key_len > (3 * hash_len))
3099 /* Take first round */
3100 memset(k1, 0, sizeof(k1));
3101 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3103 /* Take second round */
3104 dist = silc_buffer_alloc_size(data_len + hash_len);
3107 silc_buffer_format(dist,
3108 SILC_STR_DATA(data, data_len),
3109 SILC_STR_DATA(k1, hash_len),
3111 memset(k2, 0, sizeof(k2));
3112 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3114 /* Take third round */
3115 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3116 silc_buffer_pull_tail(dist, hash_len);
3117 silc_buffer_pull(dist, data_len + hash_len);
3118 silc_buffer_format(dist,
3119 SILC_STR_DATA(k2, hash_len),
3121 silc_buffer_push(dist, data_len + hash_len);
3122 memset(k3, 0, sizeof(k3));
3123 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3125 /* Then, save the keys */
3126 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3127 memcpy(dtmp, k1, hash_len);
3128 memcpy(dtmp + hash_len, k2, hash_len);
3129 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3131 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3132 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3133 key->enc_key_len = req_enc_key_len;
3135 memset(dtmp, 0, (3 * hash_len));
3136 memset(k1, 0, sizeof(k1));
3137 memset(k2, 0, sizeof(k2));
3138 memset(k3, 0, sizeof(k3));
3140 silc_buffer_clear(dist);
3141 silc_buffer_free(dist);
3143 /* Take normal hash as key */
3144 memset(hashd, 0, sizeof(hashd));
3145 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3146 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3147 memcpy(key->receive_enc_key, hashd, enc_key_len);
3148 key->enc_key_len = req_enc_key_len;
3151 /* Take HMAC keys */
3152 memset(hashd, 0, sizeof(hashd));
3154 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3155 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3156 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3157 memset(hashd, 0, sizeof(hashd));
3159 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3160 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3161 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3162 key->hmac_key_len = req_hmac_key_len;
3163 memset(hashd, 0, sizeof(hashd));
3165 silc_buffer_clear(buf);
3166 silc_buffer_free(buf);
3168 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3173 /* Processes negotiated key material as protocol specifies. This returns
3174 the actual keys to be used in the SILC. */
3177 silc_ske_process_key_material(SilcSKE ske,
3178 SilcUInt32 req_iv_len,
3179 SilcUInt32 req_enc_key_len,
3180 SilcUInt32 req_hmac_key_len,
3181 SilcSKERekeyMaterial *rekey)
3184 unsigned char *tmpbuf;
3186 SilcSKEKeyMaterial key;
3188 /* Encode KEY to binary data */
3189 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3191 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3194 silc_buffer_format(buf,
3195 SILC_STR_DATA(tmpbuf, klen),
3196 SILC_STR_DATA(ske->hash, ske->hash_len),
3199 /* Process the key material */
3200 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3201 req_iv_len, req_enc_key_len,
3205 memset(tmpbuf, 0, klen);
3207 silc_buffer_clear(buf);
3208 silc_buffer_free(buf);
3211 *rekey = silc_ske_make_rekey_material(ske, key);
3219 /* Free key material structure */
3221 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3227 silc_free(key->send_iv);
3228 if (key->receive_iv)
3229 silc_free(key->receive_iv);
3230 if (key->send_enc_key) {
3231 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3232 silc_free(key->send_enc_key);
3234 if (key->receive_enc_key) {
3235 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3236 silc_free(key->receive_enc_key);
3238 if (key->send_hmac_key) {
3239 memset(key->send_hmac_key, 0, key->hmac_key_len);
3240 silc_free(key->send_hmac_key);
3242 if (key->receive_hmac_key) {
3243 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3244 silc_free(key->receive_hmac_key);
3249 /* Free rekey material */
3251 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3255 if (rekey->send_enc_key) {
3256 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3257 silc_free(rekey->send_enc_key);
3259 silc_free(rekey->hash);
3263 /* Set keys into use */
3265 SilcBool silc_ske_set_keys(SilcSKE ske,
3266 SilcSKEKeyMaterial keymat,
3267 SilcSKESecurityProperties prop,
3268 SilcCipher *ret_send_key,
3269 SilcCipher *ret_receive_key,
3270 SilcHmac *ret_hmac_send,
3271 SilcHmac *ret_hmac_receive,
3274 unsigned char iv[SILC_HASH_MAXLEN];
3275 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3277 /* Allocate ciphers to be used in the communication */
3279 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3283 if (ret_receive_key) {
3284 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3289 /* Allocate HMACs */
3290 if (ret_hmac_send) {
3291 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3295 if (ret_hmac_receive) {
3296 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3303 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3307 /* Set key material */
3308 memset(iv, 0, sizeof(iv));
3309 if (ske->responder) {
3311 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3312 keymat->enc_key_len, TRUE);
3314 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3316 if (!ske->rekeying) {
3318 memcpy(iv, ske->hash, 4);
3320 memcpy(iv + 4, keymat->receive_iv, 8);
3322 /* Rekey, recompute the truncated hash value. */
3323 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3325 memcpy(iv + 4, keymat->receive_iv, 8);
3327 memset(iv + 4, 0, 12);
3330 silc_cipher_set_iv(*ret_send_key, iv);
3333 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3336 if (ret_receive_key) {
3337 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3338 keymat->enc_key_len, FALSE);
3340 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3342 if (!ske->rekeying) {
3344 memcpy(iv, ske->hash, 4);
3346 memcpy(iv + 4, keymat->send_iv, 8);
3348 /* Rekey, recompute the truncated hash value. */
3349 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3351 memcpy(iv + 4, keymat->send_iv, 8);
3353 memset(iv + 4, 0, 12);
3356 silc_cipher_set_iv(*ret_receive_key, iv);
3359 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3363 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3364 keymat->hmac_key_len);
3365 if (ret_hmac_receive)
3366 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3367 keymat->hmac_key_len);
3370 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3371 keymat->enc_key_len, TRUE);
3373 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3375 if (!ske->rekeying) {
3377 memcpy(iv, ske->hash, 4);
3379 memcpy(iv + 4, keymat->send_iv, 8);
3381 /* Rekey, recompute the truncated hash value. */
3382 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3384 memcpy(iv + 4, keymat->send_iv, 8);
3386 memset(iv + 4, 0, 12);
3389 silc_cipher_set_iv(*ret_send_key, iv);
3392 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3395 if (ret_receive_key) {
3396 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3397 keymat->enc_key_len, FALSE);
3399 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3401 if (!ske->rekeying) {
3402 /* Set IV. If IV Included flag was negotiated we only set the
3403 truncated hash value. */
3404 memcpy(iv, ske->hash, 4);
3406 memcpy(iv + 4, keymat->receive_iv, 8);
3408 /* Rekey, recompute the truncated hash value. */
3409 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3411 memcpy(iv + 4, keymat->receive_iv, 8);
3413 memset(iv + 4, 0, 12);
3416 silc_cipher_set_iv(*ret_receive_key, iv);
3419 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3423 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3424 keymat->hmac_key_len);
3425 if (ret_hmac_receive)
3426 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3427 keymat->hmac_key_len);
3433 const char *silc_ske_status_string[] =
3437 "Unexpected error occurred",
3438 "Bad payload in packet",
3439 "Unsupported group",
3440 "Unsupported cipher",
3442 "Unsupported hash function",
3444 "Unsupported public key (or certificate)",
3445 "Incorrect signature",
3446 "Bad or unsupported version",
3450 "Remote did not provide public key",
3451 "Bad reserved field in packet",
3452 "Bad payload length in packet",
3453 "Error computing signature",
3454 "System out of memory",
3455 "Key exchange timeout",
3460 /* Maps status to readable string and returns the string. If string is not
3461 found and empty character string ("") is returned. */
3463 const char *silc_ske_map_status(SilcSKEStatus status)
3467 for (i = 0; silc_ske_status_string[i]; i++)
3469 return silc_ske_status_string[i];
3474 /* Parses remote host's version string. */
3476 SilcBool silc_ske_parse_version(SilcSKE ske,
3477 SilcUInt32 *protocol_version,
3478 char **protocol_version_string,
3479 SilcUInt32 *software_version,
3480 char **software_version_string,
3481 char **vendor_version)
3483 return silc_parse_version_string(ske->remote_version,
3485 protocol_version_string,
3487 software_version_string,
3491 /* Get security properties */
3493 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3498 /* Get key material */
3500 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)