diff -U0 openssh-6.4p1/ChangeLog.3des-dh-size openssh-6.4p1/ChangeLog
--- openssh-6.4p1/ChangeLog.3des-dh-size 2014-01-28 14:15:25.178358616 +0100
+++ openssh-6.4p1/ChangeLog 2014-01-28 14:18:24.678444650 +0100
@@ -0,0 +1,15 @@
+20140126
+ - OpenBSD CVS Sync
+ - dtucker@cvs.openbsd.org 2014/01/25 10:12:50
+ [cipher.c cipher.h kex.c kex.h kexgexc.c]
+ Add a special case for the DH group size for 3des-cbc, which has an
+ effective strength much lower than the key size. This causes problems
+ with some cryptlib implementations, which don't support group sizes larger
+ than 4k but also don't use the largest group size it does support as
+ specified in the RFC. Based on a patch from Petr Lautrbach at Redhat,
+ reduced by me with input from Markus. ok djm@ markus@
+ - markus@cvs.openbsd.org 2014/01/25 20:35:37
+ [kex.c]
+ dh_need needs to be set to max(seclen, blocksize, ivlen, mac_len)
+ ok dtucker@, noted by mancha
+
diff -up openssh-6.4p1/cipher.c.3des-dh-size openssh-6.4p1/cipher.c
--- openssh-6.4p1/cipher.c.3des-dh-size 2014-01-28 14:15:25.101359008 +0100
+++ openssh-6.4p1/cipher.c 2014-01-28 14:17:48.119630792 +0100
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher.c,v 1.89 2013/05/17 00:13:13 djm Exp $ */
+/* $OpenBSD: cipher.c,v 1.94 2014/01/25 10:12:50 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -144,6 +144,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);
diff -up openssh-6.4p1/cipher.h.3des-dh-size openssh-6.4p1/cipher.h
--- openssh-6.4p1/cipher.h.3des-dh-size 2014-01-28 14:15:25.178358616 +0100
+++ openssh-6.4p1/cipher.h 2014-01-28 14:17:17.858784879 +0100
@@ -1,4 +1,4 @@
-/* $OpenBSD: cipher.h,v 1.40 2013/04/19 01:06:50 djm Exp $ */
+/* $OpenBSD: cipher.h,v 1.44 2014/01/25 10:12:50 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -95,6 +95,7 @@ void cipher_cleanup(CipherContext *);
int 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 *);
diff -up openssh-6.4p1/kex.c.3des-dh-size openssh-6.4p1/kex.c
--- openssh-6.4p1/kex.c.3des-dh-size 2014-01-28 14:15:25.165358682 +0100
+++ openssh-6.4p1/kex.c 2014-01-28 14:19:22.038152586 +0100
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.91 2013/05/17 00:13:13 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.97 2014/01/25 20:35:37 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -494,7 +494,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);
@@ -545,20 +545,21 @@ 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)
- need = newkeys->enc.key_len;
- if (need < newkeys->enc.block_size)
- need = newkeys->enc.block_size;
- if (need < newkeys->enc.iv_len)
- need = newkeys->enc.iv_len;
- if (need < newkeys->mac.key_len)
- need = newkeys->mac.key_len;
+ need = MAX(need, newkeys->enc.key_len);
+ need = MAX(need, newkeys->enc.block_size);
+ need = MAX(need, newkeys->enc.iv_len);
+ need = MAX(need, newkeys->mac.key_len);
+ dh_need = MAX(dh_need, cipher_seclen(newkeys->enc.cipher));
+ dh_need = MAX(dh_need, newkeys->enc.block_size);
+ dh_need = MAX(dh_need, newkeys->enc.iv_len);
+ dh_need = MAX(dh_need, newkeys->mac.key_len);
}
/* 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) &&
diff -up openssh-6.4p1/kexgexc.c.3des-dh-size openssh-6.4p1/kexgexc.c
--- openssh-6.4p1/kexgexc.c.3des-dh-size 2014-01-28 14:15:25.165358682 +0100
+++ openssh-6.4p1/kexgexc.c 2014-01-28 14:19:09.718215323 +0100
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexc.c,v 1.13 2013/05/17 00:13:13 djm Exp $ */
+/* $OpenBSD: kexgexc.c,v 1.16 2014/01/25 10:12:50 dtucker Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -60,7 +60,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 */
diff -up openssh-6.4p1/kex.h.3des-dh-size openssh-6.4p1/kex.h
--- openssh-6.4p1/kex.h.3des-dh-size 2014-01-28 14:15:25.142358799 +0100
+++ openssh-6.4p1/kex.h 2014-01-28 14:18:49.431318614 +0100
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.56 2013/07/19 07:37:48 markus Exp $ */
+/* $OpenBSD: kex.h,v 1.61 2014/01/25 10:12:50 dtucker Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -125,6 +125,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;