5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2014 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,
77 * Notify the owner of the ske that we failed. Ensures that we don't make the
78 * same callout twice, as the notification callback routines are not designed
79 * to handle that case.
81 static void silc_ske_notify_failure(SilcSKE ske)
83 SILC_LOG_DEBUG(("Notifying SKE %p owner of failure (failure_notified = %d)",
84 ske, ske->failure_notified));
87 * First, check if we have already made a failure callout. If so, then we
90 if (ske->failure_notified)
94 * Mark ourselves as having already sent the failure notification here and
97 ske->failure_notified = TRUE;
99 SILC_LOG_DEBUG(("Deliver failure notification for SKE %p (%s)",
100 ske, ske->responder ? "responder" : "initiator"));
103 * Finally, make the call to the owner's registered failure callback.
106 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
108 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
111 /* Packet callback */
113 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
114 SilcPacketStream stream,
116 void *callback_context,
119 SilcSKE ske = callback_context;
121 /* Clear retransmission */
122 ske->retry_timer = SILC_SKE_RETRY_MIN;
123 ske->retry_count = 0;
124 silc_schedule_task_del_by_callback(ske->schedule,
125 silc_ske_packet_send_retry);
127 /* Signal for new packet */
128 ske->packet = packet;
130 /* Check if we were aborted */
132 silc_packet_free(packet);
136 silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
138 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
140 silc_fsm_continue_sync(&ske->fsm);
144 /* See if received failure from remote */
145 if (packet->type == SILC_PACKET_FAILURE)
146 silc_ske_notify_failure(ske);
148 /* Handle rekey and SUCCESS packets synchronously. After SUCCESS packets
149 they keys are taken into use immediately, hence the synchronous
150 processing to get the keys in use as soon as possible. */
151 if (ske->rekeying || packet->type == SILC_PACKET_SUCCESS)
152 silc_fsm_continue_sync(&ske->fsm);
154 silc_fsm_continue(&ske->fsm);
159 /* Packet stream callbacks */
160 static SilcPacketCallbacks silc_ske_stream_cbs =
162 silc_ske_packet_receive, NULL, NULL
165 /* Aborts SKE protocol */
167 static void silc_ske_abort(SilcAsyncOperation op, void *context)
169 SilcSKE ske = context;
173 /* Public key verification completion callback */
175 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
176 void *completion_context)
178 ske->status = status;
179 SILC_FSM_CALL_CONTINUE(&ske->fsm);
182 /* SKR find callback */
184 static void silc_ske_skr_callback(SilcSKR repository,
186 SilcSKRStatus status,
187 SilcDList keys, void *context)
189 SilcSKE ske = context;
191 silc_skr_find_free(find);
193 if (status != SILC_SKR_OK) {
194 if (ske->callbacks->verify_key) {
195 /* Verify from application */
196 ske->callbacks->verify_key(ske, ske->prop->public_key,
197 ske->callbacks->context,
198 silc_ske_pk_verified, NULL);
204 silc_dlist_uninit(keys);
207 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
208 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
209 SILC_FSM_CALL_CONTINUE(&ske->fsm);
212 /* Checks remote and local versions */
214 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
216 if (!ske->remote_version || !ske->version)
217 return SILC_SKE_STATUS_BAD_VERSION;
219 if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
221 return SILC_SKE_STATUS_BAD_VERSION;
223 return SILC_SKE_STATUS_OK;
226 /* Selects the supported security properties from the initiator's Key
227 Exchange Start Payload. A responder function. Saves our reply
228 start payload to ske->start_payload. */
231 silc_ske_select_security_properties(SilcSKE ske,
232 SilcSKEStartPayload remote_payload,
233 SilcSKESecurityProperties *prop)
235 SilcSKEStatus status;
236 SilcSKEStartPayload rp, payload;
240 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
244 return SILC_SKE_STATUS_BAD_VERSION;
246 /* Check for mandatory fields */
247 if (!rp->ke_grp_len) {
248 SILC_LOG_DEBUG(("KE group not defined in payload"));
249 return SILC_SKE_STATUS_BAD_PAYLOAD;
251 if (!rp->pkcs_alg_len) {
252 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
253 return SILC_SKE_STATUS_BAD_PAYLOAD;
255 if (!rp->enc_alg_len) {
256 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
257 return SILC_SKE_STATUS_BAD_PAYLOAD;
259 if (!rp->hash_alg_len) {
260 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
261 return SILC_SKE_STATUS_BAD_PAYLOAD;
263 if (!rp->hmac_alg_len) {
264 SILC_LOG_DEBUG(("HMAC not defined in payload"));
265 return SILC_SKE_STATUS_BAD_PAYLOAD;
268 /* Allocate security properties */
269 *prop = silc_calloc(1, sizeof(**prop));
271 return SILC_SKE_STATUS_OUT_OF_MEMORY;
273 /* Allocate our reply start payload */
274 payload = silc_calloc(1, sizeof(*payload));
277 return SILC_SKE_STATUS_OUT_OF_MEMORY;
280 /* Check version string */
281 ske->remote_version = silc_memdup(rp->version, rp->version_len);
282 status = silc_ske_check_version(ske);
283 if (status != SILC_SKE_STATUS_OK) {
284 ske->status = status;
288 /* Flags are returned unchanged. */
289 (*prop)->flags = payload->flags = rp->flags;
291 /* Take cookie, we must return it to sender unmodified. */
292 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
293 if (!payload->cookie) {
294 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
297 payload->cookie_len = SILC_SKE_COOKIE_LEN;
298 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
300 /* In case IV included flag and session port is set the first 16-bits of
301 cookie will include our session port. */
302 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
303 /* Take remote port */
304 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
307 SILC_PUT16_MSB(ske->session_port, payload->cookie);
310 /* Put our version to our reply */
311 payload->version = strdup(ske->version);
312 if (!payload->version) {
313 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
316 payload->version_len = strlen(ske->version);
318 /* Get supported Key Exchange groups */
319 cp = rp->ke_grp_list;
320 if (cp && strchr(cp, ',')) {
324 len = strcspn(cp, ",");
325 item = silc_calloc(len + 1, sizeof(char));
327 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
330 memcpy(item, cp, len);
332 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
334 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
335 SILC_LOG_DEBUG(("Found KE group `%s'", item));
337 payload->ke_grp_len = len;
338 payload->ke_grp_list = item;
352 if (!payload->ke_grp_len && !payload->ke_grp_list) {
353 SILC_LOG_DEBUG(("Could not find supported KE group"));
355 return SILC_SKE_STATUS_UNKNOWN_GROUP;
358 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
359 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
361 payload->ke_grp_len = rp->ke_grp_len;
362 payload->ke_grp_list = strdup(rp->ke_grp_list);
365 /* Save group to security properties */
366 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
367 if (status != SILC_SKE_STATUS_OK) {
369 return SILC_SKE_STATUS_UNKNOWN_GROUP;
372 /* Get supported PKCS algorithms */
373 cp = rp->pkcs_alg_list;
374 if (cp && strchr(cp, ',')) {
378 len = strcspn(cp, ",");
379 item = silc_calloc(len + 1, sizeof(char));
381 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
384 memcpy(item, cp, len);
386 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
388 if (silc_pkcs_find_algorithm(item, NULL)) {
389 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
391 payload->pkcs_alg_len = len;
392 payload->pkcs_alg_list = item;
406 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
407 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
408 silc_free(payload->ke_grp_list);
410 return SILC_SKE_STATUS_UNKNOWN_PKCS;
413 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
414 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
416 payload->pkcs_alg_len = rp->pkcs_alg_len;
417 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
420 /* Get supported encryption algorithms */
421 cp = rp->enc_alg_list;
422 if (cp && strchr(cp, ',')) {
426 len = strcspn(cp, ",");
427 item = silc_calloc(len + 1, sizeof(char));
429 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
432 memcpy(item, cp, len);
434 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
436 if (silc_cipher_is_supported(item) == TRUE) {
437 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
439 payload->enc_alg_len = len;
440 payload->enc_alg_list = item;
454 if (!payload->enc_alg_len && !payload->enc_alg_list) {
455 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
456 silc_free(payload->ke_grp_list);
457 silc_free(payload->pkcs_alg_list);
459 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
462 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
465 payload->enc_alg_len = rp->enc_alg_len;
466 payload->enc_alg_list = strdup(rp->enc_alg_list);
469 /* Save selected cipher to security properties */
470 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
471 silc_free(payload->ke_grp_list);
472 silc_free(payload->pkcs_alg_list);
474 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
477 /* Get supported hash algorithms */
478 cp = rp->hash_alg_list;
479 if (cp && strchr(cp, ',')) {
483 len = strcspn(cp, ",");
484 item = silc_calloc(len + 1, sizeof(char));
486 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
489 memcpy(item, cp, len);
491 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
493 if (silc_hash_is_supported(item) == TRUE) {
494 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
496 payload->hash_alg_len = len;
497 payload->hash_alg_list = item;
511 if (!payload->hash_alg_len && !payload->hash_alg_list) {
512 SILC_LOG_DEBUG(("Could not find supported hash alg"));
513 silc_free(payload->ke_grp_list);
514 silc_free(payload->pkcs_alg_list);
515 silc_free(payload->enc_alg_list);
517 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
520 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
523 payload->hash_alg_len = rp->hash_alg_len;
524 payload->hash_alg_list = strdup(rp->hash_alg_list);
527 /* Save selected hash algorithm to security properties */
528 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
529 silc_free(payload->ke_grp_list);
530 silc_free(payload->pkcs_alg_list);
531 silc_free(payload->enc_alg_list);
533 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
536 /* Get supported HMACs */
537 cp = rp->hmac_alg_list;
538 if (cp && strchr(cp, ',')) {
542 len = strcspn(cp, ",");
543 item = silc_calloc(len + 1, sizeof(char));
545 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
548 memcpy(item, cp, len);
550 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
552 if (silc_hmac_is_supported(item) == TRUE) {
553 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
555 payload->hmac_alg_len = len;
556 payload->hmac_alg_list = item;
570 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
571 SILC_LOG_DEBUG(("Could not find supported HMAC"));
572 silc_free(payload->ke_grp_list);
573 silc_free(payload->pkcs_alg_list);
574 silc_free(payload->enc_alg_list);
575 silc_free(payload->hash_alg_list);
577 return SILC_SKE_STATUS_UNKNOWN_HMAC;
580 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
583 payload->hmac_alg_len = rp->hmac_alg_len;
584 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
587 /* Save selected HMACc to security properties */
588 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
589 silc_free(payload->ke_grp_list);
590 silc_free(payload->pkcs_alg_list);
591 silc_free(payload->enc_alg_list);
592 silc_free(payload->hash_alg_list);
594 return SILC_SKE_STATUS_UNKNOWN_HMAC;
597 /* Get supported compression algorithms */
598 cp = rp->comp_alg_list;
599 if (cp && strchr(cp, ',')) {
603 len = strcspn(cp, ",");
604 item = silc_calloc(len + 1, sizeof(char));
606 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
609 memcpy(item, cp, len);
611 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
614 if (!strcmp(item, "none")) {
615 SILC_LOG_DEBUG(("Found Compression `%s'", item));
616 payload->comp_alg_len = len;
617 payload->comp_alg_list = item;
621 if (silc_hmac_is_supported(item) == TRUE) {
622 SILC_LOG_DEBUG(("Found Compression `%s'", item));
623 payload->comp_alg_len = len;
624 payload->comp_alg_list = item;
640 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
641 2 + payload->version_len +
642 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
643 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
644 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
646 /* Save our reply payload */
647 ske->start_payload = payload;
649 return SILC_SKE_STATUS_OK;
652 /* Creates random number such that 1 < rnd < n and at most length
653 of len bits. The rnd sent as argument must be initialized. */
655 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
659 SilcSKEStatus status = SILC_SKE_STATUS_OK;
660 unsigned char *string;
664 return SILC_SKE_STATUS_ERROR;
666 SILC_LOG_DEBUG(("Creating random number"));
670 /* Get the random number as string */
671 string = silc_rng_get_rn_data(ske->rng, l);
673 return SILC_SKE_STATUS_OUT_OF_MEMORY;
675 /* Decode the string into a MP integer */
676 silc_mp_bin2mp(string, l, rnd);
677 silc_mp_mod_2exp(rnd, rnd, len);
680 if (silc_mp_cmp_ui(rnd, 1) < 0)
681 status = SILC_SKE_STATUS_ERROR;
682 if (silc_mp_cmp(rnd, n) >= 0)
683 status = SILC_SKE_STATUS_ERROR;
685 memset(string, 'F', l);
691 /* Creates a hash value HASH as defined in the SKE protocol. If the
692 `initiator' is TRUE then this function is used to create the HASH_i
693 hash value defined in the protocol. If it is FALSE then this is used
694 to create the HASH value defined by the protocol. */
696 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
697 unsigned char *return_hash,
698 SilcUInt32 *return_hash_len,
701 SilcSKEStatus status = SILC_SKE_STATUS_OK;
703 unsigned char *e, *f, *KEY, *s_data;
704 SilcUInt32 e_len, f_len, KEY_len, s_len;
707 SILC_LOG_DEBUG(("Start"));
709 if (initiator == FALSE) {
710 s_data = (ske->start_payload_copy ?
711 silc_buffer_data(ske->start_payload_copy) : NULL);
712 s_len = (ske->start_payload_copy ?
713 silc_buffer_len(ske->start_payload_copy) : 0);
714 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
716 return SILC_SKE_STATUS_OUT_OF_MEMORY;
717 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
719 return SILC_SKE_STATUS_OUT_OF_MEMORY;
720 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
722 return SILC_SKE_STATUS_OUT_OF_MEMORY;
724 /* Format the buffer used to compute the hash value */
725 buf = silc_buffer_alloc_size(s_len +
726 ske->ke2_payload->pk_len +
727 ske->ke1_payload->pk_len +
728 e_len + f_len + KEY_len);
730 return SILC_SKE_STATUS_OUT_OF_MEMORY;
732 /* Initiator is not required to send its public key */
733 if (!ske->ke1_payload->pk_data) {
735 silc_buffer_format(buf,
736 SILC_STR_DATA(s_data, s_len),
737 SILC_STR_DATA(ske->ke2_payload->pk_data,
738 ske->ke2_payload->pk_len),
739 SILC_STR_DATA(e, e_len),
740 SILC_STR_DATA(f, f_len),
741 SILC_STR_DATA(KEY, KEY_len),
745 silc_buffer_format(buf,
746 SILC_STR_DATA(s_data, s_len),
747 SILC_STR_DATA(ske->ke2_payload->pk_data,
748 ske->ke2_payload->pk_len),
749 SILC_STR_DATA(ske->ke1_payload->pk_data,
750 ske->ke1_payload->pk_len),
751 SILC_STR_DATA(e, e_len),
752 SILC_STR_DATA(f, f_len),
753 SILC_STR_DATA(KEY, KEY_len),
757 silc_buffer_free(buf);
760 memset(KEY, 0, KEY_len);
764 return SILC_SKE_STATUS_ERROR;
769 memset(KEY, 0, KEY_len);
774 s_data = (ske->start_payload_copy ?
775 silc_buffer_data(ske->start_payload_copy) : NULL);
776 s_len = (ske->start_payload_copy ?
777 silc_buffer_len(ske->start_payload_copy) : 0);
778 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
780 return SILC_SKE_STATUS_OUT_OF_MEMORY;
782 buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
784 return SILC_SKE_STATUS_OUT_OF_MEMORY;
786 /* Format the buffer used to compute the hash value */
788 silc_buffer_format(buf,
789 SILC_STR_DATA(s_data, s_len),
790 SILC_STR_DATA(ske->ke1_payload->pk_data,
791 ske->ke1_payload->pk_len),
792 SILC_STR_DATA(e, e_len),
795 silc_buffer_free(buf);
798 return SILC_SKE_STATUS_ERROR;
801 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
808 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
810 *return_hash_len = silc_hash_len(ske->prop->hash);
812 if (initiator == FALSE) {
813 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
815 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
818 silc_buffer_free(buf);
823 /* Generate rekey material */
825 static SilcSKERekeyMaterial
826 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
828 SilcSKERekeyMaterial rekey;
834 /* Create rekey material */
835 rekey = silc_calloc(1, sizeof(*rekey));
840 if (ske->prop->group)
841 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
842 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
843 hash = silc_hash_get_name(ske->prop->hash);
844 rekey->hash = silc_memdup(hash, strlen(hash));
849 if (rekey->pfs == FALSE) {
850 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
851 keymat->enc_key_len / 8);
852 if (!rekey->send_enc_key) {
856 rekey->enc_key_len = keymat->enc_key_len;
862 /* Assembles security properties */
864 static SilcSKEStartPayload
865 silc_ske_assemble_security_properties(SilcSKE ske,
866 SilcSKESecurityPropertyFlag flags,
868 SilcBool small_proposal)
870 SilcSKEStartPayload rp;
873 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
875 rp = silc_calloc(1, sizeof(*rp));
880 rp->flags = (unsigned char)flags;
882 /* Set random cookie */
883 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
888 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
889 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
890 rp->cookie_len = SILC_SKE_COOKIE_LEN;
892 /* In case IV included flag and session port is set the first 16-bits of
893 cookie will include our session port. */
894 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
895 SILC_PUT16_MSB(ske->session_port, rp->cookie);
898 rp->version = strdup(version);
900 rp->version_len = strlen(version);
902 /* Get supported Key Exhange groups */
903 rp->ke_grp_list = silc_ske_get_supported_groups(small_proposal);
905 rp->ke_grp_len = strlen(rp->ke_grp_list);
907 /* Get supported PKCS algorithms */
909 rp->pkcs_alg_list = strdup(silc_default_pkcs_alg[0].name);
911 rp->pkcs_alg_list = silc_pkcs_get_supported();
912 if (rp->pkcs_alg_list)
913 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
915 /* Get supported encryption algorithms */
917 rp->enc_alg_list = strdup(silc_default_ciphers[0].name);
919 rp->enc_alg_list = silc_cipher_get_supported();
920 if (rp->enc_alg_list)
921 rp->enc_alg_len = strlen(rp->enc_alg_list);
923 /* Get supported hash algorithms */
925 rp->hash_alg_list = strdup(silc_default_hash[0].name);
927 rp->hash_alg_list = silc_hash_get_supported();
928 if (rp->hash_alg_list)
929 rp->hash_alg_len = strlen(rp->hash_alg_list);
931 /* Get supported HMACs */
933 rp->hmac_alg_list = strdup(silc_default_hmacs[0].name);
935 rp->hmac_alg_list = silc_hmac_get_supported();
936 if (rp->hmac_alg_list)
937 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
939 if (!small_proposal) {
941 /* Get supported compression algorithms */
942 rp->comp_alg_list = strdup("none");
943 rp->comp_alg_len = strlen("none");
946 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
947 2 + rp->version_len +
948 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
949 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
950 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
955 /* Packet retransmission callback. */
957 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
959 SilcSKE ske = context;
961 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
963 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
964 ske->retry_count = 0;
965 ske->retry_timer = SILC_SKE_RETRY_MIN;
966 silc_free(ske->retrans.data);
967 ske->retrans.data = NULL;
968 ske->status = SILC_SKE_STATUS_TIMEOUT;
969 silc_ske_notify_failure(ske);
970 silc_fsm_continue_sync(&ske->fsm);
974 SILC_LOG_DEBUG(("Retransmitting packet"));
975 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
976 ske->retrans.data, ske->retrans.data_len);
979 /* Install retransmission timer */
981 static SilcBool silc_ske_install_retransmission(SilcSKE ske)
983 if (!silc_packet_stream_is_udp(ske->stream))
986 if (ske->retrans.data) {
987 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
989 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
990 ske, ske->retry_timer, 0);
992 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
993 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
997 /* Sends SILC packet. Handles retransmissions with UDP streams. */
999 static SilcBool silc_ske_packet_send(SilcSKE ske,
1000 SilcPacketType type,
1001 SilcPacketFlags flags,
1002 const unsigned char *data,
1003 SilcUInt32 data_len)
1007 /* Send the packet */
1008 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
1010 if (silc_packet_stream_is_udp(ske->stream) &&
1011 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
1012 silc_free(ske->retrans.data);
1013 ske->retrans.type = type;
1014 ske->retrans.flags = flags;
1015 ske->retrans.data = silc_memdup(data, data_len);
1016 if (ske->retrans.data) {
1017 ske->retrans.data_len = data_len;
1018 silc_ske_install_retransmission(ske);
1025 /* Calls completion callback. Completion is called always in this function
1026 and must not be called anywhere else. */
1028 static void silc_ske_completion(SilcSKE ske)
1030 /* Call the completion callback */
1031 if (!ske->aborted && ske->callbacks->completed) {
1032 if (ske->status != SILC_SKE_STATUS_OK)
1033 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1034 ske->callbacks->context);
1036 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1037 ske->rekey, ske->callbacks->context);
1041 /* SKE FSM destructor. */
1043 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
1044 void *destructor_context)
1046 SilcSKE ske = fsm_context;
1050 /* Key exchange timeout task callback */
1052 SILC_TASK_CALLBACK(silc_ske_timeout)
1054 SilcSKE ske = context;
1056 SILC_LOG_DEBUG(("Timeout"));
1059 ske->status = SILC_SKE_STATUS_TIMEOUT;
1060 silc_ske_notify_failure(ske);
1062 silc_fsm_continue_sync(&ske->fsm);
1065 /* Key exchange timeout task callback */
1067 SILC_TASK_CALLBACK(silc_ske_probe_timeout)
1069 SilcSKE ske = context;
1071 SILC_LOG_DEBUG(("Probe timeout"));
1074 ske->status = SILC_SKE_STATUS_PROBE_TIMEOUT;
1075 silc_ske_notify_failure(ske);
1077 silc_fsm_continue_sync(&ske->fsm);
1080 /******************************* Protocol API *******************************/
1082 /* Allocates new SKE object. */
1084 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1085 SilcSKR repository, SilcPublicKey public_key,
1086 SilcPrivateKey private_key, void *context)
1090 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1092 if (!rng || !schedule)
1096 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1100 ske = silc_calloc(1, sizeof(*ske));
1103 ske->status = SILC_SKE_STATUS_OK;
1105 ske->repository = repository;
1106 ske->user_data = context;
1107 ske->schedule = schedule;
1108 ske->public_key = public_key;
1109 ske->private_key = private_key;
1110 ske->retry_timer = SILC_SKE_RETRY_MIN;
1116 /* Free's SKE object. */
1118 void silc_ske_free(SilcSKE ske)
1123 SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu",
1124 ske, ske->aborted, ske->refcnt));
1128 * If already aborted, destroy the session immediately. Only do the
1129 * notification work if we have not already though, as doing so twice
1130 * results in memory corruption. We may have silc_ske_free called
1131 * twice, once when the abort is requested, and then again when the
1132 * FSM finish routine is called. We have to be prepared to handle
1136 ske->status = SILC_SKE_STATUS_ERROR;
1138 silc_ske_notify_failure(ske);
1140 if (silc_fsm_is_started(&ske->fsm))
1141 silc_fsm_continue_sync(&ske->fsm);
1143 SILC_LOG_DEBUG(("Not continuing FSM as it's finished for SKE %p", ske));
1147 if (ske->refcnt > 0)
1150 /* Free start payload */
1151 if (ske->start_payload)
1152 silc_ske_payload_start_free(ske->start_payload);
1154 /* Free KE payload */
1155 if (ske->ke1_payload)
1156 silc_ske_payload_ke_free(ske->ke1_payload);
1157 if (ske->ke2_payload)
1158 silc_ske_payload_ke_free(ske->ke2_payload);
1159 silc_free(ske->remote_version);
1163 if (ske->prop->group)
1164 silc_ske_group_free(ske->prop->group);
1165 if (ske->prop->cipher)
1166 silc_cipher_free(ske->prop->cipher);
1167 if (ske->prop->hash)
1168 silc_hash_free(ske->prop->hash);
1169 if (ske->prop->hmac)
1170 silc_hmac_free(ske->prop->hmac);
1171 if (ske->prop->public_key)
1172 silc_pkcs_public_key_free(ske->prop->public_key);
1173 silc_free(ske->prop);
1176 silc_ske_free_key_material(ske->keymat);
1177 if (ske->start_payload_copy)
1178 silc_buffer_free(ske->start_payload_copy);
1180 silc_mp_uninit(ske->x);
1184 silc_mp_uninit(ske->KEY);
1185 silc_free(ske->KEY);
1187 silc_free(ske->retrans.data);
1188 silc_free(ske->hash);
1189 silc_free(ske->callbacks);
1191 memset(ske, 0xdd, sizeof(*ske));
1195 /* Return user context */
1197 void *silc_ske_get_context(SilcSKE ske)
1199 return ske->user_data;
1202 /* Sets protocol callbacks */
1204 void silc_ske_set_callbacks(SilcSKE ske,
1205 SilcSKEVerifyCb verify_key,
1206 SilcSKECompletionCb completed,
1210 silc_free(ske->callbacks);
1211 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1212 if (!ske->callbacks)
1214 ske->callbacks->verify_key = verify_key;
1215 ske->callbacks->completed = completed;
1216 ske->callbacks->context = context;
1220 /******************************** Initiator *********************************/
1222 /* Start protocol. Send our proposal */
1224 SILC_FSM_STATE(silc_ske_st_initiator_start)
1226 SilcSKE ske = fsm_context;
1227 SilcBuffer payload_buf;
1230 SILC_LOG_DEBUG(("Start"));
1234 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1235 return SILC_FSM_CONTINUE;
1238 /* Encode the payload */
1239 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1241 if (status != SILC_SKE_STATUS_OK) {
1242 /** Error encoding Start Payload */
1243 ske->status = status;
1244 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1245 return SILC_FSM_CONTINUE;
1248 /* Save the the payload buffer for future use. It is later used to
1249 compute the HASH value. */
1250 ske->start_payload_copy = payload_buf;
1252 /* Send the packet. */
1253 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1254 silc_buffer_data(payload_buf),
1255 silc_buffer_len(payload_buf))) {
1256 /** Error sending packet */
1257 SILC_LOG_DEBUG(("Error sending packet"));
1258 ske->status = SILC_SKE_STATUS_ERROR;
1259 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1260 return SILC_FSM_CONTINUE;
1263 /** Wait for responder proposal */
1264 SILC_LOG_DEBUG(("Waiting for responder proposal"));
1265 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1266 return SILC_FSM_WAIT;
1269 /* Phase-1. Receives responder's proposal */
1271 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1273 SilcSKE ske = fsm_context;
1274 SilcSKEStatus status;
1275 SilcSKEStartPayload payload;
1276 SilcSKESecurityProperties prop;
1277 SilcSKEDiffieHellmanGroup group = NULL;
1278 SilcBuffer packet_buf = &ske->packet->buffer;
1279 SilcUInt16 remote_port = 0;
1283 SILC_LOG_DEBUG(("Start"));
1285 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1286 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1287 if (silc_ske_install_retransmission(ske)) {
1288 silc_packet_free(ske->packet);
1290 return SILC_FSM_WAIT;
1292 silc_packet_free(ske->packet);
1294 ske->status = SILC_SKE_STATUS_ERROR;
1295 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1296 return SILC_FSM_CONTINUE;
1300 silc_schedule_task_del_by_all(ske->schedule, 0, silc_ske_probe_timeout, ske);
1302 /* Decode the payload */
1303 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1304 if (status != SILC_SKE_STATUS_OK) {
1305 /** Error decoding Start Payload */
1306 silc_packet_free(ske->packet);
1308 ske->status = status;
1309 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1310 return SILC_FSM_CONTINUE;
1313 /* Get remote ID and set it to stream */
1314 if (ske->packet->src_id_len &&
1315 (ske->packet->src_id_type == SILC_ID_SERVER ||
1316 ske->packet->src_id_type == SILC_ID_CLIENT)) {
1317 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1318 ske->packet->src_id_type,
1319 (ske->packet->src_id_type == SILC_ID_SERVER ?
1320 (void *)&id.u.server_id : (void *)&id.u.client_id),
1321 (ske->packet->src_id_type == SILC_ID_SERVER ?
1322 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1323 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1324 (ske->packet->src_id_type == SILC_ID_SERVER ?
1325 (void *)&id.u.server_id : (void *)&id.u.client_id));
1328 silc_packet_free(ske->packet);
1331 /* Check that the cookie is returned unmodified. In case IV included
1332 flag and session port has been set, the first two bytes of cookie
1333 are the session port and we ignore them in this check. */
1334 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1335 /* Take remote port */
1336 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1339 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1340 SILC_SKE_COOKIE_LEN - coff)) {
1341 /** Invalid cookie */
1342 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1343 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1344 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1345 return SILC_FSM_CONTINUE;
1348 /* Check version string */
1349 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1350 status = silc_ske_check_version(ske);
1351 if (status != SILC_SKE_STATUS_OK) {
1352 /** Version mismatch */
1353 ske->status = status;
1354 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1355 return SILC_FSM_CONTINUE;
1358 /* Free our KE Start Payload context, we don't need it anymore. */
1359 silc_ske_payload_start_free(ske->start_payload);
1360 ske->start_payload = NULL;
1362 /* Take the selected security properties into use while doing
1363 the key exchange. This is used only while doing the key
1365 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1368 prop->flags = payload->flags;
1369 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1370 if (status != SILC_SKE_STATUS_OK)
1373 prop->group = group;
1374 prop->remote_port = remote_port;
1376 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1377 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1380 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1381 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1384 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1385 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1388 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1389 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1393 /* Save remote's KE Start Payload */
1394 ske->start_payload = payload;
1396 /** Send KE Payload */
1397 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1398 return SILC_FSM_CONTINUE;
1402 silc_ske_payload_start_free(payload);
1404 silc_ske_group_free(group);
1407 silc_cipher_free(prop->cipher);
1409 silc_hash_free(prop->hash);
1411 silc_hmac_free(prop->hmac);
1416 if (status == SILC_SKE_STATUS_OK)
1417 status = SILC_SKE_STATUS_ERROR;
1420 ske->status = status;
1421 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1422 return SILC_FSM_CONTINUE;
1425 /* Phase-2. Send KE payload */
1427 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1429 SilcSKE ske = fsm_context;
1430 SilcSKEStatus status;
1431 SilcBuffer payload_buf;
1433 SilcSKEKEPayload payload;
1436 SILC_LOG_DEBUG(("Start"));
1438 /* Create the random number x, 1 < x < q. */
1439 x = silc_calloc(1, sizeof(*x));
1441 /** Out of memory */
1442 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1443 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1444 return SILC_FSM_CONTINUE;
1448 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1449 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1451 if (status != SILC_SKE_STATUS_OK) {
1452 /** Error generating random number */
1455 ske->status = status;
1456 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1457 return SILC_FSM_CONTINUE;
1460 /* Encode the result to Key Exchange Payload. */
1462 payload = silc_calloc(1, sizeof(*payload));
1464 /** Out of memory */
1467 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1468 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1469 return SILC_FSM_CONTINUE;
1471 ske->ke1_payload = payload;
1473 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1475 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1476 silc_mp_init(&payload->x);
1477 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1478 &ske->prop->group->group);
1480 /* Get public key */
1481 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1482 if (!payload->pk_data) {
1483 /** Error encoding public key */
1486 silc_mp_uninit(&payload->x);
1488 ske->ke1_payload = NULL;
1489 ske->status = SILC_SKE_STATUS_ERROR;
1490 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1491 return SILC_FSM_CONTINUE;
1493 payload->pk_len = pk_len;
1494 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1496 /* Compute signature data if we are doing mutual authentication */
1497 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1498 unsigned char hash[SILC_HASH_MAXLEN], sign[65536 + 1];
1499 SilcUInt32 hash_len, sign_len;
1501 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1502 SILC_LOG_DEBUG(("Computing HASH_i value"));
1504 /* Compute the hash value */
1505 memset(hash, 0, sizeof(hash));
1506 if (silc_ske_make_hash(ske, hash, &hash_len, TRUE) != SILC_SKE_STATUS_OK)
1508 /** Error computing hash */
1511 silc_mp_uninit(&payload->x);
1512 silc_free(payload->pk_data);
1514 ske->ke1_payload = NULL;
1515 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1516 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1517 return SILC_FSM_CONTINUE;
1520 SILC_LOG_DEBUG(("Signing HASH_i value"));
1522 /* Sign the hash value */
1523 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1524 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1525 /** Error computing signature */
1528 silc_mp_uninit(&payload->x);
1529 silc_free(payload->pk_data);
1531 ske->ke1_payload = NULL;
1532 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1533 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1534 return SILC_FSM_CONTINUE;
1536 payload->sign_data = silc_memdup(sign, sign_len);
1537 if (payload->sign_data)
1538 payload->sign_len = sign_len;
1539 memset(sign, 0, sizeof(sign));
1542 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1543 if (status != SILC_SKE_STATUS_OK) {
1544 /** Error encoding KE payload */
1547 silc_mp_uninit(&payload->x);
1548 silc_free(payload->pk_data);
1549 silc_free(payload->sign_data);
1551 ske->ke1_payload = NULL;
1552 ske->status = status;
1553 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1554 return SILC_FSM_CONTINUE;
1559 /* Check for backwards compatibility */
1561 /* Send the packet. */
1562 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1563 silc_buffer_data(payload_buf),
1564 silc_buffer_len(payload_buf))) {
1565 /** Error sending packet */
1566 SILC_LOG_DEBUG(("Error sending packet"));
1567 ske->status = SILC_SKE_STATUS_ERROR;
1568 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1569 return SILC_FSM_CONTINUE;
1572 silc_buffer_free(payload_buf);
1574 /** Waiting responder's KE payload */
1575 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1576 return SILC_FSM_WAIT;
1579 /* Phase-3. Process responder's KE payload */
1581 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1583 SilcSKE ske = fsm_context;
1584 SilcSKEStatus status;
1585 SilcSKEKEPayload payload;
1587 SilcBuffer packet_buf = &ske->packet->buffer;
1589 SILC_LOG_DEBUG(("Start"));
1591 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1592 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1593 if (silc_ske_install_retransmission(ske)) {
1594 silc_packet_free(ske->packet);
1596 return SILC_FSM_WAIT;
1598 silc_packet_free(ske->packet);
1600 ske->status = SILC_SKE_STATUS_ERROR;
1601 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1602 return SILC_FSM_CONTINUE;
1606 /* Decode the payload */
1607 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1608 if (status != SILC_SKE_STATUS_OK) {
1609 /** Error decoding KE payload */
1610 silc_packet_free(ske->packet);
1612 ske->status = status;
1613 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1614 return SILC_FSM_CONTINUE;
1616 silc_packet_free(ske->packet);
1618 ske->ke2_payload = payload;
1620 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1621 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1622 "even though we require it"));
1623 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1627 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1629 /* Compute the shared secret key */
1630 KEY = silc_calloc(1, sizeof(*KEY));
1632 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1636 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1639 /* Decode the remote's public key */
1640 if (payload->pk_data &&
1641 !silc_pkcs_public_key_alloc(payload->pk_type,
1642 payload->pk_data, payload->pk_len,
1643 &ske->prop->public_key)) {
1644 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1645 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1649 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1651 SILC_LOG_DEBUG(("Verifying public key"));
1653 /** Waiting public key verification */
1654 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1656 /* If repository is provided, verify the key from there. */
1657 if (ske->repository) {
1660 find = silc_skr_find_alloc();
1662 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1665 silc_skr_find_set_pkcs_type(find,
1666 silc_pkcs_get_type(ske->prop->public_key));
1667 silc_skr_find_set_public_key(find, ske->prop->public_key);
1668 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1670 /* Find key from repository */
1671 SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1672 find, silc_ske_skr_callback, ske));
1674 /* Verify from application */
1675 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1676 ske->callbacks->context,
1677 silc_ske_pk_verified, NULL));
1682 /** Process key material */
1683 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1684 return SILC_FSM_CONTINUE;
1687 silc_ske_payload_ke_free(payload);
1688 ske->ke2_payload = NULL;
1690 silc_mp_uninit(ske->KEY);
1691 silc_free(ske->KEY);
1694 if (status == SILC_SKE_STATUS_OK)
1695 return SILC_SKE_STATUS_ERROR;
1698 ske->status = status;
1699 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1700 return SILC_FSM_CONTINUE;
1703 /* Process key material */
1705 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1707 SilcSKE ske = fsm_context;
1708 SilcSKEStatus status;
1709 SilcSKEKEPayload payload;
1710 unsigned char hash[SILC_HASH_MAXLEN];
1711 SilcUInt32 hash_len;
1712 int key_len, block_len;
1716 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1717 return SILC_FSM_CONTINUE;
1720 /* Check result of public key verification */
1721 if (ske->status != SILC_SKE_STATUS_OK) {
1722 /** Public key not verified */
1723 SILC_LOG_DEBUG(("Public key verification failed"));
1724 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1725 return SILC_FSM_CONTINUE;
1728 payload = ske->ke2_payload;
1730 /* Compute the HASH value */
1731 SILC_LOG_DEBUG(("Computing HASH value"));
1732 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1733 if (status != SILC_SKE_STATUS_OK)
1735 ske->hash = silc_memdup(hash, hash_len);
1737 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1740 ske->hash_len = hash_len;
1742 if (ske->prop->public_key) {
1743 SILC_LOG_DEBUG(("Public key is authentic"));
1744 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1746 /* Verify signature */
1747 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1748 payload->sign_len, hash, hash_len, NULL)) {
1749 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1750 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1754 SILC_LOG_DEBUG(("Signature is Ok"));
1755 memset(hash, 'F', hash_len);
1758 ske->status = SILC_SKE_STATUS_OK;
1760 /* In case we are doing rekey move to finish it. */
1763 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1764 return SILC_FSM_CONTINUE;
1767 /* Process key material */
1768 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1769 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1770 hash_len = silc_hash_len(ske->prop->hash);
1771 ske->keymat = silc_ske_process_key_material(ske, block_len,
1775 SILC_LOG_ERROR(("Error processing key material"));
1776 status = SILC_SKE_STATUS_ERROR;
1780 if (!ske->no_acks) {
1781 /* Send SUCCESS packet */
1782 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1783 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1784 /** Error sending packet */
1785 SILC_LOG_DEBUG(("Error sending packet"));
1786 ske->status = SILC_SKE_STATUS_ERROR;
1787 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1788 return SILC_FSM_CONTINUE;
1791 /** Waiting completion */
1792 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1793 return SILC_FSM_WAIT;
1795 /** Complete protocol */
1796 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1797 return SILC_FSM_CONTINUE;
1801 memset(hash, 'F', sizeof(hash));
1802 silc_ske_payload_ke_free(payload);
1803 ske->ke2_payload = NULL;
1805 silc_mp_uninit(ske->KEY);
1806 silc_free(ske->KEY);
1810 memset(ske->hash, 'F', hash_len);
1811 silc_free(ske->hash);
1815 if (status == SILC_SKE_STATUS_OK)
1816 status = SILC_SKE_STATUS_ERROR;
1819 ske->status = status;
1820 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1821 return SILC_FSM_CONTINUE;
1824 /* Protocol completed */
1826 SILC_FSM_STATE(silc_ske_st_initiator_end)
1828 SilcSKE ske = fsm_context;
1830 SILC_LOG_DEBUG(("Start"));
1832 if (!ske->no_acks && ske->packet->type != SILC_PACKET_SUCCESS) {
1833 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1834 if (silc_ske_install_retransmission(ske)) {
1835 silc_packet_free(ske->packet);
1837 return SILC_FSM_WAIT;
1839 silc_packet_free(ske->packet);
1841 ske->status = SILC_SKE_STATUS_ERROR;
1842 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1843 return SILC_FSM_CONTINUE;
1847 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1850 silc_packet_free(ske->packet);
1852 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1853 silc_schedule_task_del_by_context(ske->schedule, ske);
1855 /* Call completion */
1856 silc_ske_completion(ske);
1858 return SILC_FSM_FINISH;
1861 /* Aborted by application */
1863 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1865 SilcSKE ske = fsm_context;
1866 unsigned char data[4];
1868 SILC_LOG_DEBUG(("Aborted by caller"));
1870 /* Send FAILURE packet */
1871 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1872 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1874 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1875 silc_schedule_task_del_by_context(ske->schedule, ske);
1877 /* Call completion */
1878 silc_ske_completion(ske);
1880 return SILC_FSM_FINISH;
1883 /* Error occurred. Send error to remote host */
1885 SILC_FSM_STATE(silc_ske_st_initiator_error)
1887 SilcSKE ske = fsm_context;
1889 unsigned char data[4];
1891 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1892 silc_ske_map_status(ske->status), ske->status));
1894 status = ske->status;
1895 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1896 status = SILC_SKE_STATUS_ERROR;
1898 /* Send FAILURE packet */
1899 SILC_PUT32_MSB(status, data);
1900 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1902 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1903 silc_schedule_task_del_by_context(ske->schedule, ske);
1905 /* Call completion */
1906 silc_ske_completion(ske);
1908 return SILC_FSM_FINISH;
1911 /* Failure received from remote */
1913 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1915 SilcSKE ske = fsm_context;
1916 SilcUInt32 error = ske->status;
1918 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1919 SILC_GET32_MSB(error, ske->packet->buffer.data);
1920 silc_packet_free(ske->packet);
1923 if (error == SILC_SKE_STATUS_OK)
1924 error = SILC_SKE_STATUS_ERROR;
1925 ske->status = error;
1927 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1928 silc_ske_map_status(ske->status), ske->status));
1930 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1931 silc_schedule_task_del_by_context(ske->schedule, ske);
1933 /* Call completion */
1934 silc_ske_completion(ske);
1936 return SILC_FSM_FINISH;
1939 /* Starts the protocol as initiator */
1941 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1942 SilcPacketStream stream,
1943 SilcSKEParams params,
1944 SilcSKEStartPayload start_payload)
1946 SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; "
1947 "start_payload=%p", ske, stream, params, start_payload));
1949 if (!ske || !stream || !params || !params->version)
1952 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1955 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1958 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1959 ske->session_port = params->session_port;
1961 /* Generate security properties if not provided */
1962 if (!start_payload && !params->prop) {
1964 silc_ske_assemble_security_properties(ske, params->flags,
1966 params->small_proposal);
1971 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1972 ske->probe_timeout = (params->probe_timeout_secs ?
1973 params->probe_timeout_secs : 30);
1974 ske->start_payload = start_payload;
1975 ske->prop = params->prop;
1976 ske->version = params->version;
1977 ske->no_acks = params->no_acks;
1980 /* Link to packet stream to get key exchange packets */
1981 ske->stream = stream;
1982 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1983 SILC_PACKET_KEY_EXCHANGE,
1984 SILC_PACKET_KEY_EXCHANGE_2,
1985 SILC_PACKET_SUCCESS,
1986 SILC_PACKET_FAILURE, -1);
1988 /* Add key exchange timeout */
1989 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1990 ske, ske->timeout, 0);
1991 if (ske->timeout != ske->probe_timeout)
1992 silc_schedule_task_add_timeout(ske->schedule, silc_ske_probe_timeout,
1993 ske, ske->probe_timeout, 0);
1995 /* Start SKE as initiator */
1997 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1999 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_phase2);
2004 /******************************** Responder *********************************/
2006 /* Start protocol as responder. Wait initiator's start payload */
2008 SILC_FSM_STATE(silc_ske_st_responder_start)
2010 SilcSKE ske = fsm_context;
2012 SILC_LOG_DEBUG(("Start"));
2016 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2017 return SILC_FSM_CONTINUE;
2020 /** Wait for initiator */
2022 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
2024 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2025 return SILC_FSM_WAIT;
2028 /* Decode initiator's start payload. Select the security properties from
2029 the initiator's start payload and send our reply start payload back. */
2031 SILC_FSM_STATE(silc_ske_st_responder_phase1)
2033 SilcSKE ske = fsm_context;
2034 SilcSKEStatus status;
2035 SilcSKEStartPayload remote_payload = NULL;
2036 SilcBuffer packet_buf = &ske->packet->buffer;
2039 SILC_LOG_DEBUG(("Start"));
2041 /* Decode the payload */
2042 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
2043 if (status != SILC_SKE_STATUS_OK) {
2044 /** Error decoding Start Payload */
2045 silc_packet_free(ske->packet);
2047 ske->status = status;
2048 silc_fsm_next(fsm, silc_ske_st_responder_error);
2049 return SILC_FSM_CONTINUE;
2052 /* Get remote ID and set it to stream */
2053 if (ske->packet->src_id_len &&
2054 (ske->packet->src_id_type == SILC_ID_SERVER ||
2055 ske->packet->src_id_type == SILC_ID_CLIENT)) {
2056 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
2057 ske->packet->src_id_type,
2058 (ske->packet->src_id_type == SILC_ID_SERVER ?
2059 (void *)&id.u.server_id : (void *)&id.u.client_id),
2060 (ske->packet->src_id_type == SILC_ID_SERVER ?
2061 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
2062 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
2063 (ske->packet->src_id_type == SILC_ID_SERVER ?
2064 (void *)&id.u.server_id : (void *)&id.u.client_id));
2067 /* Take a copy of the payload buffer for future use. It is used to
2068 compute the HASH value. */
2069 ske->start_payload_copy = silc_buffer_copy(packet_buf);
2070 if (!ske->start_payload_copy) {
2071 silc_packet_free(ske->packet);
2073 ske->status = status;
2074 silc_fsm_next(fsm, silc_ske_st_responder_error);
2075 return SILC_FSM_CONTINUE;
2078 silc_packet_free(ske->packet);
2081 /* Force the mutual authentication flag if we want to do it. */
2082 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2083 SILC_LOG_DEBUG(("Force mutual authentication"));
2084 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
2087 /* Force PFS flag if we require it */
2088 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
2089 SILC_LOG_DEBUG(("Force PFS"));
2090 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
2093 /* Disable IV Included flag if requested */
2094 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
2095 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
2096 SILC_LOG_DEBUG(("We do not support IV Included flag"));
2097 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
2100 /* Check and select security properties */
2101 status = silc_ske_select_security_properties(ske, remote_payload,
2103 if (status != SILC_SKE_STATUS_OK) {
2104 /** Error selecting proposal */
2105 silc_ske_payload_start_free(remote_payload);
2106 ske->status = status;
2107 silc_fsm_next(fsm, silc_ske_st_responder_error);
2108 return SILC_FSM_CONTINUE;
2111 silc_ske_payload_start_free(remote_payload);
2113 /* Encode our reply payload to send the selected security properties */
2114 status = silc_ske_payload_start_encode(ske, ske->start_payload,
2116 if (status != SILC_SKE_STATUS_OK)
2119 /* Send the packet. */
2120 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
2121 silc_buffer_data(packet_buf),
2122 silc_buffer_len(packet_buf)))
2125 silc_buffer_free(packet_buf);
2127 /** Waiting initiator's KE payload */
2128 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2129 return SILC_FSM_WAIT;
2132 if (ske->prop->group)
2133 silc_ske_group_free(ske->prop->group);
2134 if (ske->prop->cipher)
2135 silc_cipher_free(ske->prop->cipher);
2136 if (ske->prop->hash)
2137 silc_hash_free(ske->prop->hash);
2138 if (ske->prop->hmac)
2139 silc_hmac_free(ske->prop->hmac);
2140 silc_free(ske->prop);
2143 if (status == SILC_SKE_STATUS_OK)
2144 status = SILC_SKE_STATUS_ERROR;
2147 ske->status = status;
2148 silc_fsm_next(fsm, silc_ske_st_responder_error);
2149 return SILC_FSM_CONTINUE;
2152 /* Phase-2. Decode initiator's KE payload */
2154 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2156 SilcSKE ske = fsm_context;
2157 SilcSKEStatus status;
2158 SilcSKEKEPayload recv_payload;
2159 SilcBuffer packet_buf = &ske->packet->buffer;
2161 SILC_LOG_DEBUG(("Start"));
2163 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2164 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2165 if (silc_ske_install_retransmission(ske)) {
2166 silc_packet_free(ske->packet);
2168 return SILC_FSM_WAIT;
2170 silc_packet_free(ske->packet);
2172 ske->status = SILC_SKE_STATUS_ERROR;
2173 silc_fsm_next(fsm, silc_ske_st_responder_error);
2174 return SILC_FSM_CONTINUE;
2178 /* Decode Key Exchange Payload */
2179 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2180 if (status != SILC_SKE_STATUS_OK) {
2181 /** Error decoding KE payload */
2182 silc_packet_free(ske->packet);
2184 ske->status = status;
2185 silc_fsm_next(fsm, silc_ske_st_responder_error);
2186 return SILC_FSM_CONTINUE;
2189 ske->ke1_payload = recv_payload;
2191 silc_packet_free(ske->packet);
2194 /* Verify public key, except in rekey, when it is not sent */
2196 if (!recv_payload->pk_data) {
2197 /** Public key not provided */
2198 SILC_LOG_ERROR(("Remote end did not send its public key (or "
2199 "certificate), even though we require it"));
2200 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2201 silc_fsm_next(fsm, silc_ske_st_responder_error);
2202 return SILC_FSM_CONTINUE;
2205 /* Decode the remote's public key */
2206 if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2207 recv_payload->pk_data,
2208 recv_payload->pk_len,
2209 &ske->prop->public_key)) {
2210 /** Error decoding public key */
2211 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2212 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2213 silc_fsm_next(fsm, silc_ske_st_responder_error);
2214 return SILC_FSM_CONTINUE;
2217 SILC_LOG_DEBUG(("Verifying public key"));
2219 /** Waiting public key verification */
2220 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2222 /* If repository is provided, verify the key from there. */
2223 if (ske->repository) {
2226 find = silc_skr_find_alloc();
2228 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2229 silc_fsm_next(fsm, silc_ske_st_responder_error);
2230 return SILC_FSM_CONTINUE;
2232 silc_skr_find_set_pkcs_type(find,
2233 silc_pkcs_get_type(ske->prop->public_key));
2234 silc_skr_find_set_public_key(find, ske->prop->public_key);
2235 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2237 /* Find key from repository */
2238 SILC_FSM_CALL(silc_skr_find(ske->repository,
2239 silc_fsm_get_schedule(fsm), find,
2240 silc_ske_skr_callback, ske));
2242 /* Verify from application */
2243 if (ske->callbacks->verify_key)
2244 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2245 ske->callbacks->context,
2246 silc_ske_pk_verified, NULL));
2250 /** Generate KE2 payload */
2251 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2252 return SILC_FSM_CONTINUE;
2255 /* Phase-4. Generate KE2 payload */
2257 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2259 SilcSKE ske = fsm_context;
2260 SilcSKEStatus status;
2261 SilcSKEKEPayload recv_payload, send_payload = NULL;
2262 SilcMPInt *x = NULL, *KEY;
2266 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2267 return SILC_FSM_CONTINUE;
2270 /* Check result of public key verification */
2271 if (ske->status != SILC_SKE_STATUS_OK) {
2272 /** Public key not verified */
2273 SILC_LOG_DEBUG(("Public key verification failed"));
2277 recv_payload = ske->ke1_payload;
2279 /* The public key verification was performed only if the Mutual
2280 Authentication flag is set. */
2281 if ((ske->start_payload &&
2282 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) ||
2283 ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2284 unsigned char hash[SILC_HASH_MAXLEN];
2285 SilcUInt32 hash_len;
2287 SILC_LOG_DEBUG(("We are doing mutual authentication"));
2289 /* Compute the hash value */
2290 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2291 if (status != SILC_SKE_STATUS_OK) {
2292 /** Error computing hash */
2293 SILC_LOG_DEBUG(("Error computing hash"));
2294 ske->status = status;
2298 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2300 /* Verify signature */
2301 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2302 recv_payload->sign_len, hash, hash_len, NULL)) {
2303 /** Incorrect signature */
2304 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2305 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2309 SILC_LOG_DEBUG(("Signature is Ok"));
2311 memset(hash, 'F', hash_len);
2314 /* Create the random number x, 1 < x < q. */
2315 x = silc_calloc(1, sizeof(*x));
2317 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2322 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2323 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2325 if (status != SILC_SKE_STATUS_OK) {
2326 /** Error generating random number */
2327 ske->status = status;
2331 /* Save the results for later processing */
2332 send_payload = silc_calloc(1, sizeof(*send_payload));
2333 if (!send_payload) {
2334 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2338 ske->ke2_payload = send_payload;
2340 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2342 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2343 silc_mp_init(&send_payload->x);
2344 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2345 &ske->prop->group->group);
2347 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2349 /* Compute the shared secret key */
2350 KEY = silc_calloc(1, sizeof(*KEY));
2352 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2356 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2357 &ske->prop->group->group);
2360 /** Send KE2 payload */
2361 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2362 return SILC_FSM_CONTINUE;
2368 silc_free(send_payload);
2369 ske->ke2_payload = NULL;
2371 silc_fsm_next(fsm, silc_ske_st_responder_error);
2372 return SILC_FSM_CONTINUE;
2375 /* Phase-5. Send KE2 payload */
2377 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2379 SilcSKE ske = fsm_context;
2380 SilcSKEStatus status;
2381 SilcBuffer payload_buf;
2382 unsigned char hash[SILC_HASH_MAXLEN], sign[65536 + 1], *pk;
2383 SilcUInt32 hash_len, sign_len, pk_len;
2385 SILC_LOG_DEBUG(("Start"));
2387 if (ske->public_key && ske->private_key) {
2388 SILC_LOG_DEBUG(("Getting public key"));
2390 /* Get the public key */
2391 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2393 /** Error encoding public key */
2394 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2395 silc_fsm_next(fsm, silc_ske_st_responder_error);
2396 return SILC_FSM_CONTINUE;
2398 ske->ke2_payload->pk_data = pk;
2399 ske->ke2_payload->pk_len = pk_len;
2402 SILC_LOG_DEBUG(("Computing HASH value"));
2404 /* Compute the hash value */
2405 memset(hash, 0, sizeof(hash));
2406 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2407 if (status != SILC_SKE_STATUS_OK) {
2408 /** Error computing hash */
2409 ske->status = status;
2410 silc_fsm_next(fsm, silc_ske_st_responder_error);
2411 return SILC_FSM_CONTINUE;
2413 ske->hash = silc_memdup(hash, hash_len);
2415 /** Error computing hash */
2416 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2417 silc_fsm_next(fsm, silc_ske_st_responder_error);
2418 return SILC_FSM_CONTINUE;
2420 ske->hash_len = hash_len;
2422 if (ske->public_key && ske->private_key) {
2423 SILC_LOG_DEBUG(("Signing HASH value"));
2425 /* Sign the hash value */
2426 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2427 sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2428 /** Error computing signature */
2429 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2430 silc_fsm_next(fsm, silc_ske_st_responder_error);
2431 return SILC_FSM_CONTINUE;
2433 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2434 if (!ske->ke2_payload->sign_data) {
2435 /** Error computing hash */
2436 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2437 silc_fsm_next(fsm, silc_ske_st_responder_error);
2438 return SILC_FSM_CONTINUE;
2440 ske->ke2_payload->sign_len = sign_len;
2441 memset(sign, 0, sizeof(sign));
2443 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2445 /* Encode the Key Exchange Payload */
2446 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2448 if (status != SILC_SKE_STATUS_OK) {
2449 /** Error encoding KE payload */
2450 ske->status = status;
2451 silc_fsm_next(fsm, silc_ske_st_responder_error);
2452 return SILC_FSM_CONTINUE;
2455 /* Send the packet. */
2456 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2457 payload_buf->data, silc_buffer_len(payload_buf))) {
2458 SILC_LOG_DEBUG(("Error sending packet"));
2459 ske->status = SILC_SKE_STATUS_ERROR;
2460 silc_fsm_next(fsm, silc_ske_st_responder_error);
2461 return SILC_FSM_CONTINUE;
2464 silc_buffer_free(payload_buf);
2466 /* In case we are doing rekey move to finish it. */
2469 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2470 return SILC_FSM_CONTINUE;
2473 if (!ske->no_acks) {
2474 /** Waiting completion */
2475 silc_fsm_next(fsm, silc_ske_st_responder_end);
2476 return SILC_FSM_WAIT;
2478 /** Complete protocol */
2479 silc_fsm_next(fsm, silc_ske_st_responder_end);
2480 return SILC_FSM_CONTINUE;
2484 /* Protocol completed */
2486 SILC_FSM_STATE(silc_ske_st_responder_end)
2488 SilcSKE ske = fsm_context;
2489 unsigned char tmp[4];
2490 SilcUInt32 hash_len, key_len, block_len;
2492 if (!ske->no_acks && ske->packet->type != SILC_PACKET_SUCCESS) {
2493 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2494 if (silc_ske_install_retransmission(ske)) {
2495 silc_packet_free(ske->packet);
2497 return SILC_FSM_WAIT;
2499 silc_packet_free(ske->packet);
2501 ske->status = SILC_SKE_STATUS_ERROR;
2502 silc_fsm_next(fsm, silc_ske_st_responder_error);
2503 return SILC_FSM_CONTINUE;
2507 silc_packet_free(ske->packet);
2510 /* Process key material */
2511 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2512 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2513 hash_len = silc_hash_len(ske->prop->hash);
2514 ske->keymat = silc_ske_process_key_material(ske, block_len,
2518 /** Error processing key material */
2519 ske->status = SILC_SKE_STATUS_ERROR;
2520 silc_fsm_next(fsm, silc_ske_st_responder_error);
2521 return SILC_FSM_CONTINUE;
2524 if (!ske->no_acks) {
2525 /* Send SUCCESS packet */
2526 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2527 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2530 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2531 silc_schedule_task_del_by_context(ske->schedule, ske);
2533 /* Call completion */
2534 silc_ske_completion(ske);
2536 return SILC_FSM_FINISH;
2539 /* Aborted by application */
2541 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2543 SilcSKE ske = fsm_context;
2544 unsigned char tmp[4];
2546 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2548 /* Send FAILURE packet */
2549 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2550 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2552 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2553 silc_schedule_task_del_by_context(ske->schedule, ske);
2555 /* Call completion */
2556 silc_ske_completion(ske);
2558 return SILC_FSM_FINISH;
2561 /* Failure received from remote */
2563 SILC_FSM_STATE(silc_ske_st_responder_failure)
2565 SilcSKE ske = fsm_context;
2566 SilcUInt32 error = ske->status;
2568 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2570 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2571 SILC_GET32_MSB(error, ske->packet->buffer.data);
2572 silc_packet_free(ske->packet);
2575 if (error == SILC_SKE_STATUS_OK)
2576 error = SILC_SKE_STATUS_ERROR;
2577 ske->status = error;
2579 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2580 silc_schedule_task_del_by_context(ske->schedule, ske);
2582 /* Call completion */
2583 silc_ske_completion(ske);
2585 return SILC_FSM_FINISH;
2588 /* Error occurred */
2590 SILC_FSM_STATE(silc_ske_st_responder_error)
2592 SilcSKE ske = fsm_context;
2593 unsigned char tmp[4];
2596 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2597 ske->status, silc_ske_map_status(ske->status)));
2599 /* Send FAILURE packet */
2600 status = ske->status;
2601 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
2602 status = SILC_SKE_STATUS_ERROR;
2603 SILC_PUT32_MSB(status, tmp);
2604 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2606 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2607 silc_schedule_task_del_by_context(ske->schedule, ske);
2609 /* Call completion */
2610 silc_ske_completion(ske);
2612 return SILC_FSM_FINISH;
2615 /* Starts the protocol as responder. */
2617 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2618 SilcPacketStream stream,
2619 SilcSKEParams params)
2621 SILC_LOG_DEBUG(("Start SKE as responder"));
2623 if (!ske || !stream || !params || !params->version)
2626 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2629 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2632 ske->responder = TRUE;
2633 ske->flags = params->flags;
2634 ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2635 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2636 ske->session_port = params->session_port;
2637 ske->version = params->version;
2638 ske->no_acks = params->no_acks;
2639 ske->prop = params->prop;
2644 /* Link to packet stream to get key exchange packets */
2645 ske->stream = stream;
2646 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2647 SILC_PACKET_KEY_EXCHANGE,
2648 SILC_PACKET_KEY_EXCHANGE_1,
2649 SILC_PACKET_SUCCESS,
2650 SILC_PACKET_FAILURE, -1);
2652 /* Add key exchange timeout */
2653 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2654 ske, ske->timeout, 0);
2656 /* Start SKE as responder */
2657 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2662 /***************************** Initiator Rekey ******************************/
2666 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2668 SilcSKE ske = fsm_context;
2671 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2675 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2676 return SILC_FSM_CONTINUE;
2679 /* Add rekey exchange timeout */
2680 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2683 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2686 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2687 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2688 return SILC_FSM_CONTINUE;
2691 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2692 /** Cannot allocate hash */
2693 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2694 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2695 return SILC_FSM_CONTINUE;
2698 /* Send REKEY packet to start rekey protocol */
2699 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2700 /** Error sending packet */
2701 SILC_LOG_DEBUG(("Error sending packet"));
2702 ske->status = SILC_SKE_STATUS_ERROR;
2703 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2704 return SILC_FSM_CONTINUE;
2707 /* If doing rekey without PFS, move directly to the end of the protocol. */
2708 if (!ske->rekey->pfs) {
2709 /** Rekey without PFS */
2710 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2711 return SILC_FSM_CONTINUE;
2714 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2716 if (status != SILC_SKE_STATUS_OK) {
2717 /** Unknown group */
2718 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2719 return SILC_FSM_CONTINUE;
2722 /** Rekey with PFS */
2723 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2724 return SILC_FSM_CONTINUE;
2727 /* Sends REKEY_DONE packet to finish the protocol. */
2729 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2731 SilcSKE ske = fsm_context;
2732 SilcCipher send_key;
2735 SilcUInt32 key_len, block_len, hash_len, x_len;
2736 unsigned char *pfsbuf;
2738 SILC_LOG_DEBUG(("Start"));
2740 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2741 key_len = silc_cipher_get_key_len(send_key);
2742 block_len = silc_cipher_get_block_len(send_key);
2743 hash = ske->prop->hash;
2744 hash_len = silc_hash_len(hash);
2746 /* Process key material */
2747 if (ske->rekey->pfs) {
2749 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2751 SILC_LOG_ERROR(("Error processing key material"));
2752 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2753 return SILC_FSM_CONTINUE;
2755 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2758 memset(pfsbuf, 0, x_len);
2763 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2764 ske->rekey->enc_key_len / 8,
2770 SILC_LOG_ERROR(("Error processing key material"));
2771 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2772 return SILC_FSM_CONTINUE;
2775 ske->prop->cipher = send_key;
2776 ske->prop->hmac = hmac_send;
2778 /* Get sending keys */
2779 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2780 &hmac_send, NULL, NULL)) {
2781 /** Cannot get keys */
2782 ske->status = SILC_SKE_STATUS_ERROR;
2783 ske->prop->cipher = NULL;
2784 ske->prop->hmac = NULL;
2785 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2786 return SILC_FSM_CONTINUE;
2789 ske->prop->cipher = NULL;
2790 ske->prop->hmac = NULL;
2792 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2793 packet sent after this call will be protected with the new keys. */
2794 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2796 /** Cannot set keys */
2797 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2798 ske->status = SILC_SKE_STATUS_ERROR;
2799 silc_cipher_free(send_key);
2800 silc_hmac_free(hmac_send);
2801 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2802 return SILC_FSM_CONTINUE;
2805 /** Wait for REKEY_DONE */
2806 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2807 return SILC_FSM_WAIT;
2810 /* Rekey protocol end */
2812 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2814 SilcSKE ske = fsm_context;
2815 SilcCipher receive_key;
2816 SilcHmac hmac_receive;
2817 SilcSKERekeyMaterial rekey;
2819 SILC_LOG_DEBUG(("Start"));
2821 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2822 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2823 silc_packet_free(ske->packet);
2825 return SILC_FSM_WAIT;
2828 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2829 ske->prop->cipher = receive_key;
2830 ske->prop->hmac = hmac_receive;
2832 /* Get receiving keys */
2833 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2834 NULL, &hmac_receive, NULL)) {
2835 /** Cannot get keys */
2836 ske->status = SILC_SKE_STATUS_ERROR;
2837 ske->prop->cipher = NULL;
2838 ske->prop->hmac = NULL;
2839 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2840 return SILC_FSM_CONTINUE;
2843 /* Set new receiving keys into use. All packets received after this will
2844 be decrypted with the new keys. */
2845 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2846 hmac_receive, FALSE)) {
2847 /** Cannot set keys */
2848 SILC_LOG_DEBUG(("Cannot set new keys"));
2849 ske->status = SILC_SKE_STATUS_ERROR;
2850 silc_cipher_free(receive_key);
2851 silc_hmac_free(hmac_receive);
2852 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2853 return SILC_FSM_CONTINUE;
2856 SILC_LOG_DEBUG(("Rekey completed successfully"));
2858 /* Generate new rekey material */
2859 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2862 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2863 ske->prop->cipher = NULL;
2864 ske->prop->hmac = NULL;
2865 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2866 return SILC_FSM_CONTINUE;
2868 rekey->pfs = ske->rekey->pfs;
2871 ske->prop->cipher = NULL;
2872 ske->prop->hmac = NULL;
2873 silc_packet_free(ske->packet);
2875 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2876 silc_schedule_task_del_by_context(ske->schedule, ske);
2878 /* Call completion */
2879 silc_ske_completion(ske);
2881 return SILC_FSM_FINISH;
2884 /* Starts rekey protocol as initiator */
2887 silc_ske_rekey_initiator(SilcSKE ske,
2888 SilcPacketStream stream,
2889 SilcSKERekeyMaterial rekey)
2891 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2893 if (!ske || !stream || !rekey) {
2894 SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2899 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2902 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2906 ske->responder = FALSE;
2907 ske->rekeying = TRUE;
2910 /* Link to packet stream to get key exchange packets */
2911 ske->stream = stream;
2912 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2914 SILC_PACKET_REKEY_DONE,
2915 SILC_PACKET_KEY_EXCHANGE_2,
2916 SILC_PACKET_SUCCESS,
2917 SILC_PACKET_FAILURE, -1);
2919 /* Start SKE rekey as initiator */
2920 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2925 /***************************** Responder Rekey ******************************/
2927 /* Wait for initiator's packet */
2929 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2931 SilcSKE ske = fsm_context;
2933 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2937 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2938 return SILC_FSM_CONTINUE;
2941 /* Add rekey exchange timeout */
2942 silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2945 silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2947 /* If REKEY packet already received process it directly */
2948 if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2949 return SILC_FSM_CONTINUE;
2951 /* Wait for REKEY */
2952 return SILC_FSM_WAIT;
2955 /* Process initiator's REKEY packet */
2957 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2959 SilcSKE ske = fsm_context;
2960 SilcSKEStatus status;
2962 SILC_LOG_DEBUG(("Start"));
2964 if (ske->packet->type != SILC_PACKET_REKEY) {
2965 ske->status = SILC_SKE_STATUS_ERROR;
2966 silc_packet_free(ske->packet);
2968 silc_fsm_next(fsm, silc_ske_st_responder_error);
2969 return SILC_FSM_CONTINUE;
2972 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2975 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2976 silc_fsm_next(fsm, silc_ske_st_responder_error);
2977 return SILC_FSM_CONTINUE;
2980 if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2981 /** Cannot allocate hash */
2982 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2983 silc_fsm_next(fsm, silc_ske_st_responder_error);
2984 return SILC_FSM_CONTINUE;
2987 /* If doing rekey without PFS, move directly to the end of the protocol. */
2988 if (!ske->rekey->pfs) {
2989 /** Rekey without PFS */
2990 silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2991 return SILC_FSM_CONTINUE;
2994 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2996 if (status != SILC_SKE_STATUS_OK) {
2997 /** Unknown group */
2998 silc_fsm_next(fsm, silc_ske_st_responder_error);
2999 return SILC_FSM_CONTINUE;
3002 /** Rekey with PFS */
3003 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
3004 return SILC_FSM_WAIT;
3007 /* Sends REKEY_DONE packet to finish the protocol. */
3009 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
3011 SilcSKE ske = fsm_context;
3012 SilcCipher send_key;
3015 SilcUInt32 key_len, block_len, hash_len, x_len;
3016 unsigned char *pfsbuf;
3018 SILC_LOG_DEBUG(("Start"));
3020 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
3021 key_len = silc_cipher_get_key_len(send_key);
3022 block_len = silc_cipher_get_block_len(send_key);
3023 hash = ske->prop->hash;
3024 hash_len = silc_hash_len(hash);
3026 /* Process key material */
3027 if (ske->rekey->pfs) {
3029 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
3031 SILC_LOG_ERROR(("Error processing key material"));
3032 silc_fsm_next(fsm, silc_ske_st_responder_error);
3033 return SILC_FSM_CONTINUE;
3035 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
3038 memset(pfsbuf, 0, x_len);
3043 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
3044 ske->rekey->enc_key_len / 8,
3050 SILC_LOG_ERROR(("Error processing key material"));
3051 silc_fsm_next(fsm, silc_ske_st_responder_error);
3052 return SILC_FSM_CONTINUE;
3055 ske->prop->cipher = send_key;
3056 ske->prop->hmac = hmac_send;
3058 /* Get sending keys */
3059 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
3060 &hmac_send, NULL, NULL)) {
3061 /** Cannot get keys */
3062 ske->status = SILC_SKE_STATUS_ERROR;
3063 ske->prop->cipher = NULL;
3064 ske->prop->hmac = NULL;
3065 silc_fsm_next(fsm, silc_ske_st_responder_error);
3066 return SILC_FSM_CONTINUE;
3069 ske->prop->cipher = NULL;
3070 ske->prop->hmac = NULL;
3072 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
3073 packet sent after this call will be protected with the new keys. */
3074 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
3076 /** Cannot set keys */
3077 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
3078 ske->status = SILC_SKE_STATUS_ERROR;
3079 silc_cipher_free(send_key);
3080 silc_hmac_free(hmac_send);
3081 silc_fsm_next(fsm, silc_ske_st_responder_error);
3082 return SILC_FSM_CONTINUE;
3085 /** Wait for REKEY_DONE */
3086 silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
3087 return SILC_FSM_WAIT;
3090 /* Rekey protocol end */
3092 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
3094 SilcSKE ske = fsm_context;
3095 SilcCipher receive_key;
3096 SilcHmac hmac_receive;
3097 SilcSKERekeyMaterial rekey;
3099 SILC_LOG_DEBUG(("Start"));
3101 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
3102 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
3103 silc_packet_free(ske->packet);
3105 return SILC_FSM_WAIT;
3108 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
3109 ske->prop->cipher = receive_key;
3110 ske->prop->hmac = hmac_receive;
3112 /* Get receiving keys */
3113 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
3114 NULL, &hmac_receive, NULL)) {
3115 /** Cannot get keys */
3116 ske->status = SILC_SKE_STATUS_ERROR;
3117 ske->prop->cipher = NULL;
3118 ske->prop->hmac = NULL;
3119 silc_fsm_next(fsm, silc_ske_st_responder_error);
3120 return SILC_FSM_CONTINUE;
3123 /* Set new receiving keys into use. All packets received after this will
3124 be decrypted with the new keys. */
3125 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3126 hmac_receive, FALSE)) {
3127 /** Cannot set keys */
3128 SILC_LOG_DEBUG(("Cannot set new keys"));
3129 ske->status = SILC_SKE_STATUS_ERROR;
3130 ske->prop->cipher = NULL;
3131 ske->prop->hmac = NULL;
3132 silc_cipher_free(receive_key);
3133 silc_hmac_free(hmac_receive);
3134 silc_fsm_next(fsm, silc_ske_st_responder_error);
3135 return SILC_FSM_CONTINUE;
3138 SILC_LOG_DEBUG(("Rekey completed successfully"));
3140 /* Generate new rekey material */
3141 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3144 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3145 ske->prop->cipher = NULL;
3146 ske->prop->hmac = NULL;
3147 silc_fsm_next(fsm, silc_ske_st_responder_error);
3148 return SILC_FSM_CONTINUE;
3150 rekey->pfs = ske->rekey->pfs;
3153 ske->prop->cipher = NULL;
3154 ske->prop->hmac = NULL;
3155 silc_packet_free(ske->packet);
3157 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3158 silc_schedule_task_del_by_context(ske->schedule, ske);
3160 /* Call completion */
3161 silc_ske_completion(ske);
3163 return SILC_FSM_FINISH;
3166 /* Starts rekey protocol as responder */
3169 silc_ske_rekey_responder(SilcSKE ske,
3170 SilcPacketStream stream,
3171 SilcSKERekeyMaterial rekey,
3174 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3176 if (!ske || !stream || !rekey)
3179 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3182 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3186 ske->responder = TRUE;
3187 ske->rekeying = TRUE;
3188 ske->packet = packet;
3191 /* Link to packet stream to get key exchange packets */
3192 ske->stream = stream;
3193 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3195 SILC_PACKET_REKEY_DONE,
3196 SILC_PACKET_KEY_EXCHANGE_1,
3197 SILC_PACKET_SUCCESS,
3198 SILC_PACKET_FAILURE, -1);
3200 /* Start SKE rekey as responder */
3201 silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3206 /* Processes the provided key material `data' as the SILC protocol
3207 specification defines. */
3210 silc_ske_process_key_material_data(unsigned char *data,
3211 SilcUInt32 data_len,
3212 SilcUInt32 req_iv_len,
3213 SilcUInt32 req_enc_key_len,
3214 SilcUInt32 req_hmac_key_len,
3218 unsigned char hashd[SILC_HASH_MAXLEN];
3219 SilcUInt32 hash_len = req_hmac_key_len;
3220 SilcUInt32 enc_key_len = req_enc_key_len / 8;
3221 SilcSKEKeyMaterial key;
3223 SILC_LOG_DEBUG(("Start"));
3225 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3228 key = silc_calloc(1, sizeof(*key));
3232 buf = silc_buffer_alloc_size(1 + data_len);
3235 silc_buffer_format(buf,
3236 SILC_STR_UI_CHAR(0),
3237 SILC_STR_DATA(data, data_len),
3241 memset(hashd, 0, sizeof(hashd));
3243 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3244 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3245 if (!key->send_iv) {
3246 silc_buffer_clear(buf);
3247 silc_buffer_free(buf);
3251 memcpy(key->send_iv, hashd, req_iv_len);
3252 memset(hashd, 0, sizeof(hashd));
3254 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3255 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3256 if (!key->receive_iv) {
3257 silc_buffer_clear(buf);
3258 silc_buffer_free(buf);
3262 memcpy(key->receive_iv, hashd, req_iv_len);
3263 key->iv_len = req_iv_len;
3265 /* Take the encryption keys. If requested key size is more than
3266 the size of hash length we will distribute more key material
3267 as protocol defines. */
3269 if (enc_key_len > hash_len) {
3271 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3272 k3[SILC_HASH_MAXLEN];
3273 unsigned char *dtmp;
3276 if (enc_key_len > (3 * hash_len))
3279 /* Take first round */
3280 memset(k1, 0, sizeof(k1));
3281 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3283 /* Take second round */
3284 dist = silc_buffer_alloc_size(data_len + hash_len);
3287 silc_buffer_format(dist,
3288 SILC_STR_DATA(data, data_len),
3289 SILC_STR_DATA(k1, hash_len),
3291 memset(k2, 0, sizeof(k2));
3292 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3294 /* Take third round */
3295 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3296 silc_buffer_pull_tail(dist, hash_len);
3297 silc_buffer_pull(dist, data_len + hash_len);
3298 silc_buffer_format(dist,
3299 SILC_STR_DATA(k2, hash_len),
3301 silc_buffer_push(dist, data_len + hash_len);
3302 memset(k3, 0, sizeof(k3));
3303 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3305 /* Then, save the keys */
3306 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3308 silc_buffer_clear(buf);
3309 silc_buffer_free(buf);
3313 memcpy(dtmp, k1, hash_len);
3314 memcpy(dtmp + hash_len, k2, hash_len);
3315 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3317 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3318 if (!key->send_enc_key) {
3319 silc_buffer_clear(buf);
3320 silc_buffer_free(buf);
3325 memcpy(key->send_enc_key, dtmp, enc_key_len);
3326 key->enc_key_len = req_enc_key_len;
3328 memset(dtmp, 0, (3 * hash_len));
3329 memset(k1, 0, sizeof(k1));
3330 memset(k2, 0, sizeof(k2));
3331 memset(k3, 0, sizeof(k3));
3333 silc_buffer_clear(dist);
3334 silc_buffer_free(dist);
3336 /* Take normal hash as key */
3337 memset(hashd, 0, sizeof(hashd));
3338 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3339 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3340 if (!key->send_enc_key) {
3341 silc_buffer_clear(buf);
3342 silc_buffer_free(buf);
3346 memcpy(key->send_enc_key, hashd, enc_key_len);
3347 key->enc_key_len = req_enc_key_len;
3351 if (enc_key_len > hash_len) {
3353 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3354 k3[SILC_HASH_MAXLEN];
3355 unsigned char *dtmp;
3358 if (enc_key_len > (3 * hash_len))
3361 /* Take first round */
3362 memset(k1, 0, sizeof(k1));
3363 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3365 /* Take second round */
3366 dist = silc_buffer_alloc_size(data_len + hash_len);
3369 silc_buffer_format(dist,
3370 SILC_STR_DATA(data, data_len),
3371 SILC_STR_DATA(k1, hash_len),
3373 memset(k2, 0, sizeof(k2));
3374 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3376 /* Take third round */
3377 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3378 silc_buffer_pull_tail(dist, hash_len);
3379 silc_buffer_pull(dist, data_len + hash_len);
3380 silc_buffer_format(dist,
3381 SILC_STR_DATA(k2, hash_len),
3383 silc_buffer_push(dist, data_len + hash_len);
3384 memset(k3, 0, sizeof(k3));
3385 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3387 /* Then, save the keys */
3388 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3390 silc_buffer_clear(buf);
3391 silc_buffer_free(buf);
3395 memcpy(dtmp, k1, hash_len);
3396 memcpy(dtmp + hash_len, k2, hash_len);
3397 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3399 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3400 if (!key->receive_enc_key) {
3401 silc_buffer_clear(buf);
3402 silc_buffer_free(buf);
3407 memcpy(key->receive_enc_key, dtmp, enc_key_len);
3408 key->enc_key_len = req_enc_key_len;
3410 memset(dtmp, 0, (3 * hash_len));
3411 memset(k1, 0, sizeof(k1));
3412 memset(k2, 0, sizeof(k2));
3413 memset(k3, 0, sizeof(k3));
3415 silc_buffer_clear(dist);
3416 silc_buffer_free(dist);
3418 /* Take normal hash as key */
3419 memset(hashd, 0, sizeof(hashd));
3420 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3421 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3422 if (!key->receive_enc_key) {
3423 silc_buffer_clear(buf);
3424 silc_buffer_free(buf);
3428 memcpy(key->receive_enc_key, hashd, enc_key_len);
3429 key->enc_key_len = req_enc_key_len;
3432 /* Take HMAC keys */
3433 memset(hashd, 0, sizeof(hashd));
3435 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3436 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3437 if (!key->send_hmac_key) {
3438 silc_buffer_clear(buf);
3439 silc_buffer_free(buf);
3443 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3444 memset(hashd, 0, sizeof(hashd));
3446 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3447 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3448 if (!key->receive_hmac_key) {
3449 silc_buffer_clear(buf);
3450 silc_buffer_free(buf);
3454 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3455 key->hmac_key_len = req_hmac_key_len;
3456 memset(hashd, 0, sizeof(hashd));
3458 silc_buffer_clear(buf);
3459 silc_buffer_free(buf);
3461 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3466 /* Processes negotiated key material as protocol specifies. This returns
3467 the actual keys to be used in the SILC. */
3470 silc_ske_process_key_material(SilcSKE ske,
3471 SilcUInt32 req_iv_len,
3472 SilcUInt32 req_enc_key_len,
3473 SilcUInt32 req_hmac_key_len,
3474 SilcSKERekeyMaterial *rekey)
3477 unsigned char *tmpbuf;
3479 SilcSKEKeyMaterial key;
3481 /* Encode KEY to binary data */
3482 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3484 buf = silc_buffer_alloc_size(klen + ske->hash_len);
3487 silc_buffer_format(buf,
3488 SILC_STR_DATA(tmpbuf, klen),
3489 SILC_STR_DATA(ske->hash, ske->hash_len),
3492 /* Process the key material */
3493 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3494 req_iv_len, req_enc_key_len,
3498 memset(tmpbuf, 0, klen);
3500 silc_buffer_clear(buf);
3501 silc_buffer_free(buf);
3504 *rekey = silc_ske_make_rekey_material(ske, key);
3512 /* Free key material structure */
3514 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3520 silc_free(key->send_iv);
3521 if (key->receive_iv)
3522 silc_free(key->receive_iv);
3523 if (key->send_enc_key) {
3524 memset(key->send_enc_key, 0, key->enc_key_len / 8);
3525 silc_free(key->send_enc_key);
3527 if (key->receive_enc_key) {
3528 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3529 silc_free(key->receive_enc_key);
3531 if (key->send_hmac_key) {
3532 memset(key->send_hmac_key, 0, key->hmac_key_len);
3533 silc_free(key->send_hmac_key);
3535 if (key->receive_hmac_key) {
3536 memset(key->receive_hmac_key, 0, key->hmac_key_len);
3537 silc_free(key->receive_hmac_key);
3542 /* Free rekey material */
3544 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3548 if (rekey->send_enc_key) {
3549 memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3550 silc_free(rekey->send_enc_key);
3552 silc_free(rekey->hash);
3556 /* Set keys into use */
3558 SilcBool silc_ske_set_keys(SilcSKE ske,
3559 SilcSKEKeyMaterial keymat,
3560 SilcSKESecurityProperties prop,
3561 SilcCipher *ret_send_key,
3562 SilcCipher *ret_receive_key,
3563 SilcHmac *ret_hmac_send,
3564 SilcHmac *ret_hmac_receive,
3567 unsigned char iv[SILC_HASH_MAXLEN];
3568 SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3570 /* Allocate ciphers to be used in the communication */
3572 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3576 if (ret_receive_key) {
3577 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3582 /* Allocate HMACs */
3583 if (ret_hmac_send) {
3584 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3588 if (ret_hmac_receive) {
3589 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3596 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3600 /* Set key material */
3601 memset(iv, 0, sizeof(iv));
3602 if (ske->responder) {
3604 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3605 keymat->enc_key_len, TRUE);
3607 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3609 if (!ske->rekeying) {
3611 memcpy(iv, ske->hash, 4);
3613 memcpy(iv + 4, keymat->receive_iv, 8);
3615 /* Rekey, recompute the truncated hash value. */
3616 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3618 memcpy(iv + 4, keymat->receive_iv, 8);
3620 memset(iv + 4, 0, 12);
3623 silc_cipher_set_iv(*ret_send_key, iv);
3626 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3629 if (ret_receive_key) {
3630 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3631 keymat->enc_key_len, FALSE);
3633 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3635 if (!ske->rekeying) {
3637 memcpy(iv, ske->hash, 4);
3639 memcpy(iv + 4, keymat->send_iv, 8);
3641 /* Rekey, recompute the truncated hash value. */
3642 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3644 memcpy(iv + 4, keymat->send_iv, 8);
3646 memset(iv + 4, 0, 12);
3649 silc_cipher_set_iv(*ret_receive_key, iv);
3652 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3656 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3657 keymat->hmac_key_len);
3658 if (ret_hmac_receive)
3659 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3660 keymat->hmac_key_len);
3663 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3664 keymat->enc_key_len, TRUE);
3666 if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3668 if (!ske->rekeying) {
3670 memcpy(iv, ske->hash, 4);
3672 memcpy(iv + 4, keymat->send_iv, 8);
3674 /* Rekey, recompute the truncated hash value. */
3675 silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3677 memcpy(iv + 4, keymat->send_iv, 8);
3679 memset(iv + 4, 0, 12);
3682 silc_cipher_set_iv(*ret_send_key, iv);
3685 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3688 if (ret_receive_key) {
3689 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3690 keymat->enc_key_len, FALSE);
3692 if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3694 if (!ske->rekeying) {
3695 /* Set IV. If IV Included flag was negotiated we only set the
3696 truncated hash value. */
3697 memcpy(iv, ske->hash, 4);
3699 memcpy(iv + 4, keymat->receive_iv, 8);
3701 /* Rekey, recompute the truncated hash value. */
3702 silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3704 memcpy(iv + 4, keymat->receive_iv, 8);
3706 memset(iv + 4, 0, 12);
3709 silc_cipher_set_iv(*ret_receive_key, iv);
3712 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3716 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3717 keymat->hmac_key_len);
3718 if (ret_hmac_receive)
3719 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3720 keymat->hmac_key_len);
3726 const char *silc_ske_status_string[] =
3730 "Unexpected error occurred",
3731 "Bad payload in packet",
3732 "Unsupported group",
3733 "Unsupported cipher",
3735 "Unsupported hash function",
3737 "Public key not accepted",
3738 "Incorrect signature",
3739 "Bad or unsupported version",
3743 "Remote did not provide public key",
3744 "Bad reserved field in packet",
3745 "Bad payload length in packet",
3746 "Error computing signature",
3747 "System out of memory",
3748 "Key exchange timeout",
3749 "Key exchange timeout",
3754 /* Maps status to readable string and returns the string. If string is not
3755 found and empty character string ("") is returned. */
3757 const char *silc_ske_map_status(SilcSKEStatus status)
3761 for (i = 0; silc_ske_status_string[i]; i++)
3763 return silc_ske_status_string[i];
3768 /* Parses remote host's version string. */
3770 SilcBool silc_ske_parse_version(SilcSKE ske,
3771 SilcUInt32 *protocol_version,
3772 char **protocol_version_string,
3773 SilcUInt32 *software_version,
3774 char **software_version_string,
3775 char **vendor_version)
3777 return silc_parse_version_string(ske->remote_version,
3779 protocol_version_string,
3781 software_version_string,
3785 /* Get security properties */
3787 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3792 /* Get key material */
3794 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)