5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2006 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);
60 silc_ske_process_key_material(SilcSKE ske,
61 SilcUInt32 req_iv_len,
62 SilcUInt32 req_enc_key_len,
63 SilcUInt32 req_hmac_key_len,
64 SilcSKERekeyMaterial *rekey);
65 static SilcBool silc_ske_packet_send(SilcSKE ske,
67 SilcPacketFlags flags,
68 const unsigned char *data,
73 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
74 SilcPacketStream stream,
76 void *callback_context,
79 SilcSKE ske = callback_context;
81 /* Clear retransmission */
82 ske->retry_timer = SILC_SKE_RETRY_MIN;
84 silc_schedule_task_del_by_context(ske->schedule, ske);
86 /* Signal for new packet */
89 /* Check if we were aborted */
91 silc_packet_free(packet);
95 silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
97 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
99 silc_fsm_continue_sync(&ske->fsm);
103 /* See if received failure from remote */
104 if (packet->type == SILC_PACKET_FAILURE) {
106 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
108 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
111 /* Handle rekey synchronously */
113 silc_fsm_continue_sync(&ske->fsm);
115 silc_fsm_continue(&ske->fsm);
120 /* Packet stream callbacks */
121 static SilcPacketCallbacks silc_ske_stream_cbs =
123 silc_ske_packet_receive, NULL, NULL
126 /* Aborts SKE protocol */
128 static void silc_ske_abort(SilcAsyncOperation op, void *context)
130 SilcSKE ske = context;
134 /* Public key verification completion callback */
136 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
137 void *completion_context)
139 ske->status = status;
140 SILC_FSM_CALL_CONTINUE(&ske->fsm);
143 /* SKR find callback */
145 static void silc_ske_skr_callback(SilcSKR repository,
147 SilcSKRStatus status,
148 SilcDList keys, void *context)
150 SilcSKE ske = context;
152 silc_skr_find_free(find);
154 if (status != SILC_SKR_OK) {
155 if (ske->callbacks->verify_key) {
156 /* Verify from application */
157 ske->callbacks->verify_key(ske, ske->prop->public_key,
158 ske->callbacks->context,
159 silc_ske_pk_verified, NULL);
165 silc_dlist_uninit(keys);
168 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
169 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
170 SILC_FSM_CALL_CONTINUE(&ske->fsm);
173 /* Checks remote and local versions */
175 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
177 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
178 SilcUInt32 r_software_version = 0;
180 if (!ske->remote_version || !ske->version)
181 return SILC_SKE_STATUS_BAD_VERSION;
183 if (!silc_parse_version_string(ske->remote_version, &r_protocol_version,
184 NULL, &r_software_version, NULL, NULL))
185 return SILC_SKE_STATUS_BAD_VERSION;
187 if (!silc_parse_version_string(ske->version, &l_protocol_version,
188 NULL, NULL, NULL, NULL))
189 return SILC_SKE_STATUS_BAD_VERSION;
191 /* If remote is too new, don't connect */
192 if (l_protocol_version < r_protocol_version)
193 return SILC_SKE_STATUS_BAD_VERSION;
195 /* Backwards compatibility checks */
197 /* Old server versions requires "valid" looking Source ID in the SILC
198 packets during initial key exchange. All version before 1.1.0. */
199 if (r_software_version < 110) {
201 memset(&id, 0, sizeof(id));
203 SILC_LOG_DEBUG(("Remote is old version, add dummy Source ID to packets"));
204 silc_packet_set_ids(ske->stream, SILC_ID_CLIENT, &id, 0, NULL);
207 return SILC_SKE_STATUS_OK;
210 /* Selects the supported security properties from the initiator's Key
211 Exchange Start Payload. A responder function. Saves our reply
212 start payload to ske->start_payload. */
215 silc_ske_select_security_properties(SilcSKE ske,
216 SilcSKEStartPayload remote_payload,
217 SilcSKESecurityProperties *prop)
219 SilcSKEStatus status;
220 SilcSKEStartPayload rp, payload;
224 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
228 /* Check for mandatory fields */
229 if (!rp->ke_grp_len) {
230 SILC_LOG_DEBUG(("KE group not defined in payload"));
231 return SILC_SKE_STATUS_BAD_PAYLOAD;
233 if (!rp->pkcs_alg_len) {
234 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
235 return SILC_SKE_STATUS_BAD_PAYLOAD;
237 if (!rp->enc_alg_len) {
238 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
239 return SILC_SKE_STATUS_BAD_PAYLOAD;
241 if (!rp->hash_alg_len) {
242 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
243 return SILC_SKE_STATUS_BAD_PAYLOAD;
245 if (!rp->hmac_alg_len) {
246 SILC_LOG_DEBUG(("HMAC not defined in payload"));
247 return SILC_SKE_STATUS_BAD_PAYLOAD;
250 /* Allocate security properties */
251 *prop = silc_calloc(1, sizeof(**prop));
253 return SILC_SKE_STATUS_OUT_OF_MEMORY;
255 /* Allocate our reply start payload */
256 payload = silc_calloc(1, sizeof(*payload));
259 return SILC_SKE_STATUS_OUT_OF_MEMORY;
262 /* Check version string */
263 ske->remote_version = silc_memdup(rp->version, rp->version_len);
264 status = silc_ske_check_version(ske);
265 if (status != SILC_SKE_STATUS_OK) {
266 ske->status = status;
270 /* Flags are returned unchanged. */
271 (*prop)->flags = payload->flags = rp->flags;
273 /* Take cookie, we must return it to sender unmodified. */
274 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
275 if (!payload->cookie) {
276 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
279 payload->cookie_len = SILC_SKE_COOKIE_LEN;
280 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
282 /* In case IV included flag and session port is set the first 16-bits of
283 cookie will include our session port. */
284 if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
285 /* Take remote port */
286 SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
289 SILC_PUT16_MSB(ske->session_port, payload->cookie);
292 /* Put our version to our reply */
293 payload->version = strdup(ske->version);
294 if (!payload->version) {
295 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
298 payload->version_len = strlen(ske->version);
300 /* Get supported Key Exchange groups */
301 cp = rp->ke_grp_list;
302 if (cp && strchr(cp, ',')) {
306 len = strcspn(cp, ",");
307 item = silc_calloc(len + 1, sizeof(char));
309 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
312 memcpy(item, cp, len);
314 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
316 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
317 SILC_LOG_DEBUG(("Found KE group `%s'", item));
319 payload->ke_grp_len = len;
320 payload->ke_grp_list = item;
334 if (!payload->ke_grp_len && !payload->ke_grp_list) {
335 SILC_LOG_DEBUG(("Could not find supported KE group"));
337 return SILC_SKE_STATUS_UNKNOWN_GROUP;
340 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
341 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
343 payload->ke_grp_len = rp->ke_grp_len;
344 payload->ke_grp_list = strdup(rp->ke_grp_list);
347 /* Save group to security properties */
348 status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
349 if (status != SILC_SKE_STATUS_OK) {
351 return SILC_SKE_STATUS_UNKNOWN_GROUP;
354 /* Get supported PKCS algorithms */
355 cp = rp->pkcs_alg_list;
356 if (cp && strchr(cp, ',')) {
360 len = strcspn(cp, ",");
361 item = silc_calloc(len + 1, sizeof(char));
363 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
366 memcpy(item, cp, len);
368 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
370 if (silc_pkcs_find_algorithm(item, NULL)) {
371 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
373 payload->pkcs_alg_len = len;
374 payload->pkcs_alg_list = item;
388 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
389 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
390 silc_free(payload->ke_grp_list);
392 return SILC_SKE_STATUS_UNKNOWN_PKCS;
395 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
396 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
398 payload->pkcs_alg_len = rp->pkcs_alg_len;
399 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
402 /* Get supported encryption algorithms */
403 cp = rp->enc_alg_list;
404 if (cp && strchr(cp, ',')) {
408 len = strcspn(cp, ",");
409 item = silc_calloc(len + 1, sizeof(char));
411 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
414 memcpy(item, cp, len);
416 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
418 if (silc_cipher_is_supported(item) == TRUE) {
419 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
421 payload->enc_alg_len = len;
422 payload->enc_alg_list = item;
436 if (!payload->enc_alg_len && !payload->enc_alg_list) {
437 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
438 silc_free(payload->ke_grp_list);
439 silc_free(payload->pkcs_alg_list);
441 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
444 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
447 payload->enc_alg_len = rp->enc_alg_len;
448 payload->enc_alg_list = strdup(rp->enc_alg_list);
451 /* Save selected cipher to security properties */
452 if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
453 silc_free(payload->ke_grp_list);
454 silc_free(payload->pkcs_alg_list);
456 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
459 /* Get supported hash algorithms */
460 cp = rp->hash_alg_list;
461 if (cp && strchr(cp, ',')) {
465 len = strcspn(cp, ",");
466 item = silc_calloc(len + 1, sizeof(char));
468 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
471 memcpy(item, cp, len);
473 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
475 if (silc_hash_is_supported(item) == TRUE) {
476 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
478 payload->hash_alg_len = len;
479 payload->hash_alg_list = item;
493 if (!payload->hash_alg_len && !payload->hash_alg_list) {
494 SILC_LOG_DEBUG(("Could not find supported hash alg"));
495 silc_free(payload->ke_grp_list);
496 silc_free(payload->pkcs_alg_list);
497 silc_free(payload->enc_alg_list);
499 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
502 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
505 payload->hash_alg_len = rp->hash_alg_len;
506 payload->hash_alg_list = strdup(rp->hash_alg_list);
509 /* Save selected hash algorithm to security properties */
510 if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
511 silc_free(payload->ke_grp_list);
512 silc_free(payload->pkcs_alg_list);
513 silc_free(payload->enc_alg_list);
515 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
518 /* Get supported HMACs */
519 cp = rp->hmac_alg_list;
520 if (cp && strchr(cp, ',')) {
524 len = strcspn(cp, ",");
525 item = silc_calloc(len + 1, sizeof(char));
527 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
530 memcpy(item, cp, len);
532 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
534 if (silc_hmac_is_supported(item) == TRUE) {
535 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
537 payload->hmac_alg_len = len;
538 payload->hmac_alg_list = item;
552 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
553 SILC_LOG_DEBUG(("Could not find supported HMAC"));
554 silc_free(payload->ke_grp_list);
555 silc_free(payload->pkcs_alg_list);
556 silc_free(payload->enc_alg_list);
557 silc_free(payload->hash_alg_list);
559 return SILC_SKE_STATUS_UNKNOWN_HMAC;
562 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
565 payload->hmac_alg_len = rp->hmac_alg_len;
566 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
569 /* Save selected HMACc to security properties */
570 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
571 silc_free(payload->ke_grp_list);
572 silc_free(payload->pkcs_alg_list);
573 silc_free(payload->enc_alg_list);
574 silc_free(payload->hash_alg_list);
576 return SILC_SKE_STATUS_UNKNOWN_HMAC;
579 /* Get supported compression algorithms */
580 cp = rp->comp_alg_list;
581 if (cp && strchr(cp, ',')) {
585 len = strcspn(cp, ",");
586 item = silc_calloc(len + 1, sizeof(char));
588 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
591 memcpy(item, cp, len);
593 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
596 if (!strcmp(item, "none")) {
597 SILC_LOG_DEBUG(("Found Compression `%s'", item));
598 payload->comp_alg_len = len;
599 payload->comp_alg_list = item;
603 if (silc_hmac_is_supported(item) == TRUE) {
604 SILC_LOG_DEBUG(("Found Compression `%s'", item));
605 payload->comp_alg_len = len;
606 payload->comp_alg_list = item;
622 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
623 2 + payload->version_len +
624 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
625 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
626 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
628 /* Save our reply payload */
629 ske->start_payload = payload;
631 return SILC_SKE_STATUS_OK;
634 /* Creates random number such that 1 < rnd < n and at most length
635 of len bits. The rnd sent as argument must be initialized. */
637 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
641 SilcSKEStatus status = SILC_SKE_STATUS_OK;
642 unsigned char *string;
646 return SILC_SKE_STATUS_ERROR;
648 SILC_LOG_DEBUG(("Creating random number"));
652 /* Get the random number as string */
653 string = silc_rng_get_rn_data(ske->rng, l);
655 return SILC_SKE_STATUS_OUT_OF_MEMORY;
657 /* Decode the string into a MP integer */
658 silc_mp_bin2mp(string, l, rnd);
659 silc_mp_mod_2exp(rnd, rnd, len);
662 if (silc_mp_cmp_ui(rnd, 1) < 0)
663 status = SILC_SKE_STATUS_ERROR;
664 if (silc_mp_cmp(rnd, n) >= 0)
665 status = SILC_SKE_STATUS_ERROR;
667 memset(string, 'F', l);
673 /* Creates a hash value HASH as defined in the SKE protocol. If the
674 `initiator' is TRUE then this function is used to create the HASH_i
675 hash value defined in the protocol. If it is FALSE then this is used
676 to create the HASH value defined by the protocol. */
678 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
679 unsigned char *return_hash,
680 SilcUInt32 *return_hash_len,
683 SilcSKEStatus status = SILC_SKE_STATUS_OK;
685 unsigned char *e, *f, *KEY;
686 SilcUInt32 e_len, f_len, KEY_len;
689 SILC_LOG_DEBUG(("Start"));
691 if (initiator == FALSE) {
692 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
693 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
694 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
696 /* Format the buffer used to compute the hash value */
697 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
698 ske->ke2_payload->pk_len +
699 ske->ke1_payload->pk_len +
700 e_len + f_len + KEY_len);
702 return SILC_SKE_STATUS_OUT_OF_MEMORY;
704 /* Initiator is not required to send its public key */
705 if (!ske->ke1_payload->pk_data) {
707 silc_buffer_format(buf,
708 SILC_STR_UI_XNSTRING(
709 ske->start_payload_copy->data,
710 silc_buffer_len(ske->start_payload_copy)),
711 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
712 ske->ke2_payload->pk_len),
713 SILC_STR_UI_XNSTRING(e, e_len),
714 SILC_STR_UI_XNSTRING(f, f_len),
715 SILC_STR_UI_XNSTRING(KEY, KEY_len),
719 silc_buffer_format(buf,
720 SILC_STR_UI_XNSTRING(
721 ske->start_payload_copy->data,
722 silc_buffer_len(ske->start_payload_copy)),
723 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
724 ske->ke2_payload->pk_len),
725 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
726 ske->ke1_payload->pk_len),
727 SILC_STR_UI_XNSTRING(e, e_len),
728 SILC_STR_UI_XNSTRING(f, f_len),
729 SILC_STR_UI_XNSTRING(KEY, KEY_len),
733 silc_buffer_free(buf);
736 memset(KEY, 0, KEY_len);
740 return SILC_SKE_STATUS_ERROR;
745 memset(KEY, 0, KEY_len);
750 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
752 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
753 ske->ke1_payload->pk_len + e_len);
755 return SILC_SKE_STATUS_OUT_OF_MEMORY;
757 /* Format the buffer used to compute the hash value */
759 silc_buffer_format(buf,
760 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
761 silc_buffer_len(ske->start_payload_copy)),
762 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
763 ske->ke1_payload->pk_len),
764 SILC_STR_UI_XNSTRING(e, e_len),
767 silc_buffer_free(buf);
770 return SILC_SKE_STATUS_ERROR;
773 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
780 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
782 *return_hash_len = silc_hash_len(ske->prop->hash);
784 if (initiator == FALSE) {
785 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
787 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
790 silc_buffer_free(buf);
795 /* Generate rekey material */
797 static SilcSKERekeyMaterial
798 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
800 SilcSKERekeyMaterial rekey;
803 /* Create rekey material */
804 rekey = silc_calloc(1, sizeof(*rekey));
809 rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
810 rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
811 hash = silc_hash_get_name(ske->prop->hash);
812 rekey->hash = silc_memdup(hash, strlen(hash));
817 if (rekey->pfs == FALSE) {
818 rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
819 keymat->enc_key_len);
820 if (!rekey->send_enc_key) {
824 rekey->enc_key_len = keymat->enc_key_len;
830 /* Assembles security properties */
832 static SilcSKEStartPayload
833 silc_ske_assemble_security_properties(SilcSKE ske,
834 SilcSKESecurityPropertyFlag flags,
837 SilcSKEStartPayload rp;
840 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
842 rp = silc_calloc(1, sizeof(*rp));
845 rp->flags = (unsigned char)flags;
847 /* Set random cookie */
848 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
849 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
850 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
851 rp->cookie_len = SILC_SKE_COOKIE_LEN;
853 /* In case IV included flag and session port is set the first 16-bits of
854 cookie will include our session port. */
855 if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
856 SILC_PUT16_MSB(ske->session_port, rp->cookie);
859 rp->version = strdup(version);
860 rp->version_len = strlen(version);
862 /* Get supported Key Exhange groups */
863 rp->ke_grp_list = silc_ske_get_supported_groups();
864 rp->ke_grp_len = strlen(rp->ke_grp_list);
866 /* Get supported PKCS algorithms */
867 rp->pkcs_alg_list = silc_pkcs_get_supported();
868 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
870 /* Get supported encryption algorithms */
871 rp->enc_alg_list = silc_cipher_get_supported();
872 rp->enc_alg_len = strlen(rp->enc_alg_list);
874 /* Get supported hash algorithms */
875 rp->hash_alg_list = silc_hash_get_supported();
876 rp->hash_alg_len = strlen(rp->hash_alg_list);
878 /* Get supported HMACs */
879 rp->hmac_alg_list = silc_hmac_get_supported();
880 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
883 /* Get supported compression algorithms */
884 rp->comp_alg_list = strdup("none");
885 rp->comp_alg_len = strlen("none");
887 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
888 2 + rp->version_len +
889 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
890 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
891 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
896 /* Packet retransmission callback. */
898 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
900 SilcSKE ske = context;
902 if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
904 SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
905 ske->retry_count = 0;
906 ske->retry_timer = SILC_SKE_RETRY_MIN;
907 silc_free(ske->retrans.data);
908 ske->retrans.data = NULL;
909 ske->status = SILC_SKE_STATUS_TIMEOUT;
911 silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
913 silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
914 silc_fsm_continue_sync(&ske->fsm);
918 SILC_LOG_DEBUG(("Retransmitting packet"));
919 silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
920 ske->retrans.data, ske->retrans.data_len);
923 /* Install retransmission timer */
925 static void silc_ske_install_retransmission(SilcSKE ske)
927 if (!silc_packet_stream_is_udp(ske->stream))
930 if (ske->retrans.data) {
931 SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
933 silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
934 ske, ske->retry_timer, 0);
936 ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
937 (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
940 /* Sends SILC packet. Handles retransmissions with UDP streams. */
942 static SilcBool silc_ske_packet_send(SilcSKE ske,
944 SilcPacketFlags flags,
945 const unsigned char *data,
950 /* Send the packet */
951 ret = silc_packet_send(ske->stream, type, flags, data, data_len);
953 if (silc_packet_stream_is_udp(ske->stream) &&
954 type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
955 silc_free(ske->retrans.data);
956 ske->retrans.type = type;
957 ske->retrans.flags = flags;
958 ske->retrans.data = silc_memdup(data, data_len);
959 ske->retrans.data_len = data_len;
960 silc_ske_install_retransmission(ske);
966 /* SKE FSM destructor. We call completion callback here. All SKE
967 machines go here and call the completion. Completion must not be called
968 from any other place. */
970 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
971 void *destructor_context)
973 SilcSKE ske = fsm_context;
975 /* Call the completion callback */
976 if (!ske->freed && !ske->aborted && ske->callbacks->completed) {
977 if (ske->status != SILC_SKE_STATUS_OK)
978 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
979 ske->callbacks->context);
981 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
982 ske->rekey, ske->callbacks->context);
985 ske->running = FALSE;
990 /******************************* Protocol API *******************************/
992 /* Allocates new SKE object. */
994 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
995 SilcSKR repository, SilcPublicKey public_key,
996 SilcPrivateKey private_key, void *context)
1000 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1002 if (!rng || !schedule)
1006 SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1010 ske = silc_calloc(1, sizeof(*ske));
1013 ske->status = SILC_SKE_STATUS_OK;
1015 ske->repository = repository;
1016 ske->user_data = context;
1017 ske->schedule = schedule;
1018 ske->public_key = public_key;
1019 ske->private_key = private_key;
1020 ske->retry_timer = SILC_SKE_RETRY_MIN;
1025 /* Free's SKE object. */
1027 void silc_ske_free(SilcSKE ske)
1029 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1039 /* Free start payload */
1040 if (ske->start_payload)
1041 silc_ske_payload_start_free(ske->start_payload);
1043 /* Free KE payload */
1044 if (ske->ke1_payload)
1045 silc_ske_payload_ke_free(ske->ke1_payload);
1046 if (ske->ke2_payload)
1047 silc_ske_payload_ke_free(ske->ke2_payload);
1048 silc_free(ske->remote_version);
1052 if (ske->prop->group)
1053 silc_ske_group_free(ske->prop->group);
1054 if (ske->prop->cipher)
1055 silc_cipher_free(ske->prop->cipher);
1056 if (ske->prop->hash)
1057 silc_hash_free(ske->prop->hash);
1058 if (ske->prop->hmac)
1059 silc_hmac_free(ske->prop->hmac);
1060 silc_free(ske->prop);
1063 silc_ske_free_key_material(ske->keymat);
1064 if (ske->start_payload_copy)
1065 silc_buffer_free(ske->start_payload_copy);
1067 silc_mp_uninit(ske->x);
1071 silc_mp_uninit(ske->KEY);
1072 silc_free(ske->KEY);
1074 silc_free(ske->retrans.data);
1075 silc_free(ske->hash);
1076 silc_free(ske->callbacks);
1078 memset(ske, 'F', sizeof(*ske));
1082 /* Return user context */
1084 void *silc_ske_get_context(SilcSKE ske)
1086 return ske->user_data;
1089 /* Sets protocol callbacks */
1091 void silc_ske_set_callbacks(SilcSKE ske,
1092 SilcSKEVerifyCb verify_key,
1093 SilcSKECompletionCb completed,
1097 silc_free(ske->callbacks);
1098 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1099 if (!ske->callbacks)
1101 ske->callbacks->verify_key = verify_key;
1102 ske->callbacks->completed = completed;
1103 ske->callbacks->context = context;
1107 /******************************** Initiator *********************************/
1109 /* Start protocol. Send our proposal */
1111 SILC_FSM_STATE(silc_ske_st_initiator_start)
1113 SilcSKE ske = fsm_context;
1114 SilcBuffer payload_buf;
1117 SILC_LOG_DEBUG(("Start"));
1121 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1122 return SILC_FSM_CONTINUE;
1125 /* Encode the payload */
1126 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1128 if (status != SILC_SKE_STATUS_OK) {
1129 /** Error encoding Start Payload */
1130 ske->status = status;
1131 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1132 return SILC_FSM_CONTINUE;
1135 /* Save the the payload buffer for future use. It is later used to
1136 compute the HASH value. */
1137 ske->start_payload_copy = payload_buf;
1139 /* Send the packet. */
1140 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1141 silc_buffer_data(payload_buf),
1142 silc_buffer_len(payload_buf))) {
1143 /** Error sending packet */
1144 SILC_LOG_DEBUG(("Error sending packet"));
1145 ske->status = SILC_SKE_STATUS_ERROR;
1146 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1147 return SILC_FSM_CONTINUE;
1152 /** Wait for responder proposal */
1153 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
1154 silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1155 return SILC_FSM_WAIT;
1158 /* Phase-1. Receives responder's proposal */
1160 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1162 SilcSKE ske = fsm_context;
1163 SilcSKEStatus status;
1164 SilcSKEStartPayload payload;
1165 SilcSKESecurityProperties prop;
1166 SilcSKEDiffieHellmanGroup group = NULL;
1167 SilcBuffer packet_buf = &ske->packet->buffer;
1168 SilcUInt16 remote_port = 0;
1172 SILC_LOG_DEBUG(("Start"));
1174 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1175 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1176 silc_ske_install_retransmission(ske);
1177 silc_packet_free(ske->packet);
1179 return SILC_FSM_WAIT;
1182 /* Decode the payload */
1183 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1184 if (status != SILC_SKE_STATUS_OK) {
1185 /** Error decoding Start Payload */
1186 silc_packet_free(ske->packet);
1188 ske->status = status;
1189 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1190 return SILC_FSM_CONTINUE;
1193 /* Get remote ID and set it to stream */
1194 if (ske->packet->src_id_len) {
1195 silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1196 ske->packet->src_id_type,
1197 (ske->packet->src_id_type == SILC_ID_SERVER ?
1198 (void *)&id.u.server_id : (void *)&id.u.client_id),
1199 (ske->packet->src_id_type == SILC_ID_SERVER ?
1200 sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1201 silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1202 (ske->packet->src_id_type == SILC_ID_SERVER ?
1203 (void *)&id.u.server_id : (void *)&id.u.client_id));
1206 silc_packet_free(ske->packet);
1209 /* Check that the cookie is returned unmodified. In case IV included
1210 flag and session port has been set, the first two bytes of cookie
1211 are the session port and we ignore them in this check. */
1212 if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1213 /* Take remote port */
1214 SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1217 if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1218 SILC_SKE_COOKIE_LEN - coff)) {
1219 /** Invalid cookie */
1220 SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1221 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1222 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1223 return SILC_FSM_CONTINUE;
1226 /* Check version string */
1227 ske->remote_version = silc_memdup(payload->version, payload->version_len);
1228 status = silc_ske_check_version(ske);
1229 if (status != SILC_SKE_STATUS_OK) {
1230 /** Version mismatch */
1231 ske->status = status;
1232 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1233 return SILC_FSM_CONTINUE;
1236 /* Free our KE Start Payload context, we don't need it anymore. */
1237 silc_ske_payload_start_free(ske->start_payload);
1238 ske->start_payload = NULL;
1240 /* Take the selected security properties into use while doing
1241 the key exchange. This is used only while doing the key
1243 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1246 prop->flags = payload->flags;
1247 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1248 if (status != SILC_SKE_STATUS_OK)
1251 prop->group = group;
1252 prop->remote_port = remote_port;
1254 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1255 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1258 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1259 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1262 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1263 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1266 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1267 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1271 /* Save remote's KE Start Payload */
1272 ske->start_payload = payload;
1274 /** Send KE Payload */
1275 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1276 return SILC_FSM_CONTINUE;
1280 silc_ske_payload_start_free(payload);
1282 silc_ske_group_free(group);
1284 silc_cipher_free(prop->cipher);
1286 silc_hash_free(prop->hash);
1288 silc_hmac_free(prop->hmac);
1292 if (status == SILC_SKE_STATUS_OK)
1293 status = SILC_SKE_STATUS_ERROR;
1296 ske->status = status;
1297 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1298 return SILC_FSM_CONTINUE;
1301 /* Phase-2. Send KE payload */
1303 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1305 SilcSKE ske = fsm_context;
1306 SilcSKEStatus status;
1307 SilcBuffer payload_buf;
1309 SilcSKEKEPayload payload;
1312 SILC_LOG_DEBUG(("Start"));
1314 /* Create the random number x, 1 < x < q. */
1315 x = silc_calloc(1, sizeof(*x));
1317 /** Out of memory */
1318 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1319 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1320 return SILC_FSM_CONTINUE;
1324 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1325 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1327 if (status != SILC_SKE_STATUS_OK) {
1328 /** Error generating random number */
1331 ske->status = status;
1332 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1333 return SILC_FSM_CONTINUE;
1336 /* Encode the result to Key Exchange Payload. */
1338 payload = silc_calloc(1, sizeof(*payload));
1340 /** Out of memory */
1343 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1344 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1345 return SILC_FSM_CONTINUE;
1347 ske->ke1_payload = payload;
1349 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1351 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1352 silc_mp_init(&payload->x);
1353 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1354 &ske->prop->group->group);
1356 /* Get public key */
1357 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1358 if (!payload->pk_data) {
1359 /** Error encoding public key */
1362 silc_mp_uninit(&payload->x);
1364 ske->ke1_payload = NULL;
1365 ske->status = SILC_SKE_STATUS_ERROR;
1366 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1367 return SILC_FSM_CONTINUE;
1369 payload->pk_len = pk_len;
1370 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1372 /* Compute signature data if we are doing mutual authentication */
1373 if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1374 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1375 SilcUInt32 hash_len, sign_len;
1377 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1378 SILC_LOG_DEBUG(("Computing HASH_i value"));
1380 /* Compute the hash value */
1381 memset(hash, 0, sizeof(hash));
1382 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1384 SILC_LOG_DEBUG(("Signing HASH_i value"));
1386 /* Sign the hash value */
1387 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1388 sizeof(sign) - 1, &sign_len, NULL)) {
1389 /** Error computing signature */
1392 silc_mp_uninit(&payload->x);
1393 silc_free(payload->pk_data);
1395 ske->ke1_payload = NULL;
1396 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1397 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1398 return SILC_FSM_CONTINUE;
1400 payload->sign_data = silc_memdup(sign, sign_len);
1401 if (payload->sign_data)
1402 payload->sign_len = sign_len;
1403 memset(sign, 0, sizeof(sign));
1406 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1407 if (status != SILC_SKE_STATUS_OK) {
1408 /** Error encoding KE payload */
1411 silc_mp_uninit(&payload->x);
1412 silc_free(payload->pk_data);
1413 silc_free(payload->sign_data);
1415 ske->ke1_payload = NULL;
1416 ske->status = status;
1417 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1418 return SILC_FSM_CONTINUE;
1423 /* Check for backwards compatibility */
1425 /* Send the packet. */
1426 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1427 silc_buffer_data(payload_buf),
1428 silc_buffer_len(payload_buf))) {
1429 /** Error sending packet */
1430 SILC_LOG_DEBUG(("Error sending packet"));
1431 ske->status = SILC_SKE_STATUS_ERROR;
1432 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1433 return SILC_FSM_CONTINUE;
1436 silc_buffer_free(payload_buf);
1438 /** Waiting responder's KE payload */
1439 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1440 return SILC_FSM_WAIT;
1443 /* Phase-3. Process responder's KE payload */
1445 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1447 SilcSKE ske = fsm_context;
1448 SilcSKEStatus status;
1449 SilcSKEKEPayload payload;
1451 SilcBuffer packet_buf = &ske->packet->buffer;
1453 SILC_LOG_DEBUG(("Start"));
1455 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1456 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1457 silc_ske_install_retransmission(ske);
1458 silc_packet_free(ske->packet);
1460 return SILC_FSM_WAIT;
1463 /* Decode the payload */
1464 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1465 if (status != SILC_SKE_STATUS_OK) {
1466 /** Error decoding KE payload */
1467 silc_packet_free(ske->packet);
1469 ske->status = status;
1470 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1471 return SILC_FSM_CONTINUE;
1473 silc_packet_free(ske->packet);
1475 ske->ke2_payload = payload;
1477 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1478 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1479 "even though we require it"));
1480 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1484 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1486 /* Compute the shared secret key */
1487 KEY = silc_calloc(1, sizeof(*KEY));
1489 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1492 /* Decode the remote's public key */
1493 if (payload->pk_data &&
1494 !silc_pkcs_public_key_alloc(payload->pk_type,
1495 payload->pk_data, payload->pk_len,
1496 &ske->prop->public_key)) {
1497 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1498 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1502 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1504 SILC_LOG_DEBUG(("Verifying public key"));
1506 /** Waiting public key verification */
1507 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1509 /* If repository is provided, verify the key from there. */
1510 if (ske->repository) {
1513 find = silc_skr_find_alloc();
1515 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1518 silc_skr_find_set_pkcs_type(find,
1519 silc_pkcs_get_type(ske->prop->public_key));
1520 silc_skr_find_set_public_key(find, ske->prop->public_key);
1521 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1523 /* Find key from repository */
1524 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1525 silc_ske_skr_callback, ske));
1527 /* Verify from application */
1528 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1529 ske->callbacks->context,
1530 silc_ske_pk_verified, NULL));
1535 /** Process key material */
1536 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1537 return SILC_FSM_CONTINUE;
1540 silc_ske_payload_ke_free(payload);
1541 ske->ke2_payload = NULL;
1543 silc_mp_uninit(ske->KEY);
1544 silc_free(ske->KEY);
1547 if (status == SILC_SKE_STATUS_OK)
1548 return SILC_SKE_STATUS_ERROR;
1551 ske->status = status;
1552 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1553 return SILC_FSM_CONTINUE;
1556 /* Process key material */
1558 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1560 SilcSKE ske = fsm_context;
1561 SilcSKEStatus status;
1562 SilcSKEKEPayload payload;
1563 unsigned char hash[SILC_HASH_MAXLEN];
1564 SilcUInt32 hash_len;
1565 int key_len, block_len;
1569 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1570 return SILC_FSM_CONTINUE;
1573 /* Check result of public key verification */
1574 if (ske->status != SILC_SKE_STATUS_OK) {
1575 /** Public key not verified */
1576 SILC_LOG_DEBUG(("Public key verification failed"));
1577 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1578 return SILC_FSM_CONTINUE;
1581 payload = ske->ke2_payload;
1583 if (ske->prop->public_key) {
1584 SILC_LOG_DEBUG(("Public key is authentic"));
1586 /* Compute the hash value */
1587 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1588 if (status != SILC_SKE_STATUS_OK)
1591 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1593 /* Verify signature */
1594 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1595 payload->sign_len, hash, hash_len, NULL)) {
1596 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1597 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1601 SILC_LOG_DEBUG(("Signature is Ok"));
1603 ske->hash = silc_memdup(hash, hash_len);
1604 ske->hash_len = hash_len;
1605 memset(hash, 'F', hash_len);
1608 ske->status = SILC_SKE_STATUS_OK;
1610 /* In case we are doing rekey move to finish it. */
1613 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1614 return SILC_FSM_CONTINUE;
1617 /* Process key material */
1618 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1619 block_len = silc_cipher_get_block_len(ske->prop->cipher);
1620 hash_len = silc_hash_len(ske->prop->hash);
1621 ske->keymat = silc_ske_process_key_material(ske, block_len,
1625 SILC_LOG_ERROR(("Error processing key material"));
1626 status = SILC_SKE_STATUS_ERROR;
1630 /* Send SUCCESS packet */
1631 SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1632 if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1633 /** Error sending packet */
1634 SILC_LOG_DEBUG(("Error sending packet"));
1635 ske->status = SILC_SKE_STATUS_ERROR;
1636 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1637 return SILC_FSM_CONTINUE;
1640 /** Waiting completion */
1641 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1642 return SILC_FSM_WAIT;
1645 memset(hash, 'F', sizeof(hash));
1646 silc_ske_payload_ke_free(payload);
1647 ske->ke2_payload = NULL;
1649 silc_mp_uninit(ske->KEY);
1650 silc_free(ske->KEY);
1654 memset(ske->hash, 'F', hash_len);
1655 silc_free(ske->hash);
1659 if (status == SILC_SKE_STATUS_OK)
1660 status = SILC_SKE_STATUS_ERROR;
1663 ske->status = status;
1664 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1665 return SILC_FSM_CONTINUE;
1668 /* Protocol completed */
1670 SILC_FSM_STATE(silc_ske_st_initiator_end)
1672 SilcSKE ske = fsm_context;
1674 SILC_LOG_DEBUG(("Start"));
1676 if (ske->packet->type != SILC_PACKET_SUCCESS) {
1677 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1678 silc_ske_install_retransmission(ske);
1679 silc_packet_free(ske->packet);
1681 return SILC_FSM_WAIT;
1684 SILC_LOG_DEBUG(("Key exchange completed successfully"));
1686 silc_packet_free(ske->packet);
1688 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1689 silc_schedule_task_del_by_context(ske->schedule, ske);
1691 return SILC_FSM_FINISH;
1694 /* Aborted by application */
1696 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1698 SilcSKE ske = fsm_context;
1699 unsigned char data[4];
1701 SILC_LOG_DEBUG(("Aborted by caller"));
1703 /* Send FAILURE packet */
1704 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1705 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1707 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1708 silc_schedule_task_del_by_context(ske->schedule, ske);
1710 return SILC_FSM_FINISH;
1713 /* Error occurred. Send error to remote host */
1715 SILC_FSM_STATE(silc_ske_st_initiator_error)
1717 SilcSKE ske = fsm_context;
1718 SilcSKEStatus status;
1719 unsigned char data[4];
1721 SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1722 silc_ske_map_status(ske->status), ske->status));
1724 status = ske->status;
1725 if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1726 status = SILC_SKE_STATUS_ERROR;
1728 /* Send FAILURE packet */
1729 SILC_PUT32_MSB((SilcUInt32)status, data);
1730 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1732 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1733 silc_schedule_task_del_by_context(ske->schedule, ske);
1735 return SILC_FSM_FINISH;
1738 /* Failure received from remote */
1740 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1742 SilcSKE ske = fsm_context;
1743 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1745 SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1746 silc_ske_map_status(ske->status), ske->status));
1748 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1749 SILC_GET32_MSB(error, ske->packet->buffer.data);
1750 ske->status = error;
1751 silc_packet_free(ske->packet);
1755 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1756 silc_schedule_task_del_by_context(ske->schedule, ske);
1758 return SILC_FSM_FINISH;
1761 /* Starts the protocol as initiator */
1764 silc_ske_initiator(SilcSKE ske,
1765 SilcPacketStream stream,
1766 SilcSKEParams params,
1767 SilcSKEStartPayload start_payload)
1769 SILC_LOG_DEBUG(("Start SKE as initiator"));
1771 if (!ske || !stream || !params || !params->version)
1774 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1777 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1780 if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1781 ske->session_port = params->session_port;
1783 /* Generate security properties if not provided */
1784 if (!start_payload) {
1785 start_payload = silc_ske_assemble_security_properties(ske,
1792 ske->start_payload = start_payload;
1793 ske->version = params->version;
1794 ske->running = TRUE;
1796 /* Link to packet stream to get key exchange packets */
1797 ske->stream = stream;
1798 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1799 SILC_PACKET_KEY_EXCHANGE,
1800 SILC_PACKET_KEY_EXCHANGE_2,
1801 SILC_PACKET_SUCCESS,
1802 SILC_PACKET_FAILURE, -1);
1804 /* Start SKE as initiator */
1805 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1810 /******************************** Responder *********************************/
1812 /* Start protocol as responder. Wait initiator's start payload */
1814 SILC_FSM_STATE(silc_ske_st_responder_start)
1816 SilcSKE ske = fsm_context;
1818 SILC_LOG_DEBUG(("Start"));
1822 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1823 return SILC_FSM_CONTINUE;
1829 /** Wait for initiator */
1830 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1831 return SILC_FSM_WAIT;
1834 /* Decode initiator's start payload. Select the security properties from
1835 the initiator's start payload and send our reply start payload back. */
1837 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1839 SilcSKE ske = fsm_context;
1840 SilcSKEStatus status;
1841 SilcSKEStartPayload remote_payload = NULL;
1842 SilcBuffer packet_buf = &ske->packet->buffer;
1844 SILC_LOG_DEBUG(("Start"));
1846 /* Decode the payload */
1847 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1848 if (status != SILC_SKE_STATUS_OK) {
1849 /** Error decoding Start Payload */
1850 silc_packet_free(ske->packet);
1852 ske->status = status;
1853 silc_fsm_next(fsm, silc_ske_st_responder_error);
1854 return SILC_FSM_CONTINUE;
1857 /* Take a copy of the payload buffer for future use. It is used to
1858 compute the HASH value. */
1859 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1861 silc_packet_free(ske->packet);
1864 /* Force the mutual authentication flag if we want to do it. */
1865 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1866 SILC_LOG_DEBUG(("Force mutual authentication"));
1867 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1870 /* Force PFS flag if we require it */
1871 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1872 SILC_LOG_DEBUG(("Force PFS"));
1873 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1876 /* Disable IV Included flag if requested */
1877 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1878 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1879 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1880 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1883 /* Check and select security properties */
1884 status = silc_ske_select_security_properties(ske, remote_payload,
1886 if (status != SILC_SKE_STATUS_OK) {
1887 /** Error selecting proposal */
1888 silc_ske_payload_start_free(remote_payload);
1889 ske->status = status;
1890 silc_fsm_next(fsm, silc_ske_st_responder_error);
1891 return SILC_FSM_CONTINUE;
1894 silc_ske_payload_start_free(remote_payload);
1896 /* Encode our reply payload to send the selected security properties */
1897 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1899 if (status != SILC_SKE_STATUS_OK)
1902 /* Send the packet. */
1903 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1904 silc_buffer_data(packet_buf),
1905 silc_buffer_len(packet_buf)))
1908 silc_buffer_free(packet_buf);
1910 /** Waiting initiator's KE payload */
1911 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1912 return SILC_FSM_WAIT;
1915 if (ske->prop->group)
1916 silc_ske_group_free(ske->prop->group);
1917 if (ske->prop->cipher)
1918 silc_cipher_free(ske->prop->cipher);
1919 if (ske->prop->hash)
1920 silc_hash_free(ske->prop->hash);
1921 if (ske->prop->hmac)
1922 silc_hmac_free(ske->prop->hmac);
1923 silc_free(ske->prop);
1926 if (status == SILC_SKE_STATUS_OK)
1927 status = SILC_SKE_STATUS_ERROR;
1930 ske->status = status;
1931 silc_fsm_next(fsm, silc_ske_st_responder_error);
1932 return SILC_FSM_CONTINUE;
1935 /* Phase-2. Decode initiator's KE payload */
1937 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1939 SilcSKE ske = fsm_context;
1940 SilcSKEStatus status;
1941 SilcSKEKEPayload recv_payload;
1942 SilcBuffer packet_buf = &ske->packet->buffer;
1944 SILC_LOG_DEBUG(("Start"));
1946 if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1947 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1948 silc_ske_install_retransmission(ske);
1949 silc_packet_free(ske->packet);
1951 return SILC_FSM_WAIT;
1954 /* Decode Key Exchange Payload */
1955 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1956 if (status != SILC_SKE_STATUS_OK) {
1957 /** Error decoding KE payload */
1958 silc_packet_free(ske->packet);
1960 ske->status = status;
1961 silc_fsm_next(fsm, silc_ske_st_responder_error);
1962 return SILC_FSM_CONTINUE;
1965 ske->ke1_payload = recv_payload;
1967 silc_packet_free(ske->packet);
1970 /* Verify the received public key and verify the signature if we are
1971 doing mutual authentication. */
1972 if (ske->start_payload &&
1973 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1975 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1977 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1979 /** Public key not provided */
1980 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1981 "certificate), even though we require it"));
1982 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1983 silc_fsm_next(fsm, silc_ske_st_responder_error);
1984 return SILC_FSM_CONTINUE;
1987 /* Decode the remote's public key */
1988 if (recv_payload->pk_data &&
1989 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1990 recv_payload->pk_data,
1991 recv_payload->pk_len,
1992 &ske->prop->public_key)) {
1993 /** Error decoding public key */
1994 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1995 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1996 silc_fsm_next(fsm, silc_ske_st_responder_error);
1997 return SILC_FSM_CONTINUE;
2000 if (ske->prop->public_key && (ske->callbacks->verify_key ||
2002 SILC_LOG_DEBUG(("Verifying public key"));
2004 /** Waiting public key verification */
2005 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2007 /* If repository is provided, verify the key from there. */
2008 if (ske->repository) {
2011 find = silc_skr_find_alloc();
2013 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2014 silc_fsm_next(fsm, silc_ske_st_responder_error);
2015 return SILC_FSM_CONTINUE;
2017 silc_skr_find_set_pkcs_type(find,
2018 silc_pkcs_get_type(ske->prop->public_key));
2019 silc_skr_find_set_public_key(find, ske->prop->public_key);
2020 silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2022 /* Find key from repository */
2023 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2024 silc_ske_skr_callback, ske));
2026 /* Verify from application */
2027 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2028 ske->callbacks->context,
2029 silc_ske_pk_verified, NULL));
2035 /** Generate KE2 payload */
2036 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2037 return SILC_FSM_CONTINUE;
2040 /* Phase-4. Generate KE2 payload */
2042 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2044 SilcSKE ske = fsm_context;
2045 SilcSKEStatus status;
2046 SilcSKEKEPayload recv_payload, send_payload;
2051 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2052 return SILC_FSM_CONTINUE;
2055 /* Check result of public key verification */
2056 if (ske->status != SILC_SKE_STATUS_OK) {
2057 /** Public key not verified */
2058 SILC_LOG_DEBUG(("Public key verification failed"));
2059 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2060 return SILC_FSM_CONTINUE;
2063 recv_payload = ske->ke1_payload;
2065 /* The public key verification was performed only if the Mutual
2066 Authentication flag is set. */
2067 if (ske->start_payload &&
2068 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2069 unsigned char hash[SILC_HASH_MAXLEN];
2070 SilcUInt32 hash_len;
2072 SILC_LOG_DEBUG(("Public key is authentic"));
2074 /* Compute the hash value */
2075 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2076 if (status != SILC_SKE_STATUS_OK) {
2077 /** Error computing hash */
2078 ske->status = status;
2079 silc_fsm_next(fsm, silc_ske_st_responder_error);
2080 return SILC_FSM_CONTINUE;
2083 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2085 /* Verify signature */
2086 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2087 recv_payload->sign_len, hash, hash_len, NULL)) {
2088 /** Incorrect signature */
2089 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2090 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2091 silc_fsm_next(fsm, silc_ske_st_responder_error);
2092 return SILC_FSM_CONTINUE;
2095 SILC_LOG_DEBUG(("Signature is Ok"));
2097 memset(hash, 'F', hash_len);
2100 /* Create the random number x, 1 < x < q. */
2101 x = silc_calloc(1, sizeof(*x));
2104 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2105 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2107 if (status != SILC_SKE_STATUS_OK) {
2108 /** Error generating random number */
2111 ske->status = status;
2112 silc_fsm_next(fsm, silc_ske_st_responder_error);
2113 return SILC_FSM_CONTINUE;
2116 /* Save the results for later processing */
2117 send_payload = silc_calloc(1, sizeof(*send_payload));
2119 ske->ke2_payload = send_payload;
2121 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2123 /* Do the Diffie Hellman computation, f = g ^ x mod p */
2124 silc_mp_init(&send_payload->x);
2125 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2126 &ske->prop->group->group);
2128 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2130 /* Compute the shared secret key */
2131 KEY = silc_calloc(1, sizeof(*KEY));
2133 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2134 &ske->prop->group->group);
2137 /** Send KE2 payload */
2138 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2139 return SILC_FSM_CONTINUE;
2142 /* Phase-5. Send KE2 payload */
2144 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2146 SilcSKE ske = fsm_context;
2147 SilcSKEStatus status;
2148 SilcBuffer payload_buf;
2149 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2150 SilcUInt32 hash_len, sign_len, pk_len;
2152 SILC_LOG_DEBUG(("Start"));
2154 if (ske->public_key && ske->private_key) {
2155 SILC_LOG_DEBUG(("Getting public key"));
2157 /* Get the public key */
2158 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2160 /** Error encoding public key */
2161 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2162 silc_fsm_next(fsm, silc_ske_st_responder_error);
2163 return SILC_FSM_CONTINUE;
2165 ske->ke2_payload->pk_data = pk;
2166 ske->ke2_payload->pk_len = pk_len;
2168 SILC_LOG_DEBUG(("Computing HASH value"));
2170 /* Compute the hash value */
2171 memset(hash, 0, sizeof(hash));
2172 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2173 if (status != SILC_SKE_STATUS_OK) {
2174 /** Error computing hash */
2175 ske->status = status;
2176 silc_fsm_next(fsm, silc_ske_st_responder_error);
2177 return SILC_FSM_CONTINUE;
2180 ske->hash = silc_memdup(hash, hash_len);
2181 ske->hash_len = hash_len;
2183 SILC_LOG_DEBUG(("Signing HASH value"));
2185 /* Sign the hash value */
2186 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2187 sizeof(sign) - 1, &sign_len, NULL)) {
2188 /** Error computing signature */
2189 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2190 silc_fsm_next(fsm, silc_ske_st_responder_error);
2191 return SILC_FSM_CONTINUE;
2193 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2194 ske->ke2_payload->sign_len = sign_len;
2195 memset(sign, 0, sizeof(sign));
2197 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2199 /* Encode the Key Exchange Payload */
2200 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2202 if (status != SILC_SKE_STATUS_OK) {
2203 /** Error encoding KE payload */
2204 ske->status = status;
2205 silc_fsm_next(fsm, silc_ske_st_responder_error);
2206 return SILC_FSM_CONTINUE;
2209 /* Send the packet. */
2210 if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2211 payload_buf->data, silc_buffer_len(payload_buf))) {
2212 SILC_LOG_DEBUG(("Error sending packet"));
2213 ske->status = SILC_SKE_STATUS_ERROR;
2214 silc_fsm_next(fsm, silc_ske_st_responder_error);
2215 return SILC_FSM_CONTINUE;
2218 silc_buffer_free(payload_buf);
2220 /** Waiting completion */
2221 silc_fsm_next(fsm, silc_ske_st_responder_end);
2222 return SILC_FSM_WAIT;
2225 /* Protocol completed */
2227 SILC_FSM_STATE(silc_ske_st_responder_end)
2229 SilcSKE ske = fsm_context;
2230 unsigned char tmp[4];
2231 SilcUInt32 hash_len, key_len, block_len;
2233 if (ske->packet->type != SILC_PACKET_SUCCESS) {
2234 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2235 silc_ske_install_retransmission(ske);
2236 silc_packet_free(ske->packet);
2238 return SILC_FSM_WAIT;
2240 silc_packet_free(ske->packet);
2243 /* Process key material */
2244 key_len = silc_cipher_get_key_len(ske->prop->cipher);
2245 block_len = silc_cipher_get_block_len(ske->prop->cipher);
2246 hash_len = silc_hash_len(ske->prop->hash);
2247 ske->keymat = silc_ske_process_key_material(ske, block_len,
2251 /** Error processing key material */
2252 ske->status = SILC_SKE_STATUS_ERROR;
2253 silc_fsm_next(fsm, silc_ske_st_responder_error);
2254 return SILC_FSM_CONTINUE;
2257 /* Send SUCCESS packet */
2258 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2259 silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2261 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2262 silc_schedule_task_del_by_context(ske->schedule, ske);
2264 return SILC_FSM_FINISH;
2267 /* Aborted by application */
2269 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2271 SilcSKE ske = fsm_context;
2272 unsigned char tmp[4];
2274 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2276 /* Send FAILURE packet */
2277 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2278 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2280 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2281 silc_schedule_task_del_by_context(ske->schedule, ske);
2283 return SILC_FSM_FINISH;
2286 /* Failure received from remote */
2288 SILC_FSM_STATE(silc_ske_st_responder_failure)
2290 SilcSKE ske = fsm_context;
2291 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2293 SILC_LOG_DEBUG(("Key exchange protocol failed"));
2295 if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2296 SILC_GET32_MSB(error, ske->packet->buffer.data);
2297 ske->status = error;
2298 silc_packet_free(ske->packet);
2302 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2303 silc_schedule_task_del_by_context(ske->schedule, ske);
2305 return SILC_FSM_FINISH;
2308 /* Error occurred */
2310 SILC_FSM_STATE(silc_ske_st_responder_error)
2312 SilcSKE ske = fsm_context;
2313 unsigned char tmp[4];
2315 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2316 ske->status, silc_ske_map_status(ske->status)));
2318 /* Send FAILURE packet */
2319 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2320 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2321 SILC_PUT32_MSB(ske->status, tmp);
2322 silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2324 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2325 silc_schedule_task_del_by_context(ske->schedule, ske);
2327 return SILC_FSM_FINISH;
2330 /* Starts the protocol as responder. */
2333 silc_ske_responder(SilcSKE ske,
2334 SilcPacketStream stream,
2335 SilcSKEParams params)
2337 SILC_LOG_DEBUG(("Start SKE as responder"));
2339 if (!ske || !stream || !params || !params->version)
2342 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2345 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2348 ske->responder = TRUE;
2349 ske->flags = params->flags;
2350 if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2351 ske->session_port = params->session_port;
2352 ske->version = strdup(params->version);
2355 ske->running = TRUE;
2357 /* Link to packet stream to get key exchange packets */
2358 ske->stream = stream;
2359 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2360 SILC_PACKET_KEY_EXCHANGE,
2361 SILC_PACKET_KEY_EXCHANGE_1,
2362 SILC_PACKET_SUCCESS,
2363 SILC_PACKET_FAILURE, -1);
2365 /* Start SKE as responder */
2366 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2371 /***************************** Initiator Rekey ******************************/
2375 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2377 SilcSKE ske = fsm_context;
2380 SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2384 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2385 return SILC_FSM_CONTINUE;
2390 ske->prop = silc_calloc(1, sizeof(*ske->prop));
2393 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2394 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2395 return SILC_FSM_CONTINUE;
2398 /* Send REKEY packet to start rekey protocol */
2399 if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2400 /** Error sending packet */
2401 SILC_LOG_DEBUG(("Error sending packet"));
2402 ske->status = SILC_SKE_STATUS_ERROR;
2403 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2404 return SILC_FSM_CONTINUE;
2407 /* If doing rekey without PFS, move directly to the end of the protocol. */
2408 if (!ske->rekey->pfs) {
2409 /** Rekey without PFS */
2410 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2411 return SILC_FSM_CONTINUE;
2414 status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2416 if (status != SILC_SKE_STATUS_OK) {
2417 /** Unknown group */
2418 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2419 return SILC_FSM_CONTINUE;
2422 /** Rekey with PFS */
2423 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2424 return SILC_FSM_CONTINUE;
2427 /* Sends REKEY_DONE packet to finish the protocol. */
2429 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2431 SilcSKE ske = fsm_context;
2432 SilcCipher send_key;
2435 SilcUInt32 key_len, block_len, hash_len, x_len;
2436 unsigned char *pfsbuf;
2438 SILC_LOG_DEBUG(("Start"));
2440 silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2441 key_len = silc_cipher_get_key_len(send_key);
2442 block_len = silc_cipher_get_block_len(send_key);
2444 if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2445 /** Cannot allocate hash */
2446 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2447 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2448 return SILC_FSM_CONTINUE;
2450 hash_len = silc_hash_len(hash);
2452 /* Process key material */
2453 if (ske->rekey->pfs) {
2455 pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2457 ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2460 memset(pfsbuf, 0, x_len);
2466 silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2467 ske->rekey->enc_key_len / 8,
2473 SILC_LOG_ERROR(("Error processing key material"));
2474 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2475 return SILC_FSM_CONTINUE;
2478 ske->prop->cipher = send_key;
2479 ske->prop->hmac = hmac_send;
2480 ske->prop->hash = hash;
2482 /* Get sending keys */
2483 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2484 &hmac_send, NULL, NULL)) {
2485 /** Cannot get keys */
2486 ske->status = SILC_SKE_STATUS_ERROR;
2487 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2488 return SILC_FSM_CONTINUE;
2491 /* Set the new keys into use. This will also send REKEY_DONE packet. Any
2492 packet sent after this call will be protected with the new keys. */
2493 if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2495 /** Cannot set keys */
2496 SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2497 ske->status = SILC_SKE_STATUS_ERROR;
2498 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2499 return SILC_FSM_CONTINUE;
2502 /** Wait for REKEY_DONE */
2503 silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2504 return SILC_FSM_WAIT;
2507 /* Rekey protocol end */
2509 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2511 SilcSKE ske = fsm_context;
2512 SilcCipher receive_key;
2513 SilcHmac hmac_receive;
2514 SilcSKERekeyMaterial rekey;
2516 SILC_LOG_DEBUG(("Start"));
2518 if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2519 SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2520 silc_packet_free(ske->packet);
2522 return SILC_FSM_WAIT;
2525 silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2526 ske->prop->cipher = receive_key;
2527 ske->prop->hmac = hmac_receive;
2529 /* Get receiving keys */
2530 if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2531 NULL, &hmac_receive, NULL)) {
2532 /** Cannot get keys */
2533 ske->status = SILC_SKE_STATUS_ERROR;
2534 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2535 return SILC_FSM_CONTINUE;
2538 /* Set new receiving keys into use. All packets received after this will
2539 be decrypted with the new keys. */
2540 if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2541 hmac_receive, FALSE)) {
2542 /** Cannot set keys */
2543 SILC_LOG_DEBUG(("Cannot set new keys"));
2544 ske->status = SILC_SKE_STATUS_ERROR;
2545 silc_fsm_next(fsm, silc_ske_st_initiator_error);
2546 return SILC_FSM_CONTINUE;
2549 SILC_LOG_DEBUG(("Rekey completed successfully"));
2551 /* Generate new rekey material */
2552 rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2553 rekey->pfs = ske->rekey->pfs;
2554 rekey->ske_group = ske->rekey->ske_group;
2557 ske->prop->cipher = NULL;
2558 ske->prop->hmac = NULL;
2559 silc_packet_free(ske->packet);
2561 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2562 silc_schedule_task_del_by_context(ske->schedule, ske);
2564 return SILC_FSM_FINISH;
2567 /* Starts rekey protocol as initiator */
2570 silc_ske_rekey_initiator(SilcSKE ske,
2571 SilcPacketStream stream,
2572 SilcSKERekeyMaterial rekey)
2574 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2576 if (!ske || !stream || !rekey)
2579 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2582 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2586 ske->responder = FALSE;
2587 ske->running = TRUE;
2588 ske->rekeying = TRUE;
2590 /* Link to packet stream to get key exchange packets */
2591 ske->stream = stream;
2592 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2594 SILC_PACKET_REKEY_DONE,
2595 SILC_PACKET_KEY_EXCHANGE_2,
2596 SILC_PACKET_SUCCESS,
2597 SILC_PACKET_FAILURE, -1);
2599 /* Start SKE rekey as initiator */
2600 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2605 /***************************** Responder Rekey ******************************/
2607 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2609 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2611 return SILC_FSM_FINISH;
2614 /* Starts rekey protocol as responder */
2617 silc_ske_rekey_responder(SilcSKE ske,
2618 SilcPacketStream stream,
2619 SilcSKERekeyMaterial rekey)
2621 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2623 if (!ske || !stream || !rekey)
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))
2633 ske->responder = TRUE;
2634 ske->running = TRUE;
2635 ske->rekeying = TRUE;
2637 /* Link to packet stream to get key exchange packets */
2638 ske->stream = stream;
2639 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2641 SILC_PACKET_REKEY_DONE,
2642 SILC_PACKET_KEY_EXCHANGE_1,
2643 SILC_PACKET_SUCCESS,
2644 SILC_PACKET_FAILURE, -1);
2646 /* Start SKE rekey as responder */
2647 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2652 /* Processes the provided key material `data' as the SILC protocol
2653 specification defines. */
2656 silc_ske_process_key_material_data(unsigned char *data,
2657 SilcUInt32 data_len,
2658 SilcUInt32 req_iv_len,
2659 SilcUInt32 req_enc_key_len,
2660 SilcUInt32 req_hmac_key_len,
2664 unsigned char hashd[SILC_HASH_MAXLEN];
2665 SilcUInt32 hash_len = req_hmac_key_len;
2666 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2667 SilcSKEKeyMaterial key;
2669 SILC_LOG_DEBUG(("Start"));
2671 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2674 key = silc_calloc(1, sizeof(*key));
2678 buf = silc_buffer_alloc_size(1 + data_len);
2681 silc_buffer_format(buf,
2682 SILC_STR_UI_CHAR(0),
2683 SILC_STR_UI_XNSTRING(data, data_len),
2687 memset(hashd, 0, sizeof(hashd));
2689 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2690 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2691 memcpy(key->send_iv, hashd, req_iv_len);
2692 memset(hashd, 0, sizeof(hashd));
2694 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2695 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2696 memcpy(key->receive_iv, hashd, req_iv_len);
2697 key->iv_len = req_iv_len;
2699 /* Take the encryption keys. If requested key size is more than
2700 the size of hash length we will distribute more key material
2701 as protocol defines. */
2703 if (enc_key_len > hash_len) {
2705 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2706 k3[SILC_HASH_MAXLEN];
2707 unsigned char *dtmp;
2710 if (enc_key_len > (3 * hash_len))
2713 /* Take first round */
2714 memset(k1, 0, sizeof(k1));
2715 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2717 /* Take second round */
2718 dist = silc_buffer_alloc_size(data_len + hash_len);
2721 silc_buffer_format(dist,
2722 SILC_STR_UI_XNSTRING(data, data_len),
2723 SILC_STR_UI_XNSTRING(k1, hash_len),
2725 memset(k2, 0, sizeof(k2));
2726 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2728 /* Take third round */
2729 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2730 silc_buffer_pull_tail(dist, hash_len);
2731 silc_buffer_pull(dist, data_len + hash_len);
2732 silc_buffer_format(dist,
2733 SILC_STR_UI_XNSTRING(k2, hash_len),
2735 silc_buffer_push(dist, data_len + hash_len);
2736 memset(k3, 0, sizeof(k3));
2737 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2739 /* Then, save the keys */
2740 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2741 memcpy(dtmp, k1, hash_len);
2742 memcpy(dtmp + hash_len, k2, hash_len);
2743 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2745 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2746 memcpy(key->send_enc_key, dtmp, enc_key_len);
2747 key->enc_key_len = req_enc_key_len;
2749 memset(dtmp, 0, (3 * hash_len));
2750 memset(k1, 0, sizeof(k1));
2751 memset(k2, 0, sizeof(k2));
2752 memset(k3, 0, sizeof(k3));
2754 silc_buffer_clear(dist);
2755 silc_buffer_free(dist);
2757 /* Take normal hash as key */
2758 memset(hashd, 0, sizeof(hashd));
2759 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2760 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2761 memcpy(key->send_enc_key, hashd, enc_key_len);
2762 key->enc_key_len = req_enc_key_len;
2766 if (enc_key_len > hash_len) {
2768 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2769 k3[SILC_HASH_MAXLEN];
2770 unsigned char *dtmp;
2773 if (enc_key_len > (3 * hash_len))
2776 /* Take first round */
2777 memset(k1, 0, sizeof(k1));
2778 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2780 /* Take second round */
2781 dist = silc_buffer_alloc_size(data_len + hash_len);
2784 silc_buffer_format(dist,
2785 SILC_STR_UI_XNSTRING(data, data_len),
2786 SILC_STR_UI_XNSTRING(k1, hash_len),
2788 memset(k2, 0, sizeof(k2));
2789 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2791 /* Take third round */
2792 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2793 silc_buffer_pull_tail(dist, hash_len);
2794 silc_buffer_pull(dist, data_len + hash_len);
2795 silc_buffer_format(dist,
2796 SILC_STR_UI_XNSTRING(k2, hash_len),
2798 silc_buffer_push(dist, data_len + hash_len);
2799 memset(k3, 0, sizeof(k3));
2800 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2802 /* Then, save the keys */
2803 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2804 memcpy(dtmp, k1, hash_len);
2805 memcpy(dtmp + hash_len, k2, hash_len);
2806 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2808 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2809 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2810 key->enc_key_len = req_enc_key_len;
2812 memset(dtmp, 0, (3 * hash_len));
2813 memset(k1, 0, sizeof(k1));
2814 memset(k2, 0, sizeof(k2));
2815 memset(k3, 0, sizeof(k3));
2817 silc_buffer_clear(dist);
2818 silc_buffer_free(dist);
2820 /* Take normal hash as key */
2821 memset(hashd, 0, sizeof(hashd));
2822 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2823 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2824 memcpy(key->receive_enc_key, hashd, enc_key_len);
2825 key->enc_key_len = req_enc_key_len;
2828 /* Take HMAC keys */
2829 memset(hashd, 0, sizeof(hashd));
2831 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2832 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2833 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2834 memset(hashd, 0, sizeof(hashd));
2836 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2837 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2838 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2839 key->hmac_key_len = req_hmac_key_len;
2840 memset(hashd, 0, sizeof(hashd));
2842 silc_buffer_clear(buf);
2843 silc_buffer_free(buf);
2845 SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
2850 /* Processes negotiated key material as protocol specifies. This returns
2851 the actual keys to be used in the SILC. */
2854 silc_ske_process_key_material(SilcSKE ske,
2855 SilcUInt32 req_iv_len,
2856 SilcUInt32 req_enc_key_len,
2857 SilcUInt32 req_hmac_key_len,
2858 SilcSKERekeyMaterial *rekey)
2861 unsigned char *tmpbuf;
2863 SilcSKEKeyMaterial key;
2865 /* Encode KEY to binary data */
2866 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2868 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2871 silc_buffer_format(buf,
2872 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2873 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2876 /* Process the key material */
2877 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2878 req_iv_len, req_enc_key_len,
2882 memset(tmpbuf, 0, klen);
2884 silc_buffer_clear(buf);
2885 silc_buffer_free(buf);
2888 *rekey = silc_ske_make_rekey_material(ske, key);
2896 /* Free key material structure */
2898 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2904 silc_free(key->send_iv);
2905 if (key->receive_iv)
2906 silc_free(key->receive_iv);
2907 if (key->send_enc_key) {
2908 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2909 silc_free(key->send_enc_key);
2911 if (key->receive_enc_key) {
2912 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2913 silc_free(key->receive_enc_key);
2915 if (key->send_hmac_key) {
2916 memset(key->send_hmac_key, 0, key->hmac_key_len);
2917 silc_free(key->send_hmac_key);
2919 if (key->receive_hmac_key) {
2920 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2921 silc_free(key->receive_hmac_key);
2926 /* Free rekey material */
2928 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
2932 if (rekey->send_enc_key) {
2933 memset(rekey->send_enc_key, 0, rekey->enc_key_len);
2934 silc_free(rekey->send_enc_key);
2936 silc_free(rekey->hash);
2940 /* Set keys into use */
2942 SilcBool silc_ske_set_keys(SilcSKE ske,
2943 SilcSKEKeyMaterial keymat,
2944 SilcSKESecurityProperties prop,
2945 SilcCipher *ret_send_key,
2946 SilcCipher *ret_receive_key,
2947 SilcHmac *ret_hmac_send,
2948 SilcHmac *ret_hmac_receive,
2951 /* Allocate ciphers to be used in the communication */
2953 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2957 if (ret_receive_key) {
2958 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2963 /* Allocate HMACs */
2964 if (ret_hmac_send) {
2965 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2969 if (ret_hmac_receive) {
2970 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2975 /* Set key material */
2976 if (ske->responder) {
2978 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2979 keymat->enc_key_len);
2980 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2982 if (ret_receive_key) {
2983 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2984 keymat->enc_key_len);
2985 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2988 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2989 keymat->hmac_key_len);
2990 if (ret_hmac_receive)
2991 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2992 keymat->hmac_key_len);
2995 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2996 keymat->enc_key_len);
2997 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2999 if (ret_receive_key) {
3000 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3001 keymat->enc_key_len);
3002 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3005 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3006 keymat->hmac_key_len);
3007 if (ret_hmac_receive)
3008 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3009 keymat->hmac_key_len);
3014 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3021 const char *silc_ske_status_string[] =
3025 "Unkown error occurred",
3026 "Bad payload in packet",
3027 "Unsupported group",
3028 "Unsupported cipher",
3030 "Unsupported hash function",
3032 "Unsupported public key (or certificate)",
3033 "Incorrect signature",
3034 "Bad or unsupported version",
3038 "Remote did not provide public key",
3039 "Bad reserved field in packet",
3040 "Bad payload length in packet",
3041 "Error computing signature",
3042 "System out of memory",
3047 /* Maps status to readable string and returns the string. If string is not
3048 found and empty character string ("") is returned. */
3050 const char *silc_ske_map_status(SilcSKEStatus status)
3054 for (i = 0; silc_ske_status_string[i]; i++)
3056 return silc_ske_status_string[i];
3061 /* Parses remote host's version string. */
3063 SilcBool silc_ske_parse_version(SilcSKE ske,
3064 SilcUInt32 *protocol_version,
3065 char **protocol_version_string,
3066 SilcUInt32 *software_version,
3067 char **software_version_string,
3068 char **vendor_version)
3070 return silc_parse_version_string(ske->remote_version,
3072 protocol_version_string,
3074 software_version_string,
3078 /* Get security properties */
3080 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3085 /* Get key material */
3087 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)