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;
35 /************************ Static utility functions **************************/
38 silc_ske_process_key_material_data(unsigned char *data,
40 SilcUInt32 req_iv_len,
41 SilcUInt32 req_enc_key_len,
42 SilcUInt32 req_hmac_key_len,
45 silc_ske_process_key_material(SilcSKE ske,
46 SilcUInt32 req_iv_len,
47 SilcUInt32 req_enc_key_len,
48 SilcUInt32 req_hmac_key_len);
53 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
54 SilcPacketStream stream,
56 void *callback_context,
59 SilcSKE ske = callback_context;
61 silc_fsm_continue(&ske->fsm);
65 /* Packet stream callbacks */
66 static SilcPacketCallbacks silc_ske_stream_cbs =
68 silc_ske_packet_receive, NULL, NULL
71 /* Aborts SKE protocol */
73 static void silc_ske_abort(SilcAsyncOperation op, void *context)
75 SilcSKE ske = context;
79 /* Public key verification completion callback */
81 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
82 void *completion_context)
85 SILC_FSM_CALL_CONTINUE(&ske->fsm);
88 /* SKR find callback */
90 static void silc_ske_skr_callback(SilcSKR repository,
93 SilcDList keys, void *context)
95 SilcSKE ske = context;
97 silc_skr_find_free(find);
99 if (status != SILC_SKR_OK) {
100 if (ske->callbacks->verify_key) {
101 /* Verify from application */
102 ske->callbacks->verify_key(ske, ske->prop->public_key,
103 ske->callbacks->context,
104 silc_ske_pk_verified, NULL);
110 silc_dlist_uninit(keys);
113 ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
114 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
115 SILC_FSM_CALL_CONTINUE(&ske->fsm);
118 /* Checks remote and local versions */
120 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
122 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
124 if (!ske->remote_version || !ske->version)
125 return SILC_SKE_STATUS_BAD_VERSION;
127 if (!silc_parse_version_string(ske->remote_version, &r_protocol_version,
128 NULL, NULL, NULL, NULL))
129 return SILC_SKE_STATUS_BAD_VERSION;
131 if (!silc_parse_version_string(ske->version, &l_protocol_version,
132 NULL, NULL, NULL, NULL))
133 return SILC_SKE_STATUS_BAD_VERSION;
135 /* If remote is too new, don't connect */
136 if (l_protocol_version < r_protocol_version)
137 return SILC_SKE_STATUS_BAD_VERSION;
139 return SILC_SKE_STATUS_OK;
142 /* Selects the supported security properties from the initiator's Key
143 Exchange Start Payload. */
146 silc_ske_select_security_properties(SilcSKE ske,
147 SilcSKEStartPayload payload,
148 SilcSKEStartPayload remote_payload)
150 SilcSKEStatus status;
151 SilcSKEStartPayload rp;
155 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
159 /* Check version string */
160 ske->remote_version = silc_memdup(rp->version, rp->version_len);
161 status = silc_ske_check_version(ske);
162 if (status != SILC_SKE_STATUS_OK) {
163 ske->status = status;
167 /* Flags are returned unchanged. */
168 payload->flags = rp->flags;
170 /* Take cookie, we must return it to sender unmodified. */
171 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
172 if (!payload->cookie) {
173 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
176 payload->cookie_len = SILC_SKE_COOKIE_LEN;
177 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
179 /* Put our version to our reply */
180 payload->version = strdup(ske->version);
181 if (!payload->version) {
182 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
185 payload->version_len = strlen(ske->version);
187 /* Get supported Key Exchange groups */
188 cp = rp->ke_grp_list;
189 if (cp && strchr(cp, ',')) {
193 len = strcspn(cp, ",");
194 item = silc_calloc(len + 1, sizeof(char));
196 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
199 memcpy(item, cp, len);
201 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
203 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
204 SILC_LOG_DEBUG(("Found KE group `%s'", item));
206 payload->ke_grp_len = len;
207 payload->ke_grp_list = item;
221 if (!payload->ke_grp_len && !payload->ke_grp_list) {
222 SILC_LOG_DEBUG(("Could not find supported KE group"));
224 return SILC_SKE_STATUS_UNKNOWN_GROUP;
228 if (!rp->ke_grp_len) {
229 SILC_LOG_DEBUG(("KE group not defined in payload"));
231 return SILC_SKE_STATUS_BAD_PAYLOAD;
234 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
235 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
237 payload->ke_grp_len = rp->ke_grp_len;
238 payload->ke_grp_list = strdup(rp->ke_grp_list);
241 /* Get supported PKCS algorithms */
242 cp = rp->pkcs_alg_list;
243 if (cp && strchr(cp, ',')) {
247 len = strcspn(cp, ",");
248 item = silc_calloc(len + 1, sizeof(char));
250 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
253 memcpy(item, cp, len);
255 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
257 if (silc_pkcs_find_algorithm(item, NULL)) {
258 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
260 payload->pkcs_alg_len = len;
261 payload->pkcs_alg_list = item;
275 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
276 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
277 silc_free(payload->ke_grp_list);
279 return SILC_SKE_STATUS_UNKNOWN_PKCS;
283 if (!rp->pkcs_alg_len) {
284 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
285 silc_free(payload->ke_grp_list);
287 return SILC_SKE_STATUS_BAD_PAYLOAD;
290 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
291 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
293 payload->pkcs_alg_len = rp->pkcs_alg_len;
294 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
297 /* Get supported encryption algorithms */
298 cp = rp->enc_alg_list;
299 if (cp && strchr(cp, ',')) {
303 len = strcspn(cp, ",");
304 item = silc_calloc(len + 1, sizeof(char));
306 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
309 memcpy(item, cp, len);
311 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
313 if (silc_cipher_is_supported(item) == TRUE) {
314 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
316 payload->enc_alg_len = len;
317 payload->enc_alg_list = item;
331 if (!payload->enc_alg_len && !payload->enc_alg_list) {
332 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
333 silc_free(payload->ke_grp_list);
334 silc_free(payload->pkcs_alg_list);
336 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
340 if (!rp->enc_alg_len) {
341 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
342 silc_free(payload->ke_grp_list);
343 silc_free(payload->pkcs_alg_list);
345 return SILC_SKE_STATUS_BAD_PAYLOAD;
348 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
351 payload->enc_alg_len = rp->enc_alg_len;
352 payload->enc_alg_list = strdup(rp->enc_alg_list);
355 /* Get supported hash algorithms */
356 cp = rp->hash_alg_list;
357 if (cp && strchr(cp, ',')) {
361 len = strcspn(cp, ",");
362 item = silc_calloc(len + 1, sizeof(char));
364 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
367 memcpy(item, cp, len);
369 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
371 if (silc_hash_is_supported(item) == TRUE) {
372 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
374 payload->hash_alg_len = len;
375 payload->hash_alg_list = item;
389 if (!payload->hash_alg_len && !payload->hash_alg_list) {
390 SILC_LOG_DEBUG(("Could not find supported hash alg"));
391 silc_free(payload->ke_grp_list);
392 silc_free(payload->pkcs_alg_list);
393 silc_free(payload->enc_alg_list);
395 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
399 if (!rp->hash_alg_len) {
400 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
401 silc_free(payload->ke_grp_list);
402 silc_free(payload->pkcs_alg_list);
403 silc_free(payload->enc_alg_list);
405 return SILC_SKE_STATUS_BAD_PAYLOAD;
408 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
411 payload->hash_alg_len = rp->hash_alg_len;
412 payload->hash_alg_list = strdup(rp->hash_alg_list);
415 /* Get supported HMACs */
416 cp = rp->hmac_alg_list;
417 if (cp && strchr(cp, ',')) {
421 len = strcspn(cp, ",");
422 item = silc_calloc(len + 1, sizeof(char));
424 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
427 memcpy(item, cp, len);
429 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
431 if (silc_hmac_is_supported(item) == TRUE) {
432 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
434 payload->hmac_alg_len = len;
435 payload->hmac_alg_list = item;
449 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
450 SILC_LOG_DEBUG(("Could not find supported HMAC"));
451 silc_free(payload->ke_grp_list);
452 silc_free(payload->pkcs_alg_list);
453 silc_free(payload->enc_alg_list);
454 silc_free(payload->hash_alg_list);
456 return SILC_SKE_STATUS_UNKNOWN_HMAC;
460 if (!rp->hmac_alg_len) {
461 SILC_LOG_DEBUG(("HMAC not defined in payload"));
462 silc_free(payload->ke_grp_list);
463 silc_free(payload->pkcs_alg_list);
464 silc_free(payload->enc_alg_list);
465 silc_free(payload->hash_alg_list);
467 return SILC_SKE_STATUS_BAD_PAYLOAD;
470 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
473 payload->hmac_alg_len = rp->hmac_alg_len;
474 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
477 /* Get supported compression algorithms */
478 cp = rp->comp_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 Compression `%s'", item));
494 if (!strcmp(item, "none")) {
495 SILC_LOG_DEBUG(("Found Compression `%s'", item));
496 payload->comp_alg_len = len;
497 payload->comp_alg_list = item;
501 if (silc_hmac_is_supported(item) == TRUE) {
502 SILC_LOG_DEBUG(("Found Compression `%s'", item));
503 payload->comp_alg_len = len;
504 payload->comp_alg_list = item;
520 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
521 2 + payload->version_len +
522 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
523 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
524 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
526 return SILC_SKE_STATUS_OK;
529 /* Creates random number such that 1 < rnd < n and at most length
530 of len bits. The rnd sent as argument must be initialized. */
532 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
536 SilcSKEStatus status = SILC_SKE_STATUS_OK;
537 unsigned char *string;
541 return SILC_SKE_STATUS_ERROR;
543 SILC_LOG_DEBUG(("Creating random number"));
547 /* Get the random number as string */
548 string = silc_rng_get_rn_data(ske->rng, l);
550 return SILC_SKE_STATUS_OUT_OF_MEMORY;
552 /* Decode the string into a MP integer */
553 silc_mp_bin2mp(string, l, rnd);
554 silc_mp_mod_2exp(rnd, rnd, len);
557 if (silc_mp_cmp_ui(rnd, 1) < 0)
558 status = SILC_SKE_STATUS_ERROR;
559 if (silc_mp_cmp(rnd, n) >= 0)
560 status = SILC_SKE_STATUS_ERROR;
562 memset(string, 'F', l);
568 /* Creates a hash value HASH as defined in the SKE protocol. If the
569 `initiator' is TRUE then this function is used to create the HASH_i
570 hash value defined in the protocol. If it is FALSE then this is used
571 to create the HASH value defined by the protocol. */
573 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
574 unsigned char *return_hash,
575 SilcUInt32 *return_hash_len,
578 SilcSKEStatus status = SILC_SKE_STATUS_OK;
580 unsigned char *e, *f, *KEY;
581 SilcUInt32 e_len, f_len, KEY_len;
584 SILC_LOG_DEBUG(("Start"));
586 if (initiator == FALSE) {
587 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
588 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
589 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
591 /* Format the buffer used to compute the hash value */
592 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
593 ske->ke2_payload->pk_len +
594 ske->ke1_payload->pk_len +
595 e_len + f_len + KEY_len);
597 return SILC_SKE_STATUS_OUT_OF_MEMORY;
599 /* Initiator is not required to send its public key */
600 if (!ske->ke1_payload->pk_data) {
602 silc_buffer_format(buf,
603 SILC_STR_UI_XNSTRING(
604 ske->start_payload_copy->data,
605 silc_buffer_len(ske->start_payload_copy)),
606 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
607 ske->ke2_payload->pk_len),
608 SILC_STR_UI_XNSTRING(e, e_len),
609 SILC_STR_UI_XNSTRING(f, f_len),
610 SILC_STR_UI_XNSTRING(KEY, KEY_len),
614 silc_buffer_format(buf,
615 SILC_STR_UI_XNSTRING(
616 ske->start_payload_copy->data,
617 silc_buffer_len(ske->start_payload_copy)),
618 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
619 ske->ke2_payload->pk_len),
620 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
621 ske->ke1_payload->pk_len),
622 SILC_STR_UI_XNSTRING(e, e_len),
623 SILC_STR_UI_XNSTRING(f, f_len),
624 SILC_STR_UI_XNSTRING(KEY, KEY_len),
628 silc_buffer_free(buf);
631 memset(KEY, 0, KEY_len);
635 return SILC_SKE_STATUS_ERROR;
640 memset(KEY, 0, KEY_len);
645 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
647 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
648 ske->ke1_payload->pk_len + e_len);
650 return SILC_SKE_STATUS_OUT_OF_MEMORY;
652 /* Format the buffer used to compute the hash value */
654 silc_buffer_format(buf,
655 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
656 silc_buffer_len(ske->start_payload_copy)),
657 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
658 ske->ke1_payload->pk_len),
659 SILC_STR_UI_XNSTRING(e, e_len),
662 silc_buffer_free(buf);
665 return SILC_SKE_STATUS_ERROR;
668 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
675 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
677 *return_hash_len = silc_hash_len(ske->prop->hash);
679 if (initiator == FALSE) {
680 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
682 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
685 silc_buffer_free(buf);
691 /******************************* Protocol API *******************************/
693 /* Allocates new SKE object. */
695 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
696 SilcSKR repository, SilcPublicKey public_key,
697 SilcPrivateKey private_key, void *context)
701 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
703 if (!rng || !schedule)
706 ske = silc_calloc(1, sizeof(*ske));
709 ske->status = SILC_SKE_STATUS_OK;
711 ske->repository = repository;
712 ske->user_data = context;
713 ske->schedule = schedule;
714 ske->public_key = public_key;
715 ske->private_key = private_key;
720 /* Free's SKE object. */
722 void silc_ske_free(SilcSKE ske)
724 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
727 /* Free start payload */
728 if (ske->start_payload)
729 silc_ske_payload_start_free(ske->start_payload);
731 /* Free KE payload */
732 if (ske->ke1_payload)
733 silc_ske_payload_ke_free(ske->ke1_payload);
734 if (ske->ke2_payload)
735 silc_ske_payload_ke_free(ske->ke2_payload);
736 silc_free(ske->remote_version);
740 if (ske->prop->group)
741 silc_ske_group_free(ske->prop->group);
742 if (ske->prop->cipher)
743 silc_cipher_free(ske->prop->cipher);
745 silc_hash_free(ske->prop->hash);
747 silc_hmac_free(ske->prop->hmac);
748 silc_free(ske->prop);
750 if (ske->start_payload_copy)
751 silc_buffer_free(ske->start_payload_copy);
753 silc_mp_uninit(ske->x);
757 silc_mp_uninit(ske->KEY);
760 silc_free(ske->hash);
761 silc_free(ske->callbacks);
763 memset(ske, 'F', sizeof(*ske));
768 /* Return user context */
770 void *silc_ske_get_context(SilcSKE ske)
772 return ske->user_data;
775 /* Sets protocol callbacks */
777 void silc_ske_set_callbacks(SilcSKE ske,
778 SilcSKEVerifyCb verify_key,
779 SilcSKECompletionCb completed,
783 silc_free(ske->callbacks);
784 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
787 ske->callbacks->verify_key = verify_key;
788 ske->callbacks->completed = completed;
789 ske->callbacks->context = context;
793 /******************************** Initiator *********************************/
795 /* Initiator state machine */
796 SILC_FSM_STATE(silc_ske_st_initiator_start);
797 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
798 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
799 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
800 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
801 SILC_FSM_STATE(silc_ske_st_initiator_end);
802 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
803 SILC_FSM_STATE(silc_ske_st_initiator_error);
805 /* Start protocol. Send our proposal */
807 SILC_FSM_STATE(silc_ske_st_initiator_start)
809 SilcSKE ske = fsm_context;
810 SilcBuffer payload_buf;
813 SILC_LOG_DEBUG(("Start"));
817 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
818 return SILC_FSM_CONTINUE;
821 /* Encode the payload */
822 status = silc_ske_payload_start_encode(ske, ske->start_payload,
824 if (status != SILC_SKE_STATUS_OK) {
825 /** Error encoding Start Payload */
826 ske->status = status;
827 silc_fsm_next(fsm, silc_ske_st_initiator_error);
828 return SILC_FSM_CONTINUE;
831 /* Save the the payload buffer for future use. It is later used to
832 compute the HASH value. */
833 ske->start_payload_copy = payload_buf;
835 /* Send the packet */
838 /** Wait for responder proposal */
839 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
840 silc_fsm_next(ske, silc_ske_st_initiator_phase1);
841 return SILC_FSM_WAIT;
844 /* Phase-1. Receives responder's proposal */
846 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
848 SilcSKE ske = fsm_context;
849 SilcSKEStatus status;
850 SilcSKEStartPayload payload;
851 SilcSKESecurityProperties prop;
852 SilcSKEDiffieHellmanGroup group;
853 SilcBuffer packet_buf = &ske->packet->buffer;
855 SILC_LOG_DEBUG(("Start"));
859 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
860 return SILC_FSM_CONTINUE;
863 /* Decode the payload */
864 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
865 if (status != SILC_SKE_STATUS_OK) {
866 /** Error decoding Start Payload */
867 ske->status = status;
868 silc_fsm_next(fsm, silc_ske_st_initiator_error);
869 return SILC_FSM_CONTINUE;
872 /* Check that the cookie is returned unmodified */
873 if (memcmp(ske->start_payload->cookie, payload->cookie,
874 ske->start_payload->cookie_len)) {
875 /** Invalid cookie */
876 SILC_LOG_ERROR(("Responder modified our cookie and it must not do it"));
877 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
878 silc_fsm_next(fsm, silc_ske_st_initiator_error);
879 return SILC_FSM_CONTINUE;
882 /* Check version string */
883 ske->remote_version = silc_memdup(payload->version, payload->version_len);
884 status = silc_ske_check_version(ske);
885 if (status != SILC_SKE_STATUS_OK) {
886 /** Version mismatch */
887 ske->status = status;
888 silc_fsm_next(fsm, silc_ske_st_initiator_error);
889 return SILC_FSM_CONTINUE;
892 /* Free our KE Start Payload context, we don't need it anymore. */
893 silc_ske_payload_start_free(ske->start_payload);
894 ske->start_payload = NULL;
896 /* Take the selected security properties into use while doing
897 the key exchange. This is used only while doing the key
899 ske->prop = prop = silc_calloc(1, sizeof(*prop));
902 prop->flags = payload->flags;
903 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
904 if (status != SILC_SKE_STATUS_OK)
909 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
910 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
913 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
914 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
917 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
918 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
921 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
922 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
926 /* Save remote's KE Start Payload */
927 ske->start_payload = payload;
929 /** Send KE Payload */
930 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
931 return SILC_FSM_CONTINUE;
935 silc_ske_payload_start_free(payload);
937 silc_ske_group_free(group);
940 silc_cipher_free(prop->cipher);
942 silc_hash_free(prop->hash);
944 silc_hmac_free(prop->hmac);
948 if (status == SILC_SKE_STATUS_OK)
949 status = SILC_SKE_STATUS_ERROR;
952 ske->status = status;
953 silc_fsm_next(fsm, silc_ske_st_initiator_error);
954 return SILC_FSM_CONTINUE;
957 /* Phase-2. Send KE payload */
959 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
961 SilcSKE ske = fsm_context;
962 SilcSKEStatus status;
963 SilcBuffer payload_buf;
965 SilcSKEKEPayload payload;
968 SILC_LOG_DEBUG(("Start"));
970 /* Create the random number x, 1 < x < q. */
971 x = silc_calloc(1, sizeof(*x));
974 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
975 silc_fsm_next(fsm, silc_ske_st_initiator_error);
976 return SILC_FSM_CONTINUE;
980 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
981 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
983 if (status != SILC_SKE_STATUS_OK) {
984 /** Error generating random number */
987 ske->status = status;
988 silc_fsm_next(fsm, silc_ske_st_initiator_error);
989 return SILC_FSM_CONTINUE;
992 /* Encode the result to Key Exchange Payload. */
994 payload = silc_calloc(1, sizeof(*payload));
999 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1000 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1001 return SILC_FSM_CONTINUE;
1003 ske->ke1_payload = payload;
1005 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1007 /* Do the Diffie Hellman computation, e = g ^ x mod p */
1008 silc_mp_init(&payload->x);
1009 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1010 &ske->prop->group->group);
1012 /* Get public key */
1013 if (ske->public_key) {
1014 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1015 if (!payload->pk_data) {
1016 /** Error encoding public key */
1019 silc_mp_uninit(&payload->x);
1021 ske->ke1_payload = NULL;
1022 ske->status = SILC_SKE_STATUS_ERROR;
1023 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1024 return SILC_FSM_CONTINUE;
1026 payload->pk_len = pk_len;
1028 payload->pk_type = silc_pkcs_get_type(ske->public_key);
1030 /* Compute signature data if we are doing mutual authentication */
1031 if (ske->private_key &&
1032 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1033 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1034 SilcUInt32 hash_len, sign_len;
1036 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1037 SILC_LOG_DEBUG(("Computing HASH_i value"));
1039 /* Compute the hash value */
1040 memset(hash, 0, sizeof(hash));
1041 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1043 SILC_LOG_DEBUG(("Signing HASH_i value"));
1045 /* Sign the hash value */
1046 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1047 sizeof(sign) - 1, &sign_len, NULL)) {
1048 /** Error computing signature */
1051 silc_mp_uninit(&payload->x);
1052 silc_free(payload->pk_data);
1054 ske->ke1_payload = NULL;
1055 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1056 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1057 return SILC_FSM_CONTINUE;
1059 payload->sign_data = silc_memdup(sign, sign_len);
1060 payload->sign_len = sign_len;
1061 memset(sign, 0, sizeof(sign));
1064 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1065 if (status != SILC_SKE_STATUS_OK) {
1066 /** Error encoding KE payload */
1069 silc_mp_uninit(&payload->x);
1070 silc_free(payload->pk_data);
1071 silc_free(payload->sign_data);
1073 ske->ke1_payload = NULL;
1074 ske->status = status;
1075 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1076 return SILC_FSM_CONTINUE;
1081 /* Send the packet. */
1084 silc_buffer_free(payload_buf);
1086 /** Waiting responder's KE payload */
1087 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1088 return SILC_FSM_WAIT;
1091 /* Phase-3. Process responder's KE payload */
1093 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1095 SilcSKE ske = fsm_context;
1096 SilcSKEStatus status;
1097 SilcSKEKEPayload payload;
1099 SilcBuffer packet_buf = &ske->packet->buffer;
1101 SILC_LOG_DEBUG(("Start"));
1105 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1106 return SILC_FSM_CONTINUE;
1109 /* Decode the payload */
1110 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1111 if (status != SILC_SKE_STATUS_OK) {
1112 /** Error decoding KE payload */
1113 ske->status = status;
1114 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1115 return SILC_FSM_CONTINUE;
1117 ske->ke2_payload = payload;
1119 if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1120 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1121 "even though we require it"));
1122 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1126 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1128 /* Compute the shared secret key */
1129 KEY = silc_calloc(1, sizeof(*KEY));
1131 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1134 /* Decode the remote's public key */
1135 if (payload->pk_data &&
1136 !silc_pkcs_public_key_alloc(payload->pk_type,
1137 payload->pk_data, payload->pk_len,
1138 &ske->prop->public_key)) {
1139 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1140 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1144 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1146 SILC_LOG_DEBUG(("Verifying public key"));
1148 /** Waiting public key verification */
1149 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1151 /* If repository is provided, verify the key from there. */
1152 if (ske->repository) {
1155 find = silc_skr_find_alloc();
1157 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1160 silc_skr_find_set_pkcs_type(find,
1161 silc_pkcs_get_type(ske->prop->public_key));
1162 silc_skr_find_set_public_key(find, ske->prop->public_key);
1164 /* Find key from repository */
1165 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1166 silc_ske_skr_callback, ske));
1168 /* Verify from application */
1169 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1170 ske->callbacks->context,
1171 silc_ske_pk_verified, NULL));
1176 /** Process key material */
1177 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1178 return SILC_FSM_CONTINUE;
1181 silc_ske_payload_ke_free(payload);
1182 ske->ke2_payload = NULL;
1184 silc_mp_uninit(ske->KEY);
1185 silc_free(ske->KEY);
1188 if (status == SILC_SKE_STATUS_OK)
1189 return SILC_SKE_STATUS_ERROR;
1192 ske->status = status;
1193 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1194 return SILC_FSM_CONTINUE;
1197 /* Process key material */
1199 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1201 SilcSKE ske = fsm_context;
1202 SilcSKEStatus status;
1203 SilcSKEKEPayload payload;
1204 unsigned char hash[SILC_HASH_MAXLEN];
1205 SilcUInt32 hash_len;
1206 int key_len, block_len;
1210 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1211 return SILC_FSM_CONTINUE;
1214 /* Check result of public key verification */
1215 if (ske->status != SILC_SKE_STATUS_OK) {
1216 /** Public key not verified */
1217 SILC_LOG_DEBUG(("Public key verification failed"));
1218 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1219 return SILC_FSM_CONTINUE;
1222 payload = ske->ke2_payload;
1224 if (ske->prop->public_key) {
1225 SILC_LOG_DEBUG(("Public key is authentic"));
1227 /* Compute the hash value */
1228 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1229 if (status != SILC_SKE_STATUS_OK)
1232 ske->hash = silc_memdup(hash, hash_len);
1233 ske->hash_len = hash_len;
1235 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1237 /* Verify signature */
1238 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1239 payload->sign_len, hash, hash_len, NULL)) {
1240 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1241 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1245 SILC_LOG_DEBUG(("Signature is Ok"));
1247 memset(hash, 'F', hash_len);
1250 ske->status = SILC_SKE_STATUS_OK;
1252 /* Process key material */
1253 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1254 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1255 hash_len = silc_hash_len(ske->prop->hash);
1256 ske->keymat = silc_ske_process_key_material(ske, block_len,
1259 SILC_LOG_ERROR(("Error processing key material"));
1260 status = SILC_SKE_STATUS_ERROR;
1264 /* Send SUCCESS packet */
1267 /** Waiting completion */
1268 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1269 return SILC_FSM_WAIT;
1272 memset(hash, 'F', sizeof(hash));
1273 silc_ske_payload_ke_free(payload);
1274 ske->ke2_payload = NULL;
1276 silc_mp_uninit(ske->KEY);
1277 silc_free(ske->KEY);
1281 memset(ske->hash, 'F', hash_len);
1282 silc_free(ske->hash);
1286 if (status == SILC_SKE_STATUS_OK)
1287 status = SILC_SKE_STATUS_ERROR;
1290 ske->status = status;
1291 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1292 return SILC_FSM_CONTINUE;
1295 /* Protocol completed */
1297 SILC_FSM_STATE(silc_ske_st_initiator_end)
1299 SilcSKE ske = fsm_context;
1303 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1304 return SILC_FSM_CONTINUE;
1307 /* Call the completion callback */
1308 if (ske->callbacks->completed)
1309 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1311 return SILC_FSM_FINISH;
1314 /* Aborted by application */
1316 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1319 return SILC_FSM_FINISH;
1322 /* Error occurred */
1324 SILC_FSM_STATE(silc_ske_st_initiator_error)
1327 return SILC_FSM_FINISH;
1331 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1332 void *destructor_context)
1337 /* Starts the protocol as initiator */
1340 silc_ske_initiator(SilcSKE ske,
1341 SilcPacketStream stream,
1342 SilcSKEStartPayload start_payload)
1344 SILC_LOG_DEBUG(("Start SKE as initiator"));
1346 if (!ske || !stream || !start_payload)
1349 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1352 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1356 ske->start_payload = start_payload;
1358 /* Link to packet stream to get key exchange packets */
1359 ske->stream = stream;
1360 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1361 SILC_PACKET_KEY_EXCHANGE,
1362 SILC_PACKET_KEY_EXCHANGE_2,
1363 SILC_PACKET_SUCCESS,
1364 SILC_PACKET_FAILURE, -1);
1366 /* Start SKE as initiator */
1367 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1373 /******************************** Responder *********************************/
1375 SILC_FSM_STATE(silc_ske_st_responder_start);
1376 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1377 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1378 SILC_FSM_STATE(silc_ske_st_responder_phase3);
1379 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1380 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1381 SILC_FSM_STATE(silc_ske_st_responder_end);
1382 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1383 SILC_FSM_STATE(silc_ske_st_responder_failure);
1384 SILC_FSM_STATE(silc_ske_st_responder_error);
1386 /* Start protocol as responder. Wait initiator's start payload */
1388 SILC_FSM_STATE(silc_ske_st_responder_start)
1390 SilcSKE ske = fsm_context;
1392 SILC_LOG_DEBUG(("Start"));
1396 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1397 return SILC_FSM_CONTINUE;
1403 /** Wait for initiator */
1404 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1405 return SILC_FSM_WAIT;
1408 /* Decode initiator's start payload */
1410 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1412 SilcSKE ske = fsm_context;
1413 SilcSKEStatus status;
1414 SilcSKEStartPayload remote_payload = NULL, payload = NULL;
1415 SilcBuffer packet_buf = &ske->packet->buffer;
1417 SILC_LOG_DEBUG(("Start"));
1421 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1422 return SILC_FSM_CONTINUE;
1425 /* See if received failure from remote */
1426 if (ske->packet->type == SILC_PACKET_FAILURE) {
1427 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1428 return SILC_FSM_CONTINUE;
1431 /* Decode the payload */
1432 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1433 if (status != SILC_SKE_STATUS_OK) {
1434 /** Error decoding Start Payload */
1435 silc_packet_free(ske->packet);
1436 ske->status = status;
1437 silc_fsm_next(fsm, silc_ske_st_responder_error);
1438 return SILC_FSM_CONTINUE;
1441 /* Take a copy of the payload buffer for future use. It is used to
1442 compute the HASH value. */
1443 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1445 silc_packet_free(ske->packet);
1447 /* Force the mutual authentication flag if we want to do it. */
1448 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1449 SILC_LOG_DEBUG(("Force mutual authentication"));
1450 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1453 /* Force PFS flag if we require it */
1454 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1455 SILC_LOG_DEBUG(("Force PFS"));
1456 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1459 /* Disable IV Included flag if requested */
1460 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1461 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1462 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1463 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1466 /* Parse and select the security properties from the payload */
1467 payload = silc_calloc(1, sizeof(*payload));
1468 status = silc_ske_select_security_properties(ske, payload, remote_payload);
1469 if (status != SILC_SKE_STATUS_OK) {
1470 /** Error selecting proposal */
1472 silc_ske_payload_start_free(remote_payload);
1474 ske->status = status;
1475 silc_fsm_next(fsm, silc_ske_st_responder_error);
1476 return SILC_FSM_CONTINUE;
1479 ske->start_payload = payload;
1481 silc_ske_payload_start_free(remote_payload);
1483 /** Send proposal to initiator */
1484 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1485 return SILC_FSM_CONTINUE;
1488 /* Phase-2. Send Start Payload */
1490 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1492 SilcSKE ske = fsm_context;
1493 SilcSKEStatus status;
1494 SilcBuffer payload_buf;
1495 SilcSKESecurityProperties prop;
1496 SilcSKEDiffieHellmanGroup group = NULL;
1498 SILC_LOG_DEBUG(("Start"));
1500 /* Allocate security properties from the payload. These are allocated
1501 only for this negotiation and will be free'd after KE is over. */
1502 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1504 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1507 prop->flags = ske->start_payload->flags;
1508 status = silc_ske_group_get_by_name(ske->start_payload->ke_grp_list,
1510 if (status != SILC_SKE_STATUS_OK)
1513 prop->group = group;
1515 /* XXX these shouldn't be allocated before we know the remote's
1516 public key type. It's unnecessary to allocate these because the
1517 select_security_properties has succeeded already. */
1518 if (!silc_pkcs_find_algorithm(ske->start_payload->pkcs_alg_list, NULL)) {
1519 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1522 if (silc_cipher_alloc(ske->start_payload->enc_alg_list,
1523 &prop->cipher) == FALSE) {
1524 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1527 if (silc_hash_alloc(ske->start_payload->hash_alg_list,
1528 &prop->hash) == FALSE) {
1529 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1532 if (silc_hmac_alloc(ske->start_payload->hmac_alg_list, NULL,
1533 &prop->hmac) == FALSE) {
1534 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1538 /* Encode the payload */
1539 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1541 if (status != SILC_SKE_STATUS_OK)
1544 /* Send the packet. */
1545 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1546 payload_buf->data, silc_buffer_len(payload_buf)))
1549 silc_buffer_free(payload_buf);
1551 /** Waiting initiator's KE payload */
1552 silc_fsm_next(fsm, silc_ske_st_responder_phase3);
1553 return SILC_FSM_WAIT;
1557 silc_ske_group_free(group);
1560 silc_cipher_free(prop->cipher);
1562 silc_hash_free(prop->hash);
1564 silc_hmac_free(prop->hmac);
1568 if (status == SILC_SKE_STATUS_OK)
1569 status = SILC_SKE_STATUS_ERROR;
1572 ske->status = status;
1573 silc_fsm_next(fsm, silc_ske_st_responder_error);
1574 return SILC_FSM_CONTINUE;
1577 /* Phase-3. Decode initiator's KE payload */
1579 SILC_FSM_STATE(silc_ske_st_responder_phase3)
1581 SilcSKE ske = fsm_context;
1582 SilcSKEStatus status;
1583 SilcSKEKEPayload recv_payload;
1584 SilcBuffer packet_buf = &ske->packet->buffer;
1586 SILC_LOG_DEBUG(("Start"));
1590 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1591 return SILC_FSM_CONTINUE;
1594 /* See if received failure from remote */
1595 if (ske->packet->type == SILC_PACKET_FAILURE) {
1596 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1597 return SILC_FSM_CONTINUE;
1600 /* Decode Key Exchange Payload */
1601 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1602 if (status != SILC_SKE_STATUS_OK) {
1603 /** Error decoding KE payload */
1604 silc_packet_free(ske->packet);
1605 ske->status = status;
1606 silc_fsm_next(fsm, silc_ske_st_responder_error);
1607 return SILC_FSM_CONTINUE;
1610 ske->ke1_payload = recv_payload;
1612 silc_packet_free(ske->packet);
1614 /* Verify the received public key and verify the signature if we are
1615 doing mutual authentication. */
1616 if (ske->start_payload &&
1617 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1619 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1621 if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1623 /** Public key not provided */
1624 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1625 "certificate), even though we require it"));
1626 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1627 silc_fsm_next(fsm, silc_ske_st_responder_error);
1628 return SILC_FSM_CONTINUE;
1631 /* Decode the remote's public key */
1632 if (recv_payload->pk_data &&
1633 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1634 recv_payload->pk_data,
1635 recv_payload->pk_len,
1636 &ske->prop->public_key)) {
1637 /** Error decoding public key */
1638 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1639 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1640 silc_fsm_next(fsm, silc_ske_st_responder_error);
1641 return SILC_FSM_CONTINUE;
1644 if (ske->prop->public_key && (ske->callbacks->verify_key ||
1646 SILC_LOG_DEBUG(("Verifying public key"));
1648 /** Waiting public key verification */
1649 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1651 /* If repository is provided, verify the key from there. */
1652 if (ske->repository) {
1655 find = silc_skr_find_alloc();
1657 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1658 silc_fsm_next(fsm, silc_ske_st_responder_error);
1659 return SILC_FSM_CONTINUE;
1661 silc_skr_find_set_pkcs_type(find,
1662 silc_pkcs_get_type(ske->prop->public_key));
1663 silc_skr_find_set_public_key(find, ske->prop->public_key);
1665 /* Find key from repository */
1666 SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1667 silc_ske_skr_callback, ske));
1669 /* Verify from application */
1670 SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1671 ske->callbacks->context,
1672 silc_ske_pk_verified, NULL));
1678 /** Generate KE2 payload */
1679 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1680 return SILC_FSM_CONTINUE;
1683 /* Phase-4. Generate KE2 payload */
1685 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1687 SilcSKE ske = fsm_context;
1688 SilcSKEStatus status;
1689 SilcSKEKEPayload recv_payload, send_payload;
1694 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1695 return SILC_FSM_CONTINUE;
1698 /* Check result of public key verification */
1699 if (ske->status != SILC_SKE_STATUS_OK) {
1700 /** Public key not verified */
1701 SILC_LOG_DEBUG(("Public key verification failed"));
1702 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1703 return SILC_FSM_CONTINUE;
1706 recv_payload = ske->ke1_payload;
1708 /* The public key verification was performed only if the Mutual
1709 Authentication flag is set. */
1710 if (ske->start_payload &&
1711 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1712 unsigned char hash[SILC_HASH_MAXLEN];
1713 SilcUInt32 hash_len;
1715 SILC_LOG_DEBUG(("Public key is authentic"));
1717 /* Compute the hash value */
1718 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1719 if (status != SILC_SKE_STATUS_OK) {
1720 /** Error computing hash */
1721 ske->status = status;
1722 silc_fsm_next(fsm, silc_ske_st_responder_error);
1723 return SILC_FSM_CONTINUE;
1726 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1728 /* Verify signature */
1729 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
1730 recv_payload->sign_len, hash, hash_len, NULL)) {
1731 /** Incorrect signature */
1732 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1733 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1734 silc_fsm_next(fsm, silc_ske_st_responder_error);
1735 return SILC_FSM_CONTINUE;
1738 SILC_LOG_DEBUG(("Signature is Ok"));
1740 memset(hash, 'F', hash_len);
1743 /* Create the random number x, 1 < x < q. */
1744 x = silc_calloc(1, sizeof(*x));
1747 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1748 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1750 if (status != SILC_SKE_STATUS_OK) {
1751 /** Error generating random number */
1754 ske->status = status;
1755 silc_fsm_next(fsm, silc_ske_st_responder_error);
1756 return SILC_FSM_CONTINUE;
1759 /* Save the results for later processing */
1760 send_payload = silc_calloc(1, sizeof(*send_payload));
1762 ske->ke2_payload = send_payload;
1764 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1766 /* Do the Diffie Hellman computation, f = g ^ x mod p */
1767 silc_mp_init(&send_payload->x);
1768 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1769 &ske->prop->group->group);
1771 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1773 /* Compute the shared secret key */
1774 KEY = silc_calloc(1, sizeof(*KEY));
1776 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1777 &ske->prop->group->group);
1780 /** Send KE2 payload */
1781 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1782 return SILC_FSM_CONTINUE;
1785 /* Phase-5. Send KE2 payload */
1787 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1789 SilcSKE ske = fsm_context;
1790 SilcSKEStatus status;
1791 SilcBuffer payload_buf;
1792 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1793 SilcUInt32 hash_len, sign_len, pk_len;
1795 SILC_LOG_DEBUG(("Start"));
1797 if (ske->public_key && ske->private_key) {
1798 SILC_LOG_DEBUG(("Getting public key"));
1800 /* Get the public key */
1801 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1803 /** Error encoding public key */
1804 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1805 silc_fsm_next(fsm, silc_ske_st_responder_error);
1806 return SILC_FSM_CONTINUE;
1808 ske->ke2_payload->pk_data = pk;
1809 ske->ke2_payload->pk_len = pk_len;
1811 SILC_LOG_DEBUG(("Computing HASH value"));
1813 /* Compute the hash value */
1814 memset(hash, 0, sizeof(hash));
1815 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1816 if (status != SILC_SKE_STATUS_OK) {
1817 /** Error computing hash */
1818 ske->status = status;
1819 silc_fsm_next(fsm, silc_ske_st_responder_error);
1820 return SILC_FSM_CONTINUE;
1823 ske->hash = silc_memdup(hash, hash_len);
1824 ske->hash_len = hash_len;
1826 SILC_LOG_DEBUG(("Signing HASH value"));
1828 /* Sign the hash value */
1829 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1830 sizeof(sign) - 1, &sign_len, NULL)) {
1831 /** Error computing signature */
1832 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1833 silc_fsm_next(fsm, silc_ske_st_responder_error);
1834 return SILC_FSM_CONTINUE;
1836 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
1837 ske->ke2_payload->sign_len = sign_len;
1838 memset(sign, 0, sizeof(sign));
1840 ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
1842 /* Encode the Key Exchange Payload */
1843 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
1845 if (status != SILC_SKE_STATUS_OK) {
1846 /** Error encoding KE payload */
1847 ske->status = status;
1848 silc_fsm_next(fsm, silc_ske_st_responder_error);
1849 return SILC_FSM_CONTINUE;
1852 /* Send the packet. */
1853 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
1854 payload_buf->data, silc_buffer_len(payload_buf))) {
1855 ske->status = SILC_SKE_STATUS_ERROR;
1856 silc_fsm_next(fsm, silc_ske_st_responder_error);
1857 return SILC_FSM_CONTINUE;
1860 silc_buffer_free(payload_buf);
1862 /** Waiting completion */
1863 silc_fsm_next(fsm, silc_ske_st_responder_end);
1864 return SILC_FSM_WAIT;
1867 /* Protocol completed */
1869 SILC_FSM_STATE(silc_ske_st_responder_end)
1871 SilcSKE ske = fsm_context;
1872 unsigned char tmp[4];
1873 SilcUInt32 hash_len, key_len, block_len;
1877 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1878 return SILC_FSM_CONTINUE;
1881 /* Check the result of the protocol */
1882 if (ske->packet->type == SILC_PACKET_FAILURE) {
1883 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1884 return SILC_FSM_CONTINUE;
1886 silc_packet_free(ske->packet);
1888 /* Process key material */
1889 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1890 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1891 hash_len = silc_hash_len(ske->prop->hash);
1892 ske->keymat = silc_ske_process_key_material(ske, block_len,
1895 /** Error processing key material */
1896 ske->status = SILC_SKE_STATUS_ERROR;
1897 silc_fsm_next(fsm, silc_ske_st_responder_error);
1898 return SILC_FSM_CONTINUE;
1901 /* Send SUCCESS packet */
1902 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
1903 silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
1905 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1907 /* Call the completion callback */
1908 if (ske->callbacks->completed)
1909 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1910 ske->rekey, ske->callbacks->context);
1912 return SILC_FSM_FINISH;
1915 /* Aborted by application */
1917 SILC_FSM_STATE(silc_ske_st_responder_aborted)
1919 SilcSKE ske = fsm_context;
1920 unsigned char tmp[4];
1922 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
1924 /* Send FAILURE packet */
1925 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
1926 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
1928 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1930 return SILC_FSM_FINISH;
1933 /* Failure received from remote */
1935 SILC_FSM_STATE(silc_ske_st_responder_failure)
1937 SilcSKE ske = fsm_context;
1938 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1940 SILC_LOG_DEBUG(("Key exchange protocol failed"));
1942 if (silc_buffer_len(&ske->packet->buffer) == 4)
1943 SILC_GET32_MSB(error, ske->packet->buffer.data);
1944 ske->status = error;
1946 /* Call the completion callback */
1947 if (ske->callbacks->completed)
1948 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1949 ske->callbacks->context);
1951 silc_packet_free(ske->packet);
1952 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1954 return SILC_FSM_FINISH;
1957 /* Error occurred */
1959 SILC_FSM_STATE(silc_ske_st_responder_error)
1961 SilcSKE ske = fsm_context;
1962 unsigned char tmp[4];
1964 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
1965 ske->status, silc_ske_map_status(ske->status)));
1967 /* Send FAILURE packet */
1968 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
1969 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
1970 SILC_PUT32_MSB(ske->status, tmp);
1971 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
1973 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1975 return SILC_FSM_FINISH;
1979 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
1980 void *destructor_context)
1985 /* Starts the protocol as responder. */
1988 silc_ske_responder(SilcSKE ske,
1989 SilcPacketStream stream,
1990 const char *version,
1991 SilcSKESecurityPropertyFlag flags)
1993 SILC_LOG_DEBUG(("Start SKE as responder"));
1995 if (!ske || !stream || !version) {
1999 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2002 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2007 ske->version = strdup(version);
2010 ske->responder = TRUE;
2012 /* Link to packet stream to get key exchange packets */
2013 ske->stream = stream;
2014 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2015 SILC_PACKET_KEY_EXCHANGE,
2016 SILC_PACKET_KEY_EXCHANGE_1,
2017 SILC_PACKET_SUCCESS,
2018 SILC_PACKET_FAILURE, -1);
2020 /* Start SKE as responder */
2021 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2026 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2028 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2030 return SILC_FSM_FINISH;
2033 /* Starts rekey protocol as initiator */
2036 silc_ske_rekey_initiator(SilcSKE ske,
2037 SilcPacketStream stream,
2038 SilcSKERekeyMaterial rekey)
2040 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2042 if (!ske || !stream || !rekey)
2045 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2048 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2053 /* Link to packet stream to get key exchange packets */
2054 ske->stream = stream;
2056 /* Start SKE rekey as initiator */
2057 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2062 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2064 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2066 return SILC_FSM_FINISH;
2069 /* Starts rekey protocol as responder */
2072 silc_ske_rekey_responder(SilcSKE ske,
2073 SilcPacketStream stream,
2074 SilcBuffer ke_payload,
2075 SilcSKERekeyMaterial rekey)
2077 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2079 if (!ske || !stream || !rekey)
2081 if (rekey->pfs && !ke_payload)
2084 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2087 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2090 // ske->packet_buf = ke_payload;
2093 /* Link to packet stream to get key exchange packets */
2094 ske->stream = stream;
2096 /* Start SKE rekey as responder */
2097 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2102 /* Assembles security properties */
2105 silc_ske_assemble_security_properties(SilcSKE ske,
2106 SilcSKESecurityPropertyFlag flags,
2107 const char *version)
2109 SilcSKEStartPayload rp;
2112 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
2114 rp = silc_calloc(1, sizeof(*rp));
2117 rp->flags = (unsigned char)flags;
2119 /* Set random cookie */
2120 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
2121 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
2122 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
2123 rp->cookie_len = SILC_SKE_COOKIE_LEN;
2126 rp->version = strdup(version);
2127 rp->version_len = strlen(version);
2129 /* Get supported Key Exhange groups */
2130 rp->ke_grp_list = silc_ske_get_supported_groups();
2131 rp->ke_grp_len = strlen(rp->ke_grp_list);
2133 /* Get supported PKCS algorithms */
2134 rp->pkcs_alg_list = silc_pkcs_get_supported();
2135 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
2137 /* Get supported encryption algorithms */
2138 rp->enc_alg_list = silc_cipher_get_supported();
2139 rp->enc_alg_len = strlen(rp->enc_alg_list);
2141 /* Get supported hash algorithms */
2142 rp->hash_alg_list = silc_hash_get_supported();
2143 rp->hash_alg_len = strlen(rp->hash_alg_list);
2145 /* Get supported HMACs */
2146 rp->hmac_alg_list = silc_hmac_get_supported();
2147 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
2150 /* Get supported compression algorithms */
2151 rp->comp_alg_list = strdup("none");
2152 rp->comp_alg_len = strlen("none");
2154 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
2155 2 + rp->version_len +
2156 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
2157 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
2158 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
2163 /* Processes the provided key material `data' as the SILC protocol
2164 specification defines. */
2167 silc_ske_process_key_material_data(unsigned char *data,
2168 SilcUInt32 data_len,
2169 SilcUInt32 req_iv_len,
2170 SilcUInt32 req_enc_key_len,
2171 SilcUInt32 req_hmac_key_len,
2175 unsigned char hashd[SILC_HASH_MAXLEN];
2176 SilcUInt32 hash_len = req_hmac_key_len;
2177 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2178 SilcSKEKeyMaterial key;
2180 SILC_LOG_DEBUG(("Start"));
2182 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2185 key = silc_calloc(1, sizeof(*key));
2189 buf = silc_buffer_alloc_size(1 + data_len);
2192 silc_buffer_format(buf,
2193 SILC_STR_UI_CHAR(0),
2194 SILC_STR_UI_XNSTRING(data, data_len),
2198 memset(hashd, 0, sizeof(hashd));
2200 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2201 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2202 memcpy(key->send_iv, hashd, req_iv_len);
2203 memset(hashd, 0, sizeof(hashd));
2205 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2206 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2207 memcpy(key->receive_iv, hashd, req_iv_len);
2208 key->iv_len = req_iv_len;
2210 /* Take the encryption keys. If requested key size is more than
2211 the size of hash length we will distribute more key material
2212 as protocol defines. */
2214 if (enc_key_len > hash_len) {
2216 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2217 k3[SILC_HASH_MAXLEN];
2218 unsigned char *dtmp;
2221 if (enc_key_len > (3 * hash_len))
2224 /* Take first round */
2225 memset(k1, 0, sizeof(k1));
2226 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2228 /* Take second round */
2229 dist = silc_buffer_alloc_size(data_len + hash_len);
2232 silc_buffer_format(dist,
2233 SILC_STR_UI_XNSTRING(data, data_len),
2234 SILC_STR_UI_XNSTRING(k1, hash_len),
2236 memset(k2, 0, sizeof(k2));
2237 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2239 /* Take third round */
2240 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2241 silc_buffer_pull_tail(dist, hash_len);
2242 silc_buffer_pull(dist, data_len + hash_len);
2243 silc_buffer_format(dist,
2244 SILC_STR_UI_XNSTRING(k2, hash_len),
2246 silc_buffer_push(dist, data_len + hash_len);
2247 memset(k3, 0, sizeof(k3));
2248 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2250 /* Then, save the keys */
2251 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2252 memcpy(dtmp, k1, hash_len);
2253 memcpy(dtmp + hash_len, k2, hash_len);
2254 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2256 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2257 memcpy(key->send_enc_key, dtmp, enc_key_len);
2258 key->enc_key_len = req_enc_key_len;
2260 memset(dtmp, 0, (3 * hash_len));
2261 memset(k1, 0, sizeof(k1));
2262 memset(k2, 0, sizeof(k2));
2263 memset(k3, 0, sizeof(k3));
2265 silc_buffer_clear(dist);
2266 silc_buffer_free(dist);
2268 /* Take normal hash as key */
2269 memset(hashd, 0, sizeof(hashd));
2270 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2271 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2272 memcpy(key->send_enc_key, hashd, enc_key_len);
2273 key->enc_key_len = req_enc_key_len;
2277 if (enc_key_len > hash_len) {
2279 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2280 k3[SILC_HASH_MAXLEN];
2281 unsigned char *dtmp;
2284 if (enc_key_len > (3 * hash_len))
2287 /* Take first round */
2288 memset(k1, 0, sizeof(k1));
2289 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2291 /* Take second round */
2292 dist = silc_buffer_alloc_size(data_len + hash_len);
2295 silc_buffer_format(dist,
2296 SILC_STR_UI_XNSTRING(data, data_len),
2297 SILC_STR_UI_XNSTRING(k1, hash_len),
2299 memset(k2, 0, sizeof(k2));
2300 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2302 /* Take third round */
2303 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2304 silc_buffer_pull_tail(dist, hash_len);
2305 silc_buffer_pull(dist, data_len + hash_len);
2306 silc_buffer_format(dist,
2307 SILC_STR_UI_XNSTRING(k2, hash_len),
2309 silc_buffer_push(dist, data_len + hash_len);
2310 memset(k3, 0, sizeof(k3));
2311 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2313 /* Then, save the keys */
2314 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2315 memcpy(dtmp, k1, hash_len);
2316 memcpy(dtmp + hash_len, k2, hash_len);
2317 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2319 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2320 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2321 key->enc_key_len = req_enc_key_len;
2323 memset(dtmp, 0, (3 * hash_len));
2324 memset(k1, 0, sizeof(k1));
2325 memset(k2, 0, sizeof(k2));
2326 memset(k3, 0, sizeof(k3));
2328 silc_buffer_clear(dist);
2329 silc_buffer_free(dist);
2331 /* Take normal hash as key */
2332 memset(hashd, 0, sizeof(hashd));
2333 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2334 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2335 memcpy(key->receive_enc_key, hashd, enc_key_len);
2336 key->enc_key_len = req_enc_key_len;
2339 /* Take HMAC keys */
2340 memset(hashd, 0, sizeof(hashd));
2342 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2343 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2344 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2345 memset(hashd, 0, sizeof(hashd));
2347 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2348 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2349 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2350 key->hmac_key_len = req_hmac_key_len;
2351 memset(hashd, 0, sizeof(hashd));
2353 silc_buffer_clear(buf);
2354 silc_buffer_free(buf);
2359 /* Processes negotiated key material as protocol specifies. This returns
2360 the actual keys to be used in the SILC. */
2363 silc_ske_process_key_material(SilcSKE ske,
2364 SilcUInt32 req_iv_len,
2365 SilcUInt32 req_enc_key_len,
2366 SilcUInt32 req_hmac_key_len)
2369 unsigned char *tmpbuf;
2371 SilcSKEKeyMaterial key;
2373 /* Encode KEY to binary data */
2374 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2376 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2379 silc_buffer_format(buf,
2380 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2381 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2384 /* Process the key material */
2385 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2386 req_iv_len, req_enc_key_len,
2390 memset(tmpbuf, 0, klen);
2392 silc_buffer_clear(buf);
2393 silc_buffer_free(buf);
2398 /* Free key material structure */
2400 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2406 silc_free(key->send_iv);
2407 if (key->receive_iv)
2408 silc_free(key->receive_iv);
2409 if (key->send_enc_key) {
2410 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2411 silc_free(key->send_enc_key);
2413 if (key->receive_enc_key) {
2414 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2415 silc_free(key->receive_enc_key);
2417 if (key->send_hmac_key) {
2418 memset(key->send_hmac_key, 0, key->hmac_key_len);
2419 silc_free(key->send_hmac_key);
2421 if (key->receive_hmac_key) {
2422 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2423 silc_free(key->receive_hmac_key);
2428 /* Set keys into use */
2430 SilcBool silc_ske_set_keys(SilcSKE ske,
2431 SilcSKEKeyMaterial keymat,
2432 SilcSKESecurityProperties prop,
2433 SilcCipher *ret_send_key,
2434 SilcCipher *ret_receive_key,
2435 SilcHmac *ret_hmac_send,
2436 SilcHmac *ret_hmac_receive,
2439 /* Allocate ciphers to be used in the communication */
2441 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2445 if (ret_receive_key) {
2446 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2451 /* Allocate HMACs */
2452 if (ret_hmac_send) {
2453 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2457 if (ret_hmac_receive) {
2458 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2463 /* Set key material */
2464 if (ske->responder) {
2465 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2466 keymat->enc_key_len);
2467 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2468 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2469 keymat->enc_key_len);
2470 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2471 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2472 keymat->hmac_key_len);
2473 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2474 keymat->hmac_key_len);
2476 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2477 keymat->enc_key_len);
2478 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2479 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2480 keymat->enc_key_len);
2481 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2482 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2483 keymat->hmac_key_len);
2484 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2485 keymat->hmac_key_len);
2490 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2494 SILC_LOG_INFO(("Security properties: %s %s %s %s",
2495 ret_send_key ? silc_cipher_get_name(*ret_send_key) : "??",
2496 ret_hmac_send ? silc_hmac_get_name(*ret_hmac_send) : "??",
2497 ret_hash ? silc_hash_get_name(*ret_hash) : "??",
2498 ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : ""));
2503 const char *silc_ske_status_string[] =
2507 "Unkown error occurred",
2508 "Bad payload in packet",
2509 "Unsupported group",
2510 "Unsupported cipher",
2512 "Unsupported hash function",
2514 "Unsupported public key (or certificate)",
2515 "Incorrect signature",
2516 "Bad or unsupported version",
2520 "Remote did not provide public key",
2521 "Bad reserved field in packet",
2522 "Bad payload length in packet",
2523 "Error computing signature",
2524 "System out of memory",
2529 /* Maps status to readable string and returns the string. If string is not
2530 found and empty character string ("") is returned. */
2532 const char *silc_ske_map_status(SilcSKEStatus status)
2536 for (i = 0; silc_ske_status_string[i]; i++)
2538 return silc_ske_status_string[i];
2543 /* Parses remote host's version string. */
2545 SilcBool silc_ske_parse_version(SilcSKE ske,
2546 SilcUInt32 *protocol_version,
2547 char **protocol_version_string,
2548 SilcUInt32 *software_version,
2549 char **software_version_string,
2550 char **vendor_version)
2552 return silc_parse_version_string(ske->remote_version,
2554 protocol_version_string,
2556 software_version_string,