3des cipher and DH group size
Darren Tucker
dtucker at zip.com.au
Sat Jan 25 21:17:28 EST 2014
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.
More information about the openssh-unix-dev
mailing list