summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-01-21 10:35:09 +0000
committerDamien Miller <djm@mindrot.org>2019-01-21 23:13:03 +1100
commit71e67fff946396caa110a7964da23480757258ff (patch)
tree07cae7bce377241a7b61195d0810ec91d953685e
parent4b83e2a2cc0c12e671a77eaba1c1245894f4e884 (diff)
upstream: pass values used in KEX hash computation as sshbuf
rather than pointer+len suggested by me; implemented by markus@ ok me OpenBSD-Commit-ID: 994f33c464f4a9e0f1d21909fa3e379f5a0910f0
-rw-r--r--kex.h22
-rw-r--r--kexc25519.c38
-rw-r--r--kexdh.c16
-rw-r--r--kexecdh.c18
-rw-r--r--kexkemc.c24
-rw-r--r--kexkems.c24
-rw-r--r--kexsntrup4591761x25519.c34
-rw-r--r--packet.c8
-rw-r--r--packet.h3
9 files changed, 98 insertions, 89 deletions
diff --git a/kex.h b/kex.h
index e3be30403..6798e33f9 100644
--- a/kex.h
+++ b/kex.h
@@ -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 *);
211int kex_kem_server(struct ssh *); 211int kex_kem_server(struct ssh *);
212 212
213int kex_dh_keypair(struct kex *); 213int kex_dh_keypair(struct kex *);
214int kex_dh_enc(struct kex *, const u_char *, size_t, struct sshbuf **, 214int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **,
215 struct sshbuf **); 215 struct sshbuf **);
216int kex_dh_dec(struct kex *, const u_char *, size_t, struct sshbuf **); 216int kex_dh_dec(struct kex *, const struct sshbuf *, struct sshbuf **);
217 217
218int kex_ecdh_keypair(struct kex *); 218int kex_ecdh_keypair(struct kex *);
219int kex_ecdh_enc(struct kex *, const u_char *, size_t, struct sshbuf **, 219int kex_ecdh_enc(struct kex *, const struct sshbuf *, struct sshbuf **,
220 struct sshbuf **); 220 struct sshbuf **);
221int kex_ecdh_dec(struct kex *, const u_char *, size_t, struct sshbuf **); 221int kex_ecdh_dec(struct kex *, const struct sshbuf *, struct sshbuf **);
222 222
223int kex_c25519_keypair(struct kex *); 223int kex_c25519_keypair(struct kex *);
224int kex_c25519_enc(struct kex *, const u_char *, size_t, struct sshbuf **, 224int kex_c25519_enc(struct kex *, const struct sshbuf *, struct sshbuf **,
225 struct sshbuf **); 225 struct sshbuf **);
226int kex_c25519_dec(struct kex *, const u_char *, size_t, struct sshbuf **); 226int kex_c25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **);
227 227
228int kex_kem_sntrup4591761x25519_keypair(struct kex *); 228int kex_kem_sntrup4591761x25519_keypair(struct kex *);
229int kex_kem_sntrup4591761x25519_enc(struct kex *, const u_char *, size_t, 229int kex_kem_sntrup4591761x25519_enc(struct kex *, const struct sshbuf *,
230 struct sshbuf **, struct sshbuf **); 230 struct sshbuf **, struct sshbuf **);
231int kex_kem_sntrup4591761x25519_dec(struct kex *, const u_char *, size_t, 231int kex_kem_sntrup4591761x25519_dec(struct kex *, const struct sshbuf *,
232 struct sshbuf **); 232 struct sshbuf **);
233 233
234int kex_dh_keygen(struct kex *); 234int kex_dh_keygen(struct kex *);
@@ -243,8 +243,8 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *,
243 243
244int kex_c25519_hash(int, const struct sshbuf *, const struct sshbuf *, 244int 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
249void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) 249void 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
164int 164int
165kex_c25519_enc(struct kex *kex, const u_char *pkblob, 165kex_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
214int 216int
215kex_c25519_dec(struct kex *kex, const u_char *pkblob, 217kex_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
diff --git a/kexdh.c b/kexdh.c
index 98597eade..943774624 100644
--- a/kexdh.c
+++ b/kexdh.c
@@ -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
138int 138int
139kex_dh_enc(struct kex *kex, const u_char *pkblob, size_t pklen, 139kex_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
170int 170int
171kex_dh_dec(struct kex *kex, const u_char *pkblob, size_t pklen, 171kex_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;
diff --git a/kexecdh.c b/kexecdh.c
index 263f9fd87..ae9018773 100644
--- a/kexecdh.c
+++ b/kexecdh.c
@@ -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
45static int 45static int
46kex_ecdh_dec_key_group(struct kex *, const u_char *, size_t, EC_KEY *key, 46kex_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
49int 49int
@@ -89,7 +89,7 @@ kex_ecdh_keypair(struct kex *kex)
89} 89}
90 90
91int 91int
92kex_ecdh_enc(struct kex *kex, const u_char *pkblob, size_t pklen, 92kex_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
137static int 137static int
138kex_ecdh_dec_key_group(struct kex *kex, const u_char *pkblob, size_t pklen, 138kex_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
201int 199int
202kex_ecdh_dec(struct kex *kex, const u_char *pkblob, size_t pklen, 200kex_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;
diff --git a/kexkemc.c b/kexkemc.c
index 55055de27..942be5746 100644
--- a/kexkemc.c
+++ b/kexkemc.c
@@ -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;
diff --git a/kexkems.c b/kexkems.c
index 10ef12196..3ba8f0df5 100644
--- a/kexkems.c
+++ b/kexkems.c
@@ -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
68int 68int
69kex_kem_sntrup4591761x25519_enc(struct kex *kex, const u_char *pkblob, 69kex_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
151int 155int
152kex_kem_sntrup4591761x25519_dec(struct kex *kex, const u_char *pkblob, 156kex_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);
diff --git a/packet.c b/packet.c
index a162791b1..ec03301b9 100644
--- a/packet.c
+++ b/packet.c
@@ -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
2486int
2487sshpkt_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
2488int 2494int
diff --git a/packet.h b/packet.h
index 98338f1f1..0dfa36da1 100644
--- a/packet.h
+++ b/packet.h
@@ -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);
199int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); 199int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
200int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); 200int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
201int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); 201int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp);
202int sshpkt_getb_froms(struct ssh *ssh, struct sshbuf **valp);
202int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); 203int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g);
203int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM **valp); 204int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM **valp);
204int sshpkt_get_end(struct ssh *ssh); 205int sshpkt_get_end(struct ssh *ssh);