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_is_supported(item) == TRUE) {
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;
643 silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
645 *return_hash_len = silc_hash_len(ske->prop->hash);
647 if (initiator == FALSE) {
648 SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
650 SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
653 silc_buffer_free(buf);
659 /******************************* Protocol API *******************************/
661 /* Allocates new SKE object. */
663 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
664 SilcPublicKey public_key, SilcPrivateKey private_key,
669 SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
671 if (!rng || !schedule)
674 ske = silc_calloc(1, sizeof(*ske));
677 ske->status = SILC_SKE_STATUS_OK;
679 ske->user_data = context;
680 ske->schedule = schedule;
681 ske->public_key = public_key;
682 ske->private_key = private_key;
683 ske->pk_type = SILC_SKE_PK_TYPE_SILC;
688 /* Free's SKE object. */
690 void silc_ske_free(SilcSKE ske)
692 SILC_LOG_DEBUG(("Freeing Key Exchange object"));
695 /* Free start payload */
696 if (ske->start_payload)
697 silc_ske_payload_start_free(ske->start_payload);
699 /* Free KE payload */
700 if (ske->ke1_payload)
701 silc_ske_payload_ke_free(ske->ke1_payload);
702 if (ske->ke2_payload)
703 silc_ske_payload_ke_free(ske->ke2_payload);
704 silc_free(ske->remote_version);
708 if (ske->prop->group)
709 silc_ske_group_free(ske->prop->group);
711 silc_pkcs_free(ske->prop->pkcs);
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_alloc(payload->pkcs_alg_list, ske->pk_type,
880 &prop->pkcs) == FALSE) {
881 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
884 if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
885 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
888 if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
889 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
892 if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
893 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
897 /* Save remote's KE Start Payload */
898 ske->start_payload = payload;
900 /** Send KE Payload */
901 silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
902 return SILC_FSM_CONTINUE;
906 silc_ske_payload_start_free(payload);
908 silc_ske_group_free(group);
911 silc_pkcs_free(prop->pkcs);
913 silc_cipher_free(prop->cipher);
915 silc_hash_free(prop->hash);
917 silc_hmac_free(prop->hmac);
921 if (status == SILC_SKE_STATUS_OK)
922 status = SILC_SKE_STATUS_ERROR;
925 ske->status = status;
926 silc_fsm_next(fsm, silc_ske_st_initiator_error);
927 return SILC_FSM_CONTINUE;
930 /* Phase-2. Send KE payload */
932 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
934 SilcSKE ske = fsm_context;
935 SilcSKEStatus status;
936 SilcBuffer payload_buf;
938 SilcSKEKEPayload payload;
941 SILC_LOG_DEBUG(("Start"));
943 /* Create the random number x, 1 < x < q. */
944 x = silc_calloc(1, sizeof(*x));
947 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
948 silc_fsm_next(fsm, silc_ske_st_initiator_error);
949 return SILC_FSM_CONTINUE;
953 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
954 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
956 if (status != SILC_SKE_STATUS_OK) {
957 /** Error generating random number */
960 ske->status = status;
961 silc_fsm_next(fsm, silc_ske_st_initiator_error);
962 return SILC_FSM_CONTINUE;
965 /* Encode the result to Key Exchange Payload. */
967 payload = silc_calloc(1, sizeof(*payload));
972 ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
973 silc_fsm_next(fsm, silc_ske_st_initiator_error);
974 return SILC_FSM_CONTINUE;
976 ske->ke1_payload = payload;
978 SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
980 /* Do the Diffie Hellman computation, e = g ^ x mod p */
981 silc_mp_init(&payload->x);
982 silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
983 &ske->prop->group->group);
986 if (ske->public_key) {
987 payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
988 if (!payload->pk_data) {
989 /** Error encoding public key */
992 silc_mp_uninit(&payload->x);
994 ske->ke1_payload = NULL;
995 ske->status = SILC_SKE_STATUS_ERROR;
996 silc_fsm_next(fsm, silc_ske_st_initiator_error);
997 return SILC_FSM_CONTINUE;
999 payload->pk_len = pk_len;
1001 payload->pk_type = ske->pk_type;
1003 /* Compute signature data if we are doing mutual authentication */
1004 if (ske->private_key &&
1005 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1006 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1007 SilcUInt32 hash_len, sign_len;
1009 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1010 SILC_LOG_DEBUG(("Computing HASH_i value"));
1012 /* Compute the hash value */
1013 memset(hash, 0, sizeof(hash));
1014 silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1016 SILC_LOG_DEBUG(("Signing HASH_i value"));
1018 /* Sign the hash value */
1019 silc_pkcs_private_key_data_set(ske->prop->pkcs, ske->private_key->prv,
1020 ske->private_key->prv_len);
1021 if (silc_pkcs_get_key_len(ske->prop->pkcs) / 8 > sizeof(sign) - 1 ||
1022 !silc_pkcs_sign(ske->prop->pkcs, hash, hash_len, sign, &sign_len)) {
1023 /** Error computing signature */
1026 silc_mp_uninit(&payload->x);
1027 silc_free(payload->pk_data);
1029 ske->ke1_payload = NULL;
1030 ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1031 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1032 return SILC_FSM_CONTINUE;
1034 payload->sign_data = silc_memdup(sign, sign_len);
1035 payload->sign_len = sign_len;
1036 memset(sign, 0, sizeof(sign));
1039 status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1040 if (status != SILC_SKE_STATUS_OK) {
1041 /** Error encoding KE payload */
1044 silc_mp_uninit(&payload->x);
1045 silc_free(payload->pk_data);
1046 silc_free(payload->sign_data);
1048 ske->ke1_payload = NULL;
1049 ske->status = status;
1050 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1051 return SILC_FSM_CONTINUE;
1056 /* Send the packet. */
1059 silc_buffer_free(payload_buf);
1061 /** Waiting responder's KE payload */
1062 silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1063 return SILC_FSM_WAIT;
1066 /* Phase-3. Process responder's KE payload */
1068 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1070 SilcSKE ske = fsm_context;
1071 SilcSKEStatus status;
1072 SilcSKEKEPayload payload;
1074 SilcBuffer packet_buf = &ske->packet->buffer;
1076 SILC_LOG_DEBUG(("Start"));
1080 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1081 return SILC_FSM_CONTINUE;
1084 /* Decode the payload */
1085 status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1086 if (status != SILC_SKE_STATUS_OK) {
1087 /** Error decoding KE payload */
1088 ske->status = status;
1089 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1090 return SILC_FSM_CONTINUE;
1092 ske->ke2_payload = payload;
1094 if (!payload->pk_data && ske->callbacks->verify_key) {
1095 SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1096 "even though we require it"));
1097 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1101 SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1103 /* Compute the shared secret key */
1104 KEY = silc_calloc(1, sizeof(*KEY));
1106 silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1109 if (payload->pk_data && ske->callbacks->verify_key) {
1110 SILC_LOG_DEBUG(("Verifying public key"));
1112 /** Waiting public key verification */
1113 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1114 SILC_FSM_CALL(ske->callbacks->verify_key(ske, payload->pk_data,
1117 ske->callbacks->context,
1118 silc_ske_pk_verified, NULL));
1122 /** Process key material */
1123 silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1124 return SILC_FSM_CONTINUE;
1127 silc_ske_payload_ke_free(payload);
1128 ske->ke2_payload = NULL;
1130 silc_mp_uninit(ske->KEY);
1131 silc_free(ske->KEY);
1134 if (status == SILC_SKE_STATUS_OK)
1135 return SILC_SKE_STATUS_ERROR;
1138 ske->status = status;
1139 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1140 return SILC_FSM_CONTINUE;
1143 /* Process key material */
1145 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1147 SilcSKE ske = fsm_context;
1148 SilcSKEStatus status;
1149 SilcSKEKEPayload payload;
1150 unsigned char hash[SILC_HASH_MAXLEN];
1151 SilcUInt32 hash_len;
1152 SilcPublicKey public_key = NULL;
1153 int key_len, block_len;
1157 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1158 return SILC_FSM_CONTINUE;
1161 /* Check result of public key verification */
1162 if (ske->status != SILC_SKE_STATUS_OK) {
1163 /** Public key not verified */
1164 SILC_LOG_DEBUG(("Public key verification failed"));
1165 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1166 return SILC_FSM_CONTINUE;
1169 payload = ske->ke2_payload;
1171 if (payload->pk_data) {
1172 /* Decode the public key */
1173 if (!silc_pkcs_public_key_decode(payload->pk_data, payload->pk_len,
1175 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1176 status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1180 SILC_LOG_DEBUG(("Public key is authentic"));
1182 /* Compute the hash value */
1183 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1184 if (status != SILC_SKE_STATUS_OK)
1187 ske->hash = silc_memdup(hash, hash_len);
1188 ske->hash_len = hash_len;
1190 SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1192 /* Verify signature */
1193 silc_pkcs_public_key_set(ske->prop->pkcs, public_key);
1194 if (silc_pkcs_verify(ske->prop->pkcs, payload->sign_data,
1195 payload->sign_len, hash, hash_len) == FALSE) {
1196 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1197 status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1201 SILC_LOG_DEBUG(("Signature is Ok"));
1203 silc_pkcs_public_key_free(public_key);
1204 memset(hash, 'F', hash_len);
1207 ske->status = SILC_SKE_STATUS_OK;
1209 /* Process key material */
1210 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1211 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1212 hash_len = silc_hash_len(ske->prop->hash);
1213 ske->keymat = silc_ske_process_key_material(ske, block_len,
1216 SILC_LOG_ERROR(("Error processing key material"));
1217 status = SILC_SKE_STATUS_ERROR;
1221 /* Send SUCCESS packet */
1224 /** Waiting completion */
1225 silc_fsm_next(fsm, silc_ske_st_initiator_end);
1226 return SILC_FSM_WAIT;
1229 memset(hash, 'F', sizeof(hash));
1230 silc_ske_payload_ke_free(payload);
1231 ske->ke2_payload = NULL;
1233 silc_mp_uninit(ske->KEY);
1234 silc_free(ske->KEY);
1238 silc_pkcs_public_key_free(public_key);
1241 memset(ske->hash, 'F', hash_len);
1242 silc_free(ske->hash);
1246 if (status == SILC_SKE_STATUS_OK)
1247 status = SILC_SKE_STATUS_ERROR;
1250 ske->status = status;
1251 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1252 return SILC_FSM_CONTINUE;
1255 /* Protocol completed */
1257 SILC_FSM_STATE(silc_ske_st_initiator_end)
1259 SilcSKE ske = fsm_context;
1263 silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1264 return SILC_FSM_CONTINUE;
1267 /* Call the completion callback */
1268 if (ske->callbacks->completed)
1269 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1271 return SILC_FSM_FINISH;
1274 /* Aborted by application */
1276 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1279 return SILC_FSM_FINISH;
1282 /* Error occurred */
1284 SILC_FSM_STATE(silc_ske_st_initiator_error)
1287 return SILC_FSM_FINISH;
1291 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1292 void *destructor_context)
1297 /* Starts the protocol as initiator */
1300 silc_ske_initiator(SilcSKE ske,
1301 SilcPacketStream stream,
1302 SilcSKEStartPayload start_payload)
1304 SILC_LOG_DEBUG(("Start SKE as initiator"));
1306 if (!ske || !stream || !start_payload)
1309 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1312 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1316 ske->start_payload = start_payload;
1318 /* Link to packet stream to get key exchange packets */
1319 ske->stream = stream;
1320 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1321 SILC_PACKET_KEY_EXCHANGE,
1322 SILC_PACKET_KEY_EXCHANGE_2,
1323 SILC_PACKET_SUCCESS,
1324 SILC_PACKET_FAILURE, -1);
1326 /* Start SKE as initiator */
1327 silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1333 /******************************** Responder *********************************/
1335 SILC_FSM_STATE(silc_ske_st_responder_start);
1336 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1337 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1338 SILC_FSM_STATE(silc_ske_st_responder_phase3);
1339 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1340 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1341 SILC_FSM_STATE(silc_ske_st_responder_end);
1342 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1343 SILC_FSM_STATE(silc_ske_st_responder_failure);
1344 SILC_FSM_STATE(silc_ske_st_responder_error);
1346 /* Start protocol as responder. Wait initiator's start payload */
1348 SILC_FSM_STATE(silc_ske_st_responder_start)
1350 SilcSKE ske = fsm_context;
1352 SILC_LOG_DEBUG(("Start"));
1356 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1357 return SILC_FSM_CONTINUE;
1363 /** Wait for initiator */
1364 silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1365 return SILC_FSM_WAIT;
1368 /* Decode initiator's start payload */
1370 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1372 SilcSKE ske = fsm_context;
1373 SilcSKEStatus status;
1374 SilcSKEStartPayload remote_payload = NULL, payload = NULL;
1375 SilcBuffer packet_buf = &ske->packet->buffer;
1377 SILC_LOG_DEBUG(("Start"));
1381 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1382 return SILC_FSM_CONTINUE;
1385 /* See if received failure from remote */
1386 if (ske->packet->type == SILC_PACKET_FAILURE) {
1387 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1388 return SILC_FSM_CONTINUE;
1391 /* Decode the payload */
1392 status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1393 if (status != SILC_SKE_STATUS_OK) {
1394 /** Error decoding Start Payload */
1395 silc_packet_free(ske->packet);
1396 ske->status = status;
1397 silc_fsm_next(fsm, silc_ske_st_responder_error);
1398 return SILC_FSM_CONTINUE;
1401 /* Take a copy of the payload buffer for future use. It is used to
1402 compute the HASH value. */
1403 ske->start_payload_copy = silc_buffer_copy(packet_buf);
1405 silc_packet_free(ske->packet);
1407 /* Force the mutual authentication flag if we want to do it. */
1408 if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1409 SILC_LOG_DEBUG(("Force mutual authentication"));
1410 remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1413 /* Force PFS flag if we require it */
1414 if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1415 SILC_LOG_DEBUG(("Force PFS"));
1416 remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1419 /* Disable IV Included flag if requested */
1420 if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1421 !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1422 SILC_LOG_DEBUG(("We do not support IV Included flag"));
1423 remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1426 /* Parse and select the security properties from the payload */
1427 payload = silc_calloc(1, sizeof(*payload));
1428 status = silc_ske_select_security_properties(ske, payload, remote_payload);
1429 if (status != SILC_SKE_STATUS_OK) {
1430 /** Error selecting proposal */
1432 silc_ske_payload_start_free(remote_payload);
1434 ske->status = status;
1435 silc_fsm_next(fsm, silc_ske_st_responder_error);
1436 return SILC_FSM_CONTINUE;
1439 ske->start_payload = payload;
1441 silc_ske_payload_start_free(remote_payload);
1443 /** Send proposal to initiator */
1444 silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1445 return SILC_FSM_CONTINUE;
1448 /* Phase-2. Send Start Payload */
1450 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1452 SilcSKE ske = fsm_context;
1453 SilcSKEStatus status;
1454 SilcBuffer payload_buf;
1455 SilcSKESecurityProperties prop;
1456 SilcSKEDiffieHellmanGroup group = NULL;
1458 SILC_LOG_DEBUG(("Start"));
1460 /* Allocate security properties from the payload. These are allocated
1461 only for this negotiation and will be free'd after KE is over. */
1462 ske->prop = prop = silc_calloc(1, sizeof(*prop));
1464 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1467 prop->flags = ske->start_payload->flags;
1468 status = silc_ske_group_get_by_name(ske->start_payload->ke_grp_list,
1470 if (status != SILC_SKE_STATUS_OK)
1473 prop->group = group;
1475 /* XXX these shouldn't be allocated before we know the remote's
1476 public key type. It's unnecessary to allocate these because the
1477 select_security_properties has succeeded already. */
1478 if (silc_pkcs_alloc(ske->start_payload->pkcs_alg_list,
1479 SILC_PKCS_SILC, &prop->pkcs) == FALSE) {
1480 status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1483 if (silc_cipher_alloc(ske->start_payload->enc_alg_list,
1484 &prop->cipher) == FALSE) {
1485 status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1488 if (silc_hash_alloc(ske->start_payload->hash_alg_list,
1489 &prop->hash) == FALSE) {
1490 status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1493 if (silc_hmac_alloc(ske->start_payload->hmac_alg_list, NULL,
1494 &prop->hmac) == FALSE) {
1495 status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1499 /* Encode the payload */
1500 status = silc_ske_payload_start_encode(ske, ske->start_payload,
1502 if (status != SILC_SKE_STATUS_OK)
1505 /* Send the packet. */
1506 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1507 payload_buf->data, silc_buffer_len(payload_buf)))
1510 silc_buffer_free(payload_buf);
1512 /** Waiting initiator's KE payload */
1513 silc_fsm_next(fsm, silc_ske_st_responder_phase3);
1514 return SILC_FSM_WAIT;
1518 silc_ske_group_free(group);
1521 silc_pkcs_free(prop->pkcs);
1523 silc_cipher_free(prop->cipher);
1525 silc_hash_free(prop->hash);
1527 silc_hmac_free(prop->hmac);
1531 if (status == SILC_SKE_STATUS_OK)
1532 status = SILC_SKE_STATUS_ERROR;
1535 ske->status = status;
1536 silc_fsm_next(fsm, silc_ske_st_responder_error);
1537 return SILC_FSM_CONTINUE;
1540 /* Phase-3. Decode initiator's KE payload */
1542 SILC_FSM_STATE(silc_ske_st_responder_phase3)
1544 SilcSKE ske = fsm_context;
1545 SilcSKEStatus status;
1546 SilcSKEKEPayload recv_payload;
1547 SilcBuffer packet_buf = &ske->packet->buffer;
1549 SILC_LOG_DEBUG(("Start"));
1553 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1554 return SILC_FSM_CONTINUE;
1557 /* See if received failure from remote */
1558 if (ske->packet->type == SILC_PACKET_FAILURE) {
1559 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1560 return SILC_FSM_CONTINUE;
1563 /* Decode Key Exchange Payload */
1564 status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1565 if (status != SILC_SKE_STATUS_OK) {
1566 /** Error decoding KE payload */
1567 silc_packet_free(ske->packet);
1568 ske->status = status;
1569 silc_fsm_next(fsm, silc_ske_st_responder_error);
1570 return SILC_FSM_CONTINUE;
1573 ske->ke1_payload = recv_payload;
1575 silc_packet_free(ske->packet);
1577 /* Verify the received public key and verify the signature if we are
1578 doing mutual authentication. */
1579 if (ske->start_payload &&
1580 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1582 SILC_LOG_DEBUG(("We are doing mutual authentication"));
1584 if (!recv_payload->pk_data && ske->callbacks->verify_key) {
1585 /** Public key not provided */
1586 SILC_LOG_ERROR(("Remote end did not send its public key (or "
1587 "certificate), even though we require it"));
1588 ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1589 silc_fsm_next(fsm, silc_ske_st_responder_error);
1590 return SILC_FSM_CONTINUE;
1593 if (recv_payload->pk_data && ske->callbacks->verify_key) {
1594 SILC_LOG_DEBUG(("Verifying public key"));
1596 /** Waiting public key verification */
1597 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1598 SILC_FSM_CALL(ske->callbacks->verify_key(ske, recv_payload->pk_data,
1599 recv_payload->pk_len,
1600 recv_payload->pk_type,
1601 ske->callbacks->context,
1602 silc_ske_pk_verified, NULL));
1607 /** Generate KE2 payload */
1608 silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1609 return SILC_FSM_CONTINUE;
1612 /* Phase-4. Generate KE2 payload */
1614 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1616 SilcSKE ske = fsm_context;
1617 SilcSKEStatus status;
1618 SilcSKEKEPayload recv_payload, send_payload;
1623 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1624 return SILC_FSM_CONTINUE;
1627 /* Check result of public key verification */
1628 if (ske->status != SILC_SKE_STATUS_OK) {
1629 /** Public key not verified */
1630 SILC_LOG_DEBUG(("Public key verification failed"));
1631 silc_fsm_next(fsm, silc_ske_st_initiator_error);
1632 return SILC_FSM_CONTINUE;
1635 recv_payload = ske->ke1_payload;
1637 /* The public key verification was performed only if the Mutual
1638 Authentication flag is set. */
1639 if (ske->start_payload &&
1640 ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1641 SilcPublicKey public_key = NULL;
1642 unsigned char hash[SILC_HASH_MAXLEN];
1643 SilcUInt32 hash_len;
1645 /* Decode the public key */
1646 if (!silc_pkcs_public_key_decode(recv_payload->pk_data,
1647 recv_payload->pk_len,
1649 /** Error decoding public key */
1650 SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1651 ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1652 silc_fsm_next(fsm, silc_ske_st_responder_error);
1653 return SILC_FSM_CONTINUE;
1656 SILC_LOG_DEBUG(("Public key is authentic"));
1658 /* Compute the hash value */
1659 status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1660 if (status != SILC_SKE_STATUS_OK) {
1661 /** Error computing hash */
1662 ske->status = status;
1663 silc_fsm_next(fsm, silc_ske_st_responder_error);
1664 return SILC_FSM_CONTINUE;
1667 SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1669 /* Verify signature */
1670 silc_pkcs_public_key_set(ske->prop->pkcs, public_key);
1671 if (silc_pkcs_verify(ske->prop->pkcs, recv_payload->sign_data,
1672 recv_payload->sign_len, hash, hash_len) == FALSE) {
1673 /** Incorrect signature */
1674 SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1675 ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1676 silc_fsm_next(fsm, silc_ske_st_responder_error);
1677 return SILC_FSM_CONTINUE;
1680 SILC_LOG_DEBUG(("Signature is Ok"));
1682 silc_pkcs_public_key_free(public_key);
1683 memset(hash, 'F', hash_len);
1686 /* Create the random number x, 1 < x < q. */
1687 x = silc_calloc(1, sizeof(*x));
1690 silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1691 silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1693 if (status != SILC_SKE_STATUS_OK) {
1694 /** Error generating random number */
1697 ske->status = status;
1698 silc_fsm_next(fsm, silc_ske_st_responder_error);
1699 return SILC_FSM_CONTINUE;
1702 /* Save the results for later processing */
1703 send_payload = silc_calloc(1, sizeof(*send_payload));
1705 ske->ke2_payload = send_payload;
1707 SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1709 /* Do the Diffie Hellman computation, f = g ^ x mod p */
1710 silc_mp_init(&send_payload->x);
1711 silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1712 &ske->prop->group->group);
1714 SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1716 /* Compute the shared secret key */
1717 KEY = silc_calloc(1, sizeof(*KEY));
1719 silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1720 &ske->prop->group->group);
1723 /** Send KE2 payload */
1724 silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1725 return SILC_FSM_CONTINUE;
1728 /* Phase-5. Send KE2 payload */
1730 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1732 SilcSKE ske = fsm_context;
1733 SilcSKEStatus status;
1734 SilcBuffer payload_buf;
1735 unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1736 SilcUInt32 hash_len, sign_len, pk_len;
1738 SILC_LOG_DEBUG(("Start"));
1740 if (ske->public_key && ske->private_key) {
1741 SILC_LOG_DEBUG(("Getting public key"));
1743 /* Get the public key */
1744 pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1746 /** Error encoding public key */
1747 status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1748 silc_fsm_next(fsm, silc_ske_st_responder_error);
1749 return SILC_FSM_CONTINUE;
1751 ske->ke2_payload->pk_data = pk;
1752 ske->ke2_payload->pk_len = pk_len;
1754 SILC_LOG_DEBUG(("Computing HASH value"));
1756 /* Compute the hash value */
1757 memset(hash, 0, sizeof(hash));
1758 status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1759 if (status != SILC_SKE_STATUS_OK) {
1760 /** Error computing hash */
1761 ske->status = status;
1762 silc_fsm_next(fsm, silc_ske_st_responder_error);
1763 return SILC_FSM_CONTINUE;
1766 ske->hash = silc_memdup(hash, hash_len);
1767 ske->hash_len = hash_len;
1769 SILC_LOG_DEBUG(("Signing HASH value"));
1771 /* Sign the hash value */
1772 silc_pkcs_private_key_data_set(ske->prop->pkcs, ske->private_key->prv,
1773 ske->private_key->prv_len);
1774 if (silc_pkcs_get_key_len(ske->prop->pkcs) / 8 > sizeof(sign) - 1 ||
1775 !silc_pkcs_sign(ske->prop->pkcs, hash, hash_len, sign, &sign_len)) {
1776 /** Error computing signature */
1777 status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1778 silc_fsm_next(fsm, silc_ske_st_responder_error);
1779 return SILC_FSM_CONTINUE;
1781 ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
1782 ske->ke2_payload->sign_len = sign_len;
1783 memset(sign, 0, sizeof(sign));
1785 ske->ke2_payload->pk_type = ske->pk_type;
1787 /* Encode the Key Exchange Payload */
1788 status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
1790 if (status != SILC_SKE_STATUS_OK) {
1791 /** Error encoding KE payload */
1792 ske->status = status;
1793 silc_fsm_next(fsm, silc_ske_st_responder_error);
1794 return SILC_FSM_CONTINUE;
1797 /* Send the packet. */
1798 if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
1799 payload_buf->data, silc_buffer_len(payload_buf))) {
1800 ske->status = SILC_SKE_STATUS_ERROR;
1801 silc_fsm_next(fsm, silc_ske_st_responder_error);
1802 return SILC_FSM_CONTINUE;
1805 silc_buffer_free(payload_buf);
1807 /** Waiting completion */
1808 silc_fsm_next(fsm, silc_ske_st_responder_end);
1809 return SILC_FSM_WAIT;
1812 /* Protocol completed */
1814 SILC_FSM_STATE(silc_ske_st_responder_end)
1816 SilcSKE ske = fsm_context;
1817 unsigned char tmp[4];
1818 SilcUInt32 hash_len, key_len, block_len;
1822 silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1823 return SILC_FSM_CONTINUE;
1826 /* Check the result of the protocol */
1827 if (ske->packet->type == SILC_PACKET_FAILURE) {
1828 silc_fsm_next(fsm, silc_ske_st_responder_failure);
1829 return SILC_FSM_CONTINUE;
1831 silc_packet_free(ske->packet);
1833 /* Process key material */
1834 key_len = silc_cipher_get_key_len(ske->prop->cipher);
1835 block_len = silc_cipher_get_key_len(ske->prop->cipher);
1836 hash_len = silc_hash_len(ske->prop->hash);
1837 ske->keymat = silc_ske_process_key_material(ske, block_len,
1840 /** Error processing key material */
1841 ske->status = SILC_SKE_STATUS_ERROR;
1842 silc_fsm_next(fsm, silc_ske_st_responder_error);
1843 return SILC_FSM_CONTINUE;
1846 /* Send SUCCESS packet */
1847 SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
1848 silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
1850 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1852 /* Call the completion callback */
1853 if (ske->callbacks->completed)
1854 ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1855 ske->rekey, ske->callbacks->context);
1857 return SILC_FSM_FINISH;
1860 /* Aborted by application */
1862 SILC_FSM_STATE(silc_ske_st_responder_aborted)
1864 SilcSKE ske = fsm_context;
1865 unsigned char tmp[4];
1867 SILC_LOG_DEBUG(("Key exchange protocol aborted"));
1869 /* Send FAILURE packet */
1870 SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
1871 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
1873 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1875 return SILC_FSM_FINISH;
1878 /* Failure received from remote */
1880 SILC_FSM_STATE(silc_ske_st_responder_failure)
1882 SilcSKE ske = fsm_context;
1883 SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1885 SILC_LOG_DEBUG(("Key exchange protocol failed"));
1887 if (silc_buffer_len(&ske->packet->buffer) == 4)
1888 SILC_GET32_MSB(error, ske->packet->buffer.data);
1889 ske->status = error;
1891 /* Call the completion callback */
1892 if (ske->callbacks->completed)
1893 ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1894 ske->callbacks->context);
1896 silc_packet_free(ske->packet);
1897 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1899 return SILC_FSM_FINISH;
1902 /* Error occurred */
1904 SILC_FSM_STATE(silc_ske_st_responder_error)
1906 SilcSKE ske = fsm_context;
1907 unsigned char tmp[4];
1909 SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
1910 ske->status, silc_ske_map_status(ske->status)));
1912 /* Send FAILURE packet */
1913 if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
1914 ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
1915 SILC_PUT32_MSB(ske->status, tmp);
1916 silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
1918 silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1920 return SILC_FSM_FINISH;
1924 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
1925 void *destructor_context)
1930 /* Starts the protocol as responder. */
1933 silc_ske_responder(SilcSKE ske,
1934 SilcPacketStream stream,
1935 const char *version,
1936 SilcSKESecurityPropertyFlag flags)
1938 SILC_LOG_DEBUG(("Start SKE as responder"));
1940 if (!ske || !stream || !version) {
1944 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1947 if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
1952 ske->version = strdup(version);
1955 ske->responder = TRUE;
1957 /* Link to packet stream to get key exchange packets */
1958 ske->stream = stream;
1959 silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1960 SILC_PACKET_KEY_EXCHANGE,
1961 SILC_PACKET_KEY_EXCHANGE_1,
1962 SILC_PACKET_SUCCESS,
1963 SILC_PACKET_FAILURE, -1);
1965 /* Start SKE as responder */
1966 silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
1971 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
1973 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
1975 return SILC_FSM_FINISH;
1978 /* Starts rekey protocol as initiator */
1981 silc_ske_rekey_initiator(SilcSKE ske,
1982 SilcPacketStream stream,
1983 SilcSKERekeyMaterial rekey)
1985 SILC_LOG_DEBUG(("Start SKE rekey as initator"));
1987 if (!ske || !stream || !rekey)
1990 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1993 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
1998 /* Link to packet stream to get key exchange packets */
1999 ske->stream = stream;
2001 /* Start SKE rekey as initiator */
2002 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2007 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2009 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2011 return SILC_FSM_FINISH;
2014 /* Starts rekey protocol as responder */
2017 silc_ske_rekey_responder(SilcSKE ske,
2018 SilcPacketStream stream,
2019 SilcBuffer ke_payload,
2020 SilcSKERekeyMaterial rekey)
2022 SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2024 if (!ske || !stream || !rekey)
2026 if (rekey->pfs && !ke_payload)
2029 if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2032 if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2035 // ske->packet_buf = ke_payload;
2038 /* Link to packet stream to get key exchange packets */
2039 ske->stream = stream;
2041 /* Start SKE rekey as responder */
2042 silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2047 /* Assembles security properties */
2050 silc_ske_assemble_security_properties(SilcSKE ske,
2051 SilcSKESecurityPropertyFlag flags,
2052 const char *version)
2054 SilcSKEStartPayload rp;
2057 SILC_LOG_DEBUG(("Assembling KE Start Payload"));
2059 rp = silc_calloc(1, sizeof(*rp));
2062 rp->flags = (unsigned char)flags;
2064 /* Set random cookie */
2065 rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
2066 for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
2067 rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
2068 rp->cookie_len = SILC_SKE_COOKIE_LEN;
2071 rp->version = strdup(version);
2072 rp->version_len = strlen(version);
2074 /* Get supported Key Exhange groups */
2075 rp->ke_grp_list = silc_ske_get_supported_groups();
2076 rp->ke_grp_len = strlen(rp->ke_grp_list);
2078 /* Get supported PKCS algorithms */
2079 rp->pkcs_alg_list = silc_pkcs_get_supported();
2080 rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
2082 /* Get supported encryption algorithms */
2083 rp->enc_alg_list = silc_cipher_get_supported();
2084 rp->enc_alg_len = strlen(rp->enc_alg_list);
2086 /* Get supported hash algorithms */
2087 rp->hash_alg_list = silc_hash_get_supported();
2088 rp->hash_alg_len = strlen(rp->hash_alg_list);
2090 /* Get supported HMACs */
2091 rp->hmac_alg_list = silc_hmac_get_supported();
2092 rp->hmac_alg_len = strlen(rp->hmac_alg_list);
2095 /* Get supported compression algorithms */
2096 rp->comp_alg_list = strdup("none");
2097 rp->comp_alg_len = strlen("none");
2099 rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
2100 2 + rp->version_len +
2101 2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
2102 2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
2103 2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
2108 /* Processes the provided key material `data' as the SILC protocol
2109 specification defines. */
2112 silc_ske_process_key_material_data(unsigned char *data,
2113 SilcUInt32 data_len,
2114 SilcUInt32 req_iv_len,
2115 SilcUInt32 req_enc_key_len,
2116 SilcUInt32 req_hmac_key_len,
2120 unsigned char hashd[SILC_HASH_MAXLEN];
2121 SilcUInt32 hash_len = req_hmac_key_len;
2122 SilcUInt32 enc_key_len = req_enc_key_len / 8;
2123 SilcSKEKeyMaterial key;
2125 SILC_LOG_DEBUG(("Start"));
2127 if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2130 key = silc_calloc(1, sizeof(*key));
2134 buf = silc_buffer_alloc_size(1 + data_len);
2137 silc_buffer_format(buf,
2138 SILC_STR_UI_CHAR(0),
2139 SILC_STR_UI_XNSTRING(data, data_len),
2143 memset(hashd, 0, sizeof(hashd));
2145 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2146 key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2147 memcpy(key->send_iv, hashd, req_iv_len);
2148 memset(hashd, 0, sizeof(hashd));
2150 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2151 key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2152 memcpy(key->receive_iv, hashd, req_iv_len);
2153 key->iv_len = req_iv_len;
2155 /* Take the encryption keys. If requested key size is more than
2156 the size of hash length we will distribute more key material
2157 as protocol defines. */
2159 if (enc_key_len > hash_len) {
2161 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2162 k3[SILC_HASH_MAXLEN];
2163 unsigned char *dtmp;
2166 if (enc_key_len > (3 * hash_len))
2169 /* Take first round */
2170 memset(k1, 0, sizeof(k1));
2171 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2173 /* Take second round */
2174 dist = silc_buffer_alloc_size(data_len + hash_len);
2177 silc_buffer_format(dist,
2178 SILC_STR_UI_XNSTRING(data, data_len),
2179 SILC_STR_UI_XNSTRING(k1, hash_len),
2181 memset(k2, 0, sizeof(k2));
2182 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2184 /* Take third round */
2185 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2186 silc_buffer_pull_tail(dist, hash_len);
2187 silc_buffer_pull(dist, data_len + hash_len);
2188 silc_buffer_format(dist,
2189 SILC_STR_UI_XNSTRING(k2, hash_len),
2191 silc_buffer_push(dist, data_len + hash_len);
2192 memset(k3, 0, sizeof(k3));
2193 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2195 /* Then, save the keys */
2196 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2197 memcpy(dtmp, k1, hash_len);
2198 memcpy(dtmp + hash_len, k2, hash_len);
2199 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2201 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2202 memcpy(key->send_enc_key, dtmp, enc_key_len);
2203 key->enc_key_len = req_enc_key_len;
2205 memset(dtmp, 0, (3 * hash_len));
2206 memset(k1, 0, sizeof(k1));
2207 memset(k2, 0, sizeof(k2));
2208 memset(k3, 0, sizeof(k3));
2210 silc_buffer_clear(dist);
2211 silc_buffer_free(dist);
2213 /* Take normal hash as key */
2214 memset(hashd, 0, sizeof(hashd));
2215 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2216 key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2217 memcpy(key->send_enc_key, hashd, enc_key_len);
2218 key->enc_key_len = req_enc_key_len;
2222 if (enc_key_len > hash_len) {
2224 unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2225 k3[SILC_HASH_MAXLEN];
2226 unsigned char *dtmp;
2229 if (enc_key_len > (3 * hash_len))
2232 /* Take first round */
2233 memset(k1, 0, sizeof(k1));
2234 silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2236 /* Take second round */
2237 dist = silc_buffer_alloc_size(data_len + hash_len);
2240 silc_buffer_format(dist,
2241 SILC_STR_UI_XNSTRING(data, data_len),
2242 SILC_STR_UI_XNSTRING(k1, hash_len),
2244 memset(k2, 0, sizeof(k2));
2245 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2247 /* Take third round */
2248 dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2249 silc_buffer_pull_tail(dist, hash_len);
2250 silc_buffer_pull(dist, data_len + hash_len);
2251 silc_buffer_format(dist,
2252 SILC_STR_UI_XNSTRING(k2, hash_len),
2254 silc_buffer_push(dist, data_len + hash_len);
2255 memset(k3, 0, sizeof(k3));
2256 silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2258 /* Then, save the keys */
2259 dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2260 memcpy(dtmp, k1, hash_len);
2261 memcpy(dtmp + hash_len, k2, hash_len);
2262 memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2264 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2265 memcpy(key->receive_enc_key, dtmp, enc_key_len);
2266 key->enc_key_len = req_enc_key_len;
2268 memset(dtmp, 0, (3 * hash_len));
2269 memset(k1, 0, sizeof(k1));
2270 memset(k2, 0, sizeof(k2));
2271 memset(k3, 0, sizeof(k3));
2273 silc_buffer_clear(dist);
2274 silc_buffer_free(dist);
2276 /* Take normal hash as key */
2277 memset(hashd, 0, sizeof(hashd));
2278 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2279 key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2280 memcpy(key->receive_enc_key, hashd, enc_key_len);
2281 key->enc_key_len = req_enc_key_len;
2284 /* Take HMAC keys */
2285 memset(hashd, 0, sizeof(hashd));
2287 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2288 key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2289 memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2290 memset(hashd, 0, sizeof(hashd));
2292 silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2293 key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2294 memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2295 key->hmac_key_len = req_hmac_key_len;
2296 memset(hashd, 0, sizeof(hashd));
2298 silc_buffer_clear(buf);
2299 silc_buffer_free(buf);
2304 /* Processes negotiated key material as protocol specifies. This returns
2305 the actual keys to be used in the SILC. */
2308 silc_ske_process_key_material(SilcSKE ske,
2309 SilcUInt32 req_iv_len,
2310 SilcUInt32 req_enc_key_len,
2311 SilcUInt32 req_hmac_key_len)
2314 unsigned char *tmpbuf;
2316 SilcSKEKeyMaterial key;
2318 /* Encode KEY to binary data */
2319 tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2321 buf = silc_buffer_alloc_size(klen + ske->hash_len);
2324 silc_buffer_format(buf,
2325 SILC_STR_UI_XNSTRING(tmpbuf, klen),
2326 SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2329 /* Process the key material */
2330 key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2331 req_iv_len, req_enc_key_len,
2335 memset(tmpbuf, 0, klen);
2337 silc_buffer_clear(buf);
2338 silc_buffer_free(buf);
2343 /* Free key material structure */
2345 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2351 silc_free(key->send_iv);
2352 if (key->receive_iv)
2353 silc_free(key->receive_iv);
2354 if (key->send_enc_key) {
2355 memset(key->send_enc_key, 0, key->enc_key_len / 8);
2356 silc_free(key->send_enc_key);
2358 if (key->receive_enc_key) {
2359 memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2360 silc_free(key->receive_enc_key);
2362 if (key->send_hmac_key) {
2363 memset(key->send_hmac_key, 0, key->hmac_key_len);
2364 silc_free(key->send_hmac_key);
2366 if (key->receive_hmac_key) {
2367 memset(key->receive_hmac_key, 0, key->hmac_key_len);
2368 silc_free(key->receive_hmac_key);
2373 /* Set keys into use */
2375 SilcBool silc_ske_set_keys(SilcSKE ske,
2376 SilcSKEKeyMaterial keymat,
2377 SilcSKESecurityProperties prop,
2378 SilcCipher *ret_send_key,
2379 SilcCipher *ret_receive_key,
2380 SilcHmac *ret_hmac_send,
2381 SilcHmac *ret_hmac_receive,
2384 /* Allocate ciphers to be used in the communication */
2386 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2390 if (ret_receive_key) {
2391 if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2396 /* Allocate HMACs */
2397 if (ret_hmac_send) {
2398 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2402 if (ret_hmac_receive) {
2403 if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2408 /* Set key material */
2409 if (ske->responder) {
2410 silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2411 keymat->enc_key_len);
2412 silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2413 silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2414 keymat->enc_key_len);
2415 silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2416 silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2417 keymat->hmac_key_len);
2418 silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2419 keymat->hmac_key_len);
2421 silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2422 keymat->enc_key_len);
2423 silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2424 silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2425 keymat->enc_key_len);
2426 silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2427 silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2428 keymat->hmac_key_len);
2429 silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2430 keymat->hmac_key_len);
2435 if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2439 SILC_LOG_INFO(("Security properties: %s %s %s %s",
2440 ret_send_key ? silc_cipher_get_name(*ret_send_key) : "??",
2441 ret_hmac_send ? silc_hmac_get_name(*ret_hmac_send) : "??",
2442 ret_hash ? silc_hash_get_name(*ret_hash) : "??",
2443 ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : ""));
2448 const char *silc_ske_status_string[] =
2452 "Unkown error occurred",
2453 "Bad payload in packet",
2454 "Unsupported group",
2455 "Unsupported cipher",
2457 "Unsupported hash function",
2459 "Unsupported public key (or certificate)",
2460 "Incorrect signature",
2461 "Bad or unsupported version",
2465 "Remote did not provide public key",
2466 "Bad reserved field in packet",
2467 "Bad payload length in packet",
2468 "Error computing signature",
2469 "System out of memory",
2474 /* Maps status to readable string and returns the string. If string is not
2475 found and empty character string ("") is returned. */
2477 const char *silc_ske_map_status(SilcSKEStatus status)
2481 for (i = 0; silc_ske_status_string[i]; i++)
2483 return silc_ske_status_string[i];
2488 /* Parses remote host's version string. */
2490 SilcBool silc_ske_parse_version(SilcSKE ske,
2491 SilcUInt32 *protocol_version,
2492 char **protocol_version_string,
2493 SilcUInt32 *software_version,
2494 char **software_version_string,
2495 char **vendor_version)
2497 return silc_parse_version_string(ske->remote_version,
2499 protocol_version_string,
2501 software_version_string,