diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-12-12 17:46:00 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-12-12 17:55:44 +0100 |
commit | 55968012dcefc50590925b4ddcf556f8ca67a8b5 (patch) | |
tree | f00cabefcf030c9703f8fa0c4f20b04836b0c3a2 /lib | |
parent | 4b0c8268003bc16a374f7ab567bea29d93e2d081 (diff) | |
download | gnutls-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.c | 2 | ||||
-rw-r--r-- | lib/auth/dh_common.c | 18 | ||||
-rw-r--r-- | lib/auth/dh_common.h | 3 | ||||
-rw-r--r-- | lib/auth/dhe.c | 2 | ||||
-rw-r--r-- | lib/auth/dhe_psk.c | 2 | ||||
-rw-r--r-- | lib/crypto-backend.h | 1 | ||||
-rw-r--r-- | lib/gnutls_dh.c | 13 | ||||
-rw-r--r-- | lib/gnutls_dh.h | 3 | ||||
-rw-r--r-- | lib/gnutls_dh_primes.c | 35 | ||||
-rw-r--r-- | lib/gnutls_int.h | 2 | ||||
-rw-r--r-- | lib/nettle/mpi.c | 9 |
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", ¶ms->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; } |