1 /* $OpenBSD: kex.c,v 1.134 2017/06/13 12:13:59 djm Exp $ */
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <openssl/crypto.h>
37 #include <openssl/dh.h>
58 static int kex_choose_conf(struct ssh
*);
59 static int kex_input_newkeys(int, u_int32_t
, struct ssh
*);
61 static const char *proposal_names
[PROPOSAL_MAX
] = {
63 "host key algorithms",
80 static const struct kexalg kexalgs
[] = {
82 { KEX_DH1
, KEX_DH_GRP1_SHA1
, 0, SSH_DIGEST_SHA1
},
83 { KEX_DH14_SHA1
, KEX_DH_GRP14_SHA1
, 0, SSH_DIGEST_SHA1
},
84 { KEX_DH14_SHA256
, KEX_DH_GRP14_SHA256
, 0, SSH_DIGEST_SHA256
},
85 { KEX_DH16_SHA512
, KEX_DH_GRP16_SHA512
, 0, SSH_DIGEST_SHA512
},
86 { KEX_DH18_SHA512
, KEX_DH_GRP18_SHA512
, 0, SSH_DIGEST_SHA512
},
87 { KEX_DHGEX_SHA1
, KEX_DH_GEX_SHA1
, 0, SSH_DIGEST_SHA1
},
88 #ifdef HAVE_EVP_SHA256
89 { KEX_DHGEX_SHA256
, KEX_DH_GEX_SHA256
, 0, SSH_DIGEST_SHA256
},
90 #endif /* HAVE_EVP_SHA256 */
91 #ifdef OPENSSL_HAS_ECC
92 { KEX_ECDH_SHA2_NISTP256
, KEX_ECDH_SHA2
,
93 NID_X9_62_prime256v1
, SSH_DIGEST_SHA256
},
94 { KEX_ECDH_SHA2_NISTP384
, KEX_ECDH_SHA2
, NID_secp384r1
,
96 # ifdef OPENSSL_HAS_NISTP521
97 { KEX_ECDH_SHA2_NISTP521
, KEX_ECDH_SHA2
, NID_secp521r1
,
99 # endif /* OPENSSL_HAS_NISTP521 */
100 #endif /* OPENSSL_HAS_ECC */
101 #endif /* WITH_OPENSSL */
102 #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)
103 { KEX_CURVE25519_SHA256
, KEX_C25519_SHA256
, 0, SSH_DIGEST_SHA256
},
104 { KEX_CURVE25519_SHA256_OLD
, KEX_C25519_SHA256
, 0, SSH_DIGEST_SHA256
},
105 #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
110 kex_alg_list(char sep
)
112 char *ret
= NULL
, *tmp
;
113 size_t nlen
, rlen
= 0;
114 const struct kexalg
*k
;
116 for (k
= kexalgs
; k
->name
!= NULL
; k
++) {
119 nlen
= strlen(k
->name
);
120 if ((tmp
= realloc(ret
, rlen
+ nlen
+ 2)) == NULL
) {
125 memcpy(ret
+ rlen
, k
->name
, nlen
+ 1);
131 static const struct kexalg
*
132 kex_alg_by_name(const char *name
)
134 const struct kexalg
*k
;
136 for (k
= kexalgs
; k
->name
!= NULL
; k
++) {
137 if (strcmp(k
->name
, name
) == 0)
143 /* Validate KEX method name list */
145 kex_names_valid(const char *names
)
149 if (names
== NULL
|| strcmp(names
, "") == 0)
151 if ((s
= cp
= strdup(names
)) == NULL
)
153 for ((p
= strsep(&cp
, ",")); p
&& *p
!= '\0';
154 (p
= strsep(&cp
, ","))) {
155 if (kex_alg_by_name(p
) == NULL
) {
156 error("Unsupported KEX algorithm \"%.100s\"", p
);
161 debug3("kex names ok: [%s]", names
);
167 * Concatenate algorithm names, avoiding duplicates in the process.
168 * Caller must free returned string.
171 kex_names_cat(const char *a
, const char *b
)
173 char *ret
= NULL
, *tmp
= NULL
, *cp
, *p
, *m
;
176 if (a
== NULL
|| *a
== '\0')
178 if (b
== NULL
|| *b
== '\0')
180 if (strlen(b
) > 1024*1024)
182 len
= strlen(a
) + strlen(b
) + 2;
183 if ((tmp
= cp
= strdup(b
)) == NULL
||
184 (ret
= calloc(1, len
)) == NULL
) {
188 strlcpy(ret
, a
, len
);
189 for ((p
= strsep(&cp
, ",")); p
&& *p
!= '\0'; (p
= strsep(&cp
, ","))) {
190 if ((m
= match_list(ret
, p
, NULL
)) != NULL
) {
192 continue; /* Algorithm already present */
194 if (strlcat(ret
, ",", len
) >= len
||
195 strlcat(ret
, p
, len
) >= len
) {
198 return NULL
; /* Shouldn't happen */
206 * Assemble a list of algorithms from a default list and a string from a
207 * configuration file. The user-provided string may begin with '+' to
208 * indicate that it should be appended to the default or '-' that the
209 * specified names should be removed.
212 kex_assemble_names(const char *def
, char **list
)
216 if (list
== NULL
|| *list
== NULL
|| **list
== '\0') {
221 if ((ret
= kex_names_cat(def
, *list
+ 1)) == NULL
)
222 return SSH_ERR_ALLOC_FAIL
;
225 } else if (**list
== '-') {
226 if ((ret
= match_filter_list(def
, *list
+ 1)) == NULL
)
227 return SSH_ERR_ALLOC_FAIL
;
235 /* put algorithm proposal into buffer */
237 kex_prop2buf(struct sshbuf
*b
, char *proposal
[PROPOSAL_MAX
])
245 * add a dummy cookie, the cookie will be overwritten by
246 * kex_send_kexinit(), each time a kexinit is set
248 for (i
= 0; i
< KEX_COOKIE_LEN
; i
++) {
249 if ((r
= sshbuf_put_u8(b
, 0)) != 0)
252 for (i
= 0; i
< PROPOSAL_MAX
; i
++) {
253 if ((r
= sshbuf_put_cstring(b
, proposal
[i
])) != 0)
256 if ((r
= sshbuf_put_u8(b
, 0)) != 0 || /* first_kex_packet_follows */
257 (r
= sshbuf_put_u32(b
, 0)) != 0) /* uint32 reserved */
262 /* parse buffer and return algorithm proposal */
264 kex_buf2prop(struct sshbuf
*raw
, int *first_kex_follows
, char ***propp
)
266 struct sshbuf
*b
= NULL
;
269 char **proposal
= NULL
;
273 if ((proposal
= calloc(PROPOSAL_MAX
, sizeof(char *))) == NULL
)
274 return SSH_ERR_ALLOC_FAIL
;
275 if ((b
= sshbuf_fromb(raw
)) == NULL
) {
276 r
= SSH_ERR_ALLOC_FAIL
;
279 if ((r
= sshbuf_consume(b
, KEX_COOKIE_LEN
)) != 0) /* skip cookie */
281 /* extract kex init proposal strings */
282 for (i
= 0; i
< PROPOSAL_MAX
; i
++) {
283 if ((r
= sshbuf_get_cstring(b
, &(proposal
[i
]), NULL
)) != 0)
285 debug2("%s: %s", proposal_names
[i
], proposal
[i
]);
287 /* first kex follows / reserved */
288 if ((r
= sshbuf_get_u8(b
, &v
)) != 0 || /* first_kex_follows */
289 (r
= sshbuf_get_u32(b
, &i
)) != 0) /* reserved */
291 if (first_kex_follows
!= NULL
)
292 *first_kex_follows
= v
;
293 debug2("first_kex_follows %d ", v
);
294 debug2("reserved %u ", i
);
298 if (r
!= 0 && proposal
!= NULL
)
299 kex_prop_free(proposal
);
305 kex_prop_free(char **proposal
)
309 if (proposal
== NULL
)
311 for (i
= 0; i
< PROPOSAL_MAX
; i
++)
318 kex_protocol_error(int type
, u_int32_t seq
, struct ssh
*ssh
)
322 error("kex protocol error: type %d seq %u", type
, seq
);
323 if ((r
= sshpkt_start(ssh
, SSH2_MSG_UNIMPLEMENTED
)) != 0 ||
324 (r
= sshpkt_put_u32(ssh
, seq
)) != 0 ||
325 (r
= sshpkt_send(ssh
)) != 0)
331 kex_reset_dispatch(struct ssh
*ssh
)
333 ssh_dispatch_range(ssh
, SSH2_MSG_TRANSPORT_MIN
,
334 SSH2_MSG_TRANSPORT_MAX
, &kex_protocol_error
);
338 kex_send_ext_info(struct ssh
*ssh
)
343 if ((algs
= sshkey_alg_list(0, 1, 1, ',')) == NULL
)
344 return SSH_ERR_ALLOC_FAIL
;
345 if ((r
= sshpkt_start(ssh
, SSH2_MSG_EXT_INFO
)) != 0 ||
346 (r
= sshpkt_put_u32(ssh
, 1)) != 0 ||
347 (r
= sshpkt_put_cstring(ssh
, "server-sig-algs")) != 0 ||
348 (r
= sshpkt_put_cstring(ssh
, algs
)) != 0 ||
349 (r
= sshpkt_send(ssh
)) != 0)
359 kex_send_newkeys(struct ssh
*ssh
)
363 kex_reset_dispatch(ssh
);
364 if ((r
= sshpkt_start(ssh
, SSH2_MSG_NEWKEYS
)) != 0 ||
365 (r
= sshpkt_send(ssh
)) != 0)
367 debug("SSH2_MSG_NEWKEYS sent");
368 debug("expecting SSH2_MSG_NEWKEYS");
369 ssh_dispatch_set(ssh
, SSH2_MSG_NEWKEYS
, &kex_input_newkeys
);
370 if (ssh
->kex
->ext_info_c
)
371 if ((r
= kex_send_ext_info(ssh
)) != 0)
377 kex_input_ext_info(int type
, u_int32_t seq
, struct ssh
*ssh
)
379 struct kex
*kex
= ssh
->kex
;
386 debug("SSH2_MSG_EXT_INFO received");
387 ssh_dispatch_set(ssh
, SSH2_MSG_EXT_INFO
, &kex_protocol_error
);
388 if ((r
= sshpkt_get_u32(ssh
, &ninfo
)) != 0)
390 for (i
= 0; i
< ninfo
; i
++) {
391 if ((r
= sshpkt_get_cstring(ssh
, &name
, NULL
)) != 0)
393 if ((r
= sshpkt_get_string(ssh
, &val
, &vlen
)) != 0) {
397 if (strcmp(name
, "server-sig-algs") == 0) {
398 /* Ensure no \0 lurking in value */
399 if (memchr(val
, '\0', vlen
) != NULL
) {
400 error("%s: nul byte in %s", __func__
, name
);
401 return SSH_ERR_INVALID_FORMAT
;
403 debug("%s: %s=<%s>", __func__
, name
, val
);
404 found
= match_list("rsa-sha2-256", val
, NULL
);
409 found
= match_list("rsa-sha2-512", val
, NULL
);
415 debug("%s: %s (unrecognised)", __func__
, name
);
419 return sshpkt_get_end(ssh
);
423 kex_input_newkeys(int type
, u_int32_t seq
, struct ssh
*ssh
)
425 struct kex
*kex
= ssh
->kex
;
428 debug("SSH2_MSG_NEWKEYS received");
429 ssh_dispatch_set(ssh
, SSH2_MSG_NEWKEYS
, &kex_protocol_error
);
430 ssh_dispatch_set(ssh
, SSH2_MSG_KEXINIT
, &kex_input_kexinit
);
431 if ((r
= sshpkt_get_end(ssh
)) != 0)
433 if ((r
= ssh_set_newkeys(ssh
, MODE_IN
)) != 0)
436 sshbuf_reset(kex
->peer
);
437 /* sshbuf_reset(kex->my); */
438 kex
->flags
&= ~KEX_INIT_SENT
;
445 kex_send_kexinit(struct ssh
*ssh
)
448 struct kex
*kex
= ssh
->kex
;
452 return SSH_ERR_INTERNAL_ERROR
;
453 if (kex
->flags
& KEX_INIT_SENT
)
457 /* generate a random cookie */
458 if (sshbuf_len(kex
->my
) < KEX_COOKIE_LEN
)
459 return SSH_ERR_INVALID_FORMAT
;
460 if ((cookie
= sshbuf_mutable_ptr(kex
->my
)) == NULL
)
461 return SSH_ERR_INTERNAL_ERROR
;
462 arc4random_buf(cookie
, KEX_COOKIE_LEN
);
464 if ((r
= sshpkt_start(ssh
, SSH2_MSG_KEXINIT
)) != 0 ||
465 (r
= sshpkt_putb(ssh
, kex
->my
)) != 0 ||
466 (r
= sshpkt_send(ssh
)) != 0)
468 debug("SSH2_MSG_KEXINIT sent");
469 kex
->flags
|= KEX_INIT_SENT
;
475 kex_input_kexinit(int type
, u_int32_t seq
, struct ssh
*ssh
)
477 struct kex
*kex
= ssh
->kex
;
483 debug("SSH2_MSG_KEXINIT received");
485 return SSH_ERR_INVALID_ARGUMENT
;
487 ssh_dispatch_set(ssh
, SSH2_MSG_KEXINIT
, NULL
);
488 ptr
= sshpkt_ptr(ssh
, &dlen
);
489 if ((r
= sshbuf_put(kex
->peer
, ptr
, dlen
)) != 0)
493 for (i
= 0; i
< KEX_COOKIE_LEN
; i
++)
494 if ((r
= sshpkt_get_u8(ssh
, NULL
)) != 0)
496 for (i
= 0; i
< PROPOSAL_MAX
; i
++)
497 if ((r
= sshpkt_get_string(ssh
, NULL
, NULL
)) != 0)
500 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
501 * KEX method has the server move first, but a server might be using
502 * a custom method or one that we otherwise don't support. We should
503 * be prepared to remember first_kex_follows here so we can eat a
505 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
506 * for cases where the server *doesn't* go first. I guess we should
507 * ignore it when it is set for these cases, which is what we do now.
509 if ((r
= sshpkt_get_u8(ssh
, NULL
)) != 0 || /* first_kex_follows */
510 (r
= sshpkt_get_u32(ssh
, NULL
)) != 0 || /* reserved */
511 (r
= sshpkt_get_end(ssh
)) != 0)
514 if (!(kex
->flags
& KEX_INIT_SENT
))
515 if ((r
= kex_send_kexinit(ssh
)) != 0)
517 if ((r
= kex_choose_conf(ssh
)) != 0)
520 if (kex
->kex_type
< KEX_MAX
&& kex
->kex
[kex
->kex_type
] != NULL
)
521 return (kex
->kex
[kex
->kex_type
])(ssh
);
523 return SSH_ERR_INTERNAL_ERROR
;
527 kex_new(struct ssh
*ssh
, char *proposal
[PROPOSAL_MAX
], struct kex
**kexp
)
533 if ((kex
= calloc(1, sizeof(*kex
))) == NULL
)
534 return SSH_ERR_ALLOC_FAIL
;
535 if ((kex
->peer
= sshbuf_new()) == NULL
||
536 (kex
->my
= sshbuf_new()) == NULL
) {
537 r
= SSH_ERR_ALLOC_FAIL
;
540 if ((r
= kex_prop2buf(kex
->my
, proposal
)) != 0)
543 kex_reset_dispatch(ssh
);
544 ssh_dispatch_set(ssh
, SSH2_MSG_KEXINIT
, &kex_input_kexinit
);
554 kex_free_newkeys(struct newkeys
*newkeys
)
558 if (newkeys
->enc
.key
) {
559 explicit_bzero(newkeys
->enc
.key
, newkeys
->enc
.key_len
);
560 free(newkeys
->enc
.key
);
561 newkeys
->enc
.key
= NULL
;
563 if (newkeys
->enc
.iv
) {
564 explicit_bzero(newkeys
->enc
.iv
, newkeys
->enc
.iv_len
);
565 free(newkeys
->enc
.iv
);
566 newkeys
->enc
.iv
= NULL
;
568 free(newkeys
->enc
.name
);
569 explicit_bzero(&newkeys
->enc
, sizeof(newkeys
->enc
));
570 free(newkeys
->comp
.name
);
571 explicit_bzero(&newkeys
->comp
, sizeof(newkeys
->comp
));
572 mac_clear(&newkeys
->mac
);
573 if (newkeys
->mac
.key
) {
574 explicit_bzero(newkeys
->mac
.key
, newkeys
->mac
.key_len
);
575 free(newkeys
->mac
.key
);
576 newkeys
->mac
.key
= NULL
;
578 free(newkeys
->mac
.name
);
579 explicit_bzero(&newkeys
->mac
, sizeof(newkeys
->mac
));
580 explicit_bzero(newkeys
, sizeof(*newkeys
));
585 kex_free(struct kex
*kex
)
592 #ifdef OPENSSL_HAS_ECC
593 if (kex
->ec_client_key
)
594 EC_KEY_free(kex
->ec_client_key
);
595 #endif /* OPENSSL_HAS_ECC */
596 #endif /* WITH_OPENSSL */
597 for (mode
= 0; mode
< MODE_MAX
; mode
++) {
598 kex_free_newkeys(kex
->newkeys
[mode
]);
599 kex
->newkeys
[mode
] = NULL
;
601 sshbuf_free(kex
->peer
);
602 sshbuf_free(kex
->my
);
603 free(kex
->session_id
);
604 free(kex
->client_version_string
);
605 free(kex
->server_version_string
);
606 free(kex
->failed_choice
);
607 free(kex
->hostkey_alg
);
613 kex_setup(struct ssh
*ssh
, char *proposal
[PROPOSAL_MAX
])
617 if ((r
= kex_new(ssh
, proposal
, &ssh
->kex
)) != 0)
619 if ((r
= kex_send_kexinit(ssh
)) != 0) { /* we start */
628 * Request key re-exchange, returns 0 on success or a ssherr.h error
629 * code otherwise. Must not be called if KEX is incomplete or in-progress.
632 kex_start_rekex(struct ssh
*ssh
)
634 if (ssh
->kex
== NULL
) {
635 error("%s: no kex", __func__
);
636 return SSH_ERR_INTERNAL_ERROR
;
638 if (ssh
->kex
->done
== 0) {
639 error("%s: requested twice", __func__
);
640 return SSH_ERR_INTERNAL_ERROR
;
643 return kex_send_kexinit(ssh
);
647 choose_enc(struct sshenc
*enc
, char *client
, char *server
)
649 char *name
= match_list(client
, server
, NULL
);
652 return SSH_ERR_NO_CIPHER_ALG_MATCH
;
653 if ((enc
->cipher
= cipher_by_name(name
)) == NULL
) {
655 return SSH_ERR_INTERNAL_ERROR
;
660 enc
->iv_len
= cipher_ivlen(enc
->cipher
);
662 enc
->key_len
= cipher_keylen(enc
->cipher
);
663 enc
->block_size
= cipher_blocksize(enc
->cipher
);
668 choose_mac(struct ssh
*ssh
, struct sshmac
*mac
, char *client
, char *server
)
670 char *name
= match_list(client
, server
, NULL
);
673 return SSH_ERR_NO_MAC_ALG_MATCH
;
674 if (mac_setup(mac
, name
) < 0) {
676 return SSH_ERR_INTERNAL_ERROR
;
678 /* truncate the key */
679 if (ssh
->compat
& SSH_BUG_HMAC
)
688 choose_comp(struct sshcomp
*comp
, char *client
, char *server
)
690 char *name
= match_list(client
, server
, NULL
);
693 return SSH_ERR_NO_COMPRESS_ALG_MATCH
;
694 if (strcmp(name
, "zlib@openssh.com") == 0) {
695 comp
->type
= COMP_DELAYED
;
696 } else if (strcmp(name
, "zlib") == 0) {
697 comp
->type
= COMP_ZLIB
;
698 } else if (strcmp(name
, "none") == 0) {
699 comp
->type
= COMP_NONE
;
702 return SSH_ERR_INTERNAL_ERROR
;
709 choose_kex(struct kex
*k
, char *client
, char *server
)
711 const struct kexalg
*kexalg
;
713 k
->name
= match_list(client
, server
, NULL
);
715 debug("kex: algorithm: %s", k
->name
? k
->name
: "(no match)");
717 return SSH_ERR_NO_KEX_ALG_MATCH
;
718 if ((kexalg
= kex_alg_by_name(k
->name
)) == NULL
)
719 return SSH_ERR_INTERNAL_ERROR
;
720 k
->kex_type
= kexalg
->type
;
721 k
->hash_alg
= kexalg
->hash_alg
;
722 k
->ec_nid
= kexalg
->ec_nid
;
727 choose_hostkeyalg(struct kex
*k
, char *client
, char *server
)
729 k
->hostkey_alg
= match_list(client
, server
, NULL
);
731 debug("kex: host key algorithm: %s",
732 k
->hostkey_alg
? k
->hostkey_alg
: "(no match)");
733 if (k
->hostkey_alg
== NULL
)
734 return SSH_ERR_NO_HOSTKEY_ALG_MATCH
;
735 k
->hostkey_type
= sshkey_type_from_name(k
->hostkey_alg
);
736 if (k
->hostkey_type
== KEY_UNSPEC
)
737 return SSH_ERR_INTERNAL_ERROR
;
738 k
->hostkey_nid
= sshkey_ecdsa_nid_from_name(k
->hostkey_alg
);
743 proposals_match(char *my
[PROPOSAL_MAX
], char *peer
[PROPOSAL_MAX
])
745 static int check
[] = {
746 PROPOSAL_KEX_ALGS
, PROPOSAL_SERVER_HOST_KEY_ALGS
, -1
751 for (idx
= &check
[0]; *idx
!= -1; idx
++) {
752 if ((p
= strchr(my
[*idx
], ',')) != NULL
)
754 if ((p
= strchr(peer
[*idx
], ',')) != NULL
)
756 if (strcmp(my
[*idx
], peer
[*idx
]) != 0) {
757 debug2("proposal mismatch: my %s peer %s",
758 my
[*idx
], peer
[*idx
]);
762 debug2("proposals match");
767 kex_choose_conf(struct ssh
*ssh
)
769 struct kex
*kex
= ssh
->kex
;
770 struct newkeys
*newkeys
;
771 char **my
= NULL
, **peer
= NULL
;
772 char **cprop
, **sprop
;
773 int nenc
, nmac
, ncomp
;
774 u_int mode
, ctos
, need
, dh_need
, authlen
;
775 int r
, first_kex_follows
;
777 debug2("local %s KEXINIT proposal", kex
->server
? "server" : "client");
778 if ((r
= kex_buf2prop(kex
->my
, NULL
, &my
)) != 0)
780 debug2("peer %s KEXINIT proposal", kex
->server
? "client" : "server");
781 if ((r
= kex_buf2prop(kex
->peer
, &first_kex_follows
, &peer
)) != 0)
792 /* Check whether client supports ext_info_c */
796 ext
= match_list("ext-info-c", peer
[PROPOSAL_KEX_ALGS
], NULL
);
797 kex
->ext_info_c
= (ext
!= NULL
);
801 /* Algorithm Negotiation */
802 if ((r
= choose_kex(kex
, cprop
[PROPOSAL_KEX_ALGS
],
803 sprop
[PROPOSAL_KEX_ALGS
])) != 0) {
804 kex
->failed_choice
= peer
[PROPOSAL_KEX_ALGS
];
805 peer
[PROPOSAL_KEX_ALGS
] = NULL
;
808 if ((r
= choose_hostkeyalg(kex
, cprop
[PROPOSAL_SERVER_HOST_KEY_ALGS
],
809 sprop
[PROPOSAL_SERVER_HOST_KEY_ALGS
])) != 0) {
810 kex
->failed_choice
= peer
[PROPOSAL_SERVER_HOST_KEY_ALGS
];
811 peer
[PROPOSAL_SERVER_HOST_KEY_ALGS
] = NULL
;
814 for (mode
= 0; mode
< MODE_MAX
; mode
++) {
815 if ((newkeys
= calloc(1, sizeof(*newkeys
))) == NULL
) {
816 r
= SSH_ERR_ALLOC_FAIL
;
819 kex
->newkeys
[mode
] = newkeys
;
820 ctos
= (!kex
->server
&& mode
== MODE_OUT
) ||
821 (kex
->server
&& mode
== MODE_IN
);
822 nenc
= ctos
? PROPOSAL_ENC_ALGS_CTOS
: PROPOSAL_ENC_ALGS_STOC
;
823 nmac
= ctos
? PROPOSAL_MAC_ALGS_CTOS
: PROPOSAL_MAC_ALGS_STOC
;
824 ncomp
= ctos
? PROPOSAL_COMP_ALGS_CTOS
: PROPOSAL_COMP_ALGS_STOC
;
825 if ((r
= choose_enc(&newkeys
->enc
, cprop
[nenc
],
826 sprop
[nenc
])) != 0) {
827 kex
->failed_choice
= peer
[nenc
];
831 authlen
= cipher_authlen(newkeys
->enc
.cipher
);
832 /* ignore mac for authenticated encryption */
834 (r
= choose_mac(ssh
, &newkeys
->mac
, cprop
[nmac
],
835 sprop
[nmac
])) != 0) {
836 kex
->failed_choice
= peer
[nmac
];
840 if ((r
= choose_comp(&newkeys
->comp
, cprop
[ncomp
],
841 sprop
[ncomp
])) != 0) {
842 kex
->failed_choice
= peer
[ncomp
];
846 debug("kex: %s cipher: %s MAC: %s compression: %s",
847 ctos
? "client->server" : "server->client",
849 authlen
== 0 ? newkeys
->mac
.name
: "<implicit>",
853 for (mode
= 0; mode
< MODE_MAX
; mode
++) {
854 newkeys
= kex
->newkeys
[mode
];
855 need
= MAXIMUM(need
, newkeys
->enc
.key_len
);
856 need
= MAXIMUM(need
, newkeys
->enc
.block_size
);
857 need
= MAXIMUM(need
, newkeys
->enc
.iv_len
);
858 need
= MAXIMUM(need
, newkeys
->mac
.key_len
);
859 dh_need
= MAXIMUM(dh_need
, cipher_seclen(newkeys
->enc
.cipher
));
860 dh_need
= MAXIMUM(dh_need
, newkeys
->enc
.block_size
);
861 dh_need
= MAXIMUM(dh_need
, newkeys
->enc
.iv_len
);
862 dh_need
= MAXIMUM(dh_need
, newkeys
->mac
.key_len
);
864 /* XXX need runden? */
866 kex
->dh_need
= dh_need
;
868 /* ignore the next message if the proposals do not match */
869 if (first_kex_follows
&& !proposals_match(my
, peer
) &&
870 !(ssh
->compat
& SSH_BUG_FIRSTKEX
))
871 ssh
->dispatch_skip_packets
= 1;
880 derive_key(struct ssh
*ssh
, int id
, u_int need
, u_char
*hash
, u_int hashlen
,
881 const struct sshbuf
*shared_secret
, u_char
**keyp
)
883 struct kex
*kex
= ssh
->kex
;
884 struct ssh_digest_ctx
*hashctx
= NULL
;
891 if ((mdsz
= ssh_digest_bytes(kex
->hash_alg
)) == 0)
892 return SSH_ERR_INVALID_ARGUMENT
;
893 if ((digest
= calloc(1, ROUNDUP(need
, mdsz
))) == NULL
) {
894 r
= SSH_ERR_ALLOC_FAIL
;
898 /* K1 = HASH(K || H || "A" || session_id) */
899 if ((hashctx
= ssh_digest_start(kex
->hash_alg
)) == NULL
||
900 ssh_digest_update_buffer(hashctx
, shared_secret
) != 0 ||
901 ssh_digest_update(hashctx
, hash
, hashlen
) != 0 ||
902 ssh_digest_update(hashctx
, &c
, 1) != 0 ||
903 ssh_digest_update(hashctx
, kex
->session_id
,
904 kex
->session_id_len
) != 0 ||
905 ssh_digest_final(hashctx
, digest
, mdsz
) != 0) {
906 r
= SSH_ERR_LIBCRYPTO_ERROR
;
909 ssh_digest_free(hashctx
);
914 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
915 * Key = K1 || K2 || ... || Kn
917 for (have
= mdsz
; need
> have
; have
+= mdsz
) {
918 if ((hashctx
= ssh_digest_start(kex
->hash_alg
)) == NULL
||
919 ssh_digest_update_buffer(hashctx
, shared_secret
) != 0 ||
920 ssh_digest_update(hashctx
, hash
, hashlen
) != 0 ||
921 ssh_digest_update(hashctx
, digest
, have
) != 0 ||
922 ssh_digest_final(hashctx
, digest
+ have
, mdsz
) != 0) {
923 r
= SSH_ERR_LIBCRYPTO_ERROR
;
926 ssh_digest_free(hashctx
);
930 fprintf(stderr
, "key '%c'== ", c
);
931 dump_digest("key", digest
, need
);
938 ssh_digest_free(hashctx
);
944 kex_derive_keys(struct ssh
*ssh
, u_char
*hash
, u_int hashlen
,
945 const struct sshbuf
*shared_secret
)
947 struct kex
*kex
= ssh
->kex
;
949 u_int i
, j
, mode
, ctos
;
952 for (i
= 0; i
< NKEYS
; i
++) {
953 if ((r
= derive_key(ssh
, 'A'+i
, kex
->we_need
, hash
, hashlen
,
954 shared_secret
, &keys
[i
])) != 0) {
955 for (j
= 0; j
< i
; j
++)
960 for (mode
= 0; mode
< MODE_MAX
; mode
++) {
961 ctos
= (!kex
->server
&& mode
== MODE_OUT
) ||
962 (kex
->server
&& mode
== MODE_IN
);
963 kex
->newkeys
[mode
]->enc
.iv
= keys
[ctos
? 0 : 1];
964 kex
->newkeys
[mode
]->enc
.key
= keys
[ctos
? 2 : 3];
965 kex
->newkeys
[mode
]->mac
.key
= keys
[ctos
? 4 : 5];
972 kex_derive_keys_bn(struct ssh
*ssh
, u_char
*hash
, u_int hashlen
,
973 const BIGNUM
*secret
)
975 struct sshbuf
*shared_secret
;
978 if ((shared_secret
= sshbuf_new()) == NULL
)
979 return SSH_ERR_ALLOC_FAIL
;
980 if ((r
= sshbuf_put_bignum2(shared_secret
, secret
)) == 0)
981 r
= kex_derive_keys(ssh
, hash
, hashlen
, shared_secret
);
982 sshbuf_free(shared_secret
);
988 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
990 dump_digest(char *msg
, u_char
*digest
, int len
)
992 fprintf(stderr
, "%s\n", msg
);
993 sshbuf_dump_data(digest
, len
, stderr
);