summaryrefslogtreecommitdiffstats
path: root/test/dhtest.c
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2021-03-29 13:38:00 +1000
committerShane Lontis <shane.lontis@oracle.com>2021-04-01 09:07:08 +1000
commite454a3934c287aede194cac49c8934f04bf6a04f (patch)
treec43916f0a50c5e2d1a9aa1caa00539c0629f1175 /test/dhtest.c
parent9e6f30e683fd0f243cf15d2bac2cdef2bcbbac12 (diff)
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.c116
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));