xref: /openbsd-src/regress/lib/libcrypto/ecdh/ecdhtest.c (revision 35671554a3f71a3620dfbda5649acdb27119f8c8)
1*35671554Stb /*	$OpenBSD: ecdhtest.c,v 1.22 2024/12/24 18:32:31 tb Exp $ */
23c6bd008Smiod /* ====================================================================
33c6bd008Smiod  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
43c6bd008Smiod  *
53c6bd008Smiod  * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
63c6bd008Smiod  * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
73c6bd008Smiod  * to the OpenSSL project.
83c6bd008Smiod  *
93c6bd008Smiod  * The ECC Code is licensed pursuant to the OpenSSL open source
103c6bd008Smiod  * license provided below.
113c6bd008Smiod  *
123c6bd008Smiod  * The ECDH software is originally written by Douglas Stebila of
133c6bd008Smiod  * Sun Microsystems Laboratories.
143c6bd008Smiod  *
153c6bd008Smiod  */
163c6bd008Smiod /* ====================================================================
173c6bd008Smiod  * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
183c6bd008Smiod  *
193c6bd008Smiod  * Redistribution and use in source and binary forms, with or without
203c6bd008Smiod  * modification, are permitted provided that the following conditions
213c6bd008Smiod  * are met:
223c6bd008Smiod  *
233c6bd008Smiod  * 1. Redistributions of source code must retain the above copyright
243c6bd008Smiod  *    notice, this list of conditions and the following disclaimer.
253c6bd008Smiod  *
263c6bd008Smiod  * 2. Redistributions in binary form must reproduce the above copyright
273c6bd008Smiod  *    notice, this list of conditions and the following disclaimer in
283c6bd008Smiod  *    the documentation and/or other materials provided with the
293c6bd008Smiod  *    distribution.
303c6bd008Smiod  *
313c6bd008Smiod  * 3. All advertising materials mentioning features or use of this
323c6bd008Smiod  *    software must display the following acknowledgment:
333c6bd008Smiod  *    "This product includes software developed by the OpenSSL Project
343c6bd008Smiod  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
353c6bd008Smiod  *
363c6bd008Smiod  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
373c6bd008Smiod  *    endorse or promote products derived from this software without
383c6bd008Smiod  *    prior written permission. For written permission, please contact
393c6bd008Smiod  *    openssl-core@openssl.org.
403c6bd008Smiod  *
413c6bd008Smiod  * 5. Products derived from this software may not be called "OpenSSL"
423c6bd008Smiod  *    nor may "OpenSSL" appear in their names without prior written
433c6bd008Smiod  *    permission of the OpenSSL Project.
443c6bd008Smiod  *
453c6bd008Smiod  * 6. Redistributions of any form whatsoever must retain the following
463c6bd008Smiod  *    acknowledgment:
473c6bd008Smiod  *    "This product includes software developed by the OpenSSL Project
483c6bd008Smiod  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
493c6bd008Smiod  *
503c6bd008Smiod  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
513c6bd008Smiod  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
523c6bd008Smiod  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
533c6bd008Smiod  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
543c6bd008Smiod  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
553c6bd008Smiod  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
563c6bd008Smiod  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
573c6bd008Smiod  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
583c6bd008Smiod  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
593c6bd008Smiod  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
603c6bd008Smiod  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
613c6bd008Smiod  * OF THE POSSIBILITY OF SUCH DAMAGE.
623c6bd008Smiod  * ====================================================================
633c6bd008Smiod  *
643c6bd008Smiod  * This product includes cryptographic software written by Eric Young
653c6bd008Smiod  * (eay@cryptsoft.com).  This product includes software written by Tim
663c6bd008Smiod  * Hudson (tjh@cryptsoft.com).
673c6bd008Smiod  *
683c6bd008Smiod  */
693c6bd008Smiod 
7023b02498Stb #include <err.h>
713c6bd008Smiod #include <stdio.h>
723c6bd008Smiod #include <stdlib.h>
733c6bd008Smiod #include <string.h>
743c6bd008Smiod 
753c6bd008Smiod #include <openssl/bn.h>
763c6bd008Smiod #include <openssl/objects.h>
773c6bd008Smiod #include <openssl/sha.h>
783c6bd008Smiod #include <openssl/err.h>
793c6bd008Smiod 
803c6bd008Smiod #include <openssl/ec.h>
813c6bd008Smiod #include <openssl/ecdh.h>
823c6bd008Smiod 
8323b02498Stb static void
8423b02498Stb hexdump(const unsigned char *buf, size_t len)
8523b02498Stb {
8623b02498Stb 	size_t i;
8723b02498Stb 
8823b02498Stb 	for (i = 1; i <= len; i++)
8923b02498Stb 		fprintf(stdout, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
9023b02498Stb 
9123b02498Stb 	if (len % 8)
9223b02498Stb 		fprintf(stdout, "\n");
9323b02498Stb }
9423b02498Stb 
95e2a6b165Sjsing static void *
96e2a6b165Sjsing KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
973c6bd008Smiod {
985c040a06Stb #ifdef OPENSSL_NO_SHA
995c040a06Stb 	return NULL;
1005c040a06Stb #else
1013c6bd008Smiod 	if (*outlen < SHA_DIGEST_LENGTH)
1023c6bd008Smiod 		return NULL;
1033c6bd008Smiod 	*outlen = SHA_DIGEST_LENGTH;
1043c6bd008Smiod 	return SHA1(in, inlen, out);
1053c6bd008Smiod #endif
1063c6bd008Smiod }
1073c6bd008Smiod 
108e2a6b165Sjsing static int
10923b02498Stb ecdh_keygen_test(int nid)
1103c6bd008Smiod {
11123b02498Stb 	EC_KEY *keya = NULL, *keyb = NULL;
11223b02498Stb 	const EC_POINT *puba, *pubb;
1133c6bd008Smiod 	unsigned char *abuf = NULL, *bbuf = NULL;
1145c040a06Stb 	int len = SHA_DIGEST_LENGTH;
11523b02498Stb 	int failed = 1;
1163c6bd008Smiod 
11723b02498Stb 	if ((keya = EC_KEY_new_by_curve_name(nid)) == NULL)
11823b02498Stb 		goto err;
11923b02498Stb 	if (!EC_KEY_generate_key(keya))
12023b02498Stb 		goto err;
12123b02498Stb 	if ((puba = EC_KEY_get0_public_key(keya)) == NULL)
1223c6bd008Smiod 		goto err;
1233c6bd008Smiod 
12423b02498Stb 	if ((keyb = EC_KEY_new_by_curve_name(nid)) == NULL)
125e2a6b165Sjsing 		goto err;
12623b02498Stb 	if (!EC_KEY_generate_key(keyb))
127e2a6b165Sjsing 		goto err;
12823b02498Stb 	if ((pubb = EC_KEY_get0_public_key(keyb)) == NULL)
129e2a6b165Sjsing 		goto err;
1303c6bd008Smiod 
13123b02498Stb 	if ((abuf = calloc(1, len)) == NULL)
13223b02498Stb 		goto err;
13323b02498Stb 	if ((bbuf = calloc(1, len)) == NULL)
134e2a6b165Sjsing 		goto err;
1353c6bd008Smiod 
13623b02498Stb 	if (ECDH_compute_key(abuf, len, pubb, keya, KDF1_SHA1) != len)
13723b02498Stb 		goto err;
13823b02498Stb 	if (ECDH_compute_key(bbuf, len, puba, keyb, KDF1_SHA1) != len)
139e2a6b165Sjsing 		goto err;
1403c6bd008Smiod 
14123b02498Stb 	if (memcmp(abuf, bbuf, len) != 0) {
14223b02498Stb 		printf("key generation with %s failed\n", OBJ_nid2sn(nid));
1433c6bd008Smiod 
14423b02498Stb 		EC_KEY_print_fp(stdout, keya, 1);
14523b02498Stb 		printf(" shared secret:\n");
14623b02498Stb 		hexdump(abuf, len);
1473c6bd008Smiod 
14823b02498Stb 		EC_KEY_print_fp(stdout, keyb, 1);
14923b02498Stb 		printf(" shared secret:\n");
150f8783f21Stb 		hexdump(bbuf, len);
1513c6bd008Smiod 
1523c6bd008Smiod 		fprintf(stderr, "Error in ECDH routines\n");
15323b02498Stb 
15423b02498Stb 		goto err;
1553c6bd008Smiod 	}
156e7bd14d7Sjsing 
15723b02498Stb 	failed = 0;
158f8783f21Stb 
1593c6bd008Smiod  err:
1603c6bd008Smiod 	ERR_print_errors_fp(stderr);
1613c6bd008Smiod 
16223b02498Stb 	EC_KEY_free(keya);
16323b02498Stb 	EC_KEY_free(keyb);
16423b02498Stb 	freezero(abuf, len);
16523b02498Stb 	freezero(bbuf, len);
1662f13a30dSjsing 
16723b02498Stb 	return failed;
1683c6bd008Smiod }
1693c6bd008Smiod 
17023b02498Stb static const struct ecdh_kat_test {
17123b02498Stb     const int nid;
17223b02498Stb     const char *keya;
17323b02498Stb     const char *keyb;
17423b02498Stb     const char *want;
17523b02498Stb } ecdh_kat_tests[] = {
17623b02498Stb 	/* Keys and shared secrets from RFC 5114 */
17723b02498Stb 	{
17823b02498Stb 		.nid =	NID_secp224r1,
17923b02498Stb 		.keya =	"b558eb6c288da707bbb4f8fbae2ab9e9cb62e3bc5c7573e2"
18023b02498Stb 			"2e26d37f",
18123b02498Stb 		.keyb =	"ac3b1add3d9770e6f6a708ee9f3b8e0ab3b480e9f27f85c8"
18223b02498Stb 			"8b5e6d18",
18323b02498Stb 		.want =	"52272f50f46f4edc9151569092f46df2d96ecc3b6dc1714a"
18423b02498Stb 			"4ea949fa",
18523b02498Stb 	},
18623b02498Stb 	{
18723b02498Stb 		.nid =	NID_X9_62_prime256v1,
18823b02498Stb 		.keya =	"814264145f2f56f2e96a8e337a1284993faf432a5abce59e"
18923b02498Stb 			"867b7291d507a3af",
19023b02498Stb 		.keyb =	"2ce1788ec197e096db95a200cc0ab26a19ce6bccad562b8e"
19123b02498Stb 			"ee1b593761cf7f41",
19223b02498Stb 		.want =	"dd0f5396219d1ea393310412d19a08f1f5811e9dc8ec8eea"
19323b02498Stb 			"7f80d21c820c2788",
19423b02498Stb 	},
19523b02498Stb 	{
19623b02498Stb 		.nid =	NID_secp384r1,
19723b02498Stb 		.keya =	"d27335ea71664af244dd14e9fd1260715dfd8a7965571c48"
19823b02498Stb 			"d709ee7a7962a156d706a90cbcb5df2986f05feadb9376f1",
19923b02498Stb 		.keyb =	"52d1791fdb4b70f89c0f00d456c2f7023b6125262c36a7df"
20023b02498Stb 			"1f80231121cce3d39be52e00c194a4132c4a6c768bcd94d2",
20123b02498Stb 		.want =	"5ea1fc4af7256d2055981b110575e0a8cae53160137d904c"
20223b02498Stb 			"59d926eb1b8456e427aa8a4540884c37de159a58028abc0e",
20323b02498Stb 	},
20423b02498Stb 	{
20523b02498Stb 		.nid =	NID_secp521r1,
20623b02498Stb 		.keya =	"0113f82da825735e3d97276683b2b74277bad27335ea7166"
20723b02498Stb 			"4af2430cc4f33459b9669ee78b3ffb9b8683015d344dcbfe"
20823b02498Stb 			"f6fb9af4c6c470be254516cd3c1a1fb47362",
20923b02498Stb 		.keyb =	"00cee3480d8645a17d249f2776d28bae616952d1791fdb4b"
21023b02498Stb 			"70f7c3378732aa1b22928448bcd1dc2496d435b01048066e"
21123b02498Stb 			"be4f72903c361b1a9dc1193dc2c9d0891b96",
21223b02498Stb 		.want =	"00cdea89621cfa46b132f9e4cfe2261cde2d4368eb565663"
21323b02498Stb 			"4c7cc98c7a00cde54ed1866a0dd3e6126c9d2f845daff82c"
21423b02498Stb 			"eb1da08f5d87521bb0ebeca77911169c20cc",
21523b02498Stb 	},
21623b02498Stb 	/* Keys and shared secrets from RFC 5903 */
21723b02498Stb 	{
21823b02498Stb 		.nid =	NID_X9_62_prime256v1,
21923b02498Stb 		.keya =	"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049"
22023b02498Stb 			"c62a9c57862d1433",
22123b02498Stb 		.keyb =	"c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0"
22223b02498Stb 			"b283ab46476bee53",
22323b02498Stb 		.want =	"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03"
22423b02498Stb 			"812464d04b9442de",
22523b02498Stb 	},
22623b02498Stb 	{
22723b02498Stb 		.nid =	NID_secp384r1,
22823b02498Stb 		.keya =	"099f3c7034d4a2c699884d73a375a67f7624ef7c6b3c0f16"
22923b02498Stb 			"0647b67414dce655e35b538041e649ee3faef896783ab194",
23023b02498Stb 		.keyb =	"41cb0779b4bdb85d47846725fbec3c9430fab46cc8dc5060"
23123b02498Stb 			"855cc9bda0aa2942e0308312916b8ed2960e4bd55a7448fc",
23223b02498Stb 		.want =	"11187331c279962d93d604243fd592cb9d0a926f422e4718"
23323b02498Stb 			"7521287e7156c5c4d603135569b9e9d09cf5d4a270f59746",
23423b02498Stb 	},
23523b02498Stb 	{
23623b02498Stb 		.nid =	NID_secp521r1,
23723b02498Stb 		.keya =	"0037ade9319a89f4dabdb3ef411aaccca5123c61acab57b5"
23823b02498Stb 			"393dce47608172a095aa85a30fe1c2952c6771d937ba9777"
23923b02498Stb 			"f5957b2639bab072462f68c27a57382d"
24023b02498Stb 			"4a52",
24123b02498Stb 		.keyb =	"0145ba99a847af43793fdd0e872e7cdfa16be30fdc780f97"
24223b02498Stb 			"bccc3f078380201e9c677d600b343757a3bdbf2a3163e4c2"
24323b02498Stb 			"f869cca7458aa4a4effc311f5cb151685eb9",
24423b02498Stb 		.want =	"01144c7d79ae6956bc8edb8e7c787c4521cb086fa64407f9"
24523b02498Stb 			"7894e5e6b2d79b04d1427e73ca4baa240a34786859810c06"
24623b02498Stb 			"b3c715a3a8cc3151f2bee417996d19f3ddea",
24723b02498Stb 	},
248be0309a4Smiod 	/* Keys and shared secrets from RFC 7027 */
24923b02498Stb 	{
25023b02498Stb 		.nid =	NID_brainpoolP256r1,
25123b02498Stb 		.keya =	"81db1ee100150ff2ea338d708271be38300cb54241d79950"
25223b02498Stb 			"f77b063039804f1d",
25323b02498Stb 		.keyb =	"55e40bc41e37e3e2ad25c3c6654511ffa8474a91a0032087"
25423b02498Stb 			"593852d3e7d76bd3",
25523b02498Stb 		.want =	"89afc39d41d3b327814b80940b042590f96556ec91e6ae79"
25623b02498Stb 			"39bce31f3a18bf2b",
25723b02498Stb 	},
25823b02498Stb 	{
25923b02498Stb 		.nid =	NID_brainpoolP384r1,
26023b02498Stb 		.keya =	"1e20f5e048a5886f1f157c74e91bde2b98c8b52d58e5003d"
26123b02498Stb 			"57053fc4b0bd65d6f15eb5d1ee1610df870795143627d042",
26223b02498Stb 		.keyb =	"032640bc6003c59260f7250c3db58ce647f98e1260acce4a"
26323b02498Stb 			"cda3dd869f74e01f8ba5e0324309db6a9831497abac96670",
26423b02498Stb 		.want =	"0bd9d3a7ea0b3d519d09d8e48d0785fb744a6b355e6304bc"
26523b02498Stb 			"51c229fbbce239bbadf6403715c35d4fb2a5444f575d4f42",
26623b02498Stb 	},
26723b02498Stb 	{
26823b02498Stb 		.nid =	NID_brainpoolP512r1,
26923b02498Stb 		.keya =	"16302ff0dbbb5a8d733dab7141c1b45acbc8715939677f6a"
27023b02498Stb 			"56850a38bd87bd59b09e80279609ff333eb9d4c061231fb2"
27123b02498Stb 			"6f92eeb04982a5f1d1764cad57665422",
27223b02498Stb 		.keyb =	"230e18e1bcc88a362fa54e4ea3902009292f7f8033624fd4"
27323b02498Stb 			"71b5d8ace49d12cfabbc19963dab8e2f1eba00bffb29e4d7"
27423b02498Stb 			"2d13f2224562f405cb80503666b25429",
27523b02498Stb 		.want =	"a7927098655f1f9976fa50a9d566865dc530331846381c87"
27623b02498Stb 			"256baf3226244b76d36403c024d7bbf0aa0803eaff405d3d"
27723b02498Stb 			"24f11a9b5c0bef679fe1454b21c4cd1f",
27823b02498Stb 	},
279be0309a4Smiod };
280be0309a4Smiod 
28123b02498Stb #define N_KATS (sizeof(ecdh_kat_tests) / sizeof(ecdh_kat_tests[0]))
282be0309a4Smiod 
283be0309a4Smiod /* Given private value and NID, create EC_KEY structure */
284be0309a4Smiod 
285e2a6b165Sjsing static EC_KEY *
28623b02498Stb mk_eckey(int nid, const char *priv_str)
287be0309a4Smiod {
28823b02498Stb 	EC_KEY *key = NULL;
289be0309a4Smiod 	BIGNUM *priv = NULL;
290be0309a4Smiod 	EC_POINT *pub = NULL;
29123b02498Stb 	const EC_GROUP *group;
29223b02498Stb 	EC_KEY *ret = NULL;
2932f13a30dSjsing 
29423b02498Stb 	if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
295be0309a4Smiod 		goto err;
29623b02498Stb 	if (!BN_hex2bn(&priv, priv_str))
297be0309a4Smiod 		goto err;
29823b02498Stb 	if (!EC_KEY_set_private_key(key, priv))
299be0309a4Smiod 		goto err;
30023b02498Stb 	if ((group = EC_KEY_get0_group(key)) == NULL)
301be0309a4Smiod 		goto err;
30223b02498Stb 	if ((pub = EC_POINT_new(group)) == NULL)
303be0309a4Smiod 		goto err;
30423b02498Stb 	if (!EC_POINT_mul(group, pub, priv, NULL, NULL, NULL))
305be0309a4Smiod 		goto err;
30623b02498Stb 	if (!EC_KEY_set_public_key(key, pub))
30723b02498Stb 		goto err;
30823b02498Stb 
30923b02498Stb 	ret = key;
31023b02498Stb 	key = NULL;
31123b02498Stb 
312be0309a4Smiod  err:
31323b02498Stb 	EC_KEY_free(key);
31446c2b081Stb 	BN_free(priv);
315be0309a4Smiod 	EC_POINT_free(pub);
31623b02498Stb 
31723b02498Stb 	return ret;
318be0309a4Smiod }
319be0309a4Smiod 
32023b02498Stb /*
32123b02498Stb  * Known answer test: compute shared secret and check it matches expected value.
322be0309a4Smiod  */
323e2a6b165Sjsing static int
32423b02498Stb ecdh_kat(const struct ecdh_kat_test *kat)
325be0309a4Smiod {
32623b02498Stb 	EC_KEY *keya = NULL, *keyb = NULL;
32723b02498Stb 	const EC_POINT *puba, *pubb;
32823b02498Stb 	BIGNUM *z = NULL;
32923b02498Stb 	unsigned char *want = NULL, *got = NULL;
33023b02498Stb 	int len = 0;
331f8783f21Stb 	int failed = 1;
33223b02498Stb 
33323b02498Stb 	if ((keya = mk_eckey(kat->nid, kat->keya)) == NULL)
334be0309a4Smiod 		goto err;
33523b02498Stb 	if ((puba = EC_KEY_get0_public_key(keya)) == NULL)
336be0309a4Smiod 		goto err;
33723b02498Stb 	if ((keyb = mk_eckey(kat->nid, kat->keyb)) == NULL)
338062268a7Stb 		goto err;
33923b02498Stb 	if ((pubb = EC_KEY_get0_public_key(keyb)) == NULL)
340be0309a4Smiod 		goto err;
34123b02498Stb 
34223b02498Stb 	if ((len = ECDH_size(keya)) != ECDH_size(keyb))
343be0309a4Smiod 		goto err;
34423b02498Stb 
34523b02498Stb 	if ((want = calloc(1, len)) == NULL)
346be0309a4Smiod 		goto err;
34723b02498Stb 	if ((got = calloc(1, len)) == NULL)
348be0309a4Smiod 		goto err;
34923b02498Stb 
35023b02498Stb 	if (!BN_hex2bn(&z, kat->want))
35123b02498Stb 		goto err;
35223b02498Stb 	if (BN_num_bytes(z) > len)
35323b02498Stb 		goto err;
35423b02498Stb 	if (BN_bn2binpad(z, want, len) != len)
35523b02498Stb 		goto err;
35623b02498Stb 
35723b02498Stb 	if (ECDH_compute_key(got, len, pubb, keya, NULL) != len)
35823b02498Stb 		goto err;
35923b02498Stb 	if (memcmp(got, want, len) != 0)
36023b02498Stb 		goto err;
36123b02498Stb 
36223b02498Stb 	memset(got, 0, len);
36323b02498Stb 
36423b02498Stb 	if (ECDH_compute_key(got, len, puba, keyb, NULL) != len)
36523b02498Stb 		goto err;
36623b02498Stb 	if (memcmp(got, want, len) != 0)
36723b02498Stb 		goto err;
36823b02498Stb 
36923b02498Stb 	failed = 0;
3702f13a30dSjsing 
371be0309a4Smiod  err:
37223b02498Stb 	if (failed) {
373f8783f21Stb 		printf("shared secret with %s failed", OBJ_nid2sn(kat->nid));
37423b02498Stb 
375be0309a4Smiod 		fprintf(stderr, "Error in ECDH routines\n");
376be0309a4Smiod 		ERR_print_errors_fp(stderr);
377be0309a4Smiod 	}
3782f13a30dSjsing 
37923b02498Stb 	EC_KEY_free(keya);
38023b02498Stb 	EC_KEY_free(keyb);
38123b02498Stb 	BN_free(z);
38223b02498Stb 	freezero(want, len);
38323b02498Stb 	freezero(got, len);
3842f13a30dSjsing 
38523b02498Stb 	return failed;
386be0309a4Smiod }
387be0309a4Smiod 
388e2a6b165Sjsing int
389f8783f21Stb main(void)
3903c6bd008Smiod {
39123b02498Stb 	EC_builtin_curve *curves = NULL;
39223b02498Stb 	size_t i, n_curves;
39323b02498Stb 	int failed = 0;
3943c6bd008Smiod 
39523b02498Stb 	if ((n_curves = EC_get_builtin_curves(NULL, 0)) == 0)
39623b02498Stb 		errx(1, "EC_get_builtin_curves failed");
39723b02498Stb 	if ((curves = calloc(n_curves, sizeof(*curves))) == NULL)
39823b02498Stb 		errx(1, NULL);
39923b02498Stb 	if (EC_get_builtin_curves(curves, n_curves) != n_curves)
40023b02498Stb 		errx(1, "EC_get_builtin_curves failed");
4013c6bd008Smiod 
40223b02498Stb 	for (i = 0; i < n_curves; i++)
40323b02498Stb 		failed |= ecdh_keygen_test(curves[i].nid);
4043c6bd008Smiod 
40523b02498Stb 	for (i = 0; i < N_KATS; i++)
40623b02498Stb 		failed |= ecdh_kat(&ecdh_kat_tests[i]);
4073c6bd008Smiod 
40823b02498Stb 	free(curves);
4093c6bd008Smiod 	ERR_print_errors_fp(stderr);
41023b02498Stb 
41123b02498Stb 	return failed;
4123c6bd008Smiod }
413