summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-12-12 17:46:00 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-12-12 17:55:44 +0100
commit55968012dcefc50590925b4ddcf556f8ca67a8b5 (patch)
treef00cabefcf030c9703f8fa0c4f20b04836b0c3a2 /lib
parent4b0c8268003bc16a374f7ab567bea29d93e2d081 (diff)
downloadgnutls-55968012dcefc50590925b4ddcf556f8ca67a8b5.tar.gz
Diffie Hellman PKCS #3 parameters now contain the recommended private key size.
By using the recommended key size the calculations for the server side are reduced, giving a 50% increase in DH calculations.
Diffstat (limited to 'lib')
-rw-r--r--lib/auth/anon.c2
-rw-r--r--lib/auth/dh_common.c18
-rw-r--r--lib/auth/dh_common.h3
-rw-r--r--lib/auth/dhe.c2
-rw-r--r--lib/auth/dhe_psk.c2
-rw-r--r--lib/crypto-backend.h1
-rw-r--r--lib/gnutls_dh.c13
-rw-r--r--lib/gnutls_dh.h3
-rw-r--r--lib/gnutls_dh_primes.c35
-rw-r--r--lib/gnutls_int.h2
-rw-r--r--lib/nettle/mpi.c9
11 files changed, 59 insertions, 31 deletions
diff --git a/lib/auth/anon.c b/lib/auth/anon.c
index 926bab650a..49efb497c6 100644
--- a/lib/auth/anon.c
+++ b/lib/auth/anon.c
@@ -99,7 +99,7 @@ gen_anon_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
_gnutls_dh_set_group (session, g, p);
- ret = _gnutls_dh_common_print_server_kx (session, g, p, data);
+ ret = _gnutls_dh_common_print_server_kx (session, g, p, dh_params->q_bits, data);
if (ret < 0)
{
gnutls_assert ();
diff --git a/lib/auth/dh_common.c b/lib/auth/dh_common.c
index 484fe4fceb..7a93d83789 100644
--- a/lib/auth/dh_common.c
+++ b/lib/auth/dh_common.c
@@ -129,7 +129,7 @@ _gnutls_gen_dh_common_client_kx_int (gnutls_session_t session, gnutls_buffer_st*
int ret;
X = gnutls_calc_dh_secret (&x, session->key->client_g,
- session->key->client_p);
+ session->key->client_p, 0);
if (X == NULL || x == NULL)
{
gnutls_assert ();
@@ -283,17 +283,17 @@ _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
return ret;
}
-/* If the psk flag is set, then an empty psk_identity_hint will
- * be inserted */
int
_gnutls_dh_common_print_server_kx (gnutls_session_t session,
- bigint_t g, bigint_t p, gnutls_buffer_st* data)
+ bigint_t g, bigint_t p, unsigned int q_bits,
+ gnutls_buffer_st* data)
{
- bigint_t x, X;
+ bigint_t x, Y;
int ret;
- X = gnutls_calc_dh_secret (&x, g, p);
- if (X == NULL || x == NULL)
+ /* Y=g^x mod p */
+ Y = gnutls_calc_dh_secret (&x, g, p, q_bits);
+ if (Y == NULL || x == NULL)
{
gnutls_assert ();
return GNUTLS_E_MEMORY_ERROR;
@@ -316,7 +316,7 @@ _gnutls_dh_common_print_server_kx (gnutls_session_t session,
goto cleanup;
}
- ret = _gnutls_buffer_append_mpi(data, 16, X, 0);
+ ret = _gnutls_buffer_append_mpi(data, 16, Y, 0);
if (ret < 0)
{
ret = gnutls_assert_val(ret);
@@ -324,7 +324,7 @@ _gnutls_dh_common_print_server_kx (gnutls_session_t session,
}
cleanup:
- _gnutls_mpi_release (&X);
+ _gnutls_mpi_release (&Y);
return data->length;
}
diff --git a/lib/auth/dh_common.h b/lib/auth/dh_common.h
index 20fc6983db..2ff976a9a4 100644
--- a/lib/auth/dh_common.h
+++ b/lib/auth/dh_common.h
@@ -42,7 +42,8 @@ int _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
bigint_t p, bigint_t g,
gnutls_datum_t* psk_key);
int _gnutls_dh_common_print_server_kx (gnutls_session_t, bigint_t g,
- bigint_t p, gnutls_buffer_st* data);
+ bigint_t p, unsigned int q_bits,
+ gnutls_buffer_st* data);
int _gnutls_proc_dh_common_server_kx (gnutls_session_t session, opaque * data,
size_t _data_size);
diff --git a/lib/auth/dhe.c b/lib/auth/dhe.c
index 5e9d5e0a17..87496af17d 100644
--- a/lib/auth/dhe.c
+++ b/lib/auth/dhe.c
@@ -168,7 +168,7 @@ gen_dhe_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
_gnutls_dh_set_group (session, g, p);
- ret = _gnutls_dh_common_print_server_kx (session, g, p, data);
+ ret = _gnutls_dh_common_print_server_kx (session, g, p, dh_params->q_bits, data);
}
else
{
diff --git a/lib/auth/dhe_psk.c b/lib/auth/dhe_psk.c
index d1417e34de..7170c0b11c 100644
--- a/lib/auth/dhe_psk.c
+++ b/lib/auth/dhe_psk.c
@@ -177,7 +177,7 @@ gen_psk_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
if (ret < 0)
return gnutls_assert_val(ret);
- ret = _gnutls_dh_common_print_server_kx (session, g, p, data);
+ ret = _gnutls_dh_common_print_server_kx (session, g, p, dh_params->q_bits, data);
if (ret < 0)
gnutls_assert ();
diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h
index ed89deb39d..a49b48826c 100644
--- a/lib/crypto-backend.h
+++ b/lib/crypto-backend.h
@@ -78,6 +78,7 @@
{
bigint_t g; /* group generator */
bigint_t p; /* prime */
+ int q_bits; /* the number of bits of q */
} gnutls_group_st;
/**
diff --git a/lib/gnutls_dh.c b/lib/gnutls_dh.c
index bd46e546bf..d38856b809 100644
--- a/lib/gnutls_dh.c
+++ b/lib/gnutls_dh.c
@@ -47,13 +47,16 @@
/* returns the public value (X), and the secret (ret_x).
*/
bigint_t
-gnutls_calc_dh_secret (bigint_t * ret_x, bigint_t g, bigint_t prime)
+gnutls_calc_dh_secret (bigint_t * ret_x, bigint_t g, bigint_t prime,
+ unsigned int q_bits)
{
bigint_t e, x = NULL;
- int x_size = _gnutls_mpi_get_nbits (prime) - 1;
- /* The size of the secret key is less than
- * prime/2
- */
+ int x_size;
+
+ if (q_bits == 0)
+ x_size = _gnutls_mpi_get_nbits (prime) - 1;
+ else
+ x_size = q_bits;
if (x_size > MAX_BITS || x_size <= 0)
{
diff --git a/lib/gnutls_dh.h b/lib/gnutls_dh.h
index 990294ef78..5b053705c4 100644
--- a/lib/gnutls_dh.h
+++ b/lib/gnutls_dh.h
@@ -24,7 +24,8 @@
#define GNUTLS_DH_H
const bigint_t *_gnutls_dh_params_to_mpi (gnutls_dh_params_t);
-bigint_t gnutls_calc_dh_secret (bigint_t * ret_x, bigint_t g, bigint_t prime);
+bigint_t gnutls_calc_dh_secret (bigint_t * ret_x, bigint_t g, bigint_t prime,
+ unsigned int q_bits);
bigint_t gnutls_calc_dh_key (bigint_t f, bigint_t x, bigint_t prime);
gnutls_dh_params_t
diff --git a/lib/gnutls_dh_primes.c b/lib/gnutls_dh_primes.c
index c4ea423d75..f4fac9f827 100644
--- a/lib/gnutls_dh_primes.c
+++ b/lib/gnutls_dh_primes.c
@@ -197,6 +197,7 @@ gnutls_dh_params_generate2 (gnutls_dh_params_t params, unsigned int bits)
params->params[0] = group.p;
params->params[1] = group.g;
+ params->q_bits = group.q_bits;
return 0;
}
@@ -223,6 +224,7 @@ gnutls_dh_params_import_pkcs3 (gnutls_dh_params_t params,
{
ASN1_TYPE c2;
int result, need_free = 0;
+ unsigned int q_bits;
gnutls_datum_t _params;
if (format == GNUTLS_X509_FMT_PEM)
@@ -284,6 +286,16 @@ gnutls_dh_params_import_pkcs3 (gnutls_dh_params_t params,
return _gnutls_asn2err (result);
}
+ /* Read q length */
+ result = _gnutls_x509_read_uint (c2, "privateValueLength", &q_bits);
+ if (result < 0)
+ {
+ gnutls_assert ();
+ params->q_bits = 0;
+ }
+ else
+ params->q_bits = q_bits;
+
/* Read PRIME
*/
result = _gnutls_x509_read_int (c2, "prime", &params->params[0]);
@@ -380,6 +392,18 @@ gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
return _gnutls_asn2err (result);
}
+ if (params->q_bits > 0)
+ result = _gnutls_x509_write_uint32 (c2, "privateValueLength", params->q_bits);
+ else
+ result = asn1_write_value (c2, "privateValueLength", NULL, 0);
+
+ if (result < 0)
+ {
+ gnutls_assert ();
+ asn1_delete_structure (&c2);
+ return _gnutls_asn2err (result);
+ }
+
/* Write the GENERATOR
*/
if ((result = asn1_write_value (c2, "base",
@@ -393,13 +417,6 @@ gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
gnutls_free (all_data);
- if ((result = asn1_write_value (c2, "privateValueLength",
- NULL, 0)) != ASN1_SUCCESS)
- {
- gnutls_assert ();
- asn1_delete_structure (&c2);
- return _gnutls_asn2err (result);
- }
if (format == GNUTLS_X509_FMT_DER)
{
@@ -492,7 +509,7 @@ gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
* @params: Holds the DH parameters
* @prime: will hold the new prime
* @generator: will hold the new generator
- * @bits: if non null will hold is the prime's number of bits
+ * @bits: if non null will hold the secret key's number of bits
*
* This function will export the pair of prime and generator for use
* in the Diffie-Hellman key exchange. The new parameters will be
@@ -531,7 +548,7 @@ gnutls_dh_params_export_raw (gnutls_dh_params_t params,
}
if (bits)
- *bits = _gnutls_mpi_get_nbits (params->params[0]);
+ *bits = params->q_bits;
return 0;
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index d4644d94d7..5ffbb015b1 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -586,6 +586,8 @@ typedef struct gnutls_dh_params_int
/* [0] is the prime, [1] is the generator.
*/
bigint_t params[2];
+ int q_bits; /* length of q in bits. If zero then length is unknown.
+ */
} dh_params_st;
typedef struct
diff --git a/lib/nettle/mpi.c b/lib/nettle/mpi.c
index 322811daf7..0ebdcf4d2d 100644
--- a/lib/nettle/mpi.c
+++ b/lib/nettle/mpi.c
@@ -413,7 +413,7 @@ wrap_nettle_prime_check (bigint_t pp)
*
*/
inline static int
-gen_group (mpz_t * prime, mpz_t * generator, unsigned int nbits)
+gen_group (mpz_t * prime, mpz_t * generator, unsigned int nbits, unsigned int *q_bits)
{
mpz_t q, w, r;
unsigned int p_bytes = nbits / 8;
@@ -520,8 +520,9 @@ gen_group (mpz_t * prime, mpz_t * generator, unsigned int nbits)
}
}
+ *q_bits = wrap_nettle_mpi_get_nbits (&q);
_gnutls_debug_log ("Found prime q of %u bits. Looking for generator...\n",
- wrap_nettle_mpi_get_nbits (&q));
+ *q_bits);
/* finally a prime! Let calculate generator
*/
@@ -585,6 +586,7 @@ wrap_nettle_generate_group (gnutls_group_st * group, unsigned int bits)
int ret;
bigint_t p = wrap_nettle_mpi_new (bits);
bigint_t g;
+ unsigned int q_bits;
if (p == NULL)
{
@@ -600,7 +602,7 @@ wrap_nettle_generate_group (gnutls_group_st * group, unsigned int bits)
return GNUTLS_E_MEMORY_ERROR;
}
- ret = gen_group (p, g, bits);
+ ret = gen_group (p, g, bits, &q_bits);
if (ret < 0)
{
_gnutls_mpi_release (&g);
@@ -611,6 +613,7 @@ wrap_nettle_generate_group (gnutls_group_st * group, unsigned int bits)
group->p = p;
group->g = g;
+ group->q_bits = q_bits;
return 0;
}