On Fri, Jan 24, 2014 at 05:28:03PM +0100, Petr Lautrbach wrote: > On 01/21/2014 05:14 PM, Petr Lautrbach wrote: > > Hello everybody, > > > > An issue was reported in RH bugzilla [1] about the size of the used DH > > group when combined with the 3des-cbc cipher. OpenSSH uses the > > actual key length for the size estimation. This is probably fine as far > > as the cipher has the same number of bits of security as the key > > length. But this is not true for 3TDEA where the key size is 168 resp > > 192 but it's security is only 112. > > > > Given that the key size in openssh is set to 192, DH group size is > > estimated to 7680. But according to NIST SP 800-57, the size of DH key > > should be 2048 so openssh doesn't follow that and it might cause > > problems with key exchanges with some servers. > > > > It was confirmed that openssh can't connect to the server with a server string > 'SSH-2.0-cryptlib' using diffie-hellman-group-exchange-sha1 and 3des-cbc with > SSH2_MSG_KEX_DH_GEX_REQUEST(1024<7680<8192). Thanks for the patch. Since we are so close to the 6.5 release I have committed a smaller change that should still resolve the problem (confirmed by checking the debug output for the requested group sizes). Thanks. Index: cipher.c =================================================================== RCS file: /cvs/src/usr.bin/ssh/cipher.c,v retrieving revision 1.93 diff -u -p -r1.93 cipher.c --- cipher.c 6 Dec 2013 13:34:54 -0000 1.93 +++ cipher.c 25 Jan 2014 10:04:23 -0000 @@ -136,6 +136,14 @@ cipher_keylen(const Cipher *c) } u_int +cipher_seclen(const Cipher *c) +{ + if (strcmp("3des-cbc", c->name) == 0) + return 14; + return cipher_keylen(c); +} + +u_int cipher_authlen(const Cipher *c) { return (c->auth_len); Index: cipher.h =================================================================== RCS file: /cvs/src/usr.bin/ssh/cipher.h,v retrieving revision 1.43 diff -u -p -r1.43 cipher.h --- cipher.h 6 Dec 2013 13:34:54 -0000 1.43 +++ cipher.h 25 Jan 2014 10:04:23 -0000 @@ -89,6 +89,7 @@ void cipher_cleanup(CipherContext *); void cipher_set_key_string(CipherContext *, const Cipher *, const char *, int); u_int cipher_blocksize(const Cipher *); u_int cipher_keylen(const Cipher *); +u_int cipher_seclen(const Cipher *); u_int cipher_authlen(const Cipher *); u_int cipher_ivlen(const Cipher *); u_int cipher_is_cbc(const Cipher *); Index: kex.c =================================================================== RCS file: /cvs/src/usr.bin/ssh/kex.c,v retrieving revision 1.95 diff -u -p -r1.95 kex.c --- kex.c 12 Jan 2014 08:13:13 -0000 1.95 +++ kex.c 25 Jan 2014 10:04:23 -0000 @@ -438,7 +438,7 @@ kex_choose_conf(Kex *kex) char **my, **peer; char **cprop, **sprop; int nenc, nmac, ncomp; - u_int mode, ctos, need, authlen; + u_int mode, ctos, need, dh_need, authlen; int first_kex_follows, type; my = kex_buf2prop(&kex->my, NULL); @@ -486,7 +486,7 @@ kex_choose_conf(Kex *kex) choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); - need = 0; + need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { newkeys = kex->newkeys[mode]; if (need < newkeys->enc.key_len) @@ -497,9 +497,12 @@ kex_choose_conf(Kex *kex) need = newkeys->enc.iv_len; if (need < newkeys->mac.key_len) need = newkeys->mac.key_len; + if (dh_need < cipher_seclen(newkeys->enc.cipher)) + dh_need = cipher_seclen(newkeys->enc.cipher); } /* XXX need runden? */ kex->we_need = need; + kex->dh_need = dh_need; /* ignore the next message if the proposals do not match */ if (first_kex_follows && !proposals_match(my, peer) && Index: kex.h =================================================================== RCS file: /cvs/src/usr.bin/ssh/kex.h,v retrieving revision 1.60 diff -u -p -r1.60 kex.h --- kex.h 12 Jan 2014 08:13:13 -0000 1.60 +++ kex.h 25 Jan 2014 10:04:23 -0000 @@ -121,6 +121,7 @@ struct Kex { u_int session_id_len; Newkeys *newkeys[MODE_MAX]; u_int we_need; + u_int dh_need; int server; char *name; int hostkey_type; Index: kexgexc.c =================================================================== RCS file: /cvs/src/usr.bin/ssh/kexgexc.c,v retrieving revision 1.15 diff -u -p -r1.15 kexgexc.c --- kexgexc.c 12 Jan 2014 08:13:13 -0000 1.15 +++ kexgexc.c 25 Jan 2014 10:04:23 -0000 @@ -55,7 +55,7 @@ kexgex_client(Kex *kex) int min, max, nbits; DH *dh; - nbits = dh_estimate(kex->we_need * 8); + nbits = dh_estimate(kex->dh_need * 8); if (datafellows & SSH_OLD_DHGEX) { /* Old GEX request */ -- Darren Tucker (dtucker at zip.com.au) GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69 Good judgement comes with experience. Unfortunately, the experience usually comes from bad judgement.