upstream commit

add support for additional fixed DH groups from
 draft-ietf-curdle-ssh-kex-sha2-03

diffie-hellman-group14-sha256 (2K group)
diffie-hellman-group16-sha512 (4K group)
diffie-hellman-group18-sha512 (8K group)

based on patch from Mark D. Baushke and Darren Tucker
ok markus@

Upstream-ID: ac00406ada4f0dfec41585ca0839f039545bc46f
This commit is contained in:
djm@openbsd.org 2016-05-02 10:26:04 +00:00 committed by Damien Miller
parent 57464e3934
commit 0e8eeec8e7
13 changed files with 147 additions and 33 deletions

85
dh.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: dh.c,v 1.59 2016/03/31 05:24:06 dtucker Exp $ */
/* $OpenBSD: dh.c,v 1.60 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
*
@ -314,6 +314,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus)
return (dh);
}
/* rfc2409 "Second Oakley Group" (1024 bits) */
DH *
dh_new_group1(void)
{
@ -328,6 +329,7 @@ dh_new_group1(void)
return (dh_new_group_asc(gen, group1));
}
/* rfc3526 group 14 "2048-bit MODP Group" */
DH *
dh_new_group14(void)
{
@ -347,12 +349,9 @@ dh_new_group14(void)
return (dh_new_group_asc(gen, group14));
}
/*
* 4k bit fallback group used by DH-GEX if moduli file cannot be read.
* Source: MODP group 16 from RFC3526.
*/
/* rfc3526 group 16 "4096-bit MODP Group" */
DH *
dh_new_group_fallback(int max)
dh_new_group16(void)
{
static char *gen = "2", *group16 =
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
@ -378,14 +377,77 @@ dh_new_group_fallback(int max)
"93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
"FFFFFFFF" "FFFFFFFF";
if (max < 4096) {
debug3("requested max size %d, using 2k bit group 14", max);
return dh_new_group14();
}
debug3("using 4k bit group 16");
return (dh_new_group_asc(gen, group16));
}
/* rfc3526 group 18 "8192-bit MODP Group" */
DH *
dh_new_group18(void)
{
static char *gen = "2", *group16 =
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
"C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
"83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
"670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
"E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
"DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
"15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
"ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
"ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
"F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
"BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
"43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
"88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
"2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
"287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
"1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
"93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
"36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
"F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
"179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
"DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
"5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
"D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
"23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
"CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
"06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
"DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
"12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
"38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
"741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
"3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
"22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
"4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
"062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
"4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
"B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
"4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
"9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
"60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
return (dh_new_group_asc(gen, group16));
}
/* Select fallback group used by DH-GEX if moduli file cannot be read. */
DH *
dh_new_group_fallback(int max)
{
debug3("%s: requested max size %d", __func__, max);
if (max < 3072) {
debug3("using 2k bit group 14");
return dh_new_group14();
} else if (max < 6144) {
debug3("using 4k bit group 16");
return dh_new_group16();
}
debug3("using 8k bit group 18");
return dh_new_group18();
}
/*
* Estimates the group order for a Diffie-Hellman group that has an
* attack complexity approximately the same as O(2**bits).
@ -393,7 +455,6 @@ dh_new_group_fallback(int max)
* Management Part 1 (rev 3) limited by the recommended maximum value
* from RFC4419 section 3.
*/
u_int
dh_estimate(int bits)
{

4
dh.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: dh.h,v 1.14 2015/10/16 22:32:22 djm Exp $ */
/* $OpenBSD: dh.h,v 1.15 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
@ -37,6 +37,8 @@ DH *dh_new_group_asc(const char *, const char *);
DH *dh_new_group(BIGNUM *, BIGNUM *);
DH *dh_new_group1(void);
DH *dh_new_group14(void);
DH *dh_new_group16(void);
DH *dh_new_group18(void);
DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int);

7
kex.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.c,v 1.117 2016/02/08 10:57:07 djm Exp $ */
/* $OpenBSD: kex.c,v 1.118 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@ -88,7 +88,10 @@ struct kexalg {
static const struct kexalg kexalgs[] = {
#ifdef WITH_OPENSSL
{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
{ KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },
{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
#ifdef HAVE_EVP_SHA256
{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },

12
kex.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.h,v 1.77 2016/05/02 08:49:03 djm Exp $ */
/* $OpenBSD: kex.h,v 1.78 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -51,7 +51,10 @@
#define KEX_COOKIE_LEN 16
#define KEX_DH1 "diffie-hellman-group1-sha1"
#define KEX_DH14 "diffie-hellman-group14-sha1"
#define KEX_DH14_SHA1 "diffie-hellman-group14-sha1"
#define KEX_DH14_SHA256 "diffie-hellman-group14-sha256"
#define KEX_DH16_SHA512 "diffie-hellman-group16-sha512"
#define KEX_DH18_SHA512 "diffie-hellman-group18-sha512"
#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1"
#define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256"
#define KEX_ECDH_SHA2_NISTP256 "ecdh-sha2-nistp256"
@ -88,6 +91,9 @@ enum kex_modes {
enum kex_exchange {
KEX_DH_GRP1_SHA1,
KEX_DH_GRP14_SHA1,
KEX_DH_GRP14_SHA256,
KEX_DH_GRP16_SHA512,
KEX_DH_GRP18_SHA512,
KEX_DH_GEX_SHA1,
KEX_DH_GEX_SHA256,
KEX_ECDH_SHA2,
@ -190,7 +196,7 @@ int kexecdh_server(struct ssh *);
int kexc25519_client(struct ssh *);
int kexc25519_server(struct ssh *);
int kex_dh_hash(const char *, const char *,
int kex_dh_hash(int, const char *, const char *,
const u_char *, size_t, const u_char *, size_t, const u_char *, size_t,
const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexdh.c,v 1.25 2015/01/19 20:16:15 markus Exp $ */
/* $OpenBSD: kexdh.c,v 1.26 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -43,6 +43,7 @@
int
kex_dh_hash(
int hash_alg,
const char *client_version_string,
const char *server_version_string,
const u_char *ckexinit, size_t ckexinitlen,
@ -56,7 +57,7 @@ kex_dh_hash(
struct sshbuf *b;
int r;
if (*hashlen < ssh_digest_bytes(SSH_DIGEST_SHA1))
if (*hashlen < ssh_digest_bytes(hash_alg))
return SSH_ERR_INVALID_ARGUMENT;
if ((b = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
@ -79,12 +80,12 @@ kex_dh_hash(
#ifdef DEBUG_KEX
sshbuf_dump(b, stderr);
#endif
if (ssh_digest_buffer(SSH_DIGEST_SHA1, b, hash, *hashlen) != 0) {
if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) {
sshbuf_free(b);
return SSH_ERR_LIBCRYPTO_ERROR;
}
sshbuf_free(b);
*hashlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
*hashlen = ssh_digest_bytes(hash_alg);
#ifdef DEBUG_KEX
dump_digest("hash", hash, *hashlen);
#endif

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexdhc.c,v 1.18 2015/01/26 06:10:03 djm Exp $ */
/* $OpenBSD: kexdhc.c,v 1.19 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -63,8 +63,15 @@ kexdh_client(struct ssh *ssh)
kex->dh = dh_new_group1();
break;
case KEX_DH_GRP14_SHA1:
case KEX_DH_GRP14_SHA256:
kex->dh = dh_new_group14();
break;
case KEX_DH_GRP16_SHA512:
kex->dh = dh_new_group16();
break;
case KEX_DH_GRP18_SHA512:
kex->dh = dh_new_group18();
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
@ -164,6 +171,7 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt)
/* calc and verify H */
hashlen = sizeof(hash);
if ((r = kex_dh_hash(
kex->hash_alg,
kex->client_version_string,
kex->server_version_string,
sshbuf_ptr(kex->my), sshbuf_len(kex->my),

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexdhs.c,v 1.23 2015/12/04 16:41:28 markus Exp $ */
/* $OpenBSD: kexdhs.c,v 1.24 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -63,8 +63,15 @@ kexdh_server(struct ssh *ssh)
kex->dh = dh_new_group1();
break;
case KEX_DH_GRP14_SHA1:
case KEX_DH_GRP14_SHA256:
kex->dh = dh_new_group14();
break;
case KEX_DH_GRP16_SHA512:
kex->dh = dh_new_group16();
break;
case KEX_DH_GRP18_SHA512:
kex->dh = dh_new_group18();
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
@ -158,6 +165,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
/* calc H */
hashlen = sizeof(hash);
if ((r = kex_dh_hash(
kex->hash_alg,
kex->client_version_string,
kex->server_version_string,
sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.159 2016/05/02 08:49:03 djm Exp $ */
/* $OpenBSD: monitor.c,v 1.160 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -1860,6 +1860,9 @@ monitor_apply_keystate(struct monitor *pmonitor)
#ifdef WITH_OPENSSL
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server;
kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server;
kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
# ifdef OPENSSL_HAS_ECC

View File

@ -67,13 +67,18 @@
#endif
#ifdef HAVE_EVP_SHA256
# define KEX_SHA256_METHODS \
"diffie-hellman-group-exchange-sha256,"
# define KEX_SHA2_METHODS \
"diffie-hellman-group-exchange-sha256," \
"diffie-hellman-group16-sha512," \
"diffie-hellman-group18-sha512,"
# define KEX_SHA2_GROUP14 \
"diffie-hellman-group14-sha256,"
#define SHA2_HMAC_MODES \
"hmac-sha2-256," \
"hmac-sha2-512,"
#else
# define KEX_SHA256_METHODS
# define KEX_SHA2_METHODS
# define KEX_SHA2_GROUP14
# define SHA2_HMAC_MODES
#endif
@ -86,13 +91,15 @@
#define KEX_COMMON_KEX \
KEX_CURVE25519_METHODS \
KEX_ECDH_METHODS \
KEX_SHA256_METHODS
KEX_SHA2_METHODS
#define KEX_SERVER_KEX KEX_COMMON_KEX \
KEX_SHA2_GROUP14 \
"diffie-hellman-group14-sha1" \
#define KEX_CLIENT_KEX KEX_COMMON_KEX \
"diffie-hellman-group-exchange-sha1," \
KEX_SHA2_GROUP14 \
"diffie-hellman-group14-sha1"
#define KEX_DEFAULT_PK_ALG \

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.105 2016/02/15 09:47:49 dtucker Exp $ */
/* $OpenBSD: ssh-keyscan.c,v 1.106 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@ -302,6 +302,9 @@ keygrab_ssh2(con *c)
#ifdef WITH_OPENSSL
c->c_ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
c->c_ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
c->c_ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client;
c->c_ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client;
c->c_ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client;
c->c_ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
c->c_ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
# ifdef OPENSSL_HAS_ECC

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh_api.c,v 1.5 2015/12/04 16:41:28 markus Exp $ */
/* $OpenBSD: ssh_api.c,v 1.6 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright (c) 2012 Markus Friedl. All rights reserved.
*
@ -103,6 +103,9 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
#ifdef WITH_OPENSSL
ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server;
ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server;
ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server;
ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
# ifdef OPENSSL_HAS_ECC
@ -117,6 +120,9 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
#ifdef WITH_OPENSSL
ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
ssh->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client;
ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client;
ssh->kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client;
ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
# ifdef OPENSSL_HAS_ECC

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect2.c,v 1.242 2016/05/02 08:49:03 djm Exp $ */
/* $OpenBSD: sshconnect2.c,v 1.243 2016/05/02 10:26:04 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@ -206,6 +206,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
#ifdef WITH_OPENSSL
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
kex->kex[KEX_DH_GRP14_SHA256] = kexdh_client;
kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client;
kex->kex[KEX_DH_GRP18_SHA512] = kexdh_client;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
# ifdef OPENSSL_HAS_ECC

5
sshd.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.467 2016/05/02 08:49:03 djm Exp $ */
/* $OpenBSD: sshd.c,v 1.468 2016/05/02 10:26:04 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -2637,6 +2637,9 @@ do_ssh2_kex(void)
#ifdef WITH_OPENSSL
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server;
kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server;
kex->kex[KEX_DH_GRP18_SHA512] = kexdh_server;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
# ifdef OPENSSL_HAS_ECC