Fix CVE-2016-0739 (Weak Diffie-Hellman secret generation in
dh_generate_x() and dh_generate_y()).

"Due to a byte/bit confusion, the DH secret was too short. This file was
completely reworked and will be commited in a future version."
Source:
https://git.libssh.org/projects/libssh.git/commit/?id=f8d0026c65fc8a55748ae481758e2cf376c26c86

This patch was created by upstream for libssh-0.7.3, but applied without
modification to libssh-0.6.3 by Debian. In Guix, we apply it without
modification to libssh-0.6.5.

References:
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-0739
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0739
https://security-tracker.debian.org/tracker/CVE-2016-0739

---
 src/dh.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/src/dh.c b/src/dh.c
index e489a1d..d27b66e 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -227,15 +227,21 @@ void ssh_crypto_finalize(void) {
 }
 
 int dh_generate_x(ssh_session session) {
+  int keysize;
+  if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1) {
+    keysize = 1023;
+  } else {
+    keysize = 2047;
+  }
   session->next_crypto->x = bignum_new();
   if (session->next_crypto->x == NULL) {
     return -1;
   }
 
 #ifdef HAVE_LIBGCRYPT
-  bignum_rand(session->next_crypto->x, 128);
+  bignum_rand(session->next_crypto->x, keysize);
 #elif defined HAVE_LIBCRYPTO
-  bignum_rand(session->next_crypto->x, 128, 0, -1);
+  bignum_rand(session->next_crypto->x, keysize, -1, 0);
 #endif
 
   /* not harder than this */
@@ -248,15 +254,21 @@ int dh_generate_x(ssh_session session) {
 
 /* used by server */
 int dh_generate_y(ssh_session session) {
-    session->next_crypto->y = bignum_new();
+  int keysize;
+  if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1) {
+    keysize = 1023;
+  } else {
+    keysize = 2047;
+  }
+  session->next_crypto->y = bignum_new();
   if (session->next_crypto->y == NULL) {
     return -1;
   }
 
 #ifdef HAVE_LIBGCRYPT
-  bignum_rand(session->next_crypto->y, 128);
+  bignum_rand(session->next_crypto->y, keysize);
 #elif defined HAVE_LIBCRYPTO
-  bignum_rand(session->next_crypto->y, 128, 0, -1);
+  bignum_rand(session->next_crypto->y, keysize, -1, 0);
 #endif
 
   /* not harder than this */
-- 
cgit v0.12

