]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
tests: support KAT in (EC)DH tests
authorDaiki Ueno <ueno@gnu.org>
Fri, 23 Feb 2024 00:03:46 +0000 (09:03 +0900)
committerDaiki Ueno <ueno@gnu.org>
Fri, 23 Feb 2024 12:26:56 +0000 (21:26 +0900)
While the logic existed, known answer tests were omitted in
tests/dh-compute, tests/dh-compute2, tests/ecdh-compute, and
tests/ecdh-compute2.  This enables the support for it as well as fixes
a couple of issues in the logic: avoid using `success` variable as it
shadows the helper function with the same name defined in
tests/utils.h, invert the memcmp condition, and properly use peer_x
and peer_y in place of x and y in ecdh-compute2.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
lib/pubkey.c
tests/Makefile.am
tests/dh-compute.c
tests/dh-compute.h [new file with mode: 0644]
tests/dh-compute2.c
tests/ecdh-compute.c
tests/ecdh-compute2.c

index c3e4168b1f87f2d3de4e7ace8a0967f75a5f2075..da2cb8cb16ecc98c5bf82ef2b409ffa9bbaf7ba6 100644 (file)
@@ -2038,6 +2038,7 @@ int gnutls_pubkey_import_dh_raw(gnutls_pubkey_t key,
                key->params.params[DH_Q] = _gnutls_mpi_copy(params->params[2]);
        }
        key->params.qbits = params->q_bits;
+       key->params.params_nr = DH_PUBLIC_PARAMS;
 
        if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Y], y->data,
                                     y->size)) {
@@ -2046,7 +2047,6 @@ int gnutls_pubkey_import_dh_raw(gnutls_pubkey_t key,
                goto cleanup;
        }
 
-       key->params.params_nr = DH_PUBLIC_PARAMS;
        key->params.algo = GNUTLS_PK_DH;
        key->bits = pubkey_to_bits(&key->params);
 
index babf3be108082f879e1a5c8cba200517c5873a82..cd56ad64411ba923a46b07a028ab42032aff6da8 100644 (file)
@@ -78,7 +78,7 @@ EXTRA_DIST = suppressions.valgrind eagain-common.h cert-common.h test-chains.h \
        testpkcs11-certs/ca.key testpkcs11-certs/client.crt testpkcs11-certs/client-tmpl testpkcs11-certs/server.key \
        crt_type-neg-common.c \
        system-override-default-priority-string.bad.config system-override-default-priority-string.none.config system-override-default-priority-string.only-tls13.config system-override-session-hash.sh \
-       client-secrets.h server-secrets.h
+       client-secrets.h server-secrets.h dh-compute.h
 
 AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
 AM_CPPFLAGS = \
index ee6889b6817a11562de05b5a6a9980e79bbde8a8..ed250a4cc217f05c9344fb8f96570af901e40865 100644 (file)
@@ -34,6 +34,8 @@
 #include "utils.h"
 
 #ifdef ENABLE_FIPS140
+#include "dh-compute.h"
+
 int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params,
                            gnutls_datum_t *priv_key, gnutls_datum_t *pub_key);
 
@@ -70,10 +72,10 @@ static void compute_key(const char *name, const gnutls_dh_params_t dh_params,
                        const gnutls_datum_t *priv_key,
                        const gnutls_datum_t *pub_key,
                        const gnutls_datum_t *peer_key, int expect_error,
-                       gnutls_datum_t *result, bool expect_success)
+                       const gnutls_datum_t *result)
 {
        gnutls_datum_t Z = { 0 };
-       bool success;
+       bool ok;
        int ret;
 
        ret = _gnutls_dh_compute_key(dh_params, priv_key, pub_key, peer_key,
@@ -82,10 +84,17 @@ static void compute_key(const char *name, const gnutls_dh_params_t dh_params,
                fail("%s: error %d (expected %d)\n", name, ret, expect_error);
 
        if (result) {
-               success = (Z.size != result->size &&
-                          memcmp(Z.data, result->data, Z.size));
-               if (success != expect_success)
+               ok = Z.size == result->size &&
+                    memcmp(Z.data, result->data, Z.size) == 0;
+               if (!ok) {
+                       success("priv_key\n");
+                       hexprint(priv_key->data, priv_key->size);
+                       success("pub_key\n");
+                       hexprint(pub_key->data, pub_key->size);
+                       success("Z\n");
+                       hexprint(Z.data, Z.size);
                        fail("%s: failed to match result\n", name);
+               }
        }
        gnutls_free(Z.data);
 }
@@ -96,6 +105,9 @@ struct dh_test_data {
        const gnutls_datum_t q;
        const gnutls_datum_t generator;
        const gnutls_datum_t peer_key;
+       const gnutls_datum_t priv_key;
+       const gnutls_datum_t pub_key;
+       const gnutls_datum_t result;
        int expected_error;
        gnutls_fips140_operation_state_t fips_state_genkey;
        gnutls_fips140_operation_state_t fips_state_compute_key;
@@ -110,6 +122,9 @@ void doit(void)
                        gnutls_ffdhe_2048_group_q,
                        gnutls_ffdhe_2048_group_generator,
                        { (void *)"\x00", 1 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
                        GNUTLS_E_MPI_SCAN_FAILED,
                        GNUTLS_FIPS140_OP_APPROVED,
                        /* does not reach _wrap_nettle_pk_derive */
@@ -121,6 +136,9 @@ void doit(void)
                        gnutls_ffdhe_2048_group_q,
                        gnutls_ffdhe_2048_group_generator,
                        { (void *)"\x01", 1 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
                        GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER,
                        GNUTLS_FIPS140_OP_APPROVED,
                        GNUTLS_FIPS140_OP_ERROR,
@@ -131,6 +149,9 @@ void doit(void)
                        gnutls_ffdhe_2048_group_q,
                        gnutls_ffdhe_2048_group_generator,
                        gnutls_ffdhe_2048_group_prime,
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
                        GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER,
                        GNUTLS_FIPS140_OP_APPROVED,
                        GNUTLS_FIPS140_OP_ERROR,
@@ -141,6 +162,9 @@ void doit(void)
                        gnutls_ffdhe_2048_group_q,
                        gnutls_ffdhe_2048_group_generator,
                        gnutls_ffdhe_2048_group_q,
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
                        GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER,
                        GNUTLS_FIPS140_OP_APPROVED,
                        GNUTLS_FIPS140_OP_ERROR,
@@ -151,6 +175,28 @@ void doit(void)
                        gnutls_ffdhe_2048_group_q,
                        gnutls_ffdhe_2048_group_generator,
                        { (void *)"\x02", 1 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       0,
+                       GNUTLS_FIPS140_OP_APPROVED,
+                       GNUTLS_FIPS140_OP_APPROVED,
+               },
+               {
+                       "Legal Input (KAT)",
+                       gnutls_ffdhe_2048_group_prime,
+                       gnutls_ffdhe_2048_group_q,
+                       gnutls_ffdhe_2048_group_generator,
+                       { (void *)"\x02", 1 },
+                       { (void *)ffdhe_2048_priv_key,
+                         sizeof(ffdhe_2048_priv_key) /
+                                 sizeof(ffdhe_2048_priv_key[0]) },
+                       { (void *)ffdhe_2048_pub_key,
+                         sizeof(ffdhe_2048_pub_key) /
+                                 sizeof(ffdhe_2048_pub_key[0]) },
+                       { (void *)ffdhe_2048_result,
+                         sizeof(ffdhe_2048_result) /
+                                 sizeof(ffdhe_2048_result[0]) },
                        0,
                        GNUTLS_FIPS140_OP_APPROVED,
                        GNUTLS_FIPS140_OP_APPROVED,
@@ -160,6 +206,9 @@ void doit(void)
 
        for (int i = 0; test_data[i].name != NULL; i++) {
                gnutls_datum_t priv_key, pub_key;
+               const gnutls_datum_t *result =
+                       test_data[i].result.data == NULL ? NULL :
+                                                          &test_data[i].result;
                gnutls_dh_params_t dh_params;
                gnutls_fips140_context_t fips_context;
                int ret;
@@ -176,24 +225,33 @@ void doit(void)
                       &test_data[i].generator);
                fips_pop_context(fips_context, GNUTLS_FIPS140_OP_INITIAL);
 
-               success("%s genkey\n", test_data[i].name);
+               if (test_data[i].priv_key.data == NULL) {
+                       success("%s genkey\n", test_data[i].name);
 
-               fips_push_context(fips_context);
-               genkey(dh_params, &priv_key, &pub_key);
-               fips_pop_context(fips_context, test_data[i].fips_state_genkey);
+                       fips_push_context(fips_context);
+                       genkey(dh_params, &priv_key, &pub_key);
+                       fips_pop_context(fips_context,
+                                        test_data[i].fips_state_genkey);
+               } else {
+                       priv_key = test_data[i].priv_key;
+                       pub_key = test_data[i].pub_key;
+               }
 
                success("%s compute_key\n", test_data[i].name);
 
                fips_push_context(fips_context);
                compute_key(test_data[i].name, dh_params, &priv_key, &pub_key,
                            &test_data[i].peer_key, test_data[i].expected_error,
-                           NULL, 0);
+                           result);
                fips_pop_context(fips_context,
                                 test_data[i].fips_state_compute_key);
 
                gnutls_dh_params_deinit(dh_params);
-               gnutls_free(priv_key.data);
-               gnutls_free(pub_key.data);
+
+               if (test_data[i].priv_key.data == NULL) {
+                       gnutls_free(priv_key.data);
+                       gnutls_free(pub_key.data);
+               }
 
                if (gnutls_fips140_mode_enabled()) {
                        gnutls_fips140_context_deinit(fips_context);
diff --git a/tests/dh-compute.h b/tests/dh-compute.h
new file mode 100644 (file)
index 0000000..51bb05c
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2024 Red Hat, Inc.
+ *
+ * Author: Daiki Ueno
+ *
+ * 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUTLS_TESTS_DH_COMPUTE_H
+#define GNUTLS_TESTS_DH_COMPUTE_H
+
+#include <stdint.h>
+
+static const uint8_t ffdhe_2048_priv_key[] = {
+       0x44, 0xee, 0xae, 0x12, 0x66, 0x64, 0x92, 0x9e, 0x42, 0x44, 0x56, 0x3a,
+       0x09, 0x0e, 0x5d, 0xad, 0xad, 0x90, 0xd5, 0x82, 0xaf, 0x63, 0xc1, 0xc1,
+       0x52, 0x7e, 0xe5, 0x04, 0x30, 0x25, 0x90, 0x6b, 0x57, 0xa7, 0x28, 0x6d,
+       0x8b, 0x6a, 0x53, 0xa8, 0x87, 0xd6, 0xfe, 0xde, 0xac, 0x21, 0xb0, 0x9e,
+       0x86, 0xc1, 0x56, 0x17, 0xce, 0x45, 0x8b, 0x9e, 0x2f, 0x8f, 0xf3, 0x9a,
+       0xba, 0x97, 0x40, 0x0d, 0xff, 0xd3, 0xcd, 0x70, 0x9f, 0x27, 0x47, 0x0d,
+       0x65, 0x09, 0x98, 0x2b, 0x22, 0x1e, 0xe2, 0x51, 0xce, 0x5f, 0x27, 0x64,
+       0x45, 0x3f, 0xb3, 0x4b, 0x43, 0x45, 0x3e, 0x79, 0xe2, 0xc5, 0x61, 0x6f,
+       0xc2, 0x03, 0xfc, 0x14, 0x03, 0x22, 0x9a, 0x97, 0x3f, 0x69, 0xee, 0x83,
+       0x92, 0xa8, 0x6d, 0xf4, 0x1f, 0x49, 0xba, 0x11, 0xb1, 0x30, 0x6f, 0x84,
+       0x2b, 0xd5, 0x21, 0x31, 0x6b, 0x72, 0x19, 0x83, 0xba, 0x7b, 0x96, 0x01,
+       0x29, 0x40, 0x6a, 0xef, 0xf4, 0xc5, 0x0e, 0xb9, 0x16, 0xf4, 0x33, 0xd7,
+       0xd3, 0x5f, 0x22, 0x68, 0xc4, 0x36, 0x92, 0x09, 0x42, 0x7a, 0x60, 0x93,
+       0xf0, 0x95, 0xde, 0x0e, 0xce, 0xa3, 0x34, 0xd6, 0xd7, 0x08, 0xda, 0xc3,
+       0xa6, 0x38, 0x36, 0x72, 0x01, 0xc5, 0xaa, 0x93, 0x1a, 0xf6, 0x56, 0x45,
+       0x73, 0x57, 0x0d, 0x17, 0x23, 0xbb, 0x7a, 0x5d, 0x9b, 0x76, 0x54, 0xba,
+       0x60, 0x43, 0xbb, 0xf6, 0xca, 0x46, 0x72, 0xd0, 0x0d, 0x98, 0x00, 0xbf,
+       0x02, 0xdd, 0x1e, 0x22, 0xbb, 0xa5, 0x87, 0xc1, 0xbd, 0x79, 0xc9, 0xee,
+       0x9d, 0x3c, 0x19, 0x75, 0xcf, 0xce, 0x49, 0xd4, 0xd8, 0xad, 0x0a, 0xc7,
+       0x5d, 0x96, 0x2c, 0xb0, 0x10, 0xaf, 0xc2, 0xfe, 0xc0, 0xd9, 0x6b, 0x1e,
+       0x5f, 0x2e, 0x8c, 0x5a, 0x68, 0xaa, 0x8a, 0xda, 0xb2, 0xd8, 0x36, 0xe3,
+       0x82, 0x04, 0xed, 0x20
+};
+
+static const uint8_t ffdhe_2048_pub_key[] = {
+       0x00, 0xdd, 0x55, 0x13, 0x28, 0xc9, 0xbf, 0xf1, 0x5f, 0x42, 0x6b, 0x85,
+       0x7c, 0xe6, 0xb1, 0xcb, 0x80, 0xee, 0x6b, 0xa5, 0x0f, 0x52, 0xc5, 0x02,
+       0x49, 0x66, 0x7f, 0x3a, 0x49, 0xae, 0xb7, 0xf6, 0xee, 0xff, 0x97, 0x83,
+       0xe2, 0xce, 0xb3, 0x55, 0x73, 0xcc, 0xbf, 0x69, 0x5e, 0x6f, 0x32, 0xb8,
+       0x5a, 0x43, 0x3b, 0x2d, 0x2c, 0xb0, 0x25, 0xb8, 0xd1, 0x8c, 0x70, 0x95,
+       0xf7, 0x5c, 0x6d, 0xa2, 0x44, 0x58, 0x5d, 0x82, 0x8d, 0x4a, 0x0c, 0x4d,
+       0x28, 0x94, 0x19, 0x16, 0xb7, 0x64, 0xbf, 0x86, 0xa5, 0x78, 0x13, 0x60,
+       0x14, 0x6a, 0x2b, 0xc5, 0x45, 0x5b, 0xc7, 0xb8, 0xea, 0x1f, 0xd7, 0x1d,
+       0x29, 0xa3, 0x6c, 0xd9, 0xc8, 0x00, 0x77, 0x77, 0x5d, 0xc7, 0x5f, 0xd8,
+       0xbe, 0xa4, 0xa7, 0x2c, 0xc5, 0xcd, 0x3c, 0x47, 0x33, 0x5a, 0x59, 0x43,
+       0x3c, 0x02, 0x7d, 0xf3, 0xea, 0x69, 0xc2, 0x21, 0xd7, 0x02, 0x07, 0x58,
+       0x96, 0xee, 0xd7, 0x97, 0x4f, 0x9c, 0xa5, 0x89, 0xd9, 0xf2, 0x68, 0x15,
+       0x9c, 0x28, 0xf9, 0x50, 0x98, 0xe9, 0xe1, 0xed, 0xb3, 0x06, 0xb5, 0x41,
+       0x64, 0x10, 0x1a, 0x0c, 0xc3, 0xcc, 0x4c, 0x77, 0x47, 0xf8, 0x18, 0xff,
+       0xf4, 0x77, 0xbf, 0x95, 0x76, 0x5c, 0x9a, 0xcc, 0x72, 0x5f, 0xb3, 0x9f,
+       0xa5, 0x0d, 0x31, 0x85, 0x78, 0xea, 0xd6, 0xd4, 0x26, 0xf8, 0x96, 0xbd,
+       0x05, 0x0a, 0xea, 0x63, 0xb9, 0x51, 0x04, 0x07, 0xe5, 0xbf, 0x58, 0x20,
+       0x2d, 0x8d, 0x8b, 0x93, 0x38, 0xe4, 0x04, 0x18, 0x07, 0x29, 0xf2, 0x11,
+       0xb0, 0xf2, 0x3d, 0x09, 0xef, 0x22, 0xfd, 0xe0, 0x8c, 0x50, 0x23, 0x9f,
+       0x78, 0x1c, 0x13, 0xcc, 0x05, 0x27, 0xc2, 0xed, 0xf1, 0x24, 0x3f, 0x86,
+       0xf4, 0x8d, 0x3a, 0x60, 0x3e, 0x92, 0x0e, 0x36, 0x64, 0x67, 0xaf, 0x42,
+       0xaa, 0x90, 0x20, 0x21, 0xad
+};
+
+static const uint8_t ffdhe_2048_result[] = {
+       0xdd, 0x55, 0x13, 0x28, 0xc9, 0xbf, 0xf1, 0x5f, 0x42, 0x6b, 0x85, 0x7c,
+       0xe6, 0xb1, 0xcb, 0x80, 0xee, 0x6b, 0xa5, 0x0f, 0x52, 0xc5, 0x02, 0x49,
+       0x66, 0x7f, 0x3a, 0x49, 0xae, 0xb7, 0xf6, 0xee, 0xff, 0x97, 0x83, 0xe2,
+       0xce, 0xb3, 0x55, 0x73, 0xcc, 0xbf, 0x69, 0x5e, 0x6f, 0x32, 0xb8, 0x5a,
+       0x43, 0x3b, 0x2d, 0x2c, 0xb0, 0x25, 0xb8, 0xd1, 0x8c, 0x70, 0x95, 0xf7,
+       0x5c, 0x6d, 0xa2, 0x44, 0x58, 0x5d, 0x82, 0x8d, 0x4a, 0x0c, 0x4d, 0x28,
+       0x94, 0x19, 0x16, 0xb7, 0x64, 0xbf, 0x86, 0xa5, 0x78, 0x13, 0x60, 0x14,
+       0x6a, 0x2b, 0xc5, 0x45, 0x5b, 0xc7, 0xb8, 0xea, 0x1f, 0xd7, 0x1d, 0x29,
+       0xa3, 0x6c, 0xd9, 0xc8, 0x00, 0x77, 0x77, 0x5d, 0xc7, 0x5f, 0xd8, 0xbe,
+       0xa4, 0xa7, 0x2c, 0xc5, 0xcd, 0x3c, 0x47, 0x33, 0x5a, 0x59, 0x43, 0x3c,
+       0x02, 0x7d, 0xf3, 0xea, 0x69, 0xc2, 0x21, 0xd7, 0x02, 0x07, 0x58, 0x96,
+       0xee, 0xd7, 0x97, 0x4f, 0x9c, 0xa5, 0x89, 0xd9, 0xf2, 0x68, 0x15, 0x9c,
+       0x28, 0xf9, 0x50, 0x98, 0xe9, 0xe1, 0xed, 0xb3, 0x06, 0xb5, 0x41, 0x64,
+       0x10, 0x1a, 0x0c, 0xc3, 0xcc, 0x4c, 0x77, 0x47, 0xf8, 0x18, 0xff, 0xf4,
+       0x77, 0xbf, 0x95, 0x76, 0x5c, 0x9a, 0xcc, 0x72, 0x5f, 0xb3, 0x9f, 0xa5,
+       0x0d, 0x31, 0x85, 0x78, 0xea, 0xd6, 0xd4, 0x26, 0xf8, 0x96, 0xbd, 0x05,
+       0x0a, 0xea, 0x63, 0xb9, 0x51, 0x04, 0x07, 0xe5, 0xbf, 0x58, 0x20, 0x2d,
+       0x8d, 0x8b, 0x93, 0x38, 0xe4, 0x04, 0x18, 0x07, 0x29, 0xf2, 0x11, 0xb0,
+       0xf2, 0x3d, 0x09, 0xef, 0x22, 0xfd, 0xe0, 0x8c, 0x50, 0x23, 0x9f, 0x78,
+       0x1c, 0x13, 0xcc, 0x05, 0x27, 0xc2, 0xed, 0xf1, 0x24, 0x3f, 0x86, 0xf4,
+       0x8d, 0x3a, 0x60, 0x3e, 0x92, 0x0e, 0x36, 0x64, 0x67, 0xaf, 0x42, 0xaa,
+       0x90, 0x20, 0x21, 0xad
+};
+
+#endif /* GNUTLS_TESTS_DH_COMPUTE_H */
index 13f300e48b805ebf9707155571f826977fb5b284..9876faf0438bbce99825d827a938245dec1aecfd 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include "utils.h"
+#include "dh-compute.h"
 
 static void params(gnutls_dh_params_t *dh_params, const gnutls_datum_t *p,
                   const gnutls_datum_t *q, const gnutls_datum_t *g,
@@ -44,7 +45,7 @@ static void params(gnutls_dh_params_t *dh_params, const gnutls_datum_t *p,
 
        ret = gnutls_dh_params_import_raw3(*dh_params, p, q, g);
        if (ret != expect_error)
-               fail("error\n");
+               fail("error %d (expected %d)\n", ret, expect_error);
 }
 
 static bool dh_params_equal(const gnutls_dh_params_t a,
@@ -96,7 +97,7 @@ static void genkey(const gnutls_dh_params_t dh_params, gnutls_datum_t *priv_key,
        data.data = (unsigned char *)dh_params;
        ret = gnutls_privkey_generate2(privkey, GNUTLS_PK_DH, 0, 0, &data, 1);
        if (ret != expect_error)
-               fail("error\n");
+               fail("error %d (expected %d)\n", ret, expect_error);
 
        ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0);
        assert(ret >= 0);
@@ -156,14 +157,15 @@ static void genkey(const gnutls_dh_params_t dh_params, gnutls_datum_t *priv_key,
 static void compute_key(const char *name, const gnutls_dh_params_t dh_params,
                        const gnutls_datum_t *priv_key,
                        const gnutls_datum_t *pub_key,
-                       const gnutls_datum_t *peer_key, int expect_error,
-                       gnutls_datum_t *result, bool expect_success)
+                       const gnutls_datum_t *peer_key,
+                       int expect_error_on_import, int expect_error_on_derive,
+                       const gnutls_datum_t *result)
 {
        gnutls_datum_t Z = { 0 };
-       bool success;
+       bool ok;
        int ret;
-       gnutls_privkey_t privkey;
-       gnutls_pubkey_t pubkey;
+       gnutls_privkey_t privkey = NULL;
+       gnutls_pubkey_t pubkey = NULL;
 
        ret = gnutls_privkey_init(&privkey);
        assert(ret >= 0);
@@ -174,20 +176,37 @@ static void compute_key(const char *name, const gnutls_dh_params_t dh_params,
        ret = gnutls_pubkey_init(&pubkey);
        assert(ret >= 0);
 
-       ret = gnutls_pubkey_import_dh_raw(pubkey, dh_params, pub_key);
-       assert(ret >= 0);
+       ret = gnutls_pubkey_import_dh_raw(pubkey, dh_params, peer_key);
+       if (ret != expect_error_on_import)
+               fail("%s: error %d (expected %d)\n", name, ret,
+                    expect_error_on_import);
+
+       if (expect_error_on_import != 0)
+               goto cleanup;
 
        ret = gnutls_privkey_derive_secret(privkey, pubkey, NULL, &Z, 0);
-       if (ret != 0) {
-               fail("unable to derive secret: %s\n", gnutls_strerror(ret));
-       }
+       if (ret != expect_error_on_derive)
+               fail("%s: error %d (expected %d)\n", name, ret,
+                    expect_error_on_derive);
+
+       if (expect_error_on_derive != 0)
+               goto cleanup;
 
        if (result) {
-               success = (Z.size != result->size &&
-                          memcmp(Z.data, result->data, Z.size));
-               if (success != expect_success)
+               ok = Z.size == result->size &&
+                    memcmp(Z.data, result->data, Z.size) == 0;
+               if (!ok) {
+                       success("priv_key\n");
+                       hexprint(priv_key->data, priv_key->size);
+                       success("pub_key\n");
+                       hexprint(pub_key->data, pub_key->size);
+                       success("Z\n");
+                       hexprint(Z.data, Z.size);
                        fail("%s: failed to match result\n", name);
+               }
        }
+
+cleanup:
        gnutls_free(Z.data);
        gnutls_privkey_deinit(privkey);
        gnutls_pubkey_deinit(pubkey);
@@ -201,13 +220,17 @@ struct dh_test_data_expected {
 
 struct dh_test_data {
        const char *name;
-       const gnutls_datum_t *prime;
-       const gnutls_datum_t *q;
-       const gnutls_datum_t *generator;
+       const gnutls_datum_t prime;
+       const gnutls_datum_t q;
+       const gnutls_datum_t generator;
        const gnutls_datum_t peer_key;
+       const gnutls_datum_t priv_key;
+       const gnutls_datum_t pub_key;
+       const gnutls_datum_t result;
        struct dh_test_data_expected params_expected;
        struct dh_test_data_expected genkey_expected;
-       struct dh_test_data_expected compute_key_expected;
+       struct dh_test_data_expected import_expected;
+       struct dh_test_data_expected derive_expected;
 };
 
 static inline int get_expected(struct dh_test_data_expected *expected)
@@ -219,30 +242,124 @@ static inline int get_expected(struct dh_test_data_expected *expected)
 void doit(void)
 {
        struct dh_test_data test_data[] = {
+               {
+                       "[y == 0]",
+                       gnutls_ffdhe_2048_group_prime,
+                       gnutls_ffdhe_2048_group_q,
+                       gnutls_ffdhe_2048_group_generator,
+                       { (void *)"\x00", 1 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { 0, 0, GNUTLS_FIPS140_OP_INITIAL },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { GNUTLS_E_MPI_SCAN_FAILED, GNUTLS_E_MPI_SCAN_FAILED,
+                         GNUTLS_FIPS140_OP_INITIAL },
+               },
+               {
+                       "[y < 2]",
+                       gnutls_ffdhe_2048_group_prime,
+                       gnutls_ffdhe_2048_group_q,
+                       gnutls_ffdhe_2048_group_generator,
+                       { (void *)"\x01", 1 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { 0, 0, GNUTLS_FIPS140_OP_INITIAL },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER,
+                         GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER,
+                         GNUTLS_FIPS140_OP_ERROR },
+               },
+               {
+                       "[y > p - 2]",
+                       gnutls_ffdhe_2048_group_prime,
+                       gnutls_ffdhe_2048_group_q,
+                       gnutls_ffdhe_2048_group_generator,
+                       gnutls_ffdhe_2048_group_prime,
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { 0, 0, GNUTLS_FIPS140_OP_INITIAL },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER,
+                         GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER,
+                         GNUTLS_FIPS140_OP_ERROR },
+               },
+               {
+                       "[y ^ q mod p == 1]",
+                       gnutls_ffdhe_2048_group_prime,
+                       gnutls_ffdhe_2048_group_q,
+                       gnutls_ffdhe_2048_group_generator,
+                       gnutls_ffdhe_2048_group_q,
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { 0, 0, GNUTLS_FIPS140_OP_INITIAL },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER,
+                         GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER,
+                         GNUTLS_FIPS140_OP_ERROR },
+               },
                {
                        "Legal Input",
-                       &gnutls_ffdhe_2048_group_prime,
-                       &gnutls_ffdhe_2048_group_q,
-                       &gnutls_ffdhe_2048_group_generator,
+                       gnutls_ffdhe_2048_group_prime,
+                       gnutls_ffdhe_2048_group_q,
+                       gnutls_ffdhe_2048_group_generator,
                        { (void *)"\x02", 1 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
                        { 0, 0, GNUTLS_FIPS140_OP_INITIAL },
                        { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
                        { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
                },
                {
                        "Legal Input without Q",
-                       &gnutls_ffdhe_2048_group_prime,
-                       NULL,
-                       &gnutls_ffdhe_2048_group_generator,
+                       gnutls_ffdhe_2048_group_prime,
+                       { NULL, 0 },
+                       gnutls_ffdhe_2048_group_generator,
                        { (void *)"\x02", 1 },
+                       { NULL, 0 },
+                       { NULL, 0 },
+                       { NULL, 0 },
                        { 0, GNUTLS_E_DH_PRIME_UNACCEPTABLE,
                          GNUTLS_FIPS140_OP_INITIAL },
                },
+               {
+                       "Legal Input (KAT)",
+                       gnutls_ffdhe_2048_group_prime,
+                       gnutls_ffdhe_2048_group_q,
+                       gnutls_ffdhe_2048_group_generator,
+                       { (void *)"\x02", 1 },
+                       { (void *)ffdhe_2048_priv_key,
+                         sizeof(ffdhe_2048_priv_key) /
+                                 sizeof(ffdhe_2048_priv_key[0]) },
+                       { (void *)ffdhe_2048_pub_key,
+                         sizeof(ffdhe_2048_pub_key) /
+                                 sizeof(ffdhe_2048_pub_key[0]) },
+                       { (void *)ffdhe_2048_result,
+                         sizeof(ffdhe_2048_result) /
+                                 sizeof(ffdhe_2048_result[0]) },
+                       { 0, 0, GNUTLS_FIPS140_OP_INITIAL },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+                       { 0, 0, GNUTLS_FIPS140_OP_APPROVED },
+               },
                { NULL }
        };
 
        for (int i = 0; test_data[i].name != NULL; i++) {
                gnutls_datum_t priv_key = { NULL, 0 }, pub_key = { NULL, 0 };
+               const gnutls_datum_t *q =
+                       test_data[i].q.data == NULL ? NULL : &test_data[i].q;
+               const gnutls_datum_t *result =
+                       test_data[i].result.data == NULL ? NULL :
+                                                          &test_data[i].result;
                gnutls_dh_params_t dh_params = NULL;
                gnutls_fips140_context_t fips_context;
                int ret;
@@ -257,8 +374,8 @@ void doit(void)
                success("%s params\n", test_data[i].name);
 
                fips_push_context(fips_context);
-               params(&dh_params, test_data[i].prime, test_data[i].q,
-                      test_data[i].generator,
+               params(&dh_params, &test_data[i].prime, q,
+                      &test_data[i].generator,
                       get_expected(&test_data[i].params_expected));
                fips_pop_context(fips_context,
                                 test_data[i].params_expected.state);
@@ -267,16 +384,21 @@ void doit(void)
                        goto skip;
                }
 
-               success("%s genkey\n", test_data[i].name);
+               if (test_data[i].priv_key.data == NULL) {
+                       success("%s genkey\n", test_data[i].name);
 
-               fips_push_context(fips_context);
-               genkey(dh_params, &priv_key, &pub_key,
-                      get_expected(&test_data[i].genkey_expected));
-               fips_pop_context(fips_context,
-                                test_data[i].genkey_expected.state);
+                       fips_push_context(fips_context);
+                       genkey(dh_params, &priv_key, &pub_key,
+                              get_expected(&test_data[i].genkey_expected));
+                       fips_pop_context(fips_context,
+                                        test_data[i].genkey_expected.state);
 
-               if (get_expected(&test_data[i].genkey_expected) < 0) {
-                       goto skip;
+                       if (get_expected(&test_data[i].genkey_expected) < 0) {
+                               goto skip;
+                       }
+               } else {
+                       priv_key = test_data[i].priv_key;
+                       pub_key = test_data[i].pub_key;
                }
 
                success("%s compute_key\n", test_data[i].name);
@@ -284,19 +406,32 @@ void doit(void)
                fips_push_context(fips_context);
                compute_key(test_data[i].name, dh_params, &priv_key, &pub_key,
                            &test_data[i].peer_key,
-                           get_expected(&test_data[i].compute_key_expected),
-                           NULL, 0);
-               fips_pop_context(fips_context,
-                                test_data[i].compute_key_expected.state);
+                           get_expected(&test_data[i].import_expected),
+                           get_expected(&test_data[i].derive_expected),
+                           result);
 
-               if (get_expected(&test_data[i].compute_key_expected) < 0) {
+               if (get_expected(&test_data[i].import_expected) < 0) {
+                       fips_pop_context(fips_context,
+                                        test_data[i].import_expected.state);
                        goto skip;
                }
 
+               if (get_expected(&test_data[i].derive_expected) < 0) {
+                       fips_pop_context(fips_context,
+                                        test_data[i].derive_expected.state);
+                       goto skip;
+               }
+
+               fips_pop_context(fips_context,
+                                test_data[i].derive_expected.state);
+
        skip:
                gnutls_dh_params_deinit(dh_params);
-               gnutls_free(priv_key.data);
-               gnutls_free(pub_key.data);
+
+               if (test_data[i].priv_key.data == NULL) {
+                       gnutls_free(priv_key.data);
+                       gnutls_free(pub_key.data);
+               }
 
                if (gnutls_fips140_mode_enabled()) {
                        gnutls_fips140_context_deinit(fips_context);
index 1d589bf4881f9eee80edbdde5f8b5f57b1dd4f37..d367835475c02d030136fef6216305a4008f3769 100644 (file)
@@ -52,36 +52,40 @@ static void genkey(gnutls_ecc_curve_t curve, gnutls_datum_t *x,
                fail("error\n");
 }
 
-static void compute_key(gnutls_ecc_curve_t curve, const gnutls_datum_t *x,
-                       const gnutls_datum_t *y, const gnutls_datum_t *key,
-                       const gnutls_datum_t *peer_x,
+static void compute_key(const char *name, gnutls_ecc_curve_t curve,
+                       const gnutls_datum_t *x, const gnutls_datum_t *y,
+                       const gnutls_datum_t *key, const gnutls_datum_t *peer_x,
                        const gnutls_datum_t *peer_y, int expect_error,
-                       gnutls_datum_t *result, bool expect_success)
+                       const gnutls_datum_t *result)
 {
        gnutls_datum_t Z = { 0 };
-       bool success;
+       bool ok;
        int ret;
 
        ret = _gnutls_ecdh_compute_key(curve, x, y, key, peer_x, peer_y, &Z);
        if (expect_error != ret)
-               fail("error (%d)\n", ret);
+               fail("%s: error %d (expected %d)\n", name, ret, expect_error);
 
        if (result) {
-               success = (Z.size != result->size &&
-                          memcmp(Z.data, result->data, Z.size));
-               if (success != expect_success)
-                       fail("error\n");
+               ok = Z.size == result->size &&
+                    memcmp(Z.data, result->data, Z.size) == 0;
+               if (!ok) {
+                       hexprint(Z.data, Z.size);
+                       fail("%s: failed to match result\n", name);
+               }
        }
        gnutls_free(Z.data);
 }
 
 struct dh_test_data {
+       const char *name;
        gnutls_ecc_curve_t curve;
        const gnutls_datum_t x;
        const gnutls_datum_t y;
        const gnutls_datum_t key;
        const gnutls_datum_t peer_x;
        const gnutls_datum_t peer_y;
+       const gnutls_datum_t result;
        int expected_error;
 };
 
@@ -89,19 +93,20 @@ void doit(void)
 {
        struct dh_test_data test_data[] = {
                {
-                       /* x == 0, y == 0 */
+                       "[x == 0, y == 0]",
                        GNUTLS_ECC_CURVE_SECP256R1,
                        { 0 },
                        { 0 },
                        { 0 },
                        { (void *)"\x00", 1 },
                        { (void *)"\x00", 1 },
+                       { NULL, 0 },
                        /* Should be GNUTLS_E_PK_INVALID_PUBKEY but mpi scan
-                 * balks on values of 0 */
+                        * balks on values of 0 */
                        GNUTLS_E_MPI_SCAN_FAILED,
                },
                {
-                       /* x > p -1 */
+                       "[x > p - 1]",
                        GNUTLS_ECC_CURVE_SECP256R1,
                        { 0 },
                        { 0 },
@@ -112,10 +117,11 @@ void doit(void)
                                  "\xff\xff\xff\xff\xff\xff\xff\xff",
                          1 },
                        { (void *)"\x02", 1 },
+                       { NULL, 0 },
                        GNUTLS_E_PK_INVALID_PUBKEY,
                },
                {
-                       /* y > p -1 */
+                       "[y > p - 1]",
                        GNUTLS_ECC_CURVE_SECP256R1,
                        { 0 },
                        { 0 },
@@ -126,10 +132,11 @@ void doit(void)
                                  "\x00\x00\x00\x00\xff\xff\xff\xff"
                                  "\xff\xff\xff\xff\xff\xff\xff\xff",
                          1 },
+                       { NULL, 0 },
                        GNUTLS_E_PK_INVALID_PUBKEY,
                },
                {
-                       /* From CAVS tests */
+                       "From CAVS tests",
                        GNUTLS_ECC_CURVE_SECP521R1,
                        { (void *)"\xac\xbe\x4a\xd4\xf6\x73\x44\x0a"
                                  "\xfc\x31\xf0\xb0\x3d\x28\xd4\xd5"
@@ -181,6 +188,16 @@ void doit(void)
                                  "\x86\x92\x6c\xbe\x9b\x57\x32\xe3"
                                  "\x2c",
                          65 },
+                       { (void *)"\x00\x31\xda\x88\xde\x3b\x7b\x7b"
+                                 "\x26\xf2\x70\xd4\x9e\xf8\x80\x5a"
+                                 "\x61\xe4\x8b\xf9\x04\xe1\xf5\xf7"
+                                 "\x34\xdd\xc3\x42\x35\x36\xaf\x66"
+                                 "\xaa\xe9\x3c\x22\xfc\x83\x94\x7d"
+                                 "\x80\xc5\x2f\xfe\xda\x4b\x61\x51"
+                                 "\x1a\xbe\xd6\xd7\xcf\x53\x1b\x27"
+                                 "\xc4\x14\x94\x74\xe4\x94\x6d\xa3"
+                                 "\xe2\xd4",
+                         66 },
                        0,
                },
                { 0 }
@@ -188,8 +205,13 @@ void doit(void)
 
        for (int i = 0; test_data[i].curve != 0; i++) {
                gnutls_datum_t x, y, key;
+               const gnutls_datum_t *result =
+                       test_data[i].result.data == NULL ? NULL :
+                                                          &test_data[i].result;
 
                if (test_data[i].key.data == NULL) {
+                       success("%s genkey\n", test_data[i].name);
+
                        genkey(test_data[i].curve, &x, &y, &key);
                } else {
                        x = test_data[i].x;
@@ -197,9 +219,11 @@ void doit(void)
                        key = test_data[i].key;
                }
 
-               compute_key(test_data[i].curve, &x, &y, &key,
+               success("%s compute_key\n", test_data[i].name);
+
+               compute_key(test_data[i].name, test_data[i].curve, &x, &y, &key,
                            &test_data[i].peer_x, &test_data[i].peer_y,
-                           test_data[i].expected_error, NULL, 0);
+                           test_data[i].expected_error, result);
 
                if (test_data[i].key.data == NULL) {
                        gnutls_free(x.data);
index a4c87cbb30462ab0ec664874b2a32cfdb9338f26..5c5f4a4c793bc0aae0f2f910b18abce9b6425ad4 100644 (file)
@@ -54,17 +54,18 @@ static void genkey(gnutls_ecc_curve_t curve, gnutls_datum_t *x,
        gnutls_privkey_deinit(privkey);
 }
 
-static void compute_key(gnutls_ecc_curve_t curve, const gnutls_datum_t *x,
-                       const gnutls_datum_t *y, const gnutls_datum_t *key,
-                       const gnutls_datum_t *peer_x,
-                       const gnutls_datum_t *peer_y, int expect_error,
-                       gnutls_datum_t *result, bool expect_success)
+static void compute_key(const char *name, gnutls_ecc_curve_t curve,
+                       const gnutls_datum_t *x, const gnutls_datum_t *y,
+                       const gnutls_datum_t *key, const gnutls_datum_t *peer_x,
+                       const gnutls_datum_t *peer_y,
+                       int expect_error_on_import, int expect_error_on_derive,
+                       const gnutls_datum_t *result)
 {
        gnutls_datum_t Z = { 0 };
-       bool success;
+       bool ok;
        int ret;
-       gnutls_privkey_t privkey;
-       gnutls_pubkey_t pubkey;
+       gnutls_privkey_t privkey = NULL;
+       gnutls_pubkey_t pubkey = NULL;
 
        ret = gnutls_privkey_init(&privkey);
        if (ret != 0)
@@ -78,41 +79,101 @@ static void compute_key(gnutls_ecc_curve_t curve, const gnutls_datum_t *x,
        if (ret != 0)
                fail("error\n");
 
-       ret = gnutls_pubkey_import_ecc_raw(pubkey, curve, x, y);
-       if (ret != 0)
-               fail("error\n");
+       ret = gnutls_pubkey_import_ecc_raw(pubkey, curve, peer_x, peer_y);
+       if (ret != expect_error_on_import)
+               fail("%s: error %d (expected %d)\n", name, ret,
+                    expect_error_on_import);
+
+       if (expect_error_on_import != 0)
+               goto cleanup;
 
        ret = gnutls_privkey_derive_secret(privkey, pubkey, NULL, &Z, 0);
-       if (ret != 0)
-               fail("error\n");
+       if (ret != expect_error_on_derive)
+               fail("%s: error %d (expected %d)\n", name, ret,
+                    expect_error_on_derive);
+
+       if (expect_error_on_derive != 0)
+               goto cleanup;
 
        if (result) {
-               success = (Z.size != result->size &&
-                          memcmp(Z.data, result->data, Z.size));
-               if (success != expect_success)
+               ok = Z.size == result->size &&
+                    memcmp(Z.data, result->data, Z.size) == 0;
+               if (!ok) {
+                       hexprint(Z.data, Z.size);
                        fail("error\n");
+               }
        }
-       gnutls_free(Z.data);
 
+cleanup:
+       gnutls_free(Z.data);
        gnutls_privkey_deinit(privkey);
        gnutls_pubkey_deinit(pubkey);
 }
 
 struct dh_test_data {
+       const char *name;
        gnutls_ecc_curve_t curve;
        const gnutls_datum_t x;
        const gnutls_datum_t y;
        const gnutls_datum_t key;
        const gnutls_datum_t peer_x;
        const gnutls_datum_t peer_y;
-       int expected_error;
+       const gnutls_datum_t result;
+       int expected_error_on_import;
+       int expected_error_on_derive;
 };
 
 void doit(void)
 {
        struct dh_test_data test_data[] = {
                {
-                       /* From CAVS tests */
+                       "[x == 0, y == 0]",
+                       GNUTLS_ECC_CURVE_SECP256R1,
+                       { 0 },
+                       { 0 },
+                       { 0 },
+                       { (void *)"\x00", 1 },
+                       { (void *)"\x00", 1 },
+                       { NULL, 0 },
+                       /* Should be GNUTLS_E_PK_INVALID_PUBKEY but mpi scan
+                        * balks on values of 0 */
+                       GNUTLS_E_MPI_SCAN_FAILED,
+                       0,
+               },
+               {
+                       "[x > p - 1]",
+                       GNUTLS_ECC_CURVE_SECP256R1,
+                       { 0 },
+                       { 0 },
+                       { 0 },
+                       { (void *)"\xff\xff\xff\xff\x00\x00\x00\x01"
+                                 "\x00\x00\x00\x00\x00\x00\x00\x00"
+                                 "\x00\x00\x00\x00\xff\xff\xff\xff"
+                                 "\xff\xff\xff\xff\xff\xff\xff\xff",
+                         1 },
+                       { (void *)"\x02", 1 },
+                       { NULL, 0 },
+                       0,
+                       GNUTLS_E_PK_INVALID_PUBKEY,
+               },
+               {
+                       "[y > p - 1]",
+                       GNUTLS_ECC_CURVE_SECP256R1,
+                       { 0 },
+                       { 0 },
+                       { 0 },
+                       { (void *)"\x02", 1 },
+                       { (void *)"\xff\xff\xff\xff\x00\x00\x00\x01"
+                                 "\x00\x00\x00\x00\x00\x00\x00\x00"
+                                 "\x00\x00\x00\x00\xff\xff\xff\xff"
+                                 "\xff\xff\xff\xff\xff\xff\xff\xff",
+                         1 },
+                       { NULL, 0 },
+                       0,
+                       GNUTLS_E_PK_INVALID_PUBKEY,
+               },
+               {
+                       "From CAVS tests",
                        GNUTLS_ECC_CURVE_SECP521R1,
                        { (void *)"\xac\xbe\x4a\xd4\xf6\x73\x44\x0a"
                                  "\xfc\x31\xf0\xb0\x3d\x28\xd4\xd5"
@@ -164,6 +225,17 @@ void doit(void)
                                  "\x86\x92\x6c\xbe\x9b\x57\x32\xe3"
                                  "\x2c",
                          65 },
+                       { (void *)"\x00\x31\xda\x88\xde\x3b\x7b\x7b"
+                                 "\x26\xf2\x70\xd4\x9e\xf8\x80\x5a"
+                                 "\x61\xe4\x8b\xf9\x04\xe1\xf5\xf7"
+                                 "\x34\xdd\xc3\x42\x35\x36\xaf\x66"
+                                 "\xaa\xe9\x3c\x22\xfc\x83\x94\x7d"
+                                 "\x80\xc5\x2f\xfe\xda\x4b\x61\x51"
+                                 "\x1a\xbe\xd6\xd7\xcf\x53\x1b\x27"
+                                 "\xc4\x14\x94\x74\xe4\x94\x6d\xa3"
+                                 "\xe2\xd4",
+                         66 },
+                       0,
                        0,
                },
                { 0 }
@@ -171,8 +243,13 @@ void doit(void)
 
        for (int i = 0; test_data[i].curve != 0; i++) {
                gnutls_datum_t x, y, key;
+               const gnutls_datum_t *result =
+                       test_data[i].result.data == NULL ? NULL :
+                                                          &test_data[i].result;
 
                if (test_data[i].key.data == NULL) {
+                       success("%s genkey\n", test_data[i].name);
+
                        genkey(test_data[i].curve, &x, &y, &key);
                } else {
                        x = test_data[i].x;
@@ -180,9 +257,12 @@ void doit(void)
                        key = test_data[i].key;
                }
 
-               compute_key(test_data[i].curve, &x, &y, &key,
+               success("%s compute_key\n", test_data[i].name);
+
+               compute_key(test_data[i].name, test_data[i].curve, &x, &y, &key,
                            &test_data[i].peer_x, &test_data[i].peer_y,
-                           test_data[i].expected_error, NULL, 0);
+                           test_data[i].expected_error_on_import,
+                           test_data[i].expected_error_on_derive, result);
 
                if (test_data[i].key.data == NULL) {
                        gnutls_free(x.data);