diff options
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | kex.h | 10 | ||||
-rw-r--r-- | kexdh.c | 140 | ||||
-rw-r--r-- | kexdhc.c | 151 | ||||
-rw-r--r-- | kexdhs.c | 142 | ||||
-rw-r--r-- | kexkemc.c | 16 | ||||
-rw-r--r-- | kexkems.c | 10 | ||||
-rw-r--r-- | monitor.c | 12 | ||||
-rw-r--r-- | ssh-keyscan.c | 12 | ||||
-rw-r--r-- | ssh_api.c | 22 | ||||
-rw-r--r-- | sshconnect2.c | 12 | ||||
-rw-r--r-- | sshd.c | 12 |
12 files changed, 155 insertions, 386 deletions
diff --git a/Makefile.in b/Makefile.in index 89f930367..3a179a66f 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -98,6 +98,8 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ | |||
98 | ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ | 98 | ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ |
99 | sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ | 99 | sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \ |
100 | kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ | 100 | kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ |
101 | kexgexc.o kexecdhc.o \ | ||
102 | kexgexs.o kexecdhs.o \ | ||
101 | sntrup4591761.o kexsntrup4591761x25519.o kexkemc.o kexkems.o \ | 103 | sntrup4591761.o kexsntrup4591761x25519.o kexkemc.o kexkems.o \ |
102 | platform-pledge.o platform-tracing.o platform-misc.o | 104 | platform-pledge.o platform-tracing.o platform-misc.o |
103 | 105 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.h,v 1.100 2019/01/21 10:24:09 djm Exp $ */ | 1 | /* $OpenBSD: kex.h,v 1.101 2019/01/21 10:28:01 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -211,6 +211,11 @@ int kexc25519_server(struct ssh *); | |||
211 | int kex_kem_client(struct ssh *); | 211 | int kex_kem_client(struct ssh *); |
212 | int kex_kem_server(struct ssh *); | 212 | int kex_kem_server(struct ssh *); |
213 | 213 | ||
214 | int kex_dh_keypair(struct kex *); | ||
215 | int kex_dh_enc(struct kex *, const u_char *, size_t, struct sshbuf **, | ||
216 | struct sshbuf **); | ||
217 | int kex_dh_dec(struct kex *, const u_char *, size_t, struct sshbuf **); | ||
218 | |||
214 | int kex_c25519_keypair(struct kex *); | 219 | int kex_c25519_keypair(struct kex *); |
215 | int kex_c25519_enc(struct kex *, const u_char *, size_t, struct sshbuf **, | 220 | int kex_c25519_enc(struct kex *, const u_char *, size_t, struct sshbuf **, |
216 | struct sshbuf **); | 221 | struct sshbuf **); |
@@ -224,9 +229,6 @@ int kex_kem_sntrup4591761x25519_dec(struct kex *, const u_char *, size_t, | |||
224 | 229 | ||
225 | int kex_dh_keygen(struct kex *); | 230 | int kex_dh_keygen(struct kex *); |
226 | int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *); | 231 | int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *); |
227 | int kex_dh_hash(int, const struct sshbuf *, const struct sshbuf *, | ||
228 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, | ||
229 | const BIGNUM *, const BIGNUM *, const u_char *, size_t, u_char *, size_t *); | ||
230 | 232 | ||
231 | int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, | 233 | int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, |
232 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, | 234 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, |
@@ -1,6 +1,6 @@ | |||
1 | /* $OpenBSD: kexdh.c,v 1.29 2019/01/21 10:03:37 djm Exp $ */ | 1 | /* $OpenBSD: kexdh.c,v 1.30 2019/01/21 10:28:01 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions | 6 | * modification, are permitted provided that the following conditions |
@@ -30,17 +30,11 @@ | |||
30 | #include <sys/types.h> | 30 | #include <sys/types.h> |
31 | 31 | ||
32 | #include <signal.h> | 32 | #include <signal.h> |
33 | #include <stdio.h> | ||
34 | #include <string.h> | ||
33 | 35 | ||
34 | #include <openssl/evp.h> | ||
35 | |||
36 | #include "openbsd-compat/openssl-compat.h" | ||
37 | |||
38 | #include "ssh2.h" | ||
39 | #include "sshkey.h" | 36 | #include "sshkey.h" |
40 | #include "cipher.h" | ||
41 | #include "kex.h" | 37 | #include "kex.h" |
42 | #include "dh.h" | ||
43 | #include "ssherr.h" | ||
44 | #include "sshbuf.h" | 38 | #include "sshbuf.h" |
45 | #include "digest.h" | 39 | #include "digest.h" |
46 | #include "dh.h" | 40 | #include "dh.h" |
@@ -113,53 +107,95 @@ kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) | |||
113 | } | 107 | } |
114 | 108 | ||
115 | int | 109 | int |
116 | kex_dh_hash( | 110 | kex_dh_keypair(struct kex *kex) |
117 | int hash_alg, | ||
118 | const struct sshbuf *client_version, | ||
119 | const struct sshbuf *server_version, | ||
120 | const u_char *ckexinit, size_t ckexinitlen, | ||
121 | const u_char *skexinit, size_t skexinitlen, | ||
122 | const u_char *serverhostkeyblob, size_t sbloblen, | ||
123 | const BIGNUM *client_dh_pub, | ||
124 | const BIGNUM *server_dh_pub, | ||
125 | const u_char *shared_secret, size_t secretlen, | ||
126 | u_char *hash, size_t *hashlen) | ||
127 | { | 111 | { |
128 | struct sshbuf *b; | 112 | const BIGNUM *pub_key; |
113 | struct sshbuf *buf = NULL; | ||
129 | int r; | 114 | int r; |
130 | 115 | ||
131 | if (*hashlen < ssh_digest_bytes(hash_alg)) | 116 | if ((r = kex_dh_keygen(kex)) != 0) |
132 | return SSH_ERR_INVALID_ARGUMENT; | ||
133 | if ((b = sshbuf_new()) == NULL) | ||
134 | return SSH_ERR_ALLOC_FAIL; | ||
135 | if ((r = sshbuf_put_stringb(b, client_version)) < 0 || | ||
136 | (r = sshbuf_put_stringb(b, server_version)) < 0 || | ||
137 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ | ||
138 | (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || | ||
139 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || | ||
140 | (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 || | ||
141 | (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 || | ||
142 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || | ||
143 | (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || | ||
144 | (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || | ||
145 | (r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 || | ||
146 | (r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 || | ||
147 | (r = sshbuf_put(b, shared_secret, secretlen)) != 0) { | ||
148 | sshbuf_free(b); | ||
149 | return r; | 117 | return r; |
150 | } | 118 | DH_get0_key(kex->dh, &pub_key, NULL); |
151 | #ifdef DEBUG_KEX | 119 | if ((buf = sshbuf_new()) == NULL) |
152 | sshbuf_dump(b, stderr); | 120 | return SSH_ERR_ALLOC_FAIL; |
121 | if ((r = sshbuf_put_bignum2(buf, pub_key)) != 0 || | ||
122 | (r = sshbuf_get_u32(buf, NULL)) != 0) | ||
123 | goto out; | ||
124 | #ifdef DEBUG_KEXDH | ||
125 | DHparams_print_fp(stderr, kex->dh); | ||
126 | fprintf(stderr, "pub= "); | ||
127 | BN_print_fp(stderr, pub_key); | ||
128 | fprintf(stderr, "\n"); | ||
153 | #endif | 129 | #endif |
154 | if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) { | 130 | kex->kem_client_pub = buf; |
155 | sshbuf_free(b); | 131 | buf = NULL; |
156 | return SSH_ERR_LIBCRYPTO_ERROR; | 132 | out: |
133 | sshbuf_free(buf); | ||
134 | return r; | ||
135 | } | ||
136 | |||
137 | int | ||
138 | kex_dh_enc(struct kex *kex, const u_char *pkblob, size_t pklen, | ||
139 | struct sshbuf **server_blobp, struct sshbuf **shared_secretp) | ||
140 | { | ||
141 | const BIGNUM *pub_key; | ||
142 | struct sshbuf *server_blob = NULL; | ||
143 | int r; | ||
144 | |||
145 | *server_blobp = NULL; | ||
146 | *shared_secretp = NULL; | ||
147 | |||
148 | if ((r = kex_dh_keygen(kex)) != 0) | ||
149 | goto out; | ||
150 | DH_get0_key(kex->dh, &pub_key, NULL); | ||
151 | if ((server_blob = sshbuf_new()) == NULL) { | ||
152 | r = SSH_ERR_ALLOC_FAIL; | ||
153 | goto out; | ||
157 | } | 154 | } |
158 | sshbuf_free(b); | 155 | if ((r = sshbuf_put_bignum2(server_blob, pub_key)) != 0 || |
159 | *hashlen = ssh_digest_bytes(hash_alg); | 156 | (r = sshbuf_get_u32(server_blob, NULL)) != 0) |
160 | #ifdef DEBUG_KEX | 157 | goto out; |
161 | dump_digest("hash", hash, *hashlen); | 158 | if ((r = kex_dh_dec(kex, pkblob, pklen, shared_secretp)) != 0) |
162 | #endif | 159 | goto out; |
163 | return 0; | 160 | *server_blobp = server_blob; |
161 | server_blob = NULL; | ||
162 | out: | ||
163 | DH_free(kex->dh); | ||
164 | kex->dh = NULL; | ||
165 | sshbuf_free(server_blob); | ||
166 | return r; | ||
167 | } | ||
168 | |||
169 | int | ||
170 | kex_dh_dec(struct kex *kex, const u_char *pkblob, size_t pklen, | ||
171 | struct sshbuf **shared_secretp) | ||
172 | { | ||
173 | struct sshbuf *buf = NULL; | ||
174 | BIGNUM *dh_pub = NULL; | ||
175 | int r; | ||
176 | |||
177 | *shared_secretp = NULL; | ||
178 | |||
179 | if ((buf = sshbuf_new()) == NULL) { | ||
180 | r = SSH_ERR_ALLOC_FAIL; | ||
181 | goto out; | ||
182 | } | ||
183 | if ((r = sshbuf_put_u32(buf, pklen)) != 0 || | ||
184 | (r = sshbuf_put(buf, pkblob, pklen)) != 0) { | ||
185 | goto out; | ||
186 | } | ||
187 | if ((r = sshbuf_get_bignum2(buf, &dh_pub)) != 0) { | ||
188 | goto out; | ||
189 | } | ||
190 | sshbuf_reset(buf); | ||
191 | if ((r = kex_dh_compute_key(kex, dh_pub, buf)) != 0) | ||
192 | goto out; | ||
193 | *shared_secretp = buf; | ||
194 | buf = NULL; | ||
195 | out: | ||
196 | DH_free(kex->dh); | ||
197 | kex->dh = NULL; | ||
198 | sshbuf_free(buf); | ||
199 | return r; | ||
164 | } | 200 | } |
165 | #endif /* WITH_OPENSSL */ | 201 | #endif /* WITH_OPENSSL */ |
diff --git a/kexdhc.c b/kexdhc.c deleted file mode 100644 index a2af8cb08..000000000 --- a/kexdhc.c +++ /dev/null | |||
@@ -1,151 +0,0 @@ | |||
1 | /* $OpenBSD: kexdhc.c,v 1.29 2019/01/21 10:07:22 djm Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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. | ||
13 | * | ||
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. | ||
24 | */ | ||
25 | |||
26 | #include "includes.h" | ||
27 | |||
28 | #ifdef WITH_OPENSSL | ||
29 | |||
30 | #include <sys/types.h> | ||
31 | |||
32 | #include <openssl/dh.h> | ||
33 | |||
34 | #include <stdarg.h> | ||
35 | #include <stdio.h> | ||
36 | #include <string.h> | ||
37 | #include <signal.h> | ||
38 | |||
39 | #include "openbsd-compat/openssl-compat.h" | ||
40 | |||
41 | #include "sshkey.h" | ||
42 | #include "cipher.h" | ||
43 | #include "digest.h" | ||
44 | #include "dh.h" | ||
45 | #include "kex.h" | ||
46 | #include "log.h" | ||
47 | #include "packet.h" | ||
48 | #include "ssh2.h" | ||
49 | #include "dispatch.h" | ||
50 | #include "compat.h" | ||
51 | #include "ssherr.h" | ||
52 | #include "sshbuf.h" | ||
53 | |||
54 | static int input_kex_dh(int, u_int32_t, struct ssh *); | ||
55 | |||
56 | int | ||
57 | kexdh_client(struct ssh *ssh) | ||
58 | { | ||
59 | struct kex *kex = ssh->kex; | ||
60 | int r; | ||
61 | const BIGNUM *pub_key; | ||
62 | |||
63 | /* generate and send 'e', client DH public key */ | ||
64 | if ((r = kex_dh_keygen(kex)) != 0) | ||
65 | goto out; | ||
66 | debug("sending SSH2_MSG_KEXDH_INIT"); | ||
67 | DH_get0_key(kex->dh, &pub_key, NULL); | ||
68 | if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || | ||
69 | (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || | ||
70 | (r = sshpkt_send(ssh)) != 0) | ||
71 | goto out; | ||
72 | #ifdef DEBUG_KEXDH | ||
73 | DHparams_print_fp(stderr, kex->dh); | ||
74 | fprintf(stderr, "pub= "); | ||
75 | BN_print_fp(stderr, pub_key); | ||
76 | fprintf(stderr, "\n"); | ||
77 | #endif | ||
78 | debug("expecting SSH2_MSG_KEXDH_REPLY"); | ||
79 | ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh); | ||
80 | r = 0; | ||
81 | out: | ||
82 | return r; | ||
83 | } | ||
84 | |||
85 | static int | ||
86 | input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) | ||
87 | { | ||
88 | struct kex *kex = ssh->kex; | ||
89 | BIGNUM *dh_server_pub = NULL; | ||
90 | const BIGNUM *pub_key; | ||
91 | struct sshkey *server_host_key = NULL; | ||
92 | struct sshbuf *shared_secret = NULL; | ||
93 | u_char *server_host_key_blob = NULL, *signature = NULL; | ||
94 | u_char hash[SSH_DIGEST_MAX_LENGTH]; | ||
95 | size_t slen, sbloblen, hashlen; | ||
96 | int r; | ||
97 | |||
98 | /* key, cert */ | ||
99 | if ((r = sshpkt_get_string(ssh, &server_host_key_blob, | ||
100 | &sbloblen)) != 0 || | ||
101 | (r = sshkey_from_blob(server_host_key_blob, sbloblen, | ||
102 | &server_host_key)) != 0) | ||
103 | goto out; | ||
104 | if ((r = kex_verify_host_key(ssh, server_host_key)) != 0) | ||
105 | goto out; | ||
106 | /* DH parameter f, server public DH key, signed H */ | ||
107 | if ((r = sshpkt_get_bignum2(ssh, &dh_server_pub)) != 0 || | ||
108 | (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || | ||
109 | (r = sshpkt_get_end(ssh)) != 0) | ||
110 | goto out; | ||
111 | if ((shared_secret = sshbuf_new()) == NULL) { | ||
112 | r = SSH_ERR_ALLOC_FAIL; | ||
113 | goto out; | ||
114 | } | ||
115 | if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) | ||
116 | goto out; | ||
117 | |||
118 | /* calc and verify H */ | ||
119 | DH_get0_key(kex->dh, &pub_key, NULL); | ||
120 | hashlen = sizeof(hash); | ||
121 | if ((r = kex_dh_hash( | ||
122 | kex->hash_alg, | ||
123 | kex->client_version, | ||
124 | kex->server_version, | ||
125 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | ||
126 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | ||
127 | server_host_key_blob, sbloblen, | ||
128 | pub_key, | ||
129 | dh_server_pub, | ||
130 | sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), | ||
131 | hash, &hashlen)) != 0) | ||
132 | goto out; | ||
133 | |||
134 | if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, | ||
135 | kex->hostkey_alg, ssh->compat)) != 0) | ||
136 | goto out; | ||
137 | |||
138 | if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) | ||
139 | r = kex_send_newkeys(ssh); | ||
140 | out: | ||
141 | explicit_bzero(hash, sizeof(hash)); | ||
142 | DH_free(kex->dh); | ||
143 | kex->dh = NULL; | ||
144 | BN_clear_free(dh_server_pub); | ||
145 | sshbuf_free(shared_secret); | ||
146 | sshkey_free(server_host_key); | ||
147 | free(server_host_key_blob); | ||
148 | free(signature); | ||
149 | return r; | ||
150 | } | ||
151 | #endif /* WITH_OPENSSL */ | ||
diff --git a/kexdhs.c b/kexdhs.c deleted file mode 100644 index e33901bbf..000000000 --- a/kexdhs.c +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
1 | /* $OpenBSD: kexdhs.c,v 1.35 2019/01/21 10:05:09 djm Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
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. | ||
13 | * | ||
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. | ||
24 | */ | ||
25 | |||
26 | #include "includes.h" | ||
27 | |||
28 | #ifdef WITH_OPENSSL | ||
29 | |||
30 | #include <sys/types.h> | ||
31 | |||
32 | #include <stdarg.h> | ||
33 | #include <string.h> | ||
34 | #include <signal.h> | ||
35 | |||
36 | #include <openssl/dh.h> | ||
37 | |||
38 | #include "openbsd-compat/openssl-compat.h" | ||
39 | |||
40 | #include "sshkey.h" | ||
41 | #include "cipher.h" | ||
42 | #include "digest.h" | ||
43 | #include "dh.h" | ||
44 | #include "kex.h" | ||
45 | #include "log.h" | ||
46 | #include "packet.h" | ||
47 | #include "ssh2.h" | ||
48 | |||
49 | #include "dispatch.h" | ||
50 | #include "compat.h" | ||
51 | #include "ssherr.h" | ||
52 | #include "sshbuf.h" | ||
53 | |||
54 | static int input_kex_dh_init(int, u_int32_t, struct ssh *); | ||
55 | |||
56 | int | ||
57 | kexdh_server(struct ssh *ssh) | ||
58 | { | ||
59 | struct kex *kex = ssh->kex; | ||
60 | int r; | ||
61 | |||
62 | /* generate server DH public key */ | ||
63 | if ((r = kex_dh_keygen(kex)) != 0) | ||
64 | return r; | ||
65 | debug("expecting SSH2_MSG_KEXDH_INIT"); | ||
66 | ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | int | ||
71 | input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh) | ||
72 | { | ||
73 | struct kex *kex = ssh->kex; | ||
74 | BIGNUM *dh_client_pub = NULL; | ||
75 | const BIGNUM *pub_key; | ||
76 | struct sshkey *server_host_public, *server_host_private; | ||
77 | struct sshbuf *shared_secret = NULL; | ||
78 | u_char *signature = NULL, *server_host_key_blob = NULL; | ||
79 | u_char hash[SSH_DIGEST_MAX_LENGTH]; | ||
80 | size_t sbloblen, slen; | ||
81 | size_t hashlen; | ||
82 | int r; | ||
83 | |||
84 | if ((r = kex_load_hostkey(ssh, &server_host_private, | ||
85 | &server_host_public)) != 0) | ||
86 | goto out; | ||
87 | |||
88 | /* key, cert */ | ||
89 | if ((r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 || | ||
90 | (r = sshpkt_get_end(ssh)) != 0) | ||
91 | goto out; | ||
92 | if ((shared_secret = sshbuf_new()) == NULL) { | ||
93 | r = SSH_ERR_ALLOC_FAIL; | ||
94 | goto out; | ||
95 | } | ||
96 | if ((r = kex_dh_compute_key(kex, dh_client_pub, shared_secret)) != 0) | ||
97 | goto out; | ||
98 | if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, | ||
99 | &sbloblen)) != 0) | ||
100 | goto out; | ||
101 | /* calc H */ | ||
102 | DH_get0_key(kex->dh, &pub_key, NULL); | ||
103 | hashlen = sizeof(hash); | ||
104 | if ((r = kex_dh_hash( | ||
105 | kex->hash_alg, | ||
106 | kex->client_version, | ||
107 | kex->server_version, | ||
108 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | ||
109 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | ||
110 | server_host_key_blob, sbloblen, | ||
111 | dh_client_pub, | ||
112 | pub_key, | ||
113 | sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), | ||
114 | hash, &hashlen)) != 0) | ||
115 | goto out; | ||
116 | |||
117 | /* sign H */ | ||
118 | if ((r = kex->sign(ssh, server_host_private, server_host_public, | ||
119 | &signature, &slen, hash, hashlen, kex->hostkey_alg)) < 0) | ||
120 | goto out; | ||
121 | |||
122 | /* send server hostkey, DH pubkey 'f' and signed H */ | ||
123 | if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || | ||
124 | (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || | ||
125 | (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */ | ||
126 | (r = sshpkt_put_string(ssh, signature, slen)) != 0 || | ||
127 | (r = sshpkt_send(ssh)) != 0) | ||
128 | goto out; | ||
129 | |||
130 | if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) | ||
131 | r = kex_send_newkeys(ssh); | ||
132 | out: | ||
133 | explicit_bzero(hash, sizeof(hash)); | ||
134 | DH_free(kex->dh); | ||
135 | kex->dh = NULL; | ||
136 | BN_clear_free(dh_client_pub); | ||
137 | sshbuf_free(shared_secret); | ||
138 | free(server_host_key_blob); | ||
139 | free(signature); | ||
140 | return r; | ||
141 | } | ||
142 | #endif /* WITH_OPENSSL */ | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexkemc.c,v 1.2 2019/01/21 10:24:09 djm Exp $ */ | 1 | /* $OpenBSD: kexkemc.c,v 1.3 2019/01/21 10:28:02 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -48,6 +48,13 @@ kex_kem_client(struct ssh *ssh) | |||
48 | int r; | 48 | int r; |
49 | 49 | ||
50 | switch (kex->kex_type) { | 50 | switch (kex->kex_type) { |
51 | case KEX_DH_GRP1_SHA1: | ||
52 | case KEX_DH_GRP14_SHA1: | ||
53 | case KEX_DH_GRP14_SHA256: | ||
54 | case KEX_DH_GRP16_SHA512: | ||
55 | case KEX_DH_GRP18_SHA512: | ||
56 | r = kex_dh_keypair(kex); | ||
57 | break; | ||
51 | case KEX_C25519_SHA256: | 58 | case KEX_C25519_SHA256: |
52 | r = kex_c25519_keypair(kex); | 59 | r = kex_c25519_keypair(kex); |
53 | break; | 60 | break; |
@@ -99,6 +106,13 @@ input_kex_kem_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
99 | 106 | ||
100 | /* compute shared secret */ | 107 | /* compute shared secret */ |
101 | switch (kex->kex_type) { | 108 | switch (kex->kex_type) { |
109 | case KEX_DH_GRP1_SHA1: | ||
110 | case KEX_DH_GRP14_SHA1: | ||
111 | case KEX_DH_GRP14_SHA256: | ||
112 | case KEX_DH_GRP16_SHA512: | ||
113 | case KEX_DH_GRP18_SHA512: | ||
114 | r = kex_dh_dec(kex, server_pubkey, pklen, &shared_secret); | ||
115 | break; | ||
102 | case KEX_C25519_SHA256: | 116 | case KEX_C25519_SHA256: |
103 | r = kex_c25519_dec(kex, server_pubkey, pklen, &shared_secret); | 117 | r = kex_c25519_dec(kex, server_pubkey, pklen, &shared_secret); |
104 | break; | 118 | break; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexkems.c,v 1.2 2019/01/21 10:24:09 djm Exp $ */ | 1 | /* $OpenBSD: kexkems.c,v 1.3 2019/01/21 10:28:02 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -69,6 +69,14 @@ input_kex_kem_init(int type, u_int32_t seq, struct ssh *ssh) | |||
69 | 69 | ||
70 | /* compute shared secret */ | 70 | /* compute shared secret */ |
71 | switch (kex->kex_type) { | 71 | switch (kex->kex_type) { |
72 | case KEX_DH_GRP1_SHA1: | ||
73 | case KEX_DH_GRP14_SHA1: | ||
74 | case KEX_DH_GRP14_SHA256: | ||
75 | case KEX_DH_GRP16_SHA512: | ||
76 | case KEX_DH_GRP18_SHA512: | ||
77 | r = kex_dh_enc(kex, client_pubkey, pklen, &server_pubkey, | ||
78 | &shared_secret); | ||
79 | break; | ||
72 | case KEX_C25519_SHA256: | 80 | case KEX_C25519_SHA256: |
73 | r = kex_c25519_enc(kex, client_pubkey, pklen, &server_pubkey, | 81 | r = kex_c25519_enc(kex, client_pubkey, pklen, &server_pubkey, |
74 | &shared_secret); | 82 | &shared_secret); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.194 2019/01/21 10:24:09 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.195 2019/01/21 10:28:02 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -1677,11 +1677,11 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) | |||
1677 | if ((kex = ssh->kex) != NULL) { | 1677 | if ((kex = ssh->kex) != NULL) { |
1678 | /* XXX set callbacks */ | 1678 | /* XXX set callbacks */ |
1679 | #ifdef WITH_OPENSSL | 1679 | #ifdef WITH_OPENSSL |
1680 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; | 1680 | kex->kex[KEX_DH_GRP1_SHA1] = kex_kem_server; |
1681 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; | 1681 | kex->kex[KEX_DH_GRP14_SHA1] = kex_kem_server; |
1682 | kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server; | 1682 | kex->kex[KEX_DH_GRP14_SHA256] = kex_kem_server; |
1683 | kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; | 1683 | kex->kex[KEX_DH_GRP16_SHA512] = kex_kem_server; |
1684 | kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server; | 1684 | kex->kex[KEX_DH_GRP18_SHA512] = kex_kem_server; |
1685 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; | 1685 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; |
1686 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; | 1686 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; |
1687 | # ifdef OPENSSL_HAS_ECC | 1687 | # ifdef OPENSSL_HAS_ECC |
diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 9eebc1445..3d2760056 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keyscan.c,v 1.122 2019/01/21 10:24:09 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keyscan.c,v 1.123 2019/01/21 10:28:02 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. | 3 | * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. |
4 | * | 4 | * |
@@ -260,11 +260,11 @@ keygrab_ssh2(con *c) | |||
260 | exit(1); | 260 | exit(1); |
261 | } | 261 | } |
262 | #ifdef WITH_OPENSSL | 262 | #ifdef WITH_OPENSSL |
263 | c->c_ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; | 263 | c->c_ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_kem_client; |
264 | c->c_ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; | 264 | c->c_ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_kem_client; |
265 | c->c_ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client; | 265 | c->c_ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_kem_client; |
266 | c->c_ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; | 266 | c->c_ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_kem_client; |
267 | c->c_ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client; | 267 | c->c_ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_kem_client; |
268 | c->c_ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; | 268 | c->c_ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; |
269 | c->c_ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; | 269 | c->c_ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; |
270 | # ifdef OPENSSL_HAS_ECC | 270 | # ifdef OPENSSL_HAS_ECC |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh_api.c,v 1.12 2019/01/21 10:24:09 djm Exp $ */ | 1 | /* $OpenBSD: ssh_api.c,v 1.13 2019/01/21 10:28:02 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2012 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2012 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -99,11 +99,11 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) | |||
99 | ssh->kex->server = is_server; | 99 | ssh->kex->server = is_server; |
100 | if (is_server) { | 100 | if (is_server) { |
101 | #ifdef WITH_OPENSSL | 101 | #ifdef WITH_OPENSSL |
102 | ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; | 102 | ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_kem_server; |
103 | ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; | 103 | ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_kem_server; |
104 | ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server; | 104 | ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_kem_server; |
105 | ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; | 105 | ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_kem_server; |
106 | ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server; | 106 | ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_kem_server; |
107 | ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; | 107 | ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; |
108 | ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; | 108 | ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; |
109 | # ifdef OPENSSL_HAS_ECC | 109 | # ifdef OPENSSL_HAS_ECC |
@@ -117,11 +117,11 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) | |||
117 | ssh->kex->sign=&_ssh_host_key_sign; | 117 | ssh->kex->sign=&_ssh_host_key_sign; |
118 | } else { | 118 | } else { |
119 | #ifdef WITH_OPENSSL | 119 | #ifdef WITH_OPENSSL |
120 | ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; | 120 | ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_kem_client; |
121 | ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; | 121 | ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_kem_client; |
122 | ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client; | 122 | ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_kem_client; |
123 | ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; | 123 | ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_kem_client; |
124 | ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client; | 124 | ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_kem_client; |
125 | ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; | 125 | ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; |
126 | ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; | 126 | ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; |
127 | # ifdef OPENSSL_HAS_ECC | 127 | # ifdef OPENSSL_HAS_ECC |
diff --git a/sshconnect2.c b/sshconnect2.c index be19722bb..ebeff29bd 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.298 2019/01/21 10:24:09 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.299 2019/01/21 10:28:02 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -201,11 +201,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port) | |||
201 | if ((r = kex_setup(ssh, myproposal)) != 0) | 201 | if ((r = kex_setup(ssh, myproposal)) != 0) |
202 | fatal("kex_setup: %s", ssh_err(r)); | 202 | fatal("kex_setup: %s", ssh_err(r)); |
203 | #ifdef WITH_OPENSSL | 203 | #ifdef WITH_OPENSSL |
204 | ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; | 204 | ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_kem_client; |
205 | ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; | 205 | ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_kem_client; |
206 | ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client; | 206 | ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_kem_client; |
207 | ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; | 207 | ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_kem_client; |
208 | ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client; | 208 | ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_kem_client; |
209 | ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; | 209 | ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; |
210 | ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; | 210 | ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; |
211 | # ifdef OPENSSL_HAS_ECC | 211 | # ifdef OPENSSL_HAS_ECC |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.529 2019/01/21 10:24:09 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.530 2019/01/21 10:28:02 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -2207,11 +2207,11 @@ do_ssh2_kex(struct ssh *ssh) | |||
2207 | fatal("kex_setup: %s", ssh_err(r)); | 2207 | fatal("kex_setup: %s", ssh_err(r)); |
2208 | kex = ssh->kex; | 2208 | kex = ssh->kex; |
2209 | #ifdef WITH_OPENSSL | 2209 | #ifdef WITH_OPENSSL |
2210 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; | 2210 | kex->kex[KEX_DH_GRP1_SHA1] = kex_kem_server; |
2211 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; | 2211 | kex->kex[KEX_DH_GRP14_SHA1] = kex_kem_server; |
2212 | kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server; | 2212 | kex->kex[KEX_DH_GRP14_SHA256] = kex_kem_server; |
2213 | kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; | 2213 | kex->kex[KEX_DH_GRP16_SHA512] = kex_kem_server; |
2214 | kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server; | 2214 | kex->kex[KEX_DH_GRP18_SHA512] = kex_kem_server; |
2215 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; | 2215 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; |
2216 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; | 2216 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; |
2217 | # ifdef OPENSSL_HAS_ECC | 2217 | # ifdef OPENSSL_HAS_ECC |