diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2021-03-29 05:38:00 +0200 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2021-04-01 01:07:08 +0200 |
commit | e454a3934c287aede194cac49c8934f04bf6a04f (patch) | |
tree | c43916f0a50c5e2d1a9aa1caa00539c0629f1175 /test/dhtest.c | |
parent | CHANGES.md: reflect OSSL_HTTP_REQ_CTX_i2d renamed to OSSL_HTTP_REQ_CTX_set1_req (diff) | |
download | openssl-e454a3934c287aede194cac49c8934f04bf6a04f.tar.xz openssl-e454a3934c287aede194cac49c8934f04bf6a04f.zip |
Add a range check (from SP800-56Ar3) to DH key derivation.
Fixes #14401
Note that this moves the public key check out of DH compute_key() since
key validation does not belong inside this primitive..
The check has been moved to the EVP_PKEY_derive_set_peer() function so that
it generally applies to all exchange operations.. Use EVP_PKEY_derive_set_peer_ex()
to disable this behaviour.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14717)
Diffstat (limited to 'test/dhtest.c')
-rw-r--r-- | test/dhtest.c | 116 |
1 files changed, 60 insertions, 56 deletions
diff --git a/test/dhtest.c b/test/dhtest.c index c293dab203..836d800c29 100644 --- a/test/dhtest.c +++ b/test/dhtest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -28,6 +28,8 @@ #ifndef OPENSSL_NO_DH # include <openssl/dh.h> +# include "crypto/bn_dh.h" +# include "crypto/dh.h" static int cb(int p, int n, BN_GENCB *arg); @@ -233,6 +235,61 @@ static int cb(int p, int n, BN_GENCB *arg) return 1; } +static int dh_computekey_range_test(void) +{ + int ret = 0, sz; + DH *dh = NULL; + BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL; + unsigned char *buf = NULL; + + if (!TEST_ptr(p = BN_dup(&ossl_bignum_ffdhe2048_p)) + || !TEST_ptr(q = BN_dup(&ossl_bignum_ffdhe2048_q)) + || !TEST_ptr(g = BN_dup(&ossl_bignum_const_2)) + || !TEST_ptr(dh = DH_new()) + || !TEST_true(DH_set0_pqg(dh, p, q, g))) + goto err; + p = q = g = NULL; + sz = DH_size(dh); + + if (!TEST_ptr(buf = OPENSSL_malloc(sz)) + || !TEST_ptr(pub = BN_new()) + || !TEST_ptr(priv = BN_new())) + goto err; + + if (!TEST_true(BN_set_word(priv, 1)) + || !TEST_true(DH_set0_key(dh, NULL, priv)) + || !TEST_true(BN_set_word(pub, 1))) + goto err; + + /* Given z = pub ^ priv mod p */ + + /* Test that z == 1 fails */ + if (!TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0)) + goto err; + /* Test that z == 0 fails */ + if (!TEST_ptr(BN_copy(pub, DH_get0_p(dh))) + || !TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0)) + goto err; + /* Test that z == p - 1 fails */ + if (!TEST_true(BN_sub_word(pub, 1)) + || !TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0)) + goto err; + /* Test that z == p - 2 passes */ + if (!TEST_true(BN_sub_word(pub, 1)) + || !TEST_int_eq(ossl_dh_compute_key(buf, pub, dh), sz)) + goto err; + + ret = 1; +err: + OPENSSL_free(buf); + BN_free(pub); + BN_free(g); + BN_free(q); + BN_free(p); + DH_free(dh); + return ret; +} + /* Test data from RFC 5114 */ static const unsigned char dhtest_1024_160_xA[] = { @@ -461,31 +518,6 @@ static const unsigned char dhtest_2048_256_Z[] = { 0xC2, 0x6C, 0x5D, 0x7C }; -static const unsigned char dhtest_rfc5114_2048_224_bad_y[] = { - 0x45, 0x32, 0x5F, 0x51, 0x07, 0xE5, 0xDF, 0x1C, 0xD6, 0x02, 0x82, 0xB3, - 0x32, 0x8F, 0xA4, 0x0F, 0x87, 0xB8, 0x41, 0xFE, 0xB9, 0x35, 0xDE, 0xAD, - 0xC6, 0x26, 0x85, 0xB4, 0xFF, 0x94, 0x8C, 0x12, 0x4C, 0xBF, 0x5B, 0x20, - 0xC4, 0x46, 0xA3, 0x26, 0xEB, 0xA4, 0x25, 0xB7, 0x68, 0x8E, 0xCC, 0x67, - 0xBA, 0xEA, 0x58, 0xD0, 0xF2, 0xE9, 0xD2, 0x24, 0x72, 0x60, 0xDA, 0x88, - 0x18, 0x9C, 0xE0, 0x31, 0x6A, 0xAD, 0x50, 0x6D, 0x94, 0x35, 0x8B, 0x83, - 0x4A, 0x6E, 0xFA, 0x48, 0x73, 0x0F, 0x83, 0x87, 0xFF, 0x6B, 0x66, 0x1F, - 0xA8, 0x82, 0xC6, 0x01, 0xE5, 0x80, 0xB5, 0xB0, 0x52, 0xD0, 0xE9, 0xD8, - 0x72, 0xF9, 0x7D, 0x5B, 0x8B, 0xA5, 0x4C, 0xA5, 0x25, 0x95, 0x74, 0xE2, - 0x7A, 0x61, 0x4E, 0xA7, 0x8F, 0x12, 0xE2, 0xD2, 0x9D, 0x8C, 0x02, 0x70, - 0x34, 0x44, 0x32, 0xC7, 0xB2, 0xF3, 0xB9, 0xFE, 0x17, 0x2B, 0xD6, 0x1F, - 0x8B, 0x7E, 0x4A, 0xFA, 0xA3, 0xB5, 0x3E, 0x7A, 0x81, 0x9A, 0x33, 0x66, - 0x62, 0xA4, 0x50, 0x18, 0x3E, 0xA2, 0x5F, 0x00, 0x07, 0xD8, 0x9B, 0x22, - 0xE4, 0xEC, 0x84, 0xD5, 0xEB, 0x5A, 0xF3, 0x2A, 0x31, 0x23, 0xD8, 0x44, - 0x22, 0x2A, 0x8B, 0x37, 0x44, 0xCC, 0xC6, 0x87, 0x4B, 0xBE, 0x50, 0x9D, - 0x4A, 0xC4, 0x8E, 0x45, 0xCF, 0x72, 0x4D, 0xC0, 0x89, 0xB3, 0x72, 0xED, - 0x33, 0x2C, 0xBC, 0x7F, 0x16, 0x39, 0x3B, 0xEB, 0xD2, 0xDD, 0xA8, 0x01, - 0x73, 0x84, 0x62, 0xB9, 0x29, 0xD2, 0xC9, 0x51, 0x32, 0x9E, 0x7A, 0x6A, - 0xCF, 0xC1, 0x0A, 0xDB, 0x0E, 0xE0, 0x62, 0x77, 0x6F, 0x59, 0x62, 0x72, - 0x5A, 0x69, 0xA6, 0x5B, 0x70, 0xCA, 0x65, 0xC4, 0x95, 0x6F, 0x9A, 0xC2, - 0xDF, 0x72, 0x6D, 0xB1, 0x1E, 0x54, 0x7B, 0x51, 0xB4, 0xEF, 0x7F, 0x89, - 0x93, 0x74, 0x89, 0x59 -}; - typedef struct { DH *(*get_param) (void); const unsigned char *xA; @@ -523,7 +555,7 @@ static int rfc5114_test(void) unsigned char *Z1 = NULL; unsigned char *Z2 = NULL; const rfc5114_td *td = NULL; - BIGNUM *bady = NULL, *priv_key = NULL, *pub_key = NULL; + BIGNUM *priv_key = NULL, *pub_key = NULL; const BIGNUM *pub_key_tmp; for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) { @@ -576,37 +608,9 @@ static int rfc5114_test(void) OPENSSL_free(Z2); Z2 = NULL; } - - /* Now i == OSSL_NELEM(rfctd) */ - /* RFC5114 uses unsafe primes, so now test an invalid y value */ - if (!TEST_ptr(dhA = DH_get_2048_224()) - || !TEST_ptr(Z1 = OPENSSL_malloc(DH_size(dhA)))) - goto bad_err; - - if (!TEST_ptr(bady = BN_bin2bn(dhtest_rfc5114_2048_224_bad_y, - sizeof(dhtest_rfc5114_2048_224_bad_y), - NULL))) - goto bad_err; - - if (!DH_generate_key(dhA)) - goto bad_err; - - if (DH_compute_key(Z1, bady, dhA) != -1) { - /* - * DH_compute_key should fail with -1. If we get here we unexpectedly - * allowed an invalid y value - */ - goto err; - } - /* We'll have a stale error on the queue from the above test so clear it */ - ERR_clear_error(); - BN_free(bady); - DH_free(dhA); - OPENSSL_free(Z1); return 1; bad_err: - BN_free(bady); DH_free(dhA); DH_free(dhB); BN_free(pub_key); @@ -617,7 +621,6 @@ static int rfc5114_test(void) return 0; err: - BN_free(bady); DH_free(dhA); DH_free(dhB); OPENSSL_free(Z1); @@ -793,6 +796,7 @@ int setup_tests(void) TEST_note("No DH support"); #else ADD_TEST(dh_test); + ADD_TEST(dh_computekey_range_test); ADD_TEST(rfc5114_test); ADD_TEST(rfc7919_test); ADD_ALL_TESTS(dh_test_prime_groups, OSSL_NELEM(prime_groups)); |