Skip to content
/ src Public

Commit 3e284e1

Browse files
committed
Update/replace the experimental post-quantim hybrid key exchange
method based on Streamlined NTRU Prime (coupled with X25519). The previous sntrup4591761x25519-sha512@tinyssh.org method is replaced with sntrup761x25519-sha512@openssh.com. Per the authors, sntrup4591761 was replaced almost two years ago by sntrup761. The sntrup761 implementaion, like sntrup4591761 before it, is public domain code extracted from the SUPERCOP cryptography benchmark suite (https://bench.cr.yp.to/supercop.html). Thanks for Daniel J Bernstein for guidance on algorithm selection. Patch from Tobias Heider; feedback & ok markus@ and myself (note this both the updated method and the one that it replaced are disabled by default)
1 parent b6faad1 commit 3e284e1

File tree

16 files changed

+1496
-1207
lines changed

16 files changed

+1496
-1207
lines changed

usr.bin/ssh/Makefile.inc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $OpenBSD: Makefile.inc,v 1.85 2020/10/16 13:24:45 djm Exp $
1+
# $OpenBSD: Makefile.inc,v 1.86 2020/12/29 00:59:15 djm Exp $
22

33
.include <bsd.own.mk>
44

@@ -69,8 +69,8 @@ SRCS_KEXS+= kexgexs.c
6969
SRCS_KEX+= kexc25519.c
7070
SRCS_KEX+= smult_curve25519_ref.c
7171
SRCS_KEX+= kexgen.c
72-
SRCS_KEX+= kexsntrup4591761x25519.c
73-
SRCS_KEX+= sntrup4591761.c
72+
SRCS_KEX+= kexsntrup761x25519.c
73+
SRCS_KEX+= sntrup761.c
7474

7575
SRCS_KEY+= sshkey.c
7676
SRCS_KEY+= cipher.c

usr.bin/ssh/crypto_api.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: crypto_api.h,v 1.5 2019/01/21 10:20:12 djm Exp $ */
1+
/* $OpenBSD: crypto_api.h,v 1.6 2020/12/29 00:59:15 djm Exp $ */
22

33
/*
44
* Assembled from generated headers and source files by Markus Friedl.
@@ -38,15 +38,15 @@ int crypto_sign_ed25519_open(unsigned char *, unsigned long long *,
3838
const unsigned char *, unsigned long long, const unsigned char *);
3939
int crypto_sign_ed25519_keypair(unsigned char *, unsigned char *);
4040

41-
#define crypto_kem_sntrup4591761_PUBLICKEYBYTES 1218
42-
#define crypto_kem_sntrup4591761_SECRETKEYBYTES 1600
43-
#define crypto_kem_sntrup4591761_CIPHERTEXTBYTES 1047
44-
#define crypto_kem_sntrup4591761_BYTES 32
41+
#define crypto_kem_sntrup761_PUBLICKEYBYTES 1158
42+
#define crypto_kem_sntrup761_SECRETKEYBYTES 1763
43+
#define crypto_kem_sntrup761_CIPHERTEXTBYTES 1039
44+
#define crypto_kem_sntrup761_BYTES 32
4545

46-
int crypto_kem_sntrup4591761_enc(unsigned char *cstr, unsigned char *k,
46+
int crypto_kem_sntrup761_enc(unsigned char *cstr, unsigned char *k,
4747
const unsigned char *pk);
48-
int crypto_kem_sntrup4591761_dec(unsigned char *k,
48+
int crypto_kem_sntrup761_dec(unsigned char *k,
4949
const unsigned char *cstr, const unsigned char *sk);
50-
int crypto_kem_sntrup4591761_keypair(unsigned char *pk, unsigned char *sk);
50+
int crypto_kem_sntrup761_keypair(unsigned char *pk, unsigned char *sk);
5151

5252
#endif /* crypto_api_h */

usr.bin/ssh/kex.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: kex.c,v 1.162 2020/12/04 02:27:57 djm Exp $ */
1+
/* $OpenBSD: kex.c,v 1.163 2020/12/29 00:59:15 djm Exp $ */
22
/*
33
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
44
*
@@ -98,7 +98,7 @@ static const struct kexalg kexalgs[] = {
9898
#endif
9999
{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
100100
{ KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
101-
{ KEX_SNTRUP4591761X25519_SHA512, KEX_KEM_SNTRUP4591761X25519_SHA512, 0,
101+
{ KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0,
102102
SSH_DIGEST_SHA512 },
103103
{ NULL, 0, -1, -1},
104104
};

usr.bin/ssh/kex.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: kex.h,v 1.111 2020/10/07 02:22:23 djm Exp $ */
1+
/* $OpenBSD: kex.h,v 1.112 2020/12/29 00:59:15 djm Exp $ */
22

33
/*
44
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -55,7 +55,7 @@
5555
#define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521"
5656
#define KEX_CURVE25519_SHA256 "curve25519-sha256"
5757
#define KEX_CURVE25519_SHA256_OLD "curve25519-sha256@libssh.org"
58-
#define KEX_SNTRUP4591761X25519_SHA512 "sntrup4591761x25519-sha512@tinyssh.org"
58+
#define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512@openssh.com"
5959

6060
#define COMP_NONE 0
6161
/* pre-auth compression (COMP_ZLIB) is only supported in the client */
@@ -94,7 +94,7 @@ enum kex_exchange {
9494
KEX_DH_GEX_SHA256,
9595
KEX_ECDH_SHA2,
9696
KEX_C25519_SHA256,
97-
KEX_KEM_SNTRUP4591761X25519_SHA512,
97+
KEX_KEM_SNTRUP761X25519_SHA512,
9898
KEX_MAX
9999
};
100100

@@ -161,7 +161,7 @@ struct kex {
161161
const EC_GROUP *ec_group; /* ECDH */
162162
u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */
163163
u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */
164-
u_char sntrup4591761_client_key[crypto_kem_sntrup4591761_SECRETKEYBYTES]; /* KEM */
164+
u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */
165165
struct sshbuf *client_pub;
166166
};
167167

@@ -211,10 +211,10 @@ int kex_c25519_enc(struct kex *, const struct sshbuf *, struct sshbuf **,
211211
struct sshbuf **);
212212
int kex_c25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **);
213213

214-
int kex_kem_sntrup4591761x25519_keypair(struct kex *);
215-
int kex_kem_sntrup4591761x25519_enc(struct kex *, const struct sshbuf *,
214+
int kex_kem_sntrup761x25519_keypair(struct kex *);
215+
int kex_kem_sntrup761x25519_enc(struct kex *, const struct sshbuf *,
216216
struct sshbuf **, struct sshbuf **);
217-
int kex_kem_sntrup4591761x25519_dec(struct kex *, const struct sshbuf *,
217+
int kex_kem_sntrup761x25519_dec(struct kex *, const struct sshbuf *,
218218
struct sshbuf **);
219219

220220
int kex_dh_keygen(struct kex *);

usr.bin/ssh/kexgen.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: kexgen.c,v 1.4 2019/11/25 00:51:37 djm Exp $ */
1+
/* $OpenBSD: kexgen.c,v 1.5 2020/12/29 00:59:15 djm Exp $ */
22
/*
33
* Copyright (c) 2019 Markus Friedl. All rights reserved.
44
*
@@ -114,8 +114,8 @@ kex_gen_client(struct ssh *ssh)
114114
case KEX_C25519_SHA256:
115115
r = kex_c25519_keypair(kex);
116116
break;
117-
case KEX_KEM_SNTRUP4591761X25519_SHA512:
118-
r = kex_kem_sntrup4591761x25519_keypair(kex);
117+
case KEX_KEM_SNTRUP761X25519_SHA512:
118+
r = kex_kem_sntrup761x25519_keypair(kex);
119119
break;
120120
default:
121121
r = SSH_ERR_INVALID_ARGUMENT;
@@ -182,8 +182,8 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
182182
case KEX_C25519_SHA256:
183183
r = kex_c25519_dec(kex, server_blob, &shared_secret);
184184
break;
185-
case KEX_KEM_SNTRUP4591761X25519_SHA512:
186-
r = kex_kem_sntrup4591761x25519_dec(kex, server_blob,
185+
case KEX_KEM_SNTRUP761X25519_SHA512:
186+
r = kex_kem_sntrup761x25519_dec(kex, server_blob,
187187
&shared_secret);
188188
break;
189189
default:
@@ -217,8 +217,8 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
217217
out:
218218
explicit_bzero(hash, sizeof(hash));
219219
explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key));
220-
explicit_bzero(kex->sntrup4591761_client_key,
221-
sizeof(kex->sntrup4591761_client_key));
220+
explicit_bzero(kex->sntrup761_client_key,
221+
sizeof(kex->sntrup761_client_key));
222222
sshbuf_free(server_host_key_blob);
223223
free(signature);
224224
sshbuf_free(tmp);
@@ -279,8 +279,8 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
279279
r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
280280
&shared_secret);
281281
break;
282-
case KEX_KEM_SNTRUP4591761X25519_SHA512:
283-
r = kex_kem_sntrup4591761x25519_enc(kex, client_pubkey,
282+
case KEX_KEM_SNTRUP761X25519_SHA512:
283+
r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
284284
&server_pubkey, &shared_secret);
285285
break;
286286
default:
Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: kexsntrup4591761x25519.c,v 1.4 2020/12/19 22:09:21 tobhe Exp $ */
1+
/* $OpenBSD: kexsntrup761x25519.c,v 1.1 2020/12/29 00:59:15 djm Exp $ */
22
/*
33
* Copyright (c) 2019 Markus Friedl. All rights reserved.
44
*
@@ -36,7 +36,7 @@
3636
#include "ssherr.h"
3737

3838
int
39-
kex_kem_sntrup4591761x25519_keypair(struct kex *kex)
39+
kex_kem_sntrup761x25519_keypair(struct kex *kex)
4040
{
4141
struct sshbuf *buf = NULL;
4242
u_char *cp = NULL;
@@ -45,15 +45,15 @@ kex_kem_sntrup4591761x25519_keypair(struct kex *kex)
4545

4646
if ((buf = sshbuf_new()) == NULL)
4747
return SSH_ERR_ALLOC_FAIL;
48-
need = crypto_kem_sntrup4591761_PUBLICKEYBYTES + CURVE25519_SIZE;
48+
need = crypto_kem_sntrup761_PUBLICKEYBYTES + CURVE25519_SIZE;
4949
if ((r = sshbuf_reserve(buf, need, &cp)) != 0)
5050
goto out;
51-
crypto_kem_sntrup4591761_keypair(cp, kex->sntrup4591761_client_key);
51+
crypto_kem_sntrup761_keypair(cp, kex->sntrup761_client_key);
5252
#ifdef DEBUG_KEXECDH
53-
dump_digest("client public key sntrup4591761:", cp,
54-
crypto_kem_sntrup4591761_PUBLICKEYBYTES);
53+
dump_digest("client public key sntrup761:", cp,
54+
crypto_kem_sntrup761_PUBLICKEYBYTES);
5555
#endif
56-
cp += crypto_kem_sntrup4591761_PUBLICKEYBYTES;
56+
cp += crypto_kem_sntrup761_PUBLICKEYBYTES;
5757
kexc25519_keygen(kex->c25519_client_key, cp);
5858
#ifdef DEBUG_KEXECDH
5959
dump_digest("client public key c25519:", cp, CURVE25519_SIZE);
@@ -66,7 +66,7 @@ kex_kem_sntrup4591761x25519_keypair(struct kex *kex)
6666
}
6767

6868
int
69-
kex_kem_sntrup4591761x25519_enc(struct kex *kex,
69+
kex_kem_sntrup761x25519_enc(struct kex *kex,
7070
const struct sshbuf *client_blob, struct sshbuf **server_blobp,
7171
struct sshbuf **shared_secretp)
7272
{
@@ -83,17 +83,17 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex,
8383
*shared_secretp = NULL;
8484

8585
/* client_blob contains both KEM and ECDH client pubkeys */
86-
need = crypto_kem_sntrup4591761_PUBLICKEYBYTES + CURVE25519_SIZE;
86+
need = crypto_kem_sntrup761_PUBLICKEYBYTES + CURVE25519_SIZE;
8787
if (sshbuf_len(client_blob) != need) {
8888
r = SSH_ERR_SIGNATURE_INVALID;
8989
goto out;
9090
}
9191
client_pub = sshbuf_ptr(client_blob);
9292
#ifdef DEBUG_KEXECDH
93-
dump_digest("client public key sntrup4591761:", client_pub,
94-
crypto_kem_sntrup4591761_PUBLICKEYBYTES);
93+
dump_digest("client public key sntrup761:", client_pub,
94+
crypto_kem_sntrup761_PUBLICKEYBYTES);
9595
dump_digest("client public key 25519:",
96-
client_pub + crypto_kem_sntrup4591761_PUBLICKEYBYTES,
96+
client_pub + crypto_kem_sntrup761_PUBLICKEYBYTES,
9797
CURVE25519_SIZE);
9898
#endif
9999
/* allocate buffer for concatenation of KEM key and ECDH shared key */
@@ -102,32 +102,32 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex,
102102
r = SSH_ERR_ALLOC_FAIL;
103103
goto out;
104104
}
105-
if ((r = sshbuf_reserve(buf, crypto_kem_sntrup4591761_BYTES,
105+
if ((r = sshbuf_reserve(buf, crypto_kem_sntrup761_BYTES,
106106
&kem_key)) != 0)
107107
goto out;
108108
/* allocate space for encrypted KEM key and ECDH pub key */
109109
if ((server_blob = sshbuf_new()) == NULL) {
110110
r = SSH_ERR_ALLOC_FAIL;
111111
goto out;
112112
}
113-
need = crypto_kem_sntrup4591761_CIPHERTEXTBYTES + CURVE25519_SIZE;
113+
need = crypto_kem_sntrup761_CIPHERTEXTBYTES + CURVE25519_SIZE;
114114
if ((r = sshbuf_reserve(server_blob, need, &ciphertext)) != 0)
115115
goto out;
116116
/* generate and encrypt KEM key with client key */
117-
crypto_kem_sntrup4591761_enc(ciphertext, kem_key, client_pub);
117+
crypto_kem_sntrup761_enc(ciphertext, kem_key, client_pub);
118118
/* generate ECDH key pair, store server pubkey after ciphertext */
119-
server_pub = ciphertext + crypto_kem_sntrup4591761_CIPHERTEXTBYTES;
119+
server_pub = ciphertext + crypto_kem_sntrup761_CIPHERTEXTBYTES;
120120
kexc25519_keygen(server_key, server_pub);
121121
/* append ECDH shared key */
122-
client_pub += crypto_kem_sntrup4591761_PUBLICKEYBYTES;
122+
client_pub += crypto_kem_sntrup761_PUBLICKEYBYTES;
123123
if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 1)) < 0)
124124
goto out;
125125
if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0)
126126
goto out;
127127
#ifdef DEBUG_KEXECDH
128128
dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE);
129129
dump_digest("server cipher text:", ciphertext,
130-
crypto_kem_sntrup4591761_CIPHERTEXTBYTES);
130+
crypto_kem_sntrup761_CIPHERTEXTBYTES);
131131
dump_digest("server kem key:", kem_key, sizeof(kem_key));
132132
dump_digest("concatenation of KEM key and ECDH shared key:",
133133
sshbuf_ptr(buf), sshbuf_len(buf));
@@ -153,7 +153,7 @@ kex_kem_sntrup4591761x25519_enc(struct kex *kex,
153153
}
154154

155155
int
156-
kex_kem_sntrup4591761x25519_dec(struct kex *kex,
156+
kex_kem_sntrup761x25519_dec(struct kex *kex,
157157
const struct sshbuf *server_blob, struct sshbuf **shared_secretp)
158158
{
159159
struct sshbuf *buf = NULL;
@@ -165,35 +165,35 @@ kex_kem_sntrup4591761x25519_dec(struct kex *kex,
165165

166166
*shared_secretp = NULL;
167167

168-
need = crypto_kem_sntrup4591761_CIPHERTEXTBYTES + CURVE25519_SIZE;
168+
need = crypto_kem_sntrup761_CIPHERTEXTBYTES + CURVE25519_SIZE;
169169
if (sshbuf_len(server_blob) != need) {
170170
r = SSH_ERR_SIGNATURE_INVALID;
171171
goto out;
172172
}
173173
ciphertext = sshbuf_ptr(server_blob);
174-
server_pub = ciphertext + crypto_kem_sntrup4591761_CIPHERTEXTBYTES;
174+
server_pub = ciphertext + crypto_kem_sntrup761_CIPHERTEXTBYTES;
175175
#ifdef DEBUG_KEXECDH
176176
dump_digest("server cipher text:", ciphertext,
177-
crypto_kem_sntrup4591761_CIPHERTEXTBYTES);
177+
crypto_kem_sntrup761_CIPHERTEXTBYTES);
178178
dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE);
179179
#endif
180180
/* hash concatenation of KEM key and ECDH shared key */
181181
if ((buf = sshbuf_new()) == NULL) {
182182
r = SSH_ERR_ALLOC_FAIL;
183183
goto out;
184184
}
185-
if ((r = sshbuf_reserve(buf, crypto_kem_sntrup4591761_BYTES,
185+
if ((r = sshbuf_reserve(buf, crypto_kem_sntrup761_BYTES,
186186
&kem_key)) != 0)
187187
goto out;
188-
decoded = crypto_kem_sntrup4591761_dec(kem_key, ciphertext,
189-
kex->sntrup4591761_client_key);
188+
decoded = crypto_kem_sntrup761_dec(kem_key, ciphertext,
189+
kex->sntrup761_client_key);
190190
if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, server_pub,
191191
buf, 1)) < 0)
192192
goto out;
193193
if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0)
194194
goto out;
195195
#ifdef DEBUG_KEXECDH
196-
dump_digest("client kem key:", kem_key, crypto_kem_sntrup4591761_BYTES);
196+
dump_digest("client kem key:", kem_key, crypto_kem_sntrup761_BYTES);
197197
dump_digest("concatenation of KEM key and ECDH shared key:",
198198
sshbuf_ptr(buf), sshbuf_len(buf));
199199
#endif

usr.bin/ssh/monitor.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: monitor.c,v 1.218 2020/11/27 00:37:10 djm Exp $ */
1+
/* $OpenBSD: monitor.c,v 1.219 2020/12/29 00:59:15 djm Exp $ */
22
/*
33
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
44
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -1429,7 +1429,7 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor)
14291429
kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
14301430
#endif
14311431
kex->kex[KEX_C25519_SHA256] = kex_gen_server;
1432-
kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server;
1432+
kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
14331433
kex->load_host_public_key=&get_hostkey_public_by_type;
14341434
kex->load_host_private_key=&get_hostkey_private_by_type;
14351435
kex->host_key_index=&get_hostkey_index;

0 commit comments

Comments
 (0)