diff options
-rw-r--r-- | NEWS | 3 | ||||
-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 | ||||
-rw-r--r-- | src/benchmark-tls.c | 23 | ||||
-rw-r--r-- | src/benchmark.c | 4 | ||||
-rw-r--r-- | src/prime.c | 8 |
15 files changed, 82 insertions, 46 deletions
@@ -8,6 +8,9 @@ See the end for copying conditions. it will only list the ciphersuites that are enabled by the given priority string. +** libgnutls: Optimizations in Diffie-Hellman parameters generation +and key exchange. + ** libgnutls: When session tickets are negotiated and used in a session, a server will not store that session data into its cache. 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; } diff --git a/src/benchmark-tls.c b/src/benchmark-tls.c index fcb7e564ee..d2a742de63 100644 --- a/src/benchmark-tls.c +++ b/src/benchmark-tls.c @@ -55,9 +55,12 @@ #ifdef PARAMS_1024 const char *pkcs3 = "-----BEGIN DH PARAMETERS-----\n" - "MIGHAoGBAO6vCrmts43WnDP4CvqPxehgcmGHdf88C56iMUycJWV21nTfdJbqgdM4\n" - "O0gT1pLG4ODV2OJQuYvkjklcHWCJ2tFdx9e0YVTWts6O9K1psV1JglWbKXvPGIXF\n" - "KfVmZg5X7GjtvDwFcmzAL9TL9Jduqpr9UTj+g3ZDW5/GHS/A6wbjAgEC\n" + "MIIBCwKBgQCsIrA9BK23OUVIwrC4c65YJ2t8bqoGpJpuISjO07lAbWHWa47Kf9/t\n" + "F9ckO2AF6Yj1Y7xS+FSCDeoIZsp0LCq3nAP9Ls25fgHrKSMPQBJt2vd5mUdm90Wr\n" + "wCK2YjogQ7YVQlovVHsnJWC6Kf0P+OQ4hrihoBCGSj9sGK3wH57m+wKBgH5xlPNR\n" + "pI8E2WBNqB6y4sV3eMGRvygScbbFUFFO1ccmNJl5Y5L/O+fP0ZXtmUJVsSvlY0fp\n" + "Kcl6k5WCWMY8h6iHlJ9teHmC4s2jifXtaV759kJXdqrGEjRPEku50y3ANzDLzklW\n" + "8R7HcSO397vIdouaUt38FbQESnIWOIZqDtq6AgIAnw==\n" "-----END DH PARAMETERS-----\n"; /* RSA key of 1024 bits */ @@ -98,13 +101,13 @@ static unsigned char server_key_pem[] = */ const char *pkcs3 = "-----BEGIN DH PARAMETERS-----\n" - "MIIBPgKBnBw2c5yglfuVfHxYAmWQmLfO1K2sEqTY4panDGgf/aF4HGuGcTfy511c\n" - "d3+/C7SJuMEM9RwKt503qb9pLEHVbZsXLECGVFcX3c5UAkPKKB/zhcmz6facSLn7\n" - "o8hLC30DQM9IQ26N7BaOGcEgeya+NGGUk7yC+v+tRiCG2OU/0mQTAx4g7OCVBRAn\n" - "piJ6yW5kNzNJkKKGOnLXzcXbzwKBnA/aNsM6bmYOx5N2iybHQ0/Dltp8s/2Sw9YY\n" - "oWBZNLJRCHyB1Q+MH1n3GJ7oEqG0/D9i+byA41I/KNvaaZVK+Oai8pvcdDwdrSxW\n" - "AMbtukYTxc4eGedtDuwHP55+AlRS+daRZQXbq43aFauPgGiwpm0I+EnMhg25owV2\n" - "jgL3Ag174DhfvwcMsgC1EO1G0gsxjCc4BD5NKdqvJDNaxw==\n" + "MIIBQwKBnQDgLx3SqWyHOfGn/03r1tRwf3pByo3C4V1YIjjDQUoIzn82tRMPEKsL\n" + "vos7WXjKgF1+S+T5Y9A7XqivGv1XJ1ZmDvewXVRByxjGRZbkoqCPw4Zv0Uyl9pjV\n" + "WaR/Y/emZrN51K0zkdFJCzCt3lPlO3UprnYYHkySRpxTJ4ab5iXRFXETA5rJ5WH0\n" + "itGpoR5xb2fR1Gmg5kXCNutkZ9cCgZwqJUZwqKIHJ9cYtzvZXFpjZNgF+mRWyiFr\n" + "AQooJbFbVX3o2seJZl3mMqaetaLHF+L8anZFQipNgxenzQgEWEv8FubHXStaOnX1\n" + "cwjwwxmCUK4lpfCQZtJ1K3os2JCcNaTBUyxAfiXFIYJmO/os0hFhR6a4EjIlkcq0\n" + "yDDLN1weTNOpBPstp1WGHZCsKdJZzgfVvYL6er4zVBtBS0cCAgCg\n" "-----END DH PARAMETERS-----\n"; static unsigned char server_cert_pem[] = diff --git a/src/benchmark.c b/src/benchmark.c index 42f821c473..a5dabc4e28 100644 --- a/src/benchmark.c +++ b/src/benchmark.c @@ -102,14 +102,14 @@ void start_benchmark(struct benchmark_st * st) fprintf (stderr, "error: CreateThread %u\n", GetLastError ()); exit(1); } - st->alarm_timeout.QuadPart = (5) * 10000000; + st->alarm_timeout.QuadPart = (2) * 10000000; if (SetWaitableTimer (st->wtimer, &st->alarm_timeout, 0, NULL, NULL, FALSE) == 0) { fprintf (stderr, "error: SetWaitableTimer %u\n", GetLastError ()); exit(1); } #else - alarm (5); + alarm (2); #endif } diff --git a/src/prime.c b/src/prime.c index 111337515f..0855a8f3c1 100644 --- a/src/prime.c +++ b/src/prime.c @@ -48,6 +48,7 @@ generate_prime (int how, common_info_st * info) gnutls_dh_params_t dh_params; gnutls_datum_t p, g; int bits = get_bits (GNUTLS_PK_DH, info->bits, info->sec_param); + unsigned int q_bits = 0; gnutls_dh_params_init (&dh_params); @@ -69,7 +70,7 @@ generate_prime (int how, common_info_st * info) exit (1); } - ret = gnutls_dh_params_export_raw (dh_params, &p, &g, NULL); + ret = gnutls_dh_params_export_raw (dh_params, &p, &g, &q_bits); if (ret < 0) { fprintf (stderr, "Error exporting parameters: %s\n", @@ -189,8 +190,9 @@ generate_prime (int how, common_info_st * info) fprintf (outfile, "%.2x", p.data[i]); } - fprintf (outfile, "\n\n"); - + if (q_bits > 0) + fprintf (outfile, "\n\nRecommended key length: %d bits\n", q_bits); + fprintf (outfile, "\n"); } if (!cparams) |