From 23b02498d12cd3d4bd0c93f1afa0e187abdf708a Mon Sep 17 00:00:00 2001 From: tb Date: Sat, 15 Jul 2023 23:35:02 +0000 Subject: [PATCH] Rework the ecdhtest Test keyshare for all built-in curves and simplify, especially printing on failure. Incorporate known answer tests from RFC 5114 and RFC 5903. All in all, this is a lot less code and a lot more test coverage and hopefully a little less eyebleed. Very loosely based on OpenSSL b438f0ed by Billy Brumley --- regress/lib/libcrypto/ecdh/ecdhtest.c | 512 +++++++++++++------------- 1 file changed, 252 insertions(+), 260 deletions(-) diff --git a/regress/lib/libcrypto/ecdh/ecdhtest.c b/regress/lib/libcrypto/ecdh/ecdhtest.c index 6388343cfe8..fc534f14bd8 100644 --- a/regress/lib/libcrypto/ecdh/ecdhtest.c +++ b/regress/lib/libcrypto/ecdh/ecdhtest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecdhtest.c,v 1.17 2023/07/15 20:11:37 tb Exp $ */ +/* $OpenBSD: ecdhtest.c,v 1.18 2023/07/15 23:35:02 tb Exp $ */ /* ==================================================================== * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -67,6 +67,7 @@ * */ +#include #include #include #include @@ -81,6 +82,18 @@ #include #include +static void +hexdump(const unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) + fprintf(stdout, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n"); + + if (len % 8) + fprintf(stdout, "\n"); +} + static const int KDF1_SHA1_len = 20; static void * KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen) @@ -96,335 +109,314 @@ KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen) #endif } - static int -test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out) +ecdh_keygen_test(int nid) { - BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL; - EC_KEY *a = NULL, *b = NULL; - const EC_GROUP *group; + EC_KEY *keya = NULL, *keyb = NULL; + const EC_POINT *puba, *pubb; unsigned char *abuf = NULL, *bbuf = NULL; - int i, alen, blen, aout, bout, ret = 0; - char buf[12]; + int len = KDF1_SHA1_len; + int failed = 1; - a = EC_KEY_new_by_curve_name(nid); - b = EC_KEY_new_by_curve_name(nid); - if (a == NULL || b == NULL) + if ((keya = EC_KEY_new_by_curve_name(nid)) == NULL) goto err; - - group = EC_KEY_get0_group(a); - - if ((x_a = BN_new()) == NULL) + if (!EC_KEY_generate_key(keya)) goto err; - if ((y_a = BN_new()) == NULL) + if ((puba = EC_KEY_get0_public_key(keya)) == NULL) goto err; - if ((x_b = BN_new()) == NULL) + + if ((keyb = EC_KEY_new_by_curve_name(nid)) == NULL) goto err; - if ((y_b = BN_new()) == NULL) + if (!EC_KEY_generate_key(keyb)) goto err; - - BIO_puts(out, "Testing key generation with "); - BIO_puts(out, text); - (void)BIO_flush(out); - - if (!EC_KEY_generate_key(a)) + if ((pubb = EC_KEY_get0_public_key(keyb)) == NULL) goto err; - if (!EC_POINT_get_affine_coordinates(group, - EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err; - - BIO_printf(out, " ."); - (void)BIO_flush(out); - - if (!EC_KEY_generate_key(b)) + if ((abuf = calloc(1, len)) == NULL) + goto err; + if ((bbuf = calloc(1, len)) == NULL) goto err; - if (!EC_POINT_get_affine_coordinates(group, - EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err; - - BIO_printf(out, "."); - (void)BIO_flush(out); - - alen = KDF1_SHA1_len; - if ((abuf = malloc(alen)) == NULL) + if (ECDH_compute_key(abuf, len, pubb, keya, KDF1_SHA1) != len) + goto err; + if (ECDH_compute_key(bbuf, len, puba, keyb, KDF1_SHA1) != len) goto err; - aout = ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), - a, KDF1_SHA1); - BIO_printf(out, "."); - (void)BIO_flush(out); + if (memcmp(abuf, bbuf, len) != 0) { + printf("key generation with %s failed\n", OBJ_nid2sn(nid)); - blen = KDF1_SHA1_len; - if ((bbuf = malloc(blen)) == NULL) - goto err; - bout = ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), - b, KDF1_SHA1); + EC_KEY_print_fp(stdout, keya, 1); + printf(" shared secret:\n"); + hexdump(abuf, len); - BIO_printf(out, "."); - (void)BIO_flush(out); + printf("key b:\n"); + EC_KEY_print_fp(stdout, keyb, 1); + printf(" shared secret:\n"); + hexdump(abuf, len); - if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { - BIO_printf(out, " failed\n\n"); - BIO_printf(out, "key a:\n"); - BIO_printf(out, "private key: "); - BN_print(out, EC_KEY_get0_private_key(a)); - BIO_printf(out, "\n"); - BIO_printf(out, "public key (x,y): "); - BN_print(out, x_a); - BIO_printf(out, ","); - BN_print(out, y_a); - BIO_printf(out, "\nkey b:\n"); - BIO_printf(out, "private key: "); - BN_print(out, EC_KEY_get0_private_key(b)); - BIO_printf(out, "\n"); - BIO_printf(out, "public key (x,y): "); - BN_print(out, x_b); - BIO_printf(out, ","); - BN_print(out, y_b); - BIO_printf(out, "\n"); - BIO_printf(out, "generated key a: "); - for (i = 0; i < bout; i++) { - snprintf(buf, sizeof buf, "%02X", bbuf[i]); - BIO_puts(out, buf); - } - BIO_printf(out, "\n"); - BIO_printf(out, "generated key b: "); - for (i = 0; i < aout; i++) { - snprintf(buf, sizeof buf, "%02X", abuf[i]); - BIO_puts(out, buf); - } - BIO_printf(out, "\n"); fprintf(stderr, "Error in ECDH routines\n"); - ret = 0; - } else { - BIO_printf(out, " ok\n"); - ret = 1; + + goto err; } -err: + failed = 0; + err: ERR_print_errors_fp(stderr); - free(abuf); - free(bbuf); - BN_free(x_a); - BN_free(y_a); - BN_free(x_b); - BN_free(y_b); - EC_KEY_free(b); - EC_KEY_free(a); + EC_KEY_free(keya); + EC_KEY_free(keyb); + freezero(abuf, len); + freezero(bbuf, len); - return (ret); + return failed; } -/* Keys and shared secrets from RFC 7027 */ - -static const unsigned char bp256_da[] = { - 0x81, 0xDB, 0x1E, 0xE1, 0x00, 0x15, 0x0F, 0xF2, 0xEA, 0x33, 0x8D, 0x70, - 0x82, 0x71, 0xBE, 0x38, 0x30, 0x0C, 0xB5, 0x42, 0x41, 0xD7, 0x99, 0x50, - 0xF7, 0x7B, 0x06, 0x30, 0x39, 0x80, 0x4F, 0x1D -}; - -static const unsigned char bp256_db[] = { - 0x55, 0xE4, 0x0B, 0xC4, 0x1E, 0x37, 0xE3, 0xE2, 0xAD, 0x25, 0xC3, 0xC6, - 0x65, 0x45, 0x11, 0xFF, 0xA8, 0x47, 0x4A, 0x91, 0xA0, 0x03, 0x20, 0x87, - 0x59, 0x38, 0x52, 0xD3, 0xE7, 0xD7, 0x6B, 0xD3 -}; - -static const unsigned char bp256_Z[] = { - 0x89, 0xAF, 0xC3, 0x9D, 0x41, 0xD3, 0xB3, 0x27, 0x81, 0x4B, 0x80, 0x94, - 0x0B, 0x04, 0x25, 0x90, 0xF9, 0x65, 0x56, 0xEC, 0x91, 0xE6, 0xAE, 0x79, - 0x39, 0xBC, 0xE3, 0x1F, 0x3A, 0x18, 0xBF, 0x2B -}; - -static const unsigned char bp384_da[] = { - 0x1E, 0x20, 0xF5, 0xE0, 0x48, 0xA5, 0x88, 0x6F, 0x1F, 0x15, 0x7C, 0x74, - 0xE9, 0x1B, 0xDE, 0x2B, 0x98, 0xC8, 0xB5, 0x2D, 0x58, 0xE5, 0x00, 0x3D, - 0x57, 0x05, 0x3F, 0xC4, 0xB0, 0xBD, 0x65, 0xD6, 0xF1, 0x5E, 0xB5, 0xD1, - 0xEE, 0x16, 0x10, 0xDF, 0x87, 0x07, 0x95, 0x14, 0x36, 0x27, 0xD0, 0x42 -}; - -static const unsigned char bp384_db[] = { - 0x03, 0x26, 0x40, 0xBC, 0x60, 0x03, 0xC5, 0x92, 0x60, 0xF7, 0x25, 0x0C, - 0x3D, 0xB5, 0x8C, 0xE6, 0x47, 0xF9, 0x8E, 0x12, 0x60, 0xAC, 0xCE, 0x4A, - 0xCD, 0xA3, 0xDD, 0x86, 0x9F, 0x74, 0xE0, 0x1F, 0x8B, 0xA5, 0xE0, 0x32, - 0x43, 0x09, 0xDB, 0x6A, 0x98, 0x31, 0x49, 0x7A, 0xBA, 0xC9, 0x66, 0x70 -}; - -static const unsigned char bp384_Z[] = { - 0x0B, 0xD9, 0xD3, 0xA7, 0xEA, 0x0B, 0x3D, 0x51, 0x9D, 0x09, 0xD8, 0xE4, - 0x8D, 0x07, 0x85, 0xFB, 0x74, 0x4A, 0x6B, 0x35, 0x5E, 0x63, 0x04, 0xBC, - 0x51, 0xC2, 0x29, 0xFB, 0xBC, 0xE2, 0x39, 0xBB, 0xAD, 0xF6, 0x40, 0x37, - 0x15, 0xC3, 0x5D, 0x4F, 0xB2, 0xA5, 0x44, 0x4F, 0x57, 0x5D, 0x4F, 0x42 -}; - -static const unsigned char bp512_da[] = { - 0x16, 0x30, 0x2F, 0xF0, 0xDB, 0xBB, 0x5A, 0x8D, 0x73, 0x3D, 0xAB, 0x71, - 0x41, 0xC1, 0xB4, 0x5A, 0xCB, 0xC8, 0x71, 0x59, 0x39, 0x67, 0x7F, 0x6A, - 0x56, 0x85, 0x0A, 0x38, 0xBD, 0x87, 0xBD, 0x59, 0xB0, 0x9E, 0x80, 0x27, - 0x96, 0x09, 0xFF, 0x33, 0x3E, 0xB9, 0xD4, 0xC0, 0x61, 0x23, 0x1F, 0xB2, - 0x6F, 0x92, 0xEE, 0xB0, 0x49, 0x82, 0xA5, 0xF1, 0xD1, 0x76, 0x4C, 0xAD, - 0x57, 0x66, 0x54, 0x22 -}; - -static const unsigned char bp512_db[] = { - 0x23, 0x0E, 0x18, 0xE1, 0xBC, 0xC8, 0x8A, 0x36, 0x2F, 0xA5, 0x4E, 0x4E, - 0xA3, 0x90, 0x20, 0x09, 0x29, 0x2F, 0x7F, 0x80, 0x33, 0x62, 0x4F, 0xD4, - 0x71, 0xB5, 0xD8, 0xAC, 0xE4, 0x9D, 0x12, 0xCF, 0xAB, 0xBC, 0x19, 0x96, - 0x3D, 0xAB, 0x8E, 0x2F, 0x1E, 0xBA, 0x00, 0xBF, 0xFB, 0x29, 0xE4, 0xD7, - 0x2D, 0x13, 0xF2, 0x22, 0x45, 0x62, 0xF4, 0x05, 0xCB, 0x80, 0x50, 0x36, - 0x66, 0xB2, 0x54, 0x29 +static const struct ecdh_kat_test { + const int nid; + const char *keya; + const char *keyb; + const char *want; +} ecdh_kat_tests[] = { + /* Keys and shared secrets from RFC 5114 */ + { + .nid = NID_X9_62_prime192v1, + .keya = "323fa3169d8e9c6593f59476bc142000ab5be0e249c43426", + .keyb = "631f95bb4a67632c9c476eee9ab695ab240a0499307fcf62", + .want = "ad420182633f8526bfe954acda376f05e5ff4f837f54febe", + }, + { + .nid = NID_secp224r1, + .keya = "b558eb6c288da707bbb4f8fbae2ab9e9cb62e3bc5c7573e2" + "2e26d37f", + .keyb = "ac3b1add3d9770e6f6a708ee9f3b8e0ab3b480e9f27f85c8" + "8b5e6d18", + .want = "52272f50f46f4edc9151569092f46df2d96ecc3b6dc1714a" + "4ea949fa", + }, + { + .nid = NID_X9_62_prime256v1, + .keya = "814264145f2f56f2e96a8e337a1284993faf432a5abce59e" + "867b7291d507a3af", + .keyb = "2ce1788ec197e096db95a200cc0ab26a19ce6bccad562b8e" + "ee1b593761cf7f41", + .want = "dd0f5396219d1ea393310412d19a08f1f5811e9dc8ec8eea" + "7f80d21c820c2788", + }, + { + .nid = NID_secp384r1, + .keya = "d27335ea71664af244dd14e9fd1260715dfd8a7965571c48" + "d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1", + .keyb = "52d1791fdb4b70f89c0f00d456c2f7023b6125262c36a7df" + "1f80231121cce3d39be52e00c194a4132c4a6c768bcd94d2", + .want = "5ea1fc4af7256d2055981b110575e0a8cae53160137d904c" + "59d926eb1b8456e427aa8a4540884c37de159a58028abc0e", + }, + { + .nid = NID_secp521r1, + .keya = "0113f82da825735e3d97276683b2b74277bad27335ea7166" + "4af2430cc4f33459b9669ee78b3ffb9b8683015d344dcbfe" + "f6fb9af4c6c470be254516cd3c1a1fb47362", + .keyb = "00cee3480d8645a17d249f2776d28bae616952d1791fdb4b" + "70f7c3378732aa1b22928448bcd1dc2496d435b01048066e" + "be4f72903c361b1a9dc1193dc2c9d0891b96", + .want = "00cdea89621cfa46b132f9e4cfe2261cde2d4368eb565663" + "4c7cc98c7a00cde54ed1866a0dd3e6126c9d2f845daff82c" + "eb1da08f5d87521bb0ebeca77911169c20cc", + }, + /* Keys and shared secrets from RFC 5903 */ + { + .nid = NID_X9_62_prime256v1, + .keya = "c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049" + "c62a9c57862d1433", + .keyb = "c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0" + "b283ab46476bee53", + .want = "d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03" + "812464d04b9442de", + }, + { + .nid = NID_secp384r1, + .keya = "099f3c7034d4a2c699884d73a375a67f7624ef7c6b3c0f16" + "0647b67414dce655e35b538041e649ee3faef896783ab194", + .keyb = "41cb0779b4bdb85d47846725fbec3c9430fab46cc8dc5060" + "855cc9bda0aa2942e0308312916b8ed2960e4bd55a7448fc", + .want = "11187331c279962d93d604243fd592cb9d0a926f422e4718" + "7521287e7156c5c4d603135569b9e9d09cf5d4a270f59746", + }, + { + .nid = NID_secp521r1, + .keya = "0037ade9319a89f4dabdb3ef411aaccca5123c61acab57b5" + "393dce47608172a095aa85a30fe1c2952c6771d937ba9777" + "f5957b2639bab072462f68c27a57382d" + "4a52", + .keyb = "0145ba99a847af43793fdd0e872e7cdfa16be30fdc780f97" + "bccc3f078380201e9c677d600b343757a3bdbf2a3163e4c2" + "f869cca7458aa4a4effc311f5cb151685eb9", + .want = "01144c7d79ae6956bc8edb8e7c787c4521cb086fa64407f9" + "7894e5e6b2d79b04d1427e73ca4baa240a34786859810c06" + "b3c715a3a8cc3151f2bee417996d19f3ddea", + }, + /* Keys and shared secrets from RFC 7027 */ + { + .nid = NID_brainpoolP256r1, + .keya = "81db1ee100150ff2ea338d708271be38300cb54241d79950" + "f77b063039804f1d", + .keyb = "55e40bc41e37e3e2ad25c3c6654511ffa8474a91a0032087" + "593852d3e7d76bd3", + .want = "89afc39d41d3b327814b80940b042590f96556ec91e6ae79" + "39bce31f3a18bf2b", + }, + { + .nid = NID_brainpoolP384r1, + .keya = "1e20f5e048a5886f1f157c74e91bde2b98c8b52d58e5003d" + "57053fc4b0bd65d6f15eb5d1ee1610df870795143627d042", + .keyb = "032640bc6003c59260f7250c3db58ce647f98e1260acce4a" + "cda3dd869f74e01f8ba5e0324309db6a9831497abac96670", + .want = "0bd9d3a7ea0b3d519d09d8e48d0785fb744a6b355e6304bc" + "51c229fbbce239bbadf6403715c35d4fb2a5444f575d4f42", + }, + { + .nid = NID_brainpoolP512r1, + .keya = "16302ff0dbbb5a8d733dab7141c1b45acbc8715939677f6a" + "56850a38bd87bd59b09e80279609ff333eb9d4c061231fb2" + "6f92eeb04982a5f1d1764cad57665422", + .keyb = "230e18e1bcc88a362fa54e4ea3902009292f7f8033624fd4" + "71b5d8ace49d12cfabbc19963dab8e2f1eba00bffb29e4d7" + "2d13f2224562f405cb80503666b25429", + .want = "a7927098655f1f9976fa50a9d566865dc530331846381c87" + "256baf3226244b76d36403c024d7bbf0aa0803eaff405d3d" + "24f11a9b5c0bef679fe1454b21c4cd1f", + }, }; - -static const unsigned char bp512_Z[] = { - 0xA7, 0x92, 0x70, 0x98, 0x65, 0x5F, 0x1F, 0x99, 0x76, 0xFA, 0x50, 0xA9, - 0xD5, 0x66, 0x86, 0x5D, 0xC5, 0x30, 0x33, 0x18, 0x46, 0x38, 0x1C, 0x87, - 0x25, 0x6B, 0xAF, 0x32, 0x26, 0x24, 0x4B, 0x76, 0xD3, 0x64, 0x03, 0xC0, - 0x24, 0xD7, 0xBB, 0xF0, 0xAA, 0x08, 0x03, 0xEA, 0xFF, 0x40, 0x5D, 0x3D, - 0x24, 0xF1, 0x1A, 0x9B, 0x5C, 0x0B, 0xEF, 0x67, 0x9F, 0xE1, 0x45, 0x4B, - 0x21, 0xC4, 0xCD, 0x1F -}; +#define N_KATS (sizeof(ecdh_kat_tests) / sizeof(ecdh_kat_tests[0])) /* Given private value and NID, create EC_KEY structure */ static EC_KEY * -mk_eckey(int nid, const unsigned char *p, size_t plen) +mk_eckey(int nid, const char *priv_str) { - EC_KEY *k = NULL; + EC_KEY *key = NULL; BIGNUM *priv = NULL; EC_POINT *pub = NULL; - const EC_GROUP *grp; - int ok = 0; + const EC_GROUP *group; + EC_KEY *ret = NULL; - k = EC_KEY_new_by_curve_name(nid); - if (!k) + if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) goto err; - priv = BN_bin2bn(p, plen, NULL); - if (!priv) + if (!BN_hex2bn(&priv, priv_str)) goto err; - if (!EC_KEY_set_private_key(k, priv)) + if (!EC_KEY_set_private_key(key, priv)) goto err; - grp = EC_KEY_get0_group(k); - pub = EC_POINT_new(grp); - if (!pub) + if ((group = EC_KEY_get0_group(key)) == NULL) goto err; - if (!EC_POINT_mul(grp, pub, priv, NULL, NULL, NULL)) + if ((pub = EC_POINT_new(group)) == NULL) goto err; - if (!EC_KEY_set_public_key(k, pub)) + if (!EC_POINT_mul(group, pub, priv, NULL, NULL, NULL)) goto err; - ok = 1; -err: + if (!EC_KEY_set_public_key(key, pub)) + goto err; + + ret = key; + key = NULL; + + err: + EC_KEY_free(key); BN_free(priv); EC_POINT_free(pub); - if (!ok) { - EC_KEY_free(k); - k = NULL; - } - return (k); + + return ret; } -/* Known answer test: compute shared secret and check it matches - * expected value. +/* + * Known answer test: compute shared secret and check it matches expected value. */ - static int -ecdh_kat(BIO *out, const char *cname, int nid, - const unsigned char *k1, size_t k1_len, - const unsigned char *k2, size_t k2_len, - const unsigned char *Z, size_t Zlen) +ecdh_kat(const struct ecdh_kat_test *kat) { - int rv = 0; - EC_KEY *key1 = NULL, *key2 = NULL; - unsigned char *Ztmp = NULL; - size_t Ztmplen; - BIO_puts(out, "Testing ECDH shared secret with "); - BIO_puts(out, cname); - key1 = mk_eckey(nid, k1, k1_len); - key2 = mk_eckey(nid, k2, k2_len); - if (!key1 || !key2) + EC_KEY *keya = NULL, *keyb = NULL; + const EC_POINT *puba, *pubb; + BIGNUM *z = NULL; + unsigned char *want = NULL, *got = NULL; + int len = 0; + int failed = 0; + + if ((keya = mk_eckey(kat->nid, kat->keya)) == NULL) + goto err; + if ((puba = EC_KEY_get0_public_key(keya)) == NULL) + goto err; + if ((keyb = mk_eckey(kat->nid, kat->keyb)) == NULL) + goto err; + if ((pubb = EC_KEY_get0_public_key(keyb)) == NULL) + goto err; + + if ((len = ECDH_size(keya)) != ECDH_size(keyb)) + goto err; + + if ((want = calloc(1, len)) == NULL) + goto err; + if ((got = calloc(1, len)) == NULL) + goto err; + + if (!BN_hex2bn(&z, kat->want)) goto err; - Ztmplen = ECDH_size(key1); - if (Ztmplen != Zlen) + if (BN_num_bytes(z) > len) goto err; - if ((Ztmp = malloc(Ztmplen)) == NULL) + if (BN_bn2binpad(z, want, len) != len) goto err; - if (ECDH_compute_key(Ztmp, Ztmplen, - EC_KEY_get0_public_key(key2), key1, 0) <= 0) + + if (ECDH_compute_key(got, len, pubb, keya, NULL) != len) goto err; - if (memcmp(Ztmp, Z, Zlen)) + if (memcmp(got, want, len) != 0) goto err; - memset(Ztmp, 0, Zlen); - if (ECDH_compute_key(Ztmp, Ztmplen, - EC_KEY_get0_public_key(key1), key2, 0) <= 0) + + memset(got, 0, len); + + if (ECDH_compute_key(got, len, puba, keyb, NULL) != len) goto err; - if (memcmp(Ztmp, Z, Zlen)) + if (memcmp(got, want, len) != 0) goto err; - rv = 1; -err: - if (rv) - BIO_puts(out, " ok\n"); - else { + failed = 0; + + err: + if (failed) { + printf("ECDH shared secret with %s failed", OBJ_nid2sn(kat->nid)); + fprintf(stderr, "Error in ECDH routines\n"); ERR_print_errors_fp(stderr); } - EC_KEY_free(key1); - EC_KEY_free(key2); - free(Ztmp); + EC_KEY_free(keya); + EC_KEY_free(keyb); + BN_free(z); + freezero(want, len); + freezero(got, len); - return rv; + return failed; } -#define test_ecdh_kat(bio, curve, bits) \ - ecdh_kat(bio, curve, NID_brainpoolP##bits##r1, \ - bp##bits##_da, sizeof(bp##bits##_da), \ - bp##bits##_db, sizeof(bp##bits##_db), \ - bp##bits##_Z, sizeof(bp##bits##_Z)) - int main(int argc, char *argv[]) { - BN_CTX *ctx = NULL; - int ret = 1; - BIO *out; + EC_builtin_curve *curves = NULL; + size_t i, n_curves; + int failed = 0; - out = BIO_new(BIO_s_file()); - if (out == NULL) - exit(1); - BIO_set_fp(out, stdout, BIO_NOCLOSE); - - if ((ctx = BN_CTX_new()) == NULL) - goto err; + if ((n_curves = EC_get_builtin_curves(NULL, 0)) == 0) + errx(1, "EC_get_builtin_curves failed"); + if ((curves = calloc(n_curves, sizeof(*curves))) == NULL) + errx(1, NULL); + if (EC_get_builtin_curves(curves, n_curves) != n_curves) + errx(1, "EC_get_builtin_curves failed"); - /* NIST PRIME CURVES TESTS */ - if (!test_ecdh_curve(NID_X9_62_prime192v1, "NIST Prime-Curve P-192", - ctx, out)) - goto err; - if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) - goto err; - if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", - ctx, out)) - goto err; - if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) - goto err; - if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) - goto err; - if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP256r1", 256)) - goto err; - if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP384r1", 384)) - goto err; - if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP512r1", 512)) - goto err; + for (i = 0; i < n_curves; i++) + failed |= ecdh_keygen_test(curves[i].nid); - ret = 0; + for (i = 0; i < N_KATS; i++) + failed |= ecdh_kat(&ecdh_kat_tests[i]); -err: + free(curves); ERR_print_errors_fp(stderr); - BN_CTX_free(ctx); - BIO_free(out); - CRYPTO_cleanup_all_ex_data(); - ERR_remove_thread_state(NULL); - CRYPTO_mem_leaks_fp(stderr); - exit(ret); + + return failed; } -- 2.20.1