From 45c94c76c971a709c585a1fc142ce88e0945ba21 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 10 May 2019 14:49:05 -0400 Subject: Add test to ensure DH exchange behaves correctly This test ensures that public keys are properly tested for validity before a DH exchange is computed. Signed-off-by: Simo Sorce --- tests/Makefile.am | 2 +- tests/dh-compute.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 tests/dh-compute.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 05c0a61b79..5e3cd3d934 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -209,7 +209,7 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei tls13-server-kx-neg gnutls_ext_raw_parse_dtls key-export-pkcs8 \ null_retrieve_function tls-record-size-limit tls-crt_type-neg \ resume-with-stek-expiration resume-with-previous-stek rawpk-api \ - tls-record-size-limit-asym + tls-record-size-limit-asym dh-compute if HAVE_SECCOMP_TESTS ctests += dtls-with-seccomp tls-with-seccomp dtls-client-with-seccomp tls-client-with-seccomp diff --git a/tests/dh-compute.c b/tests/dh-compute.c new file mode 100644 index 0000000000..173729312e --- /dev/null +++ b/tests/dh-compute.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2019 Red Hat, Inc. + * + * Author: Simo Sorce + * + * This file is part of GnuTLS. + * + * GnuTLS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GnuTLS; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* This program tests functionality of DH exchanges */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include "utils.h" + +#ifdef ENABLE_FIPS140 +int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params, + gnutls_datum_t *priv_key, gnutls_datum_t *pub_key); + +int _gnutls_dh_compute_key(gnutls_dh_params_t dh_params, + const gnutls_datum_t *priv_key, + const gnutls_datum_t *pub_key, + const gnutls_datum_t *peer_key, gnutls_datum_t *Z); + +static void params(gnutls_dh_params_t *dh_params, unsigned int key_bits, + const gnutls_datum_t *p, const gnutls_datum_t *g) +{ + int ret; + + ret = gnutls_dh_params_init(dh_params); + if (ret != 0) + fail("error\n"); + + ret = gnutls_dh_params_import_raw2(*dh_params, p, g, key_bits); + if (ret != 0) + fail("error\n"); +} + +static void genkey(gnutls_dh_params_t *dh_params, + gnutls_datum_t *priv_key, gnutls_datum_t *pub_key) +{ + int ret; + + ret = _gnutls_dh_generate_key(*dh_params, priv_key, pub_key); + if (ret != 0) + fail("error\n"); +} + +static void compute_key(gnutls_dh_params_t *dh_params, + gnutls_datum_t *priv_key, gnutls_datum_t *pub_key, + const gnutls_datum_t *peer_key, int expect_error, + gnutls_datum_t *result, bool expect_success) +{ + gnutls_datum_t Z; + bool success; + int ret; + + ret = _gnutls_dh_compute_key(*dh_params, priv_key, pub_key, + peer_key, &Z); + if (expect_error != ret) + fail("error (%d)\n", ret); + + if (result) { + success = (Z.size != result->size && + memcmp(Z.data, result->data, Z.size)); + if (success != expect_success) + fail("error\n"); + } + gnutls_free(Z.data); +} + +struct dh_test_data { + const unsigned int key_size; + const gnutls_datum_t prime; + const gnutls_datum_t generator; + const gnutls_datum_t peer_key; + int expected_error; +}; + +void doit(void) +{ + struct dh_test_data test_data[] = { + { + /* y == 0 */ + gnutls_ffdhe_2048_key_bits, + gnutls_ffdhe_2048_group_prime, + gnutls_ffdhe_2048_group_generator, + { (void *)"\x00", 1 }, + GNUTLS_E_MPI_SCAN_FAILED + }, + { + /* y < 2 */ + gnutls_ffdhe_2048_key_bits, + gnutls_ffdhe_2048_group_prime, + gnutls_ffdhe_2048_group_generator, + { (void *)"\x01", 1 }, + GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER + }, + { + /* y > p - 2 */ + gnutls_ffdhe_2048_key_bits, + gnutls_ffdhe_2048_group_prime, + gnutls_ffdhe_2048_group_generator, + gnutls_ffdhe_2048_group_prime, + GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER + }, + { 0 } + }; + + for (int i = 0; test_data[i].key_size != 0; i++) { + gnutls_datum_t priv_key, pub_key; + gnutls_dh_params_t dh_params; + + params(&dh_params, test_data[i].key_size, + &test_data[i].prime, &test_data[i].generator); + + genkey(&dh_params, &priv_key, &pub_key); + + compute_key(&dh_params, &priv_key, &pub_key, + &test_data[i].peer_key, + test_data[i].expected_error, + NULL, 0); + + gnutls_dh_params_deinit(dh_params); + gnutls_free(priv_key.data); + gnutls_free(pub_key.data); + } + + success("all ok\n"); +} +#else +void doit(void) +{ + return; +} +#endif -- cgit v1.2.1