5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2005 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 /* Checks remote and local versions */
90 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
92 SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
94 if (!ske->remote_version || !ske->version)
95 return SILC_SKE_STATUS_BAD_VERSION;
97 if (!silc_parse_version_string(ske->remote_version, &r_protocol_version,
98 NULL, NULL, NULL, NULL))
99 return SILC_SKE_STATUS_BAD_VERSION;
101 if (!silc_parse_version_string(ske->version, &l_protocol_version,
102 NULL, NULL, NULL, NULL))
103 return SILC_SKE_STATUS_BAD_VERSION;
105 /* If remote is too new, don't connect */
106 if (l_protocol_version < r_protocol_version)
107 return SILC_SKE_STATUS_BAD_VERSION;
109 return SILC_SKE_STATUS_OK;
112 /* Selects the supported security properties from the initiator's Key
113 Exchange Start Payload. */
116 silc_ske_select_security_properties(SilcSKE ske,
117 SilcSKEStartPayload payload,
118 SilcSKEStartPayload remote_payload)
120 SilcSKEStatus status;
121 SilcSKEStartPayload rp;
125 SILC_LOG_DEBUG(("Parsing KE Start Payload"));
129 /* Check version string */
130 ske->remote_version = silc_memdup(rp->version, rp->version_len);
131 status = silc_ske_check_version(ske);
132 if (status != SILC_SKE_STATUS_OK) {
133 ske->status = status;
137 /* Flags are returned unchanged. */
138 payload->flags = rp->flags;
140 /* Take cookie, we must return it to sender unmodified. */
141 payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
142 if (!payload->cookie) {
143 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
146 payload->cookie_len = SILC_SKE_COOKIE_LEN;
147 memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
149 /* Put our version to our reply */
150 payload->version = strdup(ske->version);
151 if (!payload->version) {
152 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
155 payload->version_len = strlen(ske->version);
157 /* Get supported Key Exchange groups */
158 cp = rp->ke_grp_list;
159 if (cp && strchr(cp, ',')) {
163 len = strcspn(cp, ",");
164 item = silc_calloc(len + 1, sizeof(char));
166 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
169 memcpy(item, cp, len);
171 SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
173 if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
174 SILC_LOG_DEBUG(("Found KE group `%s'", item));
176 payload->ke_grp_len = len;
177 payload->ke_grp_list = item;
191 if (!payload->ke_grp_len && !payload->ke_grp_list) {
192 SILC_LOG_DEBUG(("Could not find supported KE group"));
194 return SILC_SKE_STATUS_UNKNOWN_GROUP;
198 if (!rp->ke_grp_len) {
199 SILC_LOG_DEBUG(("KE group not defined in payload"));
201 return SILC_SKE_STATUS_BAD_PAYLOAD;
204 SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
205 SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
207 payload->ke_grp_len = rp->ke_grp_len;
208 payload->ke_grp_list = strdup(rp->ke_grp_list);
211 /* Get supported PKCS algorithms */
212 cp = rp->pkcs_alg_list;
213 if (cp && strchr(cp, ',')) {
217 len = strcspn(cp, ",");
218 item = silc_calloc(len + 1, sizeof(char));
220 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
223 memcpy(item, cp, len);
225 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
227 if (silc_pkcs_find_algorithm(item, NULL)) {
228 SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
230 payload->pkcs_alg_len = len;
231 payload->pkcs_alg_list = item;
245 if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
246 SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
247 silc_free(payload->ke_grp_list);
249 return SILC_SKE_STATUS_UNKNOWN_PKCS;
253 if (!rp->pkcs_alg_len) {
254 SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
255 silc_free(payload->ke_grp_list);
257 return SILC_SKE_STATUS_BAD_PAYLOAD;
260 SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
261 SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
263 payload->pkcs_alg_len = rp->pkcs_alg_len;
264 payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
267 /* Get supported encryption algorithms */
268 cp = rp->enc_alg_list;
269 if (cp && strchr(cp, ',')) {
273 len = strcspn(cp, ",");
274 item = silc_calloc(len + 1, sizeof(char));
276 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
279 memcpy(item, cp, len);
281 SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
283 if (silc_cipher_is_supported(item) == TRUE) {
284 SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
286 payload->enc_alg_len = len;
287 payload->enc_alg_list = item;
301 if (!payload->enc_alg_len && !payload->enc_alg_list) {
302 SILC_LOG_DEBUG(("Could not find supported encryption alg"));
303 silc_free(payload->ke_grp_list);
304 silc_free(payload->pkcs_alg_list);
306 return SILC_SKE_STATUS_UNKNOWN_CIPHER;
310 if (!rp->enc_alg_len) {
311 SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
312 silc_free(payload->ke_grp_list);
313 silc_free(payload->pkcs_alg_list);
315 return SILC_SKE_STATUS_BAD_PAYLOAD;
318 SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
321 payload->enc_alg_len = rp->enc_alg_len;
322 payload->enc_alg_list = strdup(rp->enc_alg_list);
325 /* Get supported hash algorithms */
326 cp = rp->hash_alg_list;
327 if (cp && strchr(cp, ',')) {
331 len = strcspn(cp, ",");
332 item = silc_calloc(len + 1, sizeof(char));
334 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
337 memcpy(item, cp, len);
339 SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
341 if (silc_hash_is_supported(item) == TRUE) {
342 SILC_LOG_DEBUG(("Found hash alg `%s'", item));
344 payload->hash_alg_len = len;
345 payload->hash_alg_list = item;
359 if (!payload->hash_alg_len && !payload->hash_alg_list) {
360 SILC_LOG_DEBUG(("Could not find supported hash alg"));
361 silc_free(payload->ke_grp_list);
362 silc_free(payload->pkcs_alg_list);
363 silc_free(payload->enc_alg_list);
365 return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
369 if (!rp->hash_alg_len) {
370 SILC_LOG_DEBUG(("Hash alg not defined in payload"));
371 silc_free(payload->ke_grp_list);
372 silc_free(payload->pkcs_alg_list);
373 silc_free(payload->enc_alg_list);
375 return SILC_SKE_STATUS_BAD_PAYLOAD;
378 SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
381 payload->hash_alg_len = rp->hash_alg_len;
382 payload->hash_alg_list = strdup(rp->hash_alg_list);
385 /* Get supported HMACs */
386 cp = rp->hmac_alg_list;
387 if (cp && strchr(cp, ',')) {
391 len = strcspn(cp, ",");
392 item = silc_calloc(len + 1, sizeof(char));
394 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
397 memcpy(item, cp, len);
399 SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
401 if (silc_hmac_is_supported(item) == TRUE) {
402 SILC_LOG_DEBUG(("Found HMAC `%s'", item));
404 payload->hmac_alg_len = len;
405 payload->hmac_alg_list = item;
419 if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
420 SILC_LOG_DEBUG(("Could not find supported HMAC"));
421 silc_free(payload->ke_grp_list);
422 silc_free(payload->pkcs_alg_list);
423 silc_free(payload->enc_alg_list);
424 silc_free(payload->hash_alg_list);
426 return SILC_SKE_STATUS_UNKNOWN_HMAC;
430 if (!rp->hmac_alg_len) {
431 SILC_LOG_DEBUG(("HMAC not defined in payload"));
432 silc_free(payload->ke_grp_list);
433 silc_free(payload->pkcs_alg_list);
434 silc_free(payload->enc_alg_list);
435 silc_free(payload->hash_alg_list);
437 return SILC_SKE_STATUS_BAD_PAYLOAD;
440 SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
443 payload->hmac_alg_len = rp->hmac_alg_len;
444 payload->hmac_alg_list = strdup(rp->hmac_alg_list);
447 /* Get supported compression algorithms */
448 cp = rp->comp_alg_list;
449 if (cp && strchr(cp, ',')) {
453 len = strcspn(cp, ",");
454 item = silc_calloc(len + 1, sizeof(char));
456 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
459 memcpy(item, cp, len);
461 SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
464 if (!strcmp(item, "none")) {
465 SILC_LOG_DEBUG(("Found Compression `%s'", item));
466 payload->comp_alg_len = len;
467 payload->comp_alg_list = item;
471 if (silc_hmac_is_supported(item) == TRUE) {
472 SILC_LOG_DEBUG(("Found Compression `%s'", item));
473 payload->comp_alg_len = len;
474 payload->comp_alg_list = item;
490 payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
491 2 + payload->version_len +
492 2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
493 2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
494 2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
496 return SILC_SKE_STATUS_OK;
499 /* Creates random number such that 1 < rnd < n and at most length
500 of len bits. The rnd sent as argument must be initialized. */
502 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
506 SilcSKEStatus status = SILC_SKE_STATUS_OK;
507 unsigned char *string;
511 return SILC_SKE_STATUS_ERROR;
513 SILC_LOG_DEBUG(("Creating random number"));
517 /* Get the random number as string */
518 string = silc_rng_get_rn_data(ske->rng, l);
520 return SILC_SKE_STATUS_OUT_OF_MEMORY;
522 /* Decode the string into a MP integer */
523 silc_mp_bin2mp(string, l, rnd);
524 silc_mp_mod_2exp(rnd, rnd, len);
527 if (silc_mp_cmp_ui(rnd, 1) < 0)
528 status = SILC_SKE_STATUS_ERROR;
529 if (silc_mp_cmp(rnd, n) >= 0)
530 status = SILC_SKE_STATUS_ERROR;
532 memset(string, 'F', l);
538 /* Creates a hash value HASH as defined in the SKE protocol. If the
539 `initiator' is TRUE then this function is used to create the HASH_i
540 hash value defined in the protocol. If it is FALSE then this is used
541 to create the HASH value defined by the protocol. */
543 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
544 unsigned char *return_hash,
545 SilcUInt32 *return_hash_len,
548 SilcSKEStatus status = SILC_SKE_STATUS_OK;
550 unsigned char *e, *f, *KEY;
551 SilcUInt32 e_len, f_len, KEY_len;
554 SILC_LOG_DEBUG(("Start"));
556 if (initiator == FALSE) {
557 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
558 f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
559 KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
561 /* Format the buffer used to compute the hash value */
562 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
563 ske->ke2_payload->pk_len +
564 ske->ke1_payload->pk_len +
565 e_len + f_len + KEY_len);
567 return SILC_SKE_STATUS_OUT_OF_MEMORY;
569 /* Initiator is not required to send its public key */
570 if (!ske->ke1_payload->pk_data) {
572 silc_buffer_format(buf,
573 SILC_STR_UI_XNSTRING(
574 ske->start_payload_copy->data,
575 silc_buffer_len(ske->start_payload_copy)),
576 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
577 ske->ke2_payload->pk_len),
578 SILC_STR_UI_XNSTRING(e, e_len),
579 SILC_STR_UI_XNSTRING(f, f_len),
580 SILC_STR_UI_XNSTRING(KEY, KEY_len),
584 silc_buffer_format(buf,
585 SILC_STR_UI_XNSTRING(
586 ske->start_payload_copy->data,
587 silc_buffer_len(ske->start_payload_copy)),
588 SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
589 ske->ke2_payload->pk_len),
590 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
591 ske->ke1_payload->pk_len),
592 SILC_STR_UI_XNSTRING(e, e_len),
593 SILC_STR_UI_XNSTRING(f, f_len),
594 SILC_STR_UI_XNSTRING(KEY, KEY_len),
598 silc_buffer_free(buf);
601 memset(KEY, 0, KEY_len);
605 return SILC_SKE_STATUS_ERROR;
610 memset(KEY, 0, KEY_len);
615 e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
617 buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
618 ske->ke1_payload->pk_len + e_len);
620 return SILC_SKE_STATUS_OUT_OF_MEMORY;
622 /* Format the buffer used to compute the hash value */
624 silc_buffer_format(buf,
625 SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
626 silc_buffer_len(ske->start_payload_copy)),
627 SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
628 ske->ke1_payload->pk_len),
629 SILC_STR_UI_XNSTRING(e, e_len),
632 silc_buffer_free(buf);
635 return SILC_SKE_STATUS_ERROR;
638 SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
645 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
647 *return_hash_len = silc_hash_len(ske->prop->hash);
649 if (initiator == FALSE) {
650 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
652 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
655 silc_buffer_free(buf);
661 /******************************* Protocol API *******************************/
663 /* Allocates new SKE object. */
665 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
666 SilcPublicKey public_key, SilcPrivateKey private_key,
671 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
673 if (!rng || !schedule)
676 ske = silc_calloc(1, sizeof(*ske));
679 ske->status = SILC_SKE_STATUS_OK;
681 ske->user_data = context;
682 ske->schedule = schedule;
683 ske->public_key = public_key;
684 ske->private_key = private_key;
685 ske->pk_type = SILC_SKE_PK_TYPE_SILC;
690 /* Free's SKE object. */
692 void silc_ske_free(SilcSKE ske)
694 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
697 /* Free start payload */
698 if (ske->start_payload)
699 silc_ske_payload_start_free(ske->start_payload);
701 /* Free KE payload */
702 if (ske->ke1_payload)
703 silc_ske_payload_ke_free(ske->ke1_payload);
704 if (ske->ke2_payload)
705 silc_ske_payload_ke_free(ske->ke2_payload);
706 silc_free(ske->remote_version);
710 if (ske->prop->group)
711 silc_ske_group_free(ske->prop->group);
712 if (ske->prop->cipher)
713 silc_cipher_free(ske->prop->cipher);
715 silc_hash_free(ske->prop->hash);
717 silc_hmac_free(ske->prop->hmac);
718 silc_free(ske->prop);
720 if (ske->start_payload_copy)
721 silc_buffer_free(ske->start_payload_copy);
723 silc_mp_uninit(ske->x);
727 silc_mp_uninit(ske->KEY);
730 silc_free(ske->hash);
731 silc_free(ske->callbacks);
733 memset(ske, 'F', sizeof(*ske));
738 /* Return user context */
740 void *silc_ske_get_context(SilcSKE ske)
742 return ske->user_data;
745 /* Sets protocol callbacks */
747 void silc_ske_set_callbacks(SilcSKE ske,
748 SilcSKEVerifyCb verify_key,
749 SilcSKECompletionCb completed,
753 silc_free(ske->callbacks);
754 ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
757 ske->callbacks->verify_key = verify_key;
758 ske->callbacks->completed = completed;
759 ske->callbacks->context = context;
763 /******************************** Initiator *********************************/
765 /* Initiator state machine */
766 SILC_FSM_STATE(silc_ske_st_initiator_start);
767 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
768 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
769 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
770 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
771 SILC_FSM_STATE(silc_ske_st_initiator_end);
772 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
773 SILC_FSM_STATE(silc_ske_st_initiator_error);
775 /* Start protocol. Send our proposal */
777 SILC_FSM_STATE(silc_ske_st_initiator_start)
779 SilcSKE ske = fsm_context;
780 SilcBuffer payload_buf;
783 SILC_LOG_DEBUG(("Start"));
787 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
788 return SILC_FSM_CONTINUE;
791 /* Encode the payload */
792 status = silc_ske_payload_start_encode(ske, ske->start_payload,
794 if (status != SILC_SKE_STATUS_OK) {
795 /** Error encoding Start Payload */
796 ske->status = status;
797 silc_fsm_next(fsm, silc_ske_st_initiator_error);
798 return SILC_FSM_CONTINUE;
801 /* Save the the payload buffer for future use. It is later used to
802 compute the HASH value. */
803 ske->start_payload_copy = payload_buf;
805 /* Send the packet */
808 /** Wait for responder proposal */
809 SILC_LOG_DEBUG(("Waiting for reponder proposal"));
810 silc_fsm_next(ske, silc_ske_st_initiator_phase1);
811 return SILC_FSM_WAIT;
814 /* Phase-1. Receives responder's proposal */
816 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
818 SilcSKE ske = fsm_context;
819 SilcSKEStatus status;
820 SilcSKEStartPayload payload;
821 SilcSKESecurityProperties prop;
822 SilcSKEDiffieHellmanGroup group;
823 SilcBuffer packet_buf = &ske->packet->buffer;
825 SILC_LOG_DEBUG(("Start"));
829 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
830 return SILC_FSM_CONTINUE;
833 /* Decode the payload */
834 status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
835 if (status != SILC_SKE_STATUS_OK) {
836 /** Error decoding Start Payload */
837 ske->status = status;
838 silc_fsm_next(fsm, silc_ske_st_initiator_error);
839 return SILC_FSM_CONTINUE;
842 /* Check that the cookie is returned unmodified */
843 if (memcmp(ske->start_payload->cookie, payload->cookie,
844 ske->start_payload->cookie_len)) {
845 /** Invalid cookie */
846 SILC_LOG_ERROR(("Responder modified our cookie and it must not do it"));
847 ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
848 silc_fsm_next(fsm, silc_ske_st_initiator_error);
849 return SILC_FSM_CONTINUE;
852 /* Check version string */
853 ske->remote_version = silc_memdup(payload->version, payload->version_len);
854 status = silc_ske_check_version(ske);
855 if (status != SILC_SKE_STATUS_OK) {
856 /** Version mismatch */
857 ske->status = status;
858 silc_fsm_next(fsm, silc_ske_st_initiator_error);
859 return SILC_FSM_CONTINUE;
862 /* Free our KE Start Payload context, we don't need it anymore. */
863 silc_ske_payload_start_free(ske->start_payload);
864 ske->start_payload = NULL;
866 /* Take the selected security properties into use while doing
867 the key exchange. This is used only while doing the key
869 ske->prop = prop = silc_calloc(1, sizeof(*prop));
872 prop->flags = payload->flags;
873 status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
874 if (status != SILC_SKE_STATUS_OK)
879 if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
880 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
883 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
884 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
887 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
888 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
891 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
892 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
896 /* Save remote's KE Start Payload */
897 ske->start_payload = payload;
899 /** Send KE Payload */
900 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
901 return SILC_FSM_CONTINUE;
905 silc_ske_payload_start_free(payload);
907 silc_ske_group_free(group);
910 silc_cipher_free(prop->cipher);
912 silc_hash_free(prop->hash);
914 silc_hmac_free(prop->hmac);
918 if (status == SILC_SKE_STATUS_OK)
919 status = SILC_SKE_STATUS_ERROR;
922 ske->status = status;
923 silc_fsm_next(fsm, silc_ske_st_initiator_error);
924 return SILC_FSM_CONTINUE;
927 /* Phase-2. Send KE payload */
929 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
931 SilcSKE ske = fsm_context;
932 SilcSKEStatus status;
933 SilcBuffer payload_buf;
935 SilcSKEKEPayload payload;
938 SILC_LOG_DEBUG(("Start"));
940 /* Create the random number x, 1 < x < q. */
941 x = silc_calloc(1, sizeof(*x));
944 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
945 silc_fsm_next(fsm, silc_ske_st_initiator_error);
946 return SILC_FSM_CONTINUE;
950 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
951 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
953 if (status != SILC_SKE_STATUS_OK) {
954 /** Error generating random number */
957 ske->status = status;
958 silc_fsm_next(fsm, silc_ske_st_initiator_error);
959 return SILC_FSM_CONTINUE;
962 /* Encode the result to Key Exchange Payload. */
964 payload = silc_calloc(1, sizeof(*payload));
969 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
970 silc_fsm_next(fsm, silc_ske_st_initiator_error);
971 return SILC_FSM_CONTINUE;
973 ske->ke1_payload = payload;
975 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
977 /* Do the Diffie Hellman computation, e = g ^ x mod p */
978 silc_mp_init(&payload->x);
979 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
980 &ske->prop->group->group);
983 if (ske->public_key) {
984 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
985 if (!payload->pk_data) {
986 /** Error encoding public key */
989 silc_mp_uninit(&payload->x);
991 ske->ke1_payload = NULL;
992 ske->status = SILC_SKE_STATUS_ERROR;
993 silc_fsm_next(fsm, silc_ske_st_initiator_error);
994 return SILC_FSM_CONTINUE;
996 payload->pk_len = pk_len;
998 payload->pk_type = ske->pk_type;
1000 /* Compute signature data if we are doing mutual authentication */
1001 if (ske->private_key &&
1002 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1003 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1004 SilcUInt32 hash_len, sign_len;
1006 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1007 SILC_LOG_DEBUG(("Computing HASH_i value"));
1009 /* Compute the hash value */
1010 memset(hash, 0, sizeof(hash));
1011 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1013 SILC_LOG_DEBUG(("Signing HASH_i value"));
1015 /* Sign the hash value */
1016 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1017 sizeof(sign) - 1, &sign_len, NULL)) {
1018 /** Error computing signature */
1021 silc_mp_uninit(&payload->x);
1022 silc_free(payload->pk_data);
1024 ske->ke1_payload = NULL;
1025 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1026 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1027 return SILC_FSM_CONTINUE;
1029 payload->sign_data = silc_memdup(sign, sign_len);
1030 payload->sign_len = sign_len;
1031 memset(sign, 0, sizeof(sign));
1034 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1035 if (status != SILC_SKE_STATUS_OK) {
1036 /** Error encoding KE payload */
1039 silc_mp_uninit(&payload->x);
1040 silc_free(payload->pk_data);
1041 silc_free(payload->sign_data);
1043 ske->ke1_payload = NULL;
1044 ske->status = status;
1045 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1046 return SILC_FSM_CONTINUE;
1051 /* Send the packet. */
1054 silc_buffer_free(payload_buf);
1056 /** Waiting responder's KE payload */
1057 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1058 return SILC_FSM_WAIT;
1061 /* Phase-3. Process responder's KE payload */
1063 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1065 SilcSKE ske = fsm_context;
1066 SilcSKEStatus status;
1067 SilcSKEKEPayload payload;
1069 SilcBuffer packet_buf = &ske->packet->buffer;
1071 SILC_LOG_DEBUG(("Start"));
1075 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1076 return SILC_FSM_CONTINUE;
1079 /* Decode the payload */
1080 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1081 if (status != SILC_SKE_STATUS_OK) {
1082 /** Error decoding KE payload */
1083 ske->status = status;
1084 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1085 return SILC_FSM_CONTINUE;
1087 ske->ke2_payload = payload;
1089 if (!payload->pk_data && ske->callbacks->verify_key) {
1090 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1091 "even though we require it"));
1092 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1096 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1098 /* Compute the shared secret key */
1099 KEY = silc_calloc(1, sizeof(*KEY));
1101 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1104 /* Decode the remote's public key */
1105 if (payload->pk_data &&
1106 !silc_pkcs_public_key_alloc(payload->pk_type,
1107 payload->pk_data, payload->pk_len,
1108 &ske->prop->public_key)) {
1109 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1110 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1114 if (ske->prop->public_key && ske->callbacks->verify_key) {
1115 SILC_LOG_DEBUG(("Verifying public key"));
1117 /** Waiting public key verification */
1118 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1119 SILC_FSM_CALL(ske->callbacks->verify_key(ske,
1121 ske->prop->public_key,
1122 ske->callbacks->context,
1123 silc_ske_pk_verified, NULL));
1127 /** Process key material */
1128 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1129 return SILC_FSM_CONTINUE;
1132 silc_ske_payload_ke_free(payload);
1133 ske->ke2_payload = NULL;
1135 silc_mp_uninit(ske->KEY);
1136 silc_free(ske->KEY);
1139 if (status == SILC_SKE_STATUS_OK)
1140 return SILC_SKE_STATUS_ERROR;
1143 ske->status = status;
1144 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1145 return SILC_FSM_CONTINUE;
1148 /* Process key material */
1150 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1152 SilcSKE ske = fsm_context;
1153 SilcSKEStatus status;
1154 SilcSKEKEPayload payload;
1155 unsigned char hash[SILC_HASH_MAXLEN];
1156 SilcUInt32 hash_len;
1157 int key_len, block_len;
1161 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1162 return SILC_FSM_CONTINUE;
1165 /* Check result of public key verification */
1166 if (ske->status != SILC_SKE_STATUS_OK) {
1167 /** Public key not verified */
1168 SILC_LOG_DEBUG(("Public key verification failed"));
1169 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1170 return SILC_FSM_CONTINUE;
1173 payload = ske->ke2_payload;
1175 if (ske->prop->public_key) {
1176 SILC_LOG_DEBUG(("Public key is authentic"));
1178 /* Compute the hash value */
1179 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1180 if (status != SILC_SKE_STATUS_OK)
1183 ske->hash = silc_memdup(hash, hash_len);
1184 ske->hash_len = hash_len;
1186 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1188 /* Verify signature */
1189 if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1190 payload->sign_len, hash, hash_len, NULL)) {
1191 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1192 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1196 SILC_LOG_DEBUG(("Signature is Ok"));
1198 memset(hash, 'F', hash_len);
1201 ske->status = SILC_SKE_STATUS_OK;
1203 /* Process key material */
1204 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1205 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1206 hash_len = silc_hash_len(ske->prop->hash);
1207 ske->keymat = silc_ske_process_key_material(ske, block_len,
1210 SILC_LOG_ERROR(("Error processing key material"));
1211 status = SILC_SKE_STATUS_ERROR;
1215 /* Send SUCCESS packet */
1218 /** Waiting completion */
1219 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1220 return SILC_FSM_WAIT;
1223 memset(hash, 'F', sizeof(hash));
1224 silc_ske_payload_ke_free(payload);
1225 ske->ke2_payload = NULL;
1227 silc_mp_uninit(ske->KEY);
1228 silc_free(ske->KEY);
1232 memset(ske->hash, 'F', hash_len);
1233 silc_free(ske->hash);
1237 if (status == SILC_SKE_STATUS_OK)
1238 status = SILC_SKE_STATUS_ERROR;
1241 ske->status = status;
1242 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1243 return SILC_FSM_CONTINUE;
1246 /* Protocol completed */
1248 SILC_FSM_STATE(silc_ske_st_initiator_end)
1250 SilcSKE ske = fsm_context;
1254 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1255 return SILC_FSM_CONTINUE;
1258 /* Call the completion callback */
1259 if (ske->callbacks->completed)
1260 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1262 return SILC_FSM_FINISH;
1265 /* Aborted by application */
1267 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1270 return SILC_FSM_FINISH;
1273 /* Error occurred */
1275 SILC_FSM_STATE(silc_ske_st_initiator_error)
1278 return SILC_FSM_FINISH;
1282 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1283 void *destructor_context)
1288 /* Starts the protocol as initiator */
1291 silc_ske_initiator(SilcSKE ske,
1292 SilcPacketStream stream,
1293 SilcSKEStartPayload start_payload)
1295 SILC_LOG_DEBUG(("Start SKE as initiator"));
1297 if (!ske || !stream || !start_payload)
1300 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1303 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1307 ske->start_payload = start_payload;
1309 /* Link to packet stream to get key exchange packets */
1310 ske->stream = stream;
1311 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1312 SILC_PACKET_KEY_EXCHANGE,
1313 SILC_PACKET_KEY_EXCHANGE_2,
1314 SILC_PACKET_SUCCESS,
1315 SILC_PACKET_FAILURE, -1);
1317 /* Start SKE as initiator */
1318 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1324 /******************************** Responder *********************************/
1326 SILC_FSM_STATE(silc_ske_st_responder_start);
1327 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1328 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1329 SILC_FSM_STATE(silc_ske_st_responder_phase3);
1330 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1331 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1332 SILC_FSM_STATE(silc_ske_st_responder_end);
1333 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1334 SILC_FSM_STATE(silc_ske_st_responder_failure);
1335 SILC_FSM_STATE(silc_ske_st_responder_error);
1337 /* Start protocol as responder. Wait initiator's start payload */
1339 SILC_FSM_STATE(silc_ske_st_responder_start)
1341 SilcSKE ske = fsm_context;
1343 SILC_LOG_DEBUG(("Start"));
1347 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1348 return SILC_FSM_CONTINUE;
1354 /** Wait for initiator */
1355 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1356 return SILC_FSM_WAIT;
1359 /* Decode initiator's start payload */
1361 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1363 SilcSKE ske = fsm_context;
1364 SilcSKEStatus status;
1365 SilcSKEStartPayload remote_payload = NULL, payload = NULL;
1366 SilcBuffer packet_buf = &ske->packet->buffer;
1368 SILC_LOG_DEBUG(("Start"));
1372 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1373 return SILC_FSM_CONTINUE;
1376 /* See if received failure from remote */
1377 if (ske->packet->type == SILC_PACKET_FAILURE) {
1378 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1379 return SILC_FSM_CONTINUE;
1382 /* Decode the payload */
1383 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1384 if (status != SILC_SKE_STATUS_OK) {
1385 /** Error decoding Start Payload */
1386 silc_packet_free(ske->packet);
1387 ske->status = status;
1388 silc_fsm_next(fsm, silc_ske_st_responder_error);
1389 return SILC_FSM_CONTINUE;
1392 /* Take a copy of the payload buffer for future use. It is used to
1393 compute the HASH value. */
1394 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1396 silc_packet_free(ske->packet);
1398 /* Force the mutual authentication flag if we want to do it. */
1399 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1400 SILC_LOG_DEBUG(("Force mutual authentication"));
1401 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1404 /* Force PFS flag if we require it */
1405 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1406 SILC_LOG_DEBUG(("Force PFS"));
1407 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1410 /* Disable IV Included flag if requested */
1411 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1412 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1413 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1414 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1417 /* Parse and select the security properties from the payload */
1418 payload = silc_calloc(1, sizeof(*payload));
1419 status = silc_ske_select_security_properties(ske, payload, remote_payload);
1420 if (status != SILC_SKE_STATUS_OK) {
1421 /** Error selecting proposal */
1423 silc_ske_payload_start_free(remote_payload);
1425 ske->status = status;
1426 silc_fsm_next(fsm, silc_ske_st_responder_error);
1427 return SILC_FSM_CONTINUE;
1430 ske->start_payload = payload;
1432 silc_ske_payload_start_free(remote_payload);
1434 /** Send proposal to initiator */
1435 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1436 return SILC_FSM_CONTINUE;
1439 /* Phase-2. Send Start Payload */
1441 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1443 SilcSKE ske = fsm_context;
1444 SilcSKEStatus status;
1445 SilcBuffer payload_buf;
1446 SilcSKESecurityProperties prop;
1447 SilcSKEDiffieHellmanGroup group = NULL;
1449 SILC_LOG_DEBUG(("Start"));
1451 /* Allocate security properties from the payload. These are allocated
1452 only for this negotiation and will be free'd after KE is over. */
1453 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1455 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1458 prop->flags = ske->start_payload->flags;
1459 status = silc_ske_group_get_by_name(ske->start_payload->ke_grp_list,
1461 if (status != SILC_SKE_STATUS_OK)
1464 prop->group = group;
1466 /* XXX these shouldn't be allocated before we know the remote's
1467 public key type. It's unnecessary to allocate these because the
1468 select_security_properties has succeeded already. */
1469 if (!silc_pkcs_find_algorithm(ske->start_payload->pkcs_alg_list, NULL)) {
1470 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1473 if (silc_cipher_alloc(ske->start_payload->enc_alg_list,
1474 &prop->cipher) == FALSE) {
1475 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1478 if (silc_hash_alloc(ske->start_payload->hash_alg_list,
1479 &prop->hash) == FALSE) {
1480 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1483 if (silc_hmac_alloc(ske->start_payload->hmac_alg_list, NULL,
1484 &prop->hmac) == FALSE) {
1485 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1489 /* Encode the payload */
1490 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1492 if (status != SILC_SKE_STATUS_OK)
1495 /* Send the packet. */
1496 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1497 payload_buf->data, silc_buffer_len(payload_buf)))
1500 silc_buffer_free(payload_buf);
1502 /** Waiting initiator's KE payload */
1503 silc_fsm_next(fsm, silc_ske_st_responder_phase3);
1504 return SILC_FSM_WAIT;
1508 silc_ske_group_free(group);
1511 silc_cipher_free(prop->cipher);
1513 silc_hash_free(prop->hash);
1515 silc_hmac_free(prop->hmac);
1519 if (status == SILC_SKE_STATUS_OK)
1520 status = SILC_SKE_STATUS_ERROR;
1523 ske->status = status;
1524 silc_fsm_next(fsm, silc_ske_st_responder_error);
1525 return SILC_FSM_CONTINUE;
1528 /* Phase-3. Decode initiator's KE payload */
1530 SILC_FSM_STATE(silc_ske_st_responder_phase3)
1532 SilcSKE ske = fsm_context;
1533 SilcSKEStatus status;
1534 SilcSKEKEPayload recv_payload;
1535 SilcBuffer packet_buf = &ske->packet->buffer;
1537 SILC_LOG_DEBUG(("Start"));
1541 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1542 return SILC_FSM_CONTINUE;
1545 /* See if received failure from remote */
1546 if (ske->packet->type == SILC_PACKET_FAILURE) {
1547 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1548 return SILC_FSM_CONTINUE;
1551 /* Decode Key Exchange Payload */
1552 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1553 if (status != SILC_SKE_STATUS_OK) {
1554 /** Error decoding KE payload */
1555 silc_packet_free(ske->packet);
1556 ske->status = status;
1557 silc_fsm_next(fsm, silc_ske_st_responder_error);
1558 return SILC_FSM_CONTINUE;
1561 ske->ke1_payload = recv_payload;
1563 silc_packet_free(ske->packet);
1565 /* Verify the received public key and verify the signature if we are
1566 doing mutual authentication. */
1567 if (ske->start_payload &&
1568 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1570 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1572 if (!recv_payload->pk_data && ske->callbacks->verify_key) {
1573 /** Public key not provided */
1574 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1575 "certificate), even though we require it"));
1576 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1577 silc_fsm_next(fsm, silc_ske_st_responder_error);
1578 return SILC_FSM_CONTINUE;
1581 /* Decode the remote's public key */
1582 if (recv_payload->pk_data &&
1583 !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1584 recv_payload->pk_data,
1585 recv_payload->pk_len,
1586 &ske->prop->public_key)) {
1587 /** Error decoding public key */
1588 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1589 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1590 silc_fsm_next(fsm, silc_ske_st_responder_error);
1591 return SILC_FSM_CONTINUE;
1594 if (ske->prop->public_key && ske->callbacks->verify_key) {
1595 SILC_LOG_DEBUG(("Verifying public key"));
1597 /** Waiting public key verification */
1598 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1599 SILC_FSM_CALL(ske->callbacks->verify_key(ske,
1600 recv_payload->pk_type,
1601 ske->prop->public_key,
1602 ske->callbacks->context,
1603 silc_ske_pk_verified, NULL));
1608 /** Generate KE2 payload */
1609 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1610 return SILC_FSM_CONTINUE;
1613 /* Phase-4. Generate KE2 payload */
1615 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1617 SilcSKE ske = fsm_context;
1618 SilcSKEStatus status;
1619 SilcSKEKEPayload recv_payload, send_payload;
1624 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1625 return SILC_FSM_CONTINUE;
1628 /* Check result of public key verification */
1629 if (ske->status != SILC_SKE_STATUS_OK) {
1630 /** Public key not verified */
1631 SILC_LOG_DEBUG(("Public key verification failed"));
1632 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1633 return SILC_FSM_CONTINUE;
1636 recv_payload = ske->ke1_payload;
1638 /* The public key verification was performed only if the Mutual
1639 Authentication flag is set. */
1640 if (ske->start_payload &&
1641 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1642 unsigned char hash[SILC_HASH_MAXLEN];
1643 SilcUInt32 hash_len;
1645 SILC_LOG_DEBUG(("Public key is authentic"));
1647 /* Compute the hash value */
1648 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1649 if (status != SILC_SKE_STATUS_OK) {
1650 /** Error computing hash */
1651 ske->status = status;
1652 silc_fsm_next(fsm, silc_ske_st_responder_error);
1653 return SILC_FSM_CONTINUE;
1656 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1658 /* Verify signature */
1659 if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
1660 recv_payload->sign_len, hash, hash_len, NULL)) {
1661 /** Incorrect signature */
1662 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1663 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1664 silc_fsm_next(fsm, silc_ske_st_responder_error);
1665 return SILC_FSM_CONTINUE;
1668 SILC_LOG_DEBUG(("Signature is Ok"));
1670 memset(hash, 'F', hash_len);
1673 /* Create the random number x, 1 < x < q. */
1674 x = silc_calloc(1, sizeof(*x));
1677 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1678 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1680 if (status != SILC_SKE_STATUS_OK) {
1681 /** Error generating random number */
1684 ske->status = status;
1685 silc_fsm_next(fsm, silc_ske_st_responder_error);
1686 return SILC_FSM_CONTINUE;
1689 /* Save the results for later processing */
1690 send_payload = silc_calloc(1, sizeof(*send_payload));
1692 ske->ke2_payload = send_payload;
1694 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1696 /* Do the Diffie Hellman computation, f = g ^ x mod p */
1697 silc_mp_init(&send_payload->x);
1698 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1699 &ske->prop->group->group);
1701 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1703 /* Compute the shared secret key */
1704 KEY = silc_calloc(1, sizeof(*KEY));
1706 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1707 &ske->prop->group->group);
1710 /** Send KE2 payload */
1711 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1712 return SILC_FSM_CONTINUE;
1715 /* Phase-5. Send KE2 payload */
1717 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1719 SilcSKE ske = fsm_context;
1720 SilcSKEStatus status;
1721 SilcBuffer payload_buf;
1722 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1723 SilcUInt32 hash_len, sign_len, pk_len;
1725 SILC_LOG_DEBUG(("Start"));
1727 if (ske->public_key && ske->private_key) {
1728 SILC_LOG_DEBUG(("Getting public key"));
1730 /* Get the public key */
1731 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1733 /** Error encoding public key */
1734 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1735 silc_fsm_next(fsm, silc_ske_st_responder_error);
1736 return SILC_FSM_CONTINUE;
1738 ske->ke2_payload->pk_data = pk;
1739 ske->ke2_payload->pk_len = pk_len;
1741 SILC_LOG_DEBUG(("Computing HASH value"));
1743 /* Compute the hash value */
1744 memset(hash, 0, sizeof(hash));
1745 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1746 if (status != SILC_SKE_STATUS_OK) {
1747 /** Error computing hash */
1748 ske->status = status;
1749 silc_fsm_next(fsm, silc_ske_st_responder_error);
1750 return SILC_FSM_CONTINUE;
1753 ske->hash = silc_memdup(hash, hash_len);
1754 ske->hash_len = hash_len;
1756 SILC_LOG_DEBUG(("Signing HASH value"));
1758 /* Sign the hash value */
1759 if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1760 sizeof(sign) - 1, &sign_len, NULL)) {
1761 /** Error computing signature */
1762 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1763 silc_fsm_next(fsm, silc_ske_st_responder_error);
1764 return SILC_FSM_CONTINUE;
1766 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
1767 ske->ke2_payload->sign_len = sign_len;
1768 memset(sign, 0, sizeof(sign));
1770 ske->ke2_payload->pk_type = ske->pk_type;
1772 /* Encode the Key Exchange Payload */
1773 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
1775 if (status != SILC_SKE_STATUS_OK) {
1776 /** Error encoding KE payload */
1777 ske->status = status;
1778 silc_fsm_next(fsm, silc_ske_st_responder_error);
1779 return SILC_FSM_CONTINUE;
1782 /* Send the packet. */
1783 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
1784 payload_buf->data, silc_buffer_len(payload_buf))) {
1785 ske->status = SILC_SKE_STATUS_ERROR;
1786 silc_fsm_next(fsm, silc_ske_st_responder_error);
1787 return SILC_FSM_CONTINUE;
1790 silc_buffer_free(payload_buf);
1792 /** Waiting completion */
1793 silc_fsm_next(fsm, silc_ske_st_responder_end);
1794 return SILC_FSM_WAIT;
1797 /* Protocol completed */
1799 SILC_FSM_STATE(silc_ske_st_responder_end)
1801 SilcSKE ske = fsm_context;
1802 unsigned char tmp[4];
1803 SilcUInt32 hash_len, key_len, block_len;
1807 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1808 return SILC_FSM_CONTINUE;
1811 /* Check the result of the protocol */
1812 if (ske->packet->type == SILC_PACKET_FAILURE) {
1813 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1814 return SILC_FSM_CONTINUE;
1816 silc_packet_free(ske->packet);
1818 /* Process key material */
1819 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1820 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1821 hash_len = silc_hash_len(ske->prop->hash);
1822 ske->keymat = silc_ske_process_key_material(ske, block_len,
1825 /** Error processing key material */
1826 ske->status = SILC_SKE_STATUS_ERROR;
1827 silc_fsm_next(fsm, silc_ske_st_responder_error);
1828 return SILC_FSM_CONTINUE;
1831 /* Send SUCCESS packet */
1832 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
1833 silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
1835 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1837 /* Call the completion callback */
1838 if (ske->callbacks->completed)
1839 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1840 ske->rekey, ske->callbacks->context);
1842 return SILC_FSM_FINISH;
1845 /* Aborted by application */
1847 SILC_FSM_STATE(silc_ske_st_responder_aborted)
1849 SilcSKE ske = fsm_context;
1850 unsigned char tmp[4];
1852 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
1854 /* Send FAILURE packet */
1855 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
1856 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
1858 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1860 return SILC_FSM_FINISH;
1863 /* Failure received from remote */
1865 SILC_FSM_STATE(silc_ske_st_responder_failure)
1867 SilcSKE ske = fsm_context;
1868 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1870 SILC_LOG_DEBUG(("Key exchange protocol failed"));
1872 if (silc_buffer_len(&ske->packet->buffer) == 4)
1873 SILC_GET32_MSB(error, ske->packet->buffer.data);
1874 ske->status = error;
1876 /* Call the completion callback */
1877 if (ske->callbacks->completed)
1878 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1879 ske->callbacks->context);
1881 silc_packet_free(ske->packet);
1882 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1884 return SILC_FSM_FINISH;
1887 /* Error occurred */
1889 SILC_FSM_STATE(silc_ske_st_responder_error)
1891 SilcSKE ske = fsm_context;
1892 unsigned char tmp[4];
1894 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
1895 ske->status, silc_ske_map_status(ske->status)));
1897 /* Send FAILURE packet */
1898 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
1899 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
1900 SILC_PUT32_MSB(ske->status, tmp);
1901 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
1903 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1905 return SILC_FSM_FINISH;
1909 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
1910 void *destructor_context)
1915 /* Starts the protocol as responder. */
1918 silc_ske_responder(SilcSKE ske,
1919 SilcPacketStream stream,
1920 const char *version,
1921 SilcSKESecurityPropertyFlag flags)
1923 SILC_LOG_DEBUG(("Start SKE as responder"));
1925 if (!ske || !stream || !version) {
1929 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1932 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
1937 ske->version = strdup(version);
1940 ske->responder = TRUE;
1942 /* Link to packet stream to get key exchange packets */
1943 ske->stream = stream;
1944 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1945 SILC_PACKET_KEY_EXCHANGE,
1946 SILC_PACKET_KEY_EXCHANGE_1,
1947 SILC_PACKET_SUCCESS,
1948 SILC_PACKET_FAILURE, -1);
1950 /* Start SKE as responder */
1951 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
1956 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
1958 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
1960 return SILC_FSM_FINISH;
1963 /* Starts rekey protocol as initiator */
1966 silc_ske_rekey_initiator(SilcSKE ske,
1967 SilcPacketStream stream,
1968 SilcSKERekeyMaterial rekey)
1970 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
1972 if (!ske || !stream || !rekey)
1975 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1978 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
1983 /* Link to packet stream to get key exchange packets */
1984 ske->stream = stream;
1986 /* Start SKE rekey as initiator */
1987 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
1992 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
1994 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
1996 return SILC_FSM_FINISH;
1999 /* Starts rekey protocol as responder */
2002 silc_ske_rekey_responder(SilcSKE ske,
2003 SilcPacketStream stream,
2004 SilcBuffer ke_payload,
2005 SilcSKERekeyMaterial rekey)
2007 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2009 if (!ske || !stream || !rekey)
2011 if (rekey->pfs && !ke_payload)
2014 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2017 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2020 // ske->packet_buf = ke_payload;
2023 /* Link to packet stream to get key exchange packets */
2024 ske->stream = stream;
2026 /* Start SKE rekey as responder */
2027 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2032 /* Assembles security properties */
2035 silc_ske_assemble_security_properties(SilcSKE ske,
2036 SilcSKESecurityPropertyFlag flags,
2037 const char *version)
2039 SilcSKEStartPayload rp;
2042 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
2044 rp = silc_calloc(1, sizeof(*rp));
2047 rp->flags = (unsigned char)flags;
2049 /* Set random cookie */
2050 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
2051 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
2052 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
2053 rp->cookie_len = SILC_SKE_COOKIE_LEN;
2056 rp->version = strdup(version);
2057 rp->version_len = strlen(version);
2059 /* Get supported Key Exhange groups */
2060 rp->ke_grp_list = silc_ske_get_supported_groups();
2061 rp->ke_grp_len = strlen(rp->ke_grp_list);
2063 /* Get supported PKCS algorithms */
2064 rp->pkcs_alg_list = silc_pkcs_get_supported();
2065 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
2067 /* Get supported encryption algorithms */
2068 rp->enc_alg_list = silc_cipher_get_supported();
2069 rp->enc_alg_len = strlen(rp->enc_alg_list);
2071 /* Get supported hash algorithms */
2072 rp->hash_alg_list = silc_hash_get_supported();
2073 rp->hash_alg_len = strlen(rp->hash_alg_list);
2075 /* Get supported HMACs */
2076 rp->hmac_alg_list = silc_hmac_get_supported();
2077 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
2080 /* Get supported compression algorithms */
2081 rp->comp_alg_list = strdup("none");
2082 rp->comp_alg_len = strlen("none");
2084 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
2085 2 + rp->version_len +
2086 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
2087 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
2088 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
2093 /* Processes the provided key material `data' as the SILC protocol
2094 specification defines. */
2097 silc_ske_process_key_material_data(unsigned char *data,
2098 SilcUInt32 data_len,
2099 SilcUInt32 req_iv_len,
2100 SilcUInt32 req_enc_key_len,
2101 SilcUInt32 req_hmac_key_len,
2105 unsigned char hashd[SILC_HASH_MAXLEN];
2106 SilcUInt32 hash_len = req_hmac_key_len;
2107 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2108 SilcSKEKeyMaterial key;
2110 SILC_LOG_DEBUG(("Start"));
2112 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2115 key = silc_calloc(1, sizeof(*key));
2119 buf = silc_buffer_alloc_size(1 + data_len);
2122 silc_buffer_format(buf,
2123 SILC_STR_UI_CHAR(0),
2124 SILC_STR_UI_XNSTRING(data, data_len),
2128 memset(hashd, 0, sizeof(hashd));
2130 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2131 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2132 memcpy(key->send_iv, hashd, req_iv_len);
2133 memset(hashd, 0, sizeof(hashd));
2135 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2136 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2137 memcpy(key->receive_iv, hashd, req_iv_len);
2138 key->iv_len = req_iv_len;
2140 /* Take the encryption keys. If requested key size is more than
2141 the size of hash length we will distribute more key material
2142 as protocol defines. */
2144 if (enc_key_len > hash_len) {
2146 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2147 k3[SILC_HASH_MAXLEN];
2148 unsigned char *dtmp;
2151 if (enc_key_len > (3 * hash_len))
2154 /* Take first round */
2155 memset(k1, 0, sizeof(k1));
2156 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2158 /* Take second round */
2159 dist = silc_buffer_alloc_size(data_len + hash_len);
2162 silc_buffer_format(dist,
2163 SILC_STR_UI_XNSTRING(data, data_len),
2164 SILC_STR_UI_XNSTRING(k1, hash_len),
2166 memset(k2, 0, sizeof(k2));
2167 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2169 /* Take third round */
2170 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2171 silc_buffer_pull_tail(dist, hash_len);
2172 silc_buffer_pull(dist, data_len + hash_len);
2173 silc_buffer_format(dist,
2174 SILC_STR_UI_XNSTRING(k2, hash_len),
2176 silc_buffer_push(dist, data_len + hash_len);
2177 memset(k3, 0, sizeof(k3));
2178 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2180 /* Then, save the keys */
2181 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2182 memcpy(dtmp, k1, hash_len);
2183 memcpy(dtmp + hash_len, k2, hash_len);
2184 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2186 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2187 memcpy(key->send_enc_key, dtmp, enc_key_len);
2188 key->enc_key_len = req_enc_key_len;
2190 memset(dtmp, 0, (3 * hash_len));
2191 memset(k1, 0, sizeof(k1));
2192 memset(k2, 0, sizeof(k2));
2193 memset(k3, 0, sizeof(k3));
2195 silc_buffer_clear(dist);
2196 silc_buffer_free(dist);
2198 /* Take normal hash as key */
2199 memset(hashd, 0, sizeof(hashd));
2200 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2201 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2202 memcpy(key->send_enc_key, hashd, enc_key_len);
2203 key->enc_key_len = req_enc_key_len;
2207 if (enc_key_len > hash_len) {
2209 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2210 k3[SILC_HASH_MAXLEN];
2211 unsigned char *dtmp;
2214 if (enc_key_len > (3 * hash_len))
2217 /* Take first round */
2218 memset(k1, 0, sizeof(k1));
2219 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2221 /* Take second round */
2222 dist = silc_buffer_alloc_size(data_len + hash_len);
2225 silc_buffer_format(dist,
2226 SILC_STR_UI_XNSTRING(data, data_len),
2227 SILC_STR_UI_XNSTRING(k1, hash_len),
2229 memset(k2, 0, sizeof(k2));
2230 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2232 /* Take third round */
2233 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2234 silc_buffer_pull_tail(dist, hash_len);
2235 silc_buffer_pull(dist, data_len + hash_len);
2236 silc_buffer_format(dist,
2237 SILC_STR_UI_XNSTRING(k2, hash_len),
2239 silc_buffer_push(dist, data_len + hash_len);
2240 memset(k3, 0, sizeof(k3));
2241 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2243 /* Then, save the keys */
2244 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2245 memcpy(dtmp, k1, hash_len);
2246 memcpy(dtmp + hash_len, k2, hash_len);
2247 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2249 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2250 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2251 key->enc_key_len = req_enc_key_len;
2253 memset(dtmp, 0, (3 * hash_len));
2254 memset(k1, 0, sizeof(k1));
2255 memset(k2, 0, sizeof(k2));
2256 memset(k3, 0, sizeof(k3));
2258 silc_buffer_clear(dist);
2259 silc_buffer_free(dist);
2261 /* Take normal hash as key */
2262 memset(hashd, 0, sizeof(hashd));
2263 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2264 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2265 memcpy(key->receive_enc_key, hashd, enc_key_len);
2266 key->enc_key_len = req_enc_key_len;
2269 /* Take HMAC keys */
2270 memset(hashd, 0, sizeof(hashd));
2272 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2273 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2274 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2275 memset(hashd, 0, sizeof(hashd));
2277 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2278 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2279 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2280 key->hmac_key_len = req_hmac_key_len;
2281 memset(hashd, 0, sizeof(hashd));
2283 silc_buffer_clear(buf);
2284 silc_buffer_free(buf);
2289 /* Processes negotiated key material as protocol specifies. This returns
2290 the actual keys to be used in the SILC. */
2293 silc_ske_process_key_material(SilcSKE ske,
2294 SilcUInt32 req_iv_len,
2295 SilcUInt32 req_enc_key_len,
2296 SilcUInt32 req_hmac_key_len)
2299 unsigned char *tmpbuf;
2301 SilcSKEKeyMaterial key;
2303 /* Encode KEY to binary data */
2304 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2306 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2309 silc_buffer_format(buf,
2310 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2311 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2314 /* Process the key material */
2315 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2316 req_iv_len, req_enc_key_len,
2320 memset(tmpbuf, 0, klen);
2322 silc_buffer_clear(buf);
2323 silc_buffer_free(buf);
2328 /* Free key material structure */
2330 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2336 silc_free(key->send_iv);
2337 if (key->receive_iv)
2338 silc_free(key->receive_iv);
2339 if (key->send_enc_key) {
2340 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2341 silc_free(key->send_enc_key);
2343 if (key->receive_enc_key) {
2344 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2345 silc_free(key->receive_enc_key);
2347 if (key->send_hmac_key) {
2348 memset(key->send_hmac_key, 0, key->hmac_key_len);
2349 silc_free(key->send_hmac_key);
2351 if (key->receive_hmac_key) {
2352 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2353 silc_free(key->receive_hmac_key);
2358 /* Set keys into use */
2360 SilcBool silc_ske_set_keys(SilcSKE ske,
2361 SilcSKEKeyMaterial keymat,
2362 SilcSKESecurityProperties prop,
2363 SilcCipher *ret_send_key,
2364 SilcCipher *ret_receive_key,
2365 SilcHmac *ret_hmac_send,
2366 SilcHmac *ret_hmac_receive,
2369 /* Allocate ciphers to be used in the communication */
2371 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2375 if (ret_receive_key) {
2376 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2381 /* Allocate HMACs */
2382 if (ret_hmac_send) {
2383 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2387 if (ret_hmac_receive) {
2388 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2393 /* Set key material */
2394 if (ske->responder) {
2395 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2396 keymat->enc_key_len);
2397 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2398 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2399 keymat->enc_key_len);
2400 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2401 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2402 keymat->hmac_key_len);
2403 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2404 keymat->hmac_key_len);
2406 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2407 keymat->enc_key_len);
2408 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2409 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2410 keymat->enc_key_len);
2411 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2412 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2413 keymat->hmac_key_len);
2414 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2415 keymat->hmac_key_len);
2420 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2424 SILC_LOG_INFO(("Security properties: %s %s %s %s",
2425 ret_send_key ? silc_cipher_get_name(*ret_send_key) : "??",
2426 ret_hmac_send ? silc_hmac_get_name(*ret_hmac_send) : "??",
2427 ret_hash ? silc_hash_get_name(*ret_hash) : "??",
2428 ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : ""));
2433 const char *silc_ske_status_string[] =
2437 "Unkown error occurred",
2438 "Bad payload in packet",
2439 "Unsupported group",
2440 "Unsupported cipher",
2442 "Unsupported hash function",
2444 "Unsupported public key (or certificate)",
2445 "Incorrect signature",
2446 "Bad or unsupported version",
2450 "Remote did not provide public key",
2451 "Bad reserved field in packet",
2452 "Bad payload length in packet",
2453 "Error computing signature",
2454 "System out of memory",
2459 /* Maps status to readable string and returns the string. If string is not
2460 found and empty character string ("") is returned. */
2462 const char *silc_ske_map_status(SilcSKEStatus status)
2466 for (i = 0; silc_ske_status_string[i]; i++)
2468 return silc_ske_status_string[i];
2473 /* Parses remote host's version string. */
2475 SilcBool silc_ske_parse_version(SilcSKE ske,
2476 SilcUInt32 *protocol_version,
2477 char **protocol_version_string,
2478 SilcUInt32 *software_version,
2479 char **software_version_string,
2480 char **vendor_version)
2482 return silc_parse_version_string(ske->remote_version,
2484 protocol_version_string,
2486 software_version_string,