1 /* $OpenBSD: kex.c,v 1.118 2016/05/02 10:26:04 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.
28 #include <sys/param.h> /* MAX roundup */
37 #include <openssl/crypto.h>
38 #include <openssl/dh.h>
58 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
59 # if defined(HAVE_EVP_SHA256)
60 # define evp_ssh_sha256 EVP_sha256
62 extern const EVP_MD
*evp_ssh_sha256(void);
67 static int kex_choose_conf(struct ssh
*);
68 static int kex_input_newkeys(int, u_int32_t
, void *);
70 static const char *proposal_names
[PROPOSAL_MAX
] = {
72 "host key algorithms",
89 static const struct kexalg kexalgs
[] = {
91 { KEX_DH1
, KEX_DH_GRP1_SHA1
, 0, SSH_DIGEST_SHA1
},
92 { KEX_DH14_SHA1
, KEX_DH_GRP14_SHA1
, 0, SSH_DIGEST_SHA1
},
93 { KEX_DH14_SHA256
, KEX_DH_GRP14_SHA256
, 0, SSH_DIGEST_SHA256
},
94 { KEX_DH16_SHA512
, KEX_DH_GRP16_SHA512
, 0, SSH_DIGEST_SHA512
},
95 { KEX_DH18_SHA512
, KEX_DH_GRP18_SHA512
, 0, SSH_DIGEST_SHA512
},
96 { KEX_DHGEX_SHA1
, KEX_DH_GEX_SHA1
, 0, SSH_DIGEST_SHA1
},
97 #ifdef HAVE_EVP_SHA256
98 { KEX_DHGEX_SHA256
, KEX_DH_GEX_SHA256
, 0, SSH_DIGEST_SHA256
},
99 #endif /* HAVE_EVP_SHA256 */
100 #ifdef OPENSSL_HAS_ECC
101 { KEX_ECDH_SHA2_NISTP256
, KEX_ECDH_SHA2
,
102 NID_X9_62_prime256v1
, SSH_DIGEST_SHA256
},
103 { KEX_ECDH_SHA2_NISTP384
, KEX_ECDH_SHA2
, NID_secp384r1
,
105 # ifdef OPENSSL_HAS_NISTP521
106 { KEX_ECDH_SHA2_NISTP521
, KEX_ECDH_SHA2
, NID_secp521r1
,
108 # endif /* OPENSSL_HAS_NISTP521 */
109 #endif /* OPENSSL_HAS_ECC */
110 #endif /* WITH_OPENSSL */
111 #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)
112 { KEX_CURVE25519_SHA256
, KEX_C25519_SHA256
, 0, SSH_DIGEST_SHA256
},
113 #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
118 kex_alg_list(char sep
)
120 char *ret
= NULL
, *tmp
;
121 size_t nlen
, rlen
= 0;
122 const struct kexalg
*k
;
124 for (k
= kexalgs
; k
->name
!= NULL
; k
++) {
127 nlen
= strlen(k
->name
);
128 if ((tmp
= realloc(ret
, rlen
+ nlen
+ 2)) == NULL
) {
133 memcpy(ret
+ rlen
, k
->name
, nlen
+ 1);
139 static const struct kexalg
*
140 kex_alg_by_name(const char *name
)
142 const struct kexalg
*k
;
144 for (k
= kexalgs
; k
->name
!= NULL
; k
++) {
145 if (strcmp(k
->name
, name
) == 0)
151 /* Validate KEX method name list */
153 kex_names_valid(const char *names
)
157 if (names
== NULL
|| strcmp(names
, "") == 0)
159 if ((s
= cp
= strdup(names
)) == NULL
)
161 for ((p
= strsep(&cp
, ",")); p
&& *p
!= '\0';
162 (p
= strsep(&cp
, ","))) {
163 if (kex_alg_by_name(p
) == NULL
) {
164 error("Unsupported KEX algorithm \"%.100s\"", p
);
169 debug3("kex names ok: [%s]", names
);
175 * Concatenate algorithm names, avoiding duplicates in the process.
176 * Caller must free returned string.
179 kex_names_cat(const char *a
, const char *b
)
181 char *ret
= NULL
, *tmp
= NULL
, *cp
, *p
;
184 if (a
== NULL
|| *a
== '\0')
186 if (b
== NULL
|| *b
== '\0')
188 if (strlen(b
) > 1024*1024)
190 len
= strlen(a
) + strlen(b
) + 2;
191 if ((tmp
= cp
= strdup(b
)) == NULL
||
192 (ret
= calloc(1, len
)) == NULL
) {
196 strlcpy(ret
, a
, len
);
197 for ((p
= strsep(&cp
, ",")); p
&& *p
!= '\0'; (p
= strsep(&cp
, ","))) {
198 if (match_list(ret
, p
, NULL
) != NULL
)
199 continue; /* Algorithm already present */
200 if (strlcat(ret
, ",", len
) >= len
||
201 strlcat(ret
, p
, len
) >= len
) {
204 return NULL
; /* Shouldn't happen */
212 * Assemble a list of algorithms from a default list and a string from a
213 * configuration file. The user-provided string may begin with '+' to
214 * indicate that it should be appended to the default.
217 kex_assemble_names(const char *def
, char **list
)
221 if (list
== NULL
|| *list
== NULL
|| **list
== '\0') {
229 if ((ret
= kex_names_cat(def
, *list
+ 1)) == NULL
)
230 return SSH_ERR_ALLOC_FAIL
;
236 /* put algorithm proposal into buffer */
238 kex_prop2buf(struct sshbuf
*b
, char *proposal
[PROPOSAL_MAX
])
246 * add a dummy cookie, the cookie will be overwritten by
247 * kex_send_kexinit(), each time a kexinit is set
249 for (i
= 0; i
< KEX_COOKIE_LEN
; i
++) {
250 if ((r
= sshbuf_put_u8(b
, 0)) != 0)
253 for (i
= 0; i
< PROPOSAL_MAX
; i
++) {
254 if ((r
= sshbuf_put_cstring(b
, proposal
[i
])) != 0)
257 if ((r
= sshbuf_put_u8(b
, 0)) != 0 || /* first_kex_packet_follows */
258 (r
= sshbuf_put_u32(b
, 0)) != 0) /* uint32 reserved */
263 /* parse buffer and return algorithm proposal */
265 kex_buf2prop(struct sshbuf
*raw
, int *first_kex_follows
, char ***propp
)
267 struct sshbuf
*b
= NULL
;
270 char **proposal
= NULL
;
274 if ((proposal
= calloc(PROPOSAL_MAX
, sizeof(char *))) == NULL
)
275 return SSH_ERR_ALLOC_FAIL
;
276 if ((b
= sshbuf_fromb(raw
)) == NULL
) {
277 r
= SSH_ERR_ALLOC_FAIL
;
280 if ((r
= sshbuf_consume(b
, KEX_COOKIE_LEN
)) != 0) /* skip cookie */
282 /* extract kex init proposal strings */
283 for (i
= 0; i
< PROPOSAL_MAX
; i
++) {
284 if ((r
= sshbuf_get_cstring(b
, &(proposal
[i
]), NULL
)) != 0)
286 debug2("%s: %s", proposal_names
[i
], proposal
[i
]);
288 /* first kex follows / reserved */
289 if ((r
= sshbuf_get_u8(b
, &v
)) != 0 || /* first_kex_follows */
290 (r
= sshbuf_get_u32(b
, &i
)) != 0) /* reserved */
292 if (first_kex_follows
!= NULL
)
293 *first_kex_follows
= v
;
294 debug2("first_kex_follows %d ", v
);
295 debug2("reserved %u ", i
);
299 if (r
!= 0 && proposal
!= NULL
)
300 kex_prop_free(proposal
);
306 kex_prop_free(char **proposal
)
310 if (proposal
== NULL
)
312 for (i
= 0; i
< PROPOSAL_MAX
; i
++)
319 kex_protocol_error(int type
, u_int32_t seq
, void *ctxt
)
321 struct ssh
*ssh
= active_state
; /* XXX */
324 error("kex protocol error: type %d seq %u", type
, seq
);
325 if ((r
= sshpkt_start(ssh
, SSH2_MSG_UNIMPLEMENTED
)) != 0 ||
326 (r
= sshpkt_put_u32(ssh
, seq
)) != 0 ||
327 (r
= sshpkt_send(ssh
)) != 0)
333 kex_reset_dispatch(struct ssh
*ssh
)
335 ssh_dispatch_range(ssh
, SSH2_MSG_TRANSPORT_MIN
,
336 SSH2_MSG_TRANSPORT_MAX
, &kex_protocol_error
);
337 ssh_dispatch_set(ssh
, SSH2_MSG_KEXINIT
, &kex_input_kexinit
);
341 kex_send_ext_info(struct ssh
*ssh
)
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
, "rsa-sha2-256,rsa-sha2-512")) != 0 ||
349 (r
= sshpkt_send(ssh
)) != 0)
355 kex_send_newkeys(struct ssh
*ssh
)
359 kex_reset_dispatch(ssh
);
360 if ((r
= sshpkt_start(ssh
, SSH2_MSG_NEWKEYS
)) != 0 ||
361 (r
= sshpkt_send(ssh
)) != 0)
363 debug("SSH2_MSG_NEWKEYS sent");
364 debug("expecting SSH2_MSG_NEWKEYS");
365 ssh_dispatch_set(ssh
, SSH2_MSG_NEWKEYS
, &kex_input_newkeys
);
366 if (ssh
->kex
->ext_info_c
)
367 if ((r
= kex_send_ext_info(ssh
)) != 0)
373 kex_input_ext_info(int type
, u_int32_t seq
, void *ctxt
)
375 struct ssh
*ssh
= ctxt
;
376 struct kex
*kex
= ssh
->kex
;
378 char *name
, *val
, *found
;
381 debug("SSH2_MSG_EXT_INFO received");
382 ssh_dispatch_set(ssh
, SSH2_MSG_EXT_INFO
, &kex_protocol_error
);
383 if ((r
= sshpkt_get_u32(ssh
, &ninfo
)) != 0)
385 for (i
= 0; i
< ninfo
; i
++) {
386 if ((r
= sshpkt_get_cstring(ssh
, &name
, NULL
)) != 0)
388 if ((r
= sshpkt_get_cstring(ssh
, &val
, NULL
)) != 0) {
392 debug("%s: %s=<%s>", __func__
, name
, val
);
393 if (strcmp(name
, "server-sig-algs") == 0) {
394 found
= match_list("rsa-sha2-256", val
, NULL
);
399 found
= match_list("rsa-sha2-512", val
, NULL
);
408 return sshpkt_get_end(ssh
);
412 kex_input_newkeys(int type
, u_int32_t seq
, void *ctxt
)
414 struct ssh
*ssh
= ctxt
;
415 struct kex
*kex
= ssh
->kex
;
418 debug("SSH2_MSG_NEWKEYS received");
419 ssh_dispatch_set(ssh
, SSH2_MSG_NEWKEYS
, &kex_protocol_error
);
420 if ((r
= sshpkt_get_end(ssh
)) != 0)
423 sshbuf_reset(kex
->peer
);
424 /* sshbuf_reset(kex->my); */
425 kex
->flags
&= ~KEX_INIT_SENT
;
432 kex_send_kexinit(struct ssh
*ssh
)
435 struct kex
*kex
= ssh
->kex
;
439 return SSH_ERR_INTERNAL_ERROR
;
440 if (kex
->flags
& KEX_INIT_SENT
)
444 /* generate a random cookie */
445 if (sshbuf_len(kex
->my
) < KEX_COOKIE_LEN
)
446 return SSH_ERR_INVALID_FORMAT
;
447 if ((cookie
= sshbuf_mutable_ptr(kex
->my
)) == NULL
)
448 return SSH_ERR_INTERNAL_ERROR
;
449 arc4random_buf(cookie
, KEX_COOKIE_LEN
);
451 if ((r
= sshpkt_start(ssh
, SSH2_MSG_KEXINIT
)) != 0 ||
452 (r
= sshpkt_putb(ssh
, kex
->my
)) != 0 ||
453 (r
= sshpkt_send(ssh
)) != 0)
455 debug("SSH2_MSG_KEXINIT sent");
456 kex
->flags
|= KEX_INIT_SENT
;
462 kex_input_kexinit(int type
, u_int32_t seq
, void *ctxt
)
464 struct ssh
*ssh
= ctxt
;
465 struct kex
*kex
= ssh
->kex
;
471 debug("SSH2_MSG_KEXINIT received");
473 return SSH_ERR_INVALID_ARGUMENT
;
475 ptr
= sshpkt_ptr(ssh
, &dlen
);
476 if ((r
= sshbuf_put(kex
->peer
, ptr
, dlen
)) != 0)
480 for (i
= 0; i
< KEX_COOKIE_LEN
; i
++)
481 if ((r
= sshpkt_get_u8(ssh
, NULL
)) != 0)
483 for (i
= 0; i
< PROPOSAL_MAX
; i
++)
484 if ((r
= sshpkt_get_string(ssh
, NULL
, NULL
)) != 0)
487 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
488 * KEX method has the server move first, but a server might be using
489 * a custom method or one that we otherwise don't support. We should
490 * be prepared to remember first_kex_follows here so we can eat a
492 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
493 * for cases where the server *doesn't* go first. I guess we should
494 * ignore it when it is set for these cases, which is what we do now.
496 if ((r
= sshpkt_get_u8(ssh
, NULL
)) != 0 || /* first_kex_follows */
497 (r
= sshpkt_get_u32(ssh
, NULL
)) != 0 || /* reserved */
498 (r
= sshpkt_get_end(ssh
)) != 0)
501 if (!(kex
->flags
& KEX_INIT_SENT
))
502 if ((r
= kex_send_kexinit(ssh
)) != 0)
504 if ((r
= kex_choose_conf(ssh
)) != 0)
507 if (kex
->kex_type
< KEX_MAX
&& kex
->kex
[kex
->kex_type
] != NULL
)
508 return (kex
->kex
[kex
->kex_type
])(ssh
);
510 return SSH_ERR_INTERNAL_ERROR
;
514 kex_new(struct ssh
*ssh
, char *proposal
[PROPOSAL_MAX
], struct kex
**kexp
)
520 if ((kex
= calloc(1, sizeof(*kex
))) == NULL
)
521 return SSH_ERR_ALLOC_FAIL
;
522 if ((kex
->peer
= sshbuf_new()) == NULL
||
523 (kex
->my
= sshbuf_new()) == NULL
) {
524 r
= SSH_ERR_ALLOC_FAIL
;
527 if ((r
= kex_prop2buf(kex
->my
, proposal
)) != 0)
530 kex_reset_dispatch(ssh
);
540 kex_free_newkeys(struct newkeys
*newkeys
)
544 if (newkeys
->enc
.key
) {
545 explicit_bzero(newkeys
->enc
.key
, newkeys
->enc
.key_len
);
546 free(newkeys
->enc
.key
);
547 newkeys
->enc
.key
= NULL
;
549 if (newkeys
->enc
.iv
) {
550 explicit_bzero(newkeys
->enc
.iv
, newkeys
->enc
.iv_len
);
551 free(newkeys
->enc
.iv
);
552 newkeys
->enc
.iv
= NULL
;
554 free(newkeys
->enc
.name
);
555 explicit_bzero(&newkeys
->enc
, sizeof(newkeys
->enc
));
556 free(newkeys
->comp
.name
);
557 explicit_bzero(&newkeys
->comp
, sizeof(newkeys
->comp
));
558 mac_clear(&newkeys
->mac
);
559 if (newkeys
->mac
.key
) {
560 explicit_bzero(newkeys
->mac
.key
, newkeys
->mac
.key_len
);
561 free(newkeys
->mac
.key
);
562 newkeys
->mac
.key
= NULL
;
564 free(newkeys
->mac
.name
);
565 explicit_bzero(&newkeys
->mac
, sizeof(newkeys
->mac
));
566 explicit_bzero(newkeys
, sizeof(*newkeys
));
571 kex_free(struct kex
*kex
)
578 #ifdef OPENSSL_HAS_ECC
579 if (kex
->ec_client_key
)
580 EC_KEY_free(kex
->ec_client_key
);
581 #endif /* OPENSSL_HAS_ECC */
582 #endif /* WITH_OPENSSL */
583 for (mode
= 0; mode
< MODE_MAX
; mode
++) {
584 kex_free_newkeys(kex
->newkeys
[mode
]);
585 kex
->newkeys
[mode
] = NULL
;
587 sshbuf_free(kex
->peer
);
588 sshbuf_free(kex
->my
);
589 free(kex
->session_id
);
590 free(kex
->client_version_string
);
591 free(kex
->server_version_string
);
592 free(kex
->failed_choice
);
593 free(kex
->hostkey_alg
);
599 kex_setup(struct ssh
*ssh
, char *proposal
[PROPOSAL_MAX
])
603 if ((r
= kex_new(ssh
, proposal
, &ssh
->kex
)) != 0)
605 if ((r
= kex_send_kexinit(ssh
)) != 0) { /* we start */
614 * Request key re-exchange, returns 0 on success or a ssherr.h error
615 * code otherwise. Must not be called if KEX is incomplete or in-progress.
618 kex_start_rekex(struct ssh
*ssh
)
620 if (ssh
->kex
== NULL
) {
621 error("%s: no kex", __func__
);
622 return SSH_ERR_INTERNAL_ERROR
;
624 if (ssh
->kex
->done
== 0) {
625 error("%s: requested twice", __func__
);
626 return SSH_ERR_INTERNAL_ERROR
;
629 return kex_send_kexinit(ssh
);
633 choose_enc(struct sshenc
*enc
, char *client
, char *server
)
635 char *name
= match_list(client
, server
, NULL
);
638 return SSH_ERR_NO_CIPHER_ALG_MATCH
;
639 if ((enc
->cipher
= cipher_by_name(name
)) == NULL
)
640 return SSH_ERR_INTERNAL_ERROR
;
644 enc
->iv_len
= cipher_ivlen(enc
->cipher
);
646 enc
->key_len
= cipher_keylen(enc
->cipher
);
647 enc
->block_size
= cipher_blocksize(enc
->cipher
);
652 choose_mac(struct ssh
*ssh
, struct sshmac
*mac
, char *client
, char *server
)
654 char *name
= match_list(client
, server
, NULL
);
657 return SSH_ERR_NO_MAC_ALG_MATCH
;
658 if (mac_setup(mac
, name
) < 0)
659 return SSH_ERR_INTERNAL_ERROR
;
660 /* truncate the key */
661 if (ssh
->compat
& SSH_BUG_HMAC
)
670 choose_comp(struct sshcomp
*comp
, char *client
, char *server
)
672 char *name
= match_list(client
, server
, NULL
);
675 return SSH_ERR_NO_COMPRESS_ALG_MATCH
;
676 if (strcmp(name
, "zlib@openssh.com") == 0) {
677 comp
->type
= COMP_DELAYED
;
678 } else if (strcmp(name
, "zlib") == 0) {
679 comp
->type
= COMP_ZLIB
;
680 } else if (strcmp(name
, "none") == 0) {
681 comp
->type
= COMP_NONE
;
683 return SSH_ERR_INTERNAL_ERROR
;
690 choose_kex(struct kex
*k
, char *client
, char *server
)
692 const struct kexalg
*kexalg
;
694 k
->name
= match_list(client
, server
, NULL
);
696 debug("kex: algorithm: %s", k
->name
? k
->name
: "(no match)");
698 return SSH_ERR_NO_KEX_ALG_MATCH
;
699 if ((kexalg
= kex_alg_by_name(k
->name
)) == NULL
)
700 return SSH_ERR_INTERNAL_ERROR
;
701 k
->kex_type
= kexalg
->type
;
702 k
->hash_alg
= kexalg
->hash_alg
;
703 k
->ec_nid
= kexalg
->ec_nid
;
708 choose_hostkeyalg(struct kex
*k
, char *client
, char *server
)
710 k
->hostkey_alg
= match_list(client
, server
, NULL
);
712 debug("kex: host key algorithm: %s",
713 k
->hostkey_alg
? k
->hostkey_alg
: "(no match)");
714 if (k
->hostkey_alg
== NULL
)
715 return SSH_ERR_NO_HOSTKEY_ALG_MATCH
;
716 k
->hostkey_type
= sshkey_type_from_name(k
->hostkey_alg
);
717 if (k
->hostkey_type
== KEY_UNSPEC
)
718 return SSH_ERR_INTERNAL_ERROR
;
719 k
->hostkey_nid
= sshkey_ecdsa_nid_from_name(k
->hostkey_alg
);
724 proposals_match(char *my
[PROPOSAL_MAX
], char *peer
[PROPOSAL_MAX
])
726 static int check
[] = {
727 PROPOSAL_KEX_ALGS
, PROPOSAL_SERVER_HOST_KEY_ALGS
, -1
732 for (idx
= &check
[0]; *idx
!= -1; idx
++) {
733 if ((p
= strchr(my
[*idx
], ',')) != NULL
)
735 if ((p
= strchr(peer
[*idx
], ',')) != NULL
)
737 if (strcmp(my
[*idx
], peer
[*idx
]) != 0) {
738 debug2("proposal mismatch: my %s peer %s",
739 my
[*idx
], peer
[*idx
]);
743 debug2("proposals match");
748 kex_choose_conf(struct ssh
*ssh
)
750 struct kex
*kex
= ssh
->kex
;
751 struct newkeys
*newkeys
;
752 char **my
= NULL
, **peer
= NULL
;
753 char **cprop
, **sprop
;
754 int nenc
, nmac
, ncomp
;
755 u_int mode
, ctos
, need
, dh_need
, authlen
;
756 int r
, first_kex_follows
;
758 debug2("local %s KEXINIT proposal", kex
->server
? "server" : "client");
759 if ((r
= kex_buf2prop(kex
->my
, NULL
, &my
)) != 0)
761 debug2("peer %s KEXINIT proposal", kex
->server
? "client" : "server");
762 if ((r
= kex_buf2prop(kex
->peer
, &first_kex_follows
, &peer
)) != 0)
773 /* Check whether client supports ext_info_c */
777 ext
= match_list("ext-info-c", peer
[PROPOSAL_KEX_ALGS
], NULL
);
784 /* Algorithm Negotiation */
785 if ((r
= choose_kex(kex
, cprop
[PROPOSAL_KEX_ALGS
],
786 sprop
[PROPOSAL_KEX_ALGS
])) != 0) {
787 kex
->failed_choice
= peer
[PROPOSAL_KEX_ALGS
];
788 peer
[PROPOSAL_KEX_ALGS
] = NULL
;
791 if ((r
= choose_hostkeyalg(kex
, cprop
[PROPOSAL_SERVER_HOST_KEY_ALGS
],
792 sprop
[PROPOSAL_SERVER_HOST_KEY_ALGS
])) != 0) {
793 kex
->failed_choice
= peer
[PROPOSAL_SERVER_HOST_KEY_ALGS
];
794 peer
[PROPOSAL_SERVER_HOST_KEY_ALGS
] = NULL
;
797 for (mode
= 0; mode
< MODE_MAX
; mode
++) {
798 if ((newkeys
= calloc(1, sizeof(*newkeys
))) == NULL
) {
799 r
= SSH_ERR_ALLOC_FAIL
;
802 kex
->newkeys
[mode
] = newkeys
;
803 ctos
= (!kex
->server
&& mode
== MODE_OUT
) ||
804 (kex
->server
&& mode
== MODE_IN
);
805 nenc
= ctos
? PROPOSAL_ENC_ALGS_CTOS
: PROPOSAL_ENC_ALGS_STOC
;
806 nmac
= ctos
? PROPOSAL_MAC_ALGS_CTOS
: PROPOSAL_MAC_ALGS_STOC
;
807 ncomp
= ctos
? PROPOSAL_COMP_ALGS_CTOS
: PROPOSAL_COMP_ALGS_STOC
;
808 if ((r
= choose_enc(&newkeys
->enc
, cprop
[nenc
],
809 sprop
[nenc
])) != 0) {
810 kex
->failed_choice
= peer
[nenc
];
814 authlen
= cipher_authlen(newkeys
->enc
.cipher
);
815 /* ignore mac for authenticated encryption */
817 (r
= choose_mac(ssh
, &newkeys
->mac
, cprop
[nmac
],
818 sprop
[nmac
])) != 0) {
819 kex
->failed_choice
= peer
[nmac
];
823 if ((r
= choose_comp(&newkeys
->comp
, cprop
[ncomp
],
824 sprop
[ncomp
])) != 0) {
825 kex
->failed_choice
= peer
[ncomp
];
829 debug("kex: %s cipher: %s MAC: %s compression: %s",
830 ctos
? "client->server" : "server->client",
832 authlen
== 0 ? newkeys
->mac
.name
: "<implicit>",
836 for (mode
= 0; mode
< MODE_MAX
; mode
++) {
837 newkeys
= kex
->newkeys
[mode
];
838 need
= MAX(need
, newkeys
->enc
.key_len
);
839 need
= MAX(need
, newkeys
->enc
.block_size
);
840 need
= MAX(need
, newkeys
->enc
.iv_len
);
841 need
= MAX(need
, newkeys
->mac
.key_len
);
842 dh_need
= MAX(dh_need
, cipher_seclen(newkeys
->enc
.cipher
));
843 dh_need
= MAX(dh_need
, newkeys
->enc
.block_size
);
844 dh_need
= MAX(dh_need
, newkeys
->enc
.iv_len
);
845 dh_need
= MAX(dh_need
, newkeys
->mac
.key_len
);
847 /* XXX need runden? */
849 kex
->dh_need
= dh_need
;
851 /* ignore the next message if the proposals do not match */
852 if (first_kex_follows
&& !proposals_match(my
, peer
) &&
853 !(ssh
->compat
& SSH_BUG_FIRSTKEX
))
854 ssh
->dispatch_skip_packets
= 1;
863 derive_key(struct ssh
*ssh
, int id
, u_int need
, u_char
*hash
, u_int hashlen
,
864 const struct sshbuf
*shared_secret
, u_char
**keyp
)
866 struct kex
*kex
= ssh
->kex
;
867 struct ssh_digest_ctx
*hashctx
= NULL
;
874 if ((mdsz
= ssh_digest_bytes(kex
->hash_alg
)) == 0)
875 return SSH_ERR_INVALID_ARGUMENT
;
876 if ((digest
= calloc(1, roundup(need
, mdsz
))) == NULL
) {
877 r
= SSH_ERR_ALLOC_FAIL
;
881 /* K1 = HASH(K || H || "A" || session_id) */
882 if ((hashctx
= ssh_digest_start(kex
->hash_alg
)) == NULL
||
883 ssh_digest_update_buffer(hashctx
, shared_secret
) != 0 ||
884 ssh_digest_update(hashctx
, hash
, hashlen
) != 0 ||
885 ssh_digest_update(hashctx
, &c
, 1) != 0 ||
886 ssh_digest_update(hashctx
, kex
->session_id
,
887 kex
->session_id_len
) != 0 ||
888 ssh_digest_final(hashctx
, digest
, mdsz
) != 0) {
889 r
= SSH_ERR_LIBCRYPTO_ERROR
;
892 ssh_digest_free(hashctx
);
897 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
898 * Key = K1 || K2 || ... || Kn
900 for (have
= mdsz
; need
> have
; have
+= mdsz
) {
901 if ((hashctx
= ssh_digest_start(kex
->hash_alg
)) == NULL
||
902 ssh_digest_update_buffer(hashctx
, shared_secret
) != 0 ||
903 ssh_digest_update(hashctx
, hash
, hashlen
) != 0 ||
904 ssh_digest_update(hashctx
, digest
, have
) != 0 ||
905 ssh_digest_final(hashctx
, digest
+ have
, mdsz
) != 0) {
906 r
= SSH_ERR_LIBCRYPTO_ERROR
;
909 ssh_digest_free(hashctx
);
913 fprintf(stderr
, "key '%c'== ", c
);
914 dump_digest("key", digest
, need
);
921 ssh_digest_free(hashctx
);
927 kex_derive_keys(struct ssh
*ssh
, u_char
*hash
, u_int hashlen
,
928 const struct sshbuf
*shared_secret
)
930 struct kex
*kex
= ssh
->kex
;
932 u_int i
, j
, mode
, ctos
;
935 for (i
= 0; i
< NKEYS
; i
++) {
936 if ((r
= derive_key(ssh
, 'A'+i
, kex
->we_need
, hash
, hashlen
,
937 shared_secret
, &keys
[i
])) != 0) {
938 for (j
= 0; j
< i
; j
++)
943 for (mode
= 0; mode
< MODE_MAX
; mode
++) {
944 ctos
= (!kex
->server
&& mode
== MODE_OUT
) ||
945 (kex
->server
&& mode
== MODE_IN
);
946 kex
->newkeys
[mode
]->enc
.iv
= keys
[ctos
? 0 : 1];
947 kex
->newkeys
[mode
]->enc
.key
= keys
[ctos
? 2 : 3];
948 kex
->newkeys
[mode
]->mac
.key
= keys
[ctos
? 4 : 5];
955 kex_derive_keys_bn(struct ssh
*ssh
, u_char
*hash
, u_int hashlen
,
956 const BIGNUM
*secret
)
958 struct sshbuf
*shared_secret
;
961 if ((shared_secret
= sshbuf_new()) == NULL
)
962 return SSH_ERR_ALLOC_FAIL
;
963 if ((r
= sshbuf_put_bignum2(shared_secret
, secret
)) == 0)
964 r
= kex_derive_keys(ssh
, hash
, hashlen
, shared_secret
);
965 sshbuf_free(shared_secret
);
972 derive_ssh1_session_id(BIGNUM
*host_modulus
, BIGNUM
*server_modulus
,
973 u_int8_t cookie
[8], u_int8_t id
[16])
975 u_int8_t hbuf
[2048], sbuf
[2048], obuf
[SSH_DIGEST_MAX_LENGTH
];
976 struct ssh_digest_ctx
*hashctx
= NULL
;
980 hlen
= BN_num_bytes(host_modulus
);
981 slen
= BN_num_bytes(server_modulus
);
982 if (hlen
< (512 / 8) || (u_int
)hlen
> sizeof(hbuf
) ||
983 slen
< (512 / 8) || (u_int
)slen
> sizeof(sbuf
))
984 return SSH_ERR_KEY_BITS_MISMATCH
;
985 if (BN_bn2bin(host_modulus
, hbuf
) <= 0 ||
986 BN_bn2bin(server_modulus
, sbuf
) <= 0) {
987 r
= SSH_ERR_LIBCRYPTO_ERROR
;
990 if ((hashctx
= ssh_digest_start(SSH_DIGEST_MD5
)) == NULL
) {
991 r
= SSH_ERR_ALLOC_FAIL
;
994 if (ssh_digest_update(hashctx
, hbuf
, hlen
) != 0 ||
995 ssh_digest_update(hashctx
, sbuf
, slen
) != 0 ||
996 ssh_digest_update(hashctx
, cookie
, 8) != 0 ||
997 ssh_digest_final(hashctx
, obuf
, sizeof(obuf
)) != 0) {
998 r
= SSH_ERR_LIBCRYPTO_ERROR
;
1001 memcpy(id
, obuf
, ssh_digest_bytes(SSH_DIGEST_MD5
));
1004 ssh_digest_free(hashctx
);
1005 explicit_bzero(hbuf
, sizeof(hbuf
));
1006 explicit_bzero(sbuf
, sizeof(sbuf
));
1007 explicit_bzero(obuf
, sizeof(obuf
));
1012 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
1014 dump_digest(char *msg
, u_char
*digest
, int len
)
1016 fprintf(stderr
, "%s\n", msg
);
1017 sshbuf_dump_data(digest
, len
, stderr
);