-/* $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.
*
*
*/
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
+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)
#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;
}