diff options
-rw-r--r-- | kex.h | 22 | ||||
-rw-r--r-- | kexc25519.c | 38 | ||||
-rw-r--r-- | kexdh.c | 16 | ||||
-rw-r--r-- | kexecdh.c | 18 | ||||
-rw-r--r-- | kexkemc.c | 24 | ||||
-rw-r--r-- | kexkems.c | 24 | ||||
-rw-r--r-- | kexsntrup4591761x25519.c | 34 | ||||
-rw-r--r-- | packet.c | 8 | ||||
-rw-r--r-- | packet.h | 3 |
9 files changed, 98 insertions, 89 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.h,v 1.103 2019/01/21 10:33:49 djm Exp $ */ | 1 | /* $OpenBSD: kex.h,v 1.104 2019/01/21 10:35:09 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,24 +211,24 @@ int kex_kem_client(struct ssh *); | |||
211 | int kex_kem_server(struct ssh *); | 211 | int kex_kem_server(struct ssh *); |
212 | 212 | ||
213 | int kex_dh_keypair(struct kex *); | 213 | int kex_dh_keypair(struct kex *); |
214 | int kex_dh_enc(struct kex *, const u_char *, size_t, struct sshbuf **, | 214 | int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, |
215 | struct sshbuf **); | 215 | struct sshbuf **); |
216 | int kex_dh_dec(struct kex *, const u_char *, size_t, struct sshbuf **); | 216 | int kex_dh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); |
217 | 217 | ||
218 | int kex_ecdh_keypair(struct kex *); | 218 | int kex_ecdh_keypair(struct kex *); |
219 | int kex_ecdh_enc(struct kex *, const u_char *, size_t, struct sshbuf **, | 219 | int kex_ecdh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, |
220 | struct sshbuf **); | 220 | struct sshbuf **); |
221 | int kex_ecdh_dec(struct kex *, const u_char *, size_t, struct sshbuf **); | 221 | int kex_ecdh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); |
222 | 222 | ||
223 | int kex_c25519_keypair(struct kex *); | 223 | int kex_c25519_keypair(struct kex *); |
224 | int kex_c25519_enc(struct kex *, const u_char *, size_t, struct sshbuf **, | 224 | int kex_c25519_enc(struct kex *, const struct sshbuf *, struct sshbuf **, |
225 | struct sshbuf **); | 225 | struct sshbuf **); |
226 | int kex_c25519_dec(struct kex *, const u_char *, size_t, struct sshbuf **); | 226 | int kex_c25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **); |
227 | 227 | ||
228 | int kex_kem_sntrup4591761x25519_keypair(struct kex *); | 228 | int kex_kem_sntrup4591761x25519_keypair(struct kex *); |
229 | int kex_kem_sntrup4591761x25519_enc(struct kex *, const u_char *, size_t, | 229 | int kex_kem_sntrup4591761x25519_enc(struct kex *, const struct sshbuf *, |
230 | struct sshbuf **, struct sshbuf **); | 230 | struct sshbuf **, struct sshbuf **); |
231 | int kex_kem_sntrup4591761x25519_dec(struct kex *, const u_char *, size_t, | 231 | int kex_kem_sntrup4591761x25519_dec(struct kex *, const struct sshbuf *, |
232 | struct sshbuf **); | 232 | struct sshbuf **); |
233 | 233 | ||
234 | int kex_dh_keygen(struct kex *); | 234 | int kex_dh_keygen(struct kex *); |
@@ -243,8 +243,8 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, | |||
243 | 243 | ||
244 | int kex_c25519_hash(int, const struct sshbuf *, const struct sshbuf *, | 244 | int kex_c25519_hash(int, const struct sshbuf *, const struct sshbuf *, |
245 | const u_char *, size_t, const u_char *, size_t, | 245 | const u_char *, size_t, const u_char *, size_t, |
246 | const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, | 246 | const u_char *, size_t, const struct sshbuf *, const struct sshbuf *, |
247 | const u_char *, size_t, u_char *, size_t *); | 247 | const struct sshbuf *, u_char *, size_t *); |
248 | 248 | ||
249 | void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) | 249 | void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) |
250 | __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) | 250 | __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) |
diff --git a/kexc25519.c b/kexc25519.c index a06c6e44b..ec5bb574f 100644 --- a/kexc25519.c +++ b/kexc25519.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexc25519.c,v 1.14 2019/01/21 10:24:09 djm Exp $ */ | 1 | /* $OpenBSD: kexc25519.c,v 1.15 2019/01/21 10:35:09 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
@@ -96,9 +96,9 @@ kex_c25519_hash( | |||
96 | const u_char *ckexinit, size_t ckexinitlen, | 96 | const u_char *ckexinit, size_t ckexinitlen, |
97 | const u_char *skexinit, size_t skexinitlen, | 97 | const u_char *skexinit, size_t skexinitlen, |
98 | const u_char *serverhostkeyblob, size_t sbloblen, | 98 | const u_char *serverhostkeyblob, size_t sbloblen, |
99 | const u_char *client_pub, size_t client_pub_len, | 99 | const struct sshbuf *client_pub, |
100 | const u_char *server_pub, size_t server_pub_len, | 100 | const struct sshbuf *server_pub, |
101 | const u_char *shared_secret, size_t secretlen, | 101 | const struct sshbuf *shared_secret, |
102 | u_char *hash, size_t *hashlen) | 102 | u_char *hash, size_t *hashlen) |
103 | { | 103 | { |
104 | struct sshbuf *b; | 104 | struct sshbuf *b; |
@@ -118,9 +118,9 @@ kex_c25519_hash( | |||
118 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || | 118 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || |
119 | (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || | 119 | (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || |
120 | (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || | 120 | (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || |
121 | (r = sshbuf_put_string(b, client_pub, client_pub_len)) != 0 || | 121 | (r = sshbuf_put_stringb(b, client_pub)) != 0 || |
122 | (r = sshbuf_put_string(b, server_pub, server_pub_len)) != 0 || | 122 | (r = sshbuf_put_stringb(b, server_pub)) != 0 || |
123 | (r = sshbuf_put(b, shared_secret, secretlen)) != 0) { | 123 | (r = sshbuf_putb(b, shared_secret)) != 0) { |
124 | sshbuf_free(b); | 124 | sshbuf_free(b); |
125 | return r; | 125 | return r; |
126 | } | 126 | } |
@@ -162,11 +162,12 @@ kex_c25519_keypair(struct kex *kex) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | int | 164 | int |
165 | kex_c25519_enc(struct kex *kex, const u_char *pkblob, | 165 | kex_c25519_enc(struct kex *kex, const struct sshbuf *client_blob, |
166 | size_t pklen, struct sshbuf **server_blobp, struct sshbuf **shared_secretp) | 166 | struct sshbuf **server_blobp, struct sshbuf **shared_secretp) |
167 | { | 167 | { |
168 | struct sshbuf *server_blob = NULL; | 168 | struct sshbuf *server_blob = NULL; |
169 | struct sshbuf *buf = NULL; | 169 | struct sshbuf *buf = NULL; |
170 | const u_char *client_pub; | ||
170 | u_char *server_pub; | 171 | u_char *server_pub; |
171 | u_char server_key[CURVE25519_SIZE]; | 172 | u_char server_key[CURVE25519_SIZE]; |
172 | int r; | 173 | int r; |
@@ -174,12 +175,13 @@ kex_c25519_enc(struct kex *kex, const u_char *pkblob, | |||
174 | *server_blobp = NULL; | 175 | *server_blobp = NULL; |
175 | *shared_secretp = NULL; | 176 | *shared_secretp = NULL; |
176 | 177 | ||
177 | if (pklen != CURVE25519_SIZE) { | 178 | if (sshbuf_len(client_blob) != CURVE25519_SIZE) { |
178 | r = SSH_ERR_SIGNATURE_INVALID; | 179 | r = SSH_ERR_SIGNATURE_INVALID; |
179 | goto out; | 180 | goto out; |
180 | } | 181 | } |
182 | client_pub = sshbuf_ptr(client_blob); | ||
181 | #ifdef DEBUG_KEXECDH | 183 | #ifdef DEBUG_KEXECDH |
182 | dump_digest("client public key 25519:", pkblob, CURVE25519_SIZE); | 184 | dump_digest("client public key 25519:", client_pub, CURVE25519_SIZE); |
183 | #endif | 185 | #endif |
184 | /* allocate space for encrypted KEM key and ECDH pub key */ | 186 | /* allocate space for encrypted KEM key and ECDH pub key */ |
185 | if ((server_blob = sshbuf_new()) == NULL) { | 187 | if ((server_blob = sshbuf_new()) == NULL) { |
@@ -194,7 +196,7 @@ kex_c25519_enc(struct kex *kex, const u_char *pkblob, | |||
194 | r = SSH_ERR_ALLOC_FAIL; | 196 | r = SSH_ERR_ALLOC_FAIL; |
195 | goto out; | 197 | goto out; |
196 | } | 198 | } |
197 | if ((r = kexc25519_shared_key_ext(server_key, pkblob, buf, 0)) < 0) | 199 | if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 0)) < 0) |
198 | goto out; | 200 | goto out; |
199 | #ifdef DEBUG_KEXECDH | 201 | #ifdef DEBUG_KEXECDH |
200 | dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE); | 202 | dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE); |
@@ -212,27 +214,29 @@ kex_c25519_enc(struct kex *kex, const u_char *pkblob, | |||
212 | } | 214 | } |
213 | 215 | ||
214 | int | 216 | int |
215 | kex_c25519_dec(struct kex *kex, const u_char *pkblob, | 217 | kex_c25519_dec(struct kex *kex, const struct sshbuf *server_blob, |
216 | size_t pklen, struct sshbuf **shared_secretp) | 218 | struct sshbuf **shared_secretp) |
217 | { | 219 | { |
218 | struct sshbuf *buf = NULL; | 220 | struct sshbuf *buf = NULL; |
221 | const u_char *server_pub; | ||
219 | int r; | 222 | int r; |
220 | 223 | ||
221 | *shared_secretp = NULL; | 224 | *shared_secretp = NULL; |
222 | 225 | ||
223 | if (pklen != CURVE25519_SIZE) { | 226 | if (sshbuf_len(server_blob) != CURVE25519_SIZE) { |
224 | r = SSH_ERR_SIGNATURE_INVALID; | 227 | r = SSH_ERR_SIGNATURE_INVALID; |
225 | goto out; | 228 | goto out; |
226 | } | 229 | } |
230 | server_pub = sshbuf_ptr(server_blob); | ||
227 | #ifdef DEBUG_KEXECDH | 231 | #ifdef DEBUG_KEXECDH |
228 | dump_digest("server public key c25519:", pkblob, CURVE25519_SIZE); | 232 | dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE); |
229 | #endif | 233 | #endif |
230 | /* shared secret */ | 234 | /* shared secret */ |
231 | if ((buf = sshbuf_new()) == NULL) { | 235 | if ((buf = sshbuf_new()) == NULL) { |
232 | r = SSH_ERR_ALLOC_FAIL; | 236 | r = SSH_ERR_ALLOC_FAIL; |
233 | goto out; | 237 | goto out; |
234 | } | 238 | } |
235 | if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, pkblob, | 239 | if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, server_pub, |
236 | buf, 0)) < 0) | 240 | buf, 0)) < 0) |
237 | goto out; | 241 | goto out; |
238 | #ifdef DEBUG_KEXECDH | 242 | #ifdef DEBUG_KEXECDH |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexdh.c,v 1.30 2019/01/21 10:28:01 djm Exp $ */ | 1 | /* $OpenBSD: kexdh.c,v 1.31 2019/01/21 10:35:09 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -136,7 +136,7 @@ kex_dh_keypair(struct kex *kex) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | int | 138 | int |
139 | kex_dh_enc(struct kex *kex, const u_char *pkblob, size_t pklen, | 139 | kex_dh_enc(struct kex *kex, const struct sshbuf *client_blob, |
140 | struct sshbuf **server_blobp, struct sshbuf **shared_secretp) | 140 | struct sshbuf **server_blobp, struct sshbuf **shared_secretp) |
141 | { | 141 | { |
142 | const BIGNUM *pub_key; | 142 | const BIGNUM *pub_key; |
@@ -156,7 +156,7 @@ kex_dh_enc(struct kex *kex, const u_char *pkblob, size_t pklen, | |||
156 | if ((r = sshbuf_put_bignum2(server_blob, pub_key)) != 0 || | 156 | if ((r = sshbuf_put_bignum2(server_blob, pub_key)) != 0 || |
157 | (r = sshbuf_get_u32(server_blob, NULL)) != 0) | 157 | (r = sshbuf_get_u32(server_blob, NULL)) != 0) |
158 | goto out; | 158 | goto out; |
159 | if ((r = kex_dh_dec(kex, pkblob, pklen, shared_secretp)) != 0) | 159 | if ((r = kex_dh_dec(kex, client_blob, shared_secretp)) != 0) |
160 | goto out; | 160 | goto out; |
161 | *server_blobp = server_blob; | 161 | *server_blobp = server_blob; |
162 | server_blob = NULL; | 162 | server_blob = NULL; |
@@ -168,7 +168,7 @@ kex_dh_enc(struct kex *kex, const u_char *pkblob, size_t pklen, | |||
168 | } | 168 | } |
169 | 169 | ||
170 | int | 170 | int |
171 | kex_dh_dec(struct kex *kex, const u_char *pkblob, size_t pklen, | 171 | kex_dh_dec(struct kex *kex, const struct sshbuf *dh_blob, |
172 | struct sshbuf **shared_secretp) | 172 | struct sshbuf **shared_secretp) |
173 | { | 173 | { |
174 | struct sshbuf *buf = NULL; | 174 | struct sshbuf *buf = NULL; |
@@ -181,13 +181,9 @@ kex_dh_dec(struct kex *kex, const u_char *pkblob, size_t pklen, | |||
181 | r = SSH_ERR_ALLOC_FAIL; | 181 | r = SSH_ERR_ALLOC_FAIL; |
182 | goto out; | 182 | goto out; |
183 | } | 183 | } |
184 | if ((r = sshbuf_put_u32(buf, pklen)) != 0 || | 184 | if ((r = sshbuf_put_stringb(buf, dh_blob)) != 0 || |
185 | (r = sshbuf_put(buf, pkblob, pklen)) != 0) { | 185 | (r = sshbuf_get_bignum2(buf, &dh_pub)) != 0) |
186 | goto out; | 186 | goto out; |
187 | } | ||
188 | if ((r = sshbuf_get_bignum2(buf, &dh_pub)) != 0) { | ||
189 | goto out; | ||
190 | } | ||
191 | sshbuf_reset(buf); | 187 | sshbuf_reset(buf); |
192 | if ((r = kex_dh_compute_key(kex, dh_pub, buf)) != 0) | 188 | if ((r = kex_dh_compute_key(kex, dh_pub, buf)) != 0) |
193 | goto out; | 189 | goto out; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexecdh.c,v 1.8 2019/01/21 10:29:56 djm Exp $ */ | 1 | /* $OpenBSD: kexecdh.c,v 1.9 2019/01/21 10:35:09 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 3 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
4 | * Copyright (c) 2019 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
@@ -43,7 +43,7 @@ | |||
43 | #include "ssherr.h" | 43 | #include "ssherr.h" |
44 | 44 | ||
45 | static int | 45 | static int |
46 | kex_ecdh_dec_key_group(struct kex *, const u_char *, size_t, EC_KEY *key, | 46 | kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key, |
47 | const EC_GROUP *, struct sshbuf **); | 47 | const EC_GROUP *, struct sshbuf **); |
48 | 48 | ||
49 | int | 49 | int |
@@ -89,7 +89,7 @@ kex_ecdh_keypair(struct kex *kex) | |||
89 | } | 89 | } |
90 | 90 | ||
91 | int | 91 | int |
92 | kex_ecdh_enc(struct kex *kex, const u_char *pkblob, size_t pklen, | 92 | kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, |
93 | struct sshbuf **server_blobp, struct sshbuf **shared_secretp) | 93 | struct sshbuf **server_blobp, struct sshbuf **shared_secretp) |
94 | { | 94 | { |
95 | const EC_GROUP *group; | 95 | const EC_GROUP *group; |
@@ -123,7 +123,7 @@ kex_ecdh_enc(struct kex *kex, const u_char *pkblob, size_t pklen, | |||
123 | if ((r = sshbuf_put_ec(server_blob, pub_key, group)) != 0 || | 123 | if ((r = sshbuf_put_ec(server_blob, pub_key, group)) != 0 || |
124 | (r = sshbuf_get_u32(server_blob, NULL)) != 0) | 124 | (r = sshbuf_get_u32(server_blob, NULL)) != 0) |
125 | goto out; | 125 | goto out; |
126 | if ((r = kex_ecdh_dec_key_group(kex, pkblob, pklen, server_key, group, | 126 | if ((r = kex_ecdh_dec_key_group(kex, client_blob, server_key, group, |
127 | shared_secretp)) != 0) | 127 | shared_secretp)) != 0) |
128 | goto out; | 128 | goto out; |
129 | *server_blobp = server_blob; | 129 | *server_blobp = server_blob; |
@@ -135,7 +135,7 @@ kex_ecdh_enc(struct kex *kex, const u_char *pkblob, size_t pklen, | |||
135 | } | 135 | } |
136 | 136 | ||
137 | static int | 137 | static int |
138 | kex_ecdh_dec_key_group(struct kex *kex, const u_char *pkblob, size_t pklen, | 138 | kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, |
139 | EC_KEY *key, const EC_GROUP *group, struct sshbuf **shared_secretp) | 139 | EC_KEY *key, const EC_GROUP *group, struct sshbuf **shared_secretp) |
140 | { | 140 | { |
141 | struct sshbuf *buf = NULL; | 141 | struct sshbuf *buf = NULL; |
@@ -151,10 +151,8 @@ kex_ecdh_dec_key_group(struct kex *kex, const u_char *pkblob, size_t pklen, | |||
151 | r = SSH_ERR_ALLOC_FAIL; | 151 | r = SSH_ERR_ALLOC_FAIL; |
152 | goto out; | 152 | goto out; |
153 | } | 153 | } |
154 | if ((r = sshbuf_put_u32(buf, pklen)) != 0 || | 154 | if ((r = sshbuf_put_stringb(buf, ec_blob)) != 0) |
155 | (r = sshbuf_put(buf, pkblob, pklen)) != 0) { | ||
156 | goto out; | 155 | goto out; |
157 | } | ||
158 | if ((dh_pub = EC_POINT_new(group)) == NULL) { | 156 | if ((dh_pub = EC_POINT_new(group)) == NULL) { |
159 | r = SSH_ERR_ALLOC_FAIL; | 157 | r = SSH_ERR_ALLOC_FAIL; |
160 | goto out; | 158 | goto out; |
@@ -199,12 +197,12 @@ kex_ecdh_dec_key_group(struct kex *kex, const u_char *pkblob, size_t pklen, | |||
199 | } | 197 | } |
200 | 198 | ||
201 | int | 199 | int |
202 | kex_ecdh_dec(struct kex *kex, const u_char *pkblob, size_t pklen, | 200 | kex_ecdh_dec(struct kex *kex, const struct sshbuf *server_blob, |
203 | struct sshbuf **shared_secretp) | 201 | struct sshbuf **shared_secretp) |
204 | { | 202 | { |
205 | int r; | 203 | int r; |
206 | 204 | ||
207 | r = kex_ecdh_dec_key_group(kex, pkblob, pklen, kex->ec_client_key, | 205 | r = kex_ecdh_dec_key_group(kex, server_blob, kex->ec_client_key, |
208 | kex->ec_group, shared_secretp); | 206 | kex->ec_group, shared_secretp); |
209 | EC_KEY_free(kex->ec_client_key); | 207 | EC_KEY_free(kex->ec_client_key); |
210 | kex->ec_client_key = NULL; | 208 | kex->ec_client_key = NULL; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexkemc.c,v 1.4 2019/01/21 10:29:56 djm Exp $ */ | 1 | /* $OpenBSD: kexkemc.c,v 1.5 2019/01/21 10:35:09 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -85,10 +85,10 @@ input_kex_kem_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
85 | struct kex *kex = ssh->kex; | 85 | struct kex *kex = ssh->kex; |
86 | struct sshkey *server_host_key = NULL; | 86 | struct sshkey *server_host_key = NULL; |
87 | struct sshbuf *shared_secret = NULL; | 87 | struct sshbuf *shared_secret = NULL; |
88 | u_char *server_pubkey = NULL; | 88 | struct sshbuf *server_blob = NULL; |
89 | u_char *server_host_key_blob = NULL, *signature = NULL; | 89 | u_char *server_host_key_blob = NULL, *signature = NULL; |
90 | u_char hash[SSH_DIGEST_MAX_LENGTH]; | 90 | u_char hash[SSH_DIGEST_MAX_LENGTH]; |
91 | size_t slen, pklen, sbloblen, hashlen; | 91 | size_t slen, sbloblen, hashlen; |
92 | int r; | 92 | int r; |
93 | 93 | ||
94 | /* hostkey */ | 94 | /* hostkey */ |
@@ -102,7 +102,7 @@ input_kex_kem_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
102 | 102 | ||
103 | /* Q_S, server public key */ | 103 | /* Q_S, server public key */ |
104 | /* signed H */ | 104 | /* signed H */ |
105 | if ((r = sshpkt_get_string(ssh, &server_pubkey, &pklen)) != 0 || | 105 | if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 || |
106 | (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || | 106 | (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || |
107 | (r = sshpkt_get_end(ssh)) != 0) | 107 | (r = sshpkt_get_end(ssh)) != 0) |
108 | goto out; | 108 | goto out; |
@@ -114,16 +114,16 @@ input_kex_kem_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
114 | case KEX_DH_GRP14_SHA256: | 114 | case KEX_DH_GRP14_SHA256: |
115 | case KEX_DH_GRP16_SHA512: | 115 | case KEX_DH_GRP16_SHA512: |
116 | case KEX_DH_GRP18_SHA512: | 116 | case KEX_DH_GRP18_SHA512: |
117 | r = kex_dh_dec(kex, server_pubkey, pklen, &shared_secret); | 117 | r = kex_dh_dec(kex, server_blob, &shared_secret); |
118 | break; | 118 | break; |
119 | case KEX_ECDH_SHA2: | 119 | case KEX_ECDH_SHA2: |
120 | r = kex_ecdh_dec(kex, server_pubkey, pklen, &shared_secret); | 120 | r = kex_ecdh_dec(kex, server_blob, &shared_secret); |
121 | break; | 121 | break; |
122 | case KEX_C25519_SHA256: | 122 | case KEX_C25519_SHA256: |
123 | r = kex_c25519_dec(kex, server_pubkey, pklen, &shared_secret); | 123 | r = kex_c25519_dec(kex, server_blob, &shared_secret); |
124 | break; | 124 | break; |
125 | case KEX_KEM_SNTRUP4591761X25519_SHA512: | 125 | case KEX_KEM_SNTRUP4591761X25519_SHA512: |
126 | r = kex_kem_sntrup4591761x25519_dec(kex, server_pubkey, pklen, | 126 | r = kex_kem_sntrup4591761x25519_dec(kex, server_blob, |
127 | &shared_secret); | 127 | &shared_secret); |
128 | break; | 128 | break; |
129 | default: | 129 | default: |
@@ -142,9 +142,9 @@ input_kex_kem_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
142 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 142 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
143 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 143 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
144 | server_host_key_blob, sbloblen, | 144 | server_host_key_blob, sbloblen, |
145 | sshbuf_ptr(kex->kem_client_pub), sshbuf_len(kex->kem_client_pub), | 145 | kex->kem_client_pub, |
146 | server_pubkey, pklen, | 146 | server_blob, |
147 | sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), | 147 | shared_secret, |
148 | hash, &hashlen)) != 0) | 148 | hash, &hashlen)) != 0) |
149 | goto out; | 149 | goto out; |
150 | 150 | ||
@@ -160,9 +160,9 @@ out: | |||
160 | explicit_bzero(kex->sntrup4591761_client_key, | 160 | explicit_bzero(kex->sntrup4591761_client_key, |
161 | sizeof(kex->sntrup4591761_client_key)); | 161 | sizeof(kex->sntrup4591761_client_key)); |
162 | free(server_host_key_blob); | 162 | free(server_host_key_blob); |
163 | free(server_pubkey); | ||
164 | free(signature); | 163 | free(signature); |
165 | sshkey_free(server_host_key); | 164 | sshkey_free(server_host_key); |
165 | sshbuf_free(server_blob); | ||
166 | sshbuf_free(shared_secret); | 166 | sshbuf_free(shared_secret); |
167 | sshbuf_free(kex->kem_client_pub); | 167 | sshbuf_free(kex->kem_client_pub); |
168 | kex->kem_client_pub = NULL; | 168 | kex->kem_client_pub = NULL; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexkems.c,v 1.4 2019/01/21 10:29:56 djm Exp $ */ | 1 | /* $OpenBSD: kexkems.c,v 1.5 2019/01/21 10:35:09 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -53,17 +53,17 @@ input_kex_kem_init(int type, u_int32_t seq, struct ssh *ssh) | |||
53 | struct sshkey *server_host_private, *server_host_public; | 53 | struct sshkey *server_host_private, *server_host_public; |
54 | struct sshbuf *shared_secret = NULL; | 54 | struct sshbuf *shared_secret = NULL; |
55 | struct sshbuf *server_pubkey = NULL; | 55 | struct sshbuf *server_pubkey = NULL; |
56 | struct sshbuf *client_pubkey = NULL; | ||
56 | u_char *server_host_key_blob = NULL, *signature = NULL; | 57 | u_char *server_host_key_blob = NULL, *signature = NULL; |
57 | u_char *client_pubkey = NULL; | ||
58 | u_char hash[SSH_DIGEST_MAX_LENGTH]; | 58 | u_char hash[SSH_DIGEST_MAX_LENGTH]; |
59 | size_t slen, pklen, sbloblen, hashlen; | 59 | size_t slen, sbloblen, hashlen; |
60 | int r; | 60 | int r; |
61 | 61 | ||
62 | if ((r = kex_load_hostkey(ssh, &server_host_private, | 62 | if ((r = kex_load_hostkey(ssh, &server_host_private, |
63 | &server_host_public)) != 0) | 63 | &server_host_public)) != 0) |
64 | goto out; | 64 | goto out; |
65 | 65 | ||
66 | if ((r = sshpkt_get_string(ssh, &client_pubkey, &pklen)) != 0 || | 66 | if ((r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 || |
67 | (r = sshpkt_get_end(ssh)) != 0) | 67 | (r = sshpkt_get_end(ssh)) != 0) |
68 | goto out; | 68 | goto out; |
69 | 69 | ||
@@ -74,19 +74,19 @@ input_kex_kem_init(int type, u_int32_t seq, struct ssh *ssh) | |||
74 | case KEX_DH_GRP14_SHA256: | 74 | case KEX_DH_GRP14_SHA256: |
75 | case KEX_DH_GRP16_SHA512: | 75 | case KEX_DH_GRP16_SHA512: |
76 | case KEX_DH_GRP18_SHA512: | 76 | case KEX_DH_GRP18_SHA512: |
77 | r = kex_dh_enc(kex, client_pubkey, pklen, &server_pubkey, | 77 | r = kex_dh_enc(kex, client_pubkey, &server_pubkey, |
78 | &shared_secret); | 78 | &shared_secret); |
79 | break; | 79 | break; |
80 | case KEX_ECDH_SHA2: | 80 | case KEX_ECDH_SHA2: |
81 | r = kex_ecdh_enc(kex, client_pubkey, pklen, &server_pubkey, | 81 | r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey, |
82 | &shared_secret); | 82 | &shared_secret); |
83 | break; | 83 | break; |
84 | case KEX_C25519_SHA256: | 84 | case KEX_C25519_SHA256: |
85 | r = kex_c25519_enc(kex, client_pubkey, pklen, &server_pubkey, | 85 | r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, |
86 | &shared_secret); | 86 | &shared_secret); |
87 | break; | 87 | break; |
88 | case KEX_KEM_SNTRUP4591761X25519_SHA512: | 88 | case KEX_KEM_SNTRUP4591761X25519_SHA512: |
89 | r = kex_kem_sntrup4591761x25519_enc(kex, client_pubkey, pklen, | 89 | r = kex_kem_sntrup4591761x25519_enc(kex, client_pubkey, |
90 | &server_pubkey, &shared_secret); | 90 | &server_pubkey, &shared_secret); |
91 | break; | 91 | break; |
92 | default: | 92 | default: |
@@ -108,9 +108,9 @@ input_kex_kem_init(int type, u_int32_t seq, struct ssh *ssh) | |||
108 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 108 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), |
109 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 109 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), |
110 | server_host_key_blob, sbloblen, | 110 | server_host_key_blob, sbloblen, |
111 | client_pubkey, pklen, | 111 | client_pubkey, |
112 | sshbuf_ptr(server_pubkey), sshbuf_len(server_pubkey), | 112 | server_pubkey, |
113 | sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), | 113 | shared_secret, |
114 | hash, &hashlen)) != 0) | 114 | hash, &hashlen)) != 0) |
115 | goto out; | 115 | goto out; |
116 | 116 | ||
@@ -133,8 +133,8 @@ out: | |||
133 | explicit_bzero(hash, sizeof(hash)); | 133 | explicit_bzero(hash, sizeof(hash)); |
134 | free(server_host_key_blob); | 134 | free(server_host_key_blob); |
135 | free(signature); | 135 | free(signature); |
136 | free(client_pubkey); | ||
137 | sshbuf_free(shared_secret); | 136 | sshbuf_free(shared_secret); |
137 | sshbuf_free(client_pubkey); | ||
138 | sshbuf_free(server_pubkey); | 138 | sshbuf_free(server_pubkey); |
139 | return r; | 139 | return r; |
140 | } | 140 | } |
diff --git a/kexsntrup4591761x25519.c b/kexsntrup4591761x25519.c index ffe05f420..d845f3d44 100644 --- a/kexsntrup4591761x25519.c +++ b/kexsntrup4591761x25519.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexsntrup4591761x25519.c,v 1.1 2019/01/21 10:20:12 djm Exp $ */ | 1 | /* $OpenBSD: kexsntrup4591761x25519.c,v 1.2 2019/01/21 10:35:09 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -66,11 +66,13 @@ kex_kem_sntrup4591761x25519_keypair(struct kex *kex) | |||
66 | } | 66 | } |
67 | 67 | ||
68 | int | 68 | int |
69 | kex_kem_sntrup4591761x25519_enc(struct kex *kex, const u_char *pkblob, | 69 | kex_kem_sntrup4591761x25519_enc(struct kex *kex, |
70 | size_t pklen, struct sshbuf **server_blobp, struct sshbuf **shared_secretp) | 70 | const struct sshbuf *client_blob, struct sshbuf **server_blobp, |
71 | struct sshbuf **shared_secretp) | ||
71 | { | 72 | { |
72 | struct sshbuf *server_blob = NULL; | 73 | struct sshbuf *server_blob = NULL; |
73 | struct sshbuf *buf = NULL; | 74 | struct sshbuf *buf = NULL; |
75 | const u_char *client_pub; | ||
74 | u_char *kem_key, *ciphertext, *server_pub; | 76 | u_char *kem_key, *ciphertext, *server_pub; |
75 | u_char server_key[CURVE25519_SIZE]; | 77 | u_char server_key[CURVE25519_SIZE]; |
76 | u_char hash[SSH_DIGEST_MAX_LENGTH]; | 78 | u_char hash[SSH_DIGEST_MAX_LENGTH]; |
@@ -80,17 +82,19 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex, const u_char *pkblob, | |||
80 | *server_blobp = NULL; | 82 | *server_blobp = NULL; |
81 | *shared_secretp = NULL; | 83 | *shared_secretp = NULL; |
82 | 84 | ||
83 | /* pkblob contains both KEM and ECDH client pubkeys */ | 85 | /* client_blob contains both KEM and ECDH client pubkeys */ |
84 | need = crypto_kem_sntrup4591761_PUBLICKEYBYTES + CURVE25519_SIZE; | 86 | need = crypto_kem_sntrup4591761_PUBLICKEYBYTES + CURVE25519_SIZE; |
85 | if (pklen != need) { | 87 | if (sshbuf_len(client_blob) != need) { |
86 | r = SSH_ERR_SIGNATURE_INVALID; | 88 | r = SSH_ERR_SIGNATURE_INVALID; |
87 | goto out; | 89 | goto out; |
88 | } | 90 | } |
91 | client_pub = sshbuf_ptr(client_blob); | ||
89 | #ifdef DEBUG_KEXECDH | 92 | #ifdef DEBUG_KEXECDH |
90 | dump_digest("client public key sntrup4591761:", pkblob, | 93 | dump_digest("client public key sntrup4591761:", client_pub, |
91 | crypto_kem_sntrup4591761_PUBLICKEYBYTES); | 94 | crypto_kem_sntrup4591761_PUBLICKEYBYTES); |
92 | dump_digest("client public key 25519:", | 95 | dump_digest("client public key 25519:", |
93 | pkblob + crypto_kem_sntrup4591761_PUBLICKEYBYTES, CURVE25519_SIZE); | 96 | client_pub + crypto_kem_sntrup4591761_PUBLICKEYBYTES, |
97 | CURVE25519_SIZE); | ||
94 | #endif | 98 | #endif |
95 | /* allocate buffer for concatenation of KEM key and ECDH shared key */ | 99 | /* allocate buffer for concatenation of KEM key and ECDH shared key */ |
96 | /* the buffer will be hashed and the result is the shared secret */ | 100 | /* the buffer will be hashed and the result is the shared secret */ |
@@ -110,13 +114,13 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex, const u_char *pkblob, | |||
110 | if ((r = sshbuf_reserve(server_blob, need, &ciphertext)) != 0) | 114 | if ((r = sshbuf_reserve(server_blob, need, &ciphertext)) != 0) |
111 | goto out; | 115 | goto out; |
112 | /* generate and encrypt KEM key with client key */ | 116 | /* generate and encrypt KEM key with client key */ |
113 | crypto_kem_sntrup4591761_enc(ciphertext, kem_key, pkblob); | 117 | crypto_kem_sntrup4591761_enc(ciphertext, kem_key, client_pub); |
114 | /* generate ECDH key pair, store server pubkey after ciphertext */ | 118 | /* generate ECDH key pair, store server pubkey after ciphertext */ |
115 | server_pub = ciphertext + crypto_kem_sntrup4591761_CIPHERTEXTBYTES; | 119 | server_pub = ciphertext + crypto_kem_sntrup4591761_CIPHERTEXTBYTES; |
116 | kexc25519_keygen(server_key, server_pub); | 120 | kexc25519_keygen(server_key, server_pub); |
117 | /* append ECDH shared key */ | 121 | /* append ECDH shared key */ |
118 | if ((r = kexc25519_shared_key_ext(server_key, | 122 | client_pub += crypto_kem_sntrup4591761_PUBLICKEYBYTES; |
119 | pkblob + crypto_kem_sntrup4591761_PUBLICKEYBYTES, buf, 1)) < 0) | 123 | if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 1)) < 0) |
120 | goto out; | 124 | goto out; |
121 | if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0) | 125 | if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0) |
122 | goto out; | 126 | goto out; |
@@ -149,8 +153,8 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex, const u_char *pkblob, | |||
149 | } | 153 | } |
150 | 154 | ||
151 | int | 155 | int |
152 | kex_kem_sntrup4591761x25519_dec(struct kex *kex, const u_char *pkblob, | 156 | kex_kem_sntrup4591761x25519_dec(struct kex *kex, |
153 | size_t pklen, struct sshbuf **shared_secretp) | 157 | const struct sshbuf *server_blob, struct sshbuf **shared_secretp) |
154 | { | 158 | { |
155 | struct sshbuf *buf = NULL; | 159 | struct sshbuf *buf = NULL; |
156 | u_char *kem_key = NULL; | 160 | u_char *kem_key = NULL; |
@@ -162,12 +166,12 @@ kex_kem_sntrup4591761x25519_dec(struct kex *kex, const u_char *pkblob, | |||
162 | *shared_secretp = NULL; | 166 | *shared_secretp = NULL; |
163 | 167 | ||
164 | need = crypto_kem_sntrup4591761_CIPHERTEXTBYTES + CURVE25519_SIZE; | 168 | need = crypto_kem_sntrup4591761_CIPHERTEXTBYTES + CURVE25519_SIZE; |
165 | if (pklen != need) { | 169 | if (sshbuf_len(server_blob) != need) { |
166 | r = SSH_ERR_SIGNATURE_INVALID; | 170 | r = SSH_ERR_SIGNATURE_INVALID; |
167 | goto out; | 171 | goto out; |
168 | } | 172 | } |
169 | ciphertext = pkblob; | 173 | ciphertext = sshbuf_ptr(server_blob); |
170 | server_pub = pkblob + crypto_kem_sntrup4591761_CIPHERTEXTBYTES; | 174 | server_pub = ciphertext + crypto_kem_sntrup4591761_CIPHERTEXTBYTES; |
171 | #ifdef DEBUG_KEXECDH | 175 | #ifdef DEBUG_KEXECDH |
172 | dump_digest("server cipher text:", ciphertext, | 176 | dump_digest("server cipher text:", ciphertext, |
173 | crypto_kem_sntrup4591761_CIPHERTEXTBYTES); | 177 | crypto_kem_sntrup4591761_CIPHERTEXTBYTES); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.281 2019/01/21 09:54:11 djm Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.282 2019/01/21 10:35:09 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 |
@@ -2483,6 +2483,12 @@ sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v) | |||
2483 | return sshbuf_put_stringb(ssh->state->outgoing_packet, v); | 2483 | return sshbuf_put_stringb(ssh->state->outgoing_packet, v); |
2484 | } | 2484 | } |
2485 | 2485 | ||
2486 | int | ||
2487 | sshpkt_getb_froms(struct ssh *ssh, struct sshbuf **valp) | ||
2488 | { | ||
2489 | return sshbuf_froms(ssh->state->incoming_packet, valp); | ||
2490 | } | ||
2491 | |||
2486 | #ifdef WITH_OPENSSL | 2492 | #ifdef WITH_OPENSSL |
2487 | #ifdef OPENSSL_HAS_ECC | 2493 | #ifdef OPENSSL_HAS_ECC |
2488 | int | 2494 | int |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.h,v 1.89 2019/01/21 09:54:11 djm Exp $ */ | 1 | /* $OpenBSD: packet.h,v 1.90 2019/01/21 10:35:09 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -199,6 +199,7 @@ int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp); | |||
199 | int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); | 199 | int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); |
200 | int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); | 200 | int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); |
201 | int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); | 201 | int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); |
202 | int sshpkt_getb_froms(struct ssh *ssh, struct sshbuf **valp); | ||
202 | int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); | 203 | int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); |
203 | int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM **valp); | 204 | int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM **valp); |
204 | int sshpkt_get_end(struct ssh *ssh); | 205 | int sshpkt_get_end(struct ssh *ssh); |