xref: /openbsd-src/regress/lib/libcrypto/ec/ec_asn1_test.c (revision 35671554a3f71a3620dfbda5649acdb27119f8c8)
1 /* $OpenBSD: ec_asn1_test.c,v 1.31 2024/12/24 18:32:31 tb Exp $ */
2 /*
3  * Copyright (c) 2017, 2021 Joel Sing <jsing@openbsd.org>
4  * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <err.h>
20 #include <string.h>
21 
22 #include <openssl/bio.h>
23 #include <openssl/ec.h>
24 #include <openssl/err.h>
25 #include <openssl/objects.h>
26 
27 /* set to 0 if/when we are going to enforce 0 <= a,b < p. */
28 #define NEGATIVE_CURVE_COEFFICIENTS_ALLOWED	1
29 
30 static const uint8_t ec_secp256r1_pkparameters_named_curve[] = {
31 	0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03,
32 	0x01, 0x07,
33 };
34 
35 static const uint8_t ec_secp256r1_pkparameters_parameters[] = {
36 	0x30, 0x81, 0xf7, 0x02, 0x01, 0x01, 0x30, 0x2c,
37 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
38 	0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff,
39 	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
40 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
42 	0xff, 0xff, 0xff, 0xff, 0x30, 0x5b, 0x04, 0x20,
43 	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
44 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
46 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
47 	0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a,
48 	0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98,
49 	0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
50 	0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2,
51 	0x60, 0x4b, 0x03, 0x15, 0x00, 0xc4, 0x9d, 0x36,
52 	0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
53 	0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e,
54 	0x90, 0x04, 0x41, 0x04, 0x6b, 0x17, 0xd1, 0xf2,
55 	0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
56 	0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81,
57 	0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45,
58 	0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
59 	0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
60 	0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
61 	0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
62 	0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff,
63 	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
64 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
65 	0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3,
66 	0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51, 0x02,
67 	0x01, 0x01,
68 };
69 
70 static const uint8_t ec_secp256k1_pkparameters_parameters[] = {
71 	0x30, 0x81, 0xe0, 0x02, 0x01, 0x01, 0x30, 0x2c,
72 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
73 	0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff,
74 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
75 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
76 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
77 	0xff, 0xff, 0xfc, 0x2f, 0x30, 0x44, 0x04, 0x20,
78 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 	0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 	0x00, 0x07, 0x04, 0x41, 0x04, 0x79, 0xbe, 0x66,
87 	0x7e, 0xf9, 0xdc, 0xbb, 0xac, 0x55, 0xa0, 0x62,
88 	0x95, 0xce, 0x87, 0x0b, 0x07, 0x02, 0x9b, 0xfc,
89 	0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59, 0xf2, 0x81,
90 	0x5b, 0x16, 0xf8, 0x17, 0x98, 0x48, 0x3a, 0xda,
91 	0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb,
92 	0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4,
93 	0x48, 0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0,
94 	0x8f, 0xfb, 0x10, 0xd4, 0xb8, 0x02, 0x21, 0x00,
95 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
96 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
97 	0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
98 	0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
99 	0x02, 0x01, 0x01,
100 };
101 
102 static void
103 hexdump(const unsigned char *buf, size_t len)
104 {
105 	size_t i;
106 
107 	for (i = 1; i <= len; i++)
108 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
109 
110 	fprintf(stderr, "\n");
111 }
112 
113 static int
114 compare_data(const char *label, const unsigned char *d1, size_t d1_len,
115     const unsigned char *d2, size_t d2_len)
116 {
117 	if (d1_len != d2_len) {
118 		fprintf(stderr, "FAIL: got %s with length %zu, want %zu\n",
119 		    label, d1_len, d2_len);
120 		return -1;
121 	}
122 	if (memcmp(d1, d2, d1_len) != 0) {
123 		fprintf(stderr, "FAIL: %s differ\n", label);
124 		fprintf(stderr, "got:\n");
125 		hexdump(d1, d1_len);
126 		fprintf(stderr, "want:\n");
127 		hexdump(d2, d2_len);
128 		return -1;
129 	}
130 	return 0;
131 }
132 
133 static int
134 ec_group_pkparameters_test(const char *label, int nid, int asn1_flag,
135     const uint8_t *test_data, size_t test_data_len)
136 {
137 	EC_GROUP *group_a = NULL, *group_b = NULL;
138 	unsigned char *out = NULL, *data = NULL;
139 	const unsigned char *p;
140 	BIO *bio_mem = NULL;
141 	int failure = 1;
142 	int len;
143 
144 	/*
145 	 * Test i2d_ECPKParameters/d2i_ECPKParameters.
146 	 */
147 	if ((group_a = EC_GROUP_new_by_curve_name(nid)) == NULL)
148 		errx(1, "failed to create EC_GROUP");
149 
150 	EC_GROUP_set_asn1_flag(group_a, asn1_flag);
151 
152 	if ((len = i2d_ECPKParameters(group_a, &out)) < 0) {
153 		fprintf(stderr, "FAIL: i2d_ECPKParameters failed\n");
154 		goto done;
155 	}
156 	if (compare_data(label, out, len, test_data, test_data_len) == -1)
157 		goto done;
158 
159 	p = out;
160 	if ((group_b = d2i_ECPKParameters(NULL, &p, len)) == NULL) {
161 		fprintf(stderr, "FAIL: d2i_ECPKParameters failed\n");
162 		goto done;
163 	}
164 
165 	if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) {
166 		fprintf(stderr, "FAIL: EC_GROUPs do not match!\n");
167 		goto done;
168 	}
169 
170 	p = out;
171 	if ((group_a = d2i_ECPKParameters(&group_a, &p, len)) == NULL) {
172 		fprintf(stderr, "FAIL: d2i_ECPKParameters failed\n");
173 		goto done;
174 	}
175 
176 	if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) {
177 		fprintf(stderr, "FAIL: EC_GROUPs do not match!\n");
178 		goto done;
179 	}
180 
181 	/*
182 	 * Test i2d_ECPKParameters_bio/d2i_ECPKParameters_bio.
183 	 */
184 	if ((bio_mem = BIO_new(BIO_s_mem())) == NULL)
185                 errx(1, "BIO_new failed for BIO_s_mem");
186 
187 	if (i2d_ECPKParameters_bio(bio_mem, group_a) < 0) {
188 		fprintf(stderr, "FAIL: i2d_ECPKParameters_bio failed\n");
189 		goto done;
190 	}
191 
192 	len = BIO_get_mem_data(bio_mem, &data);
193 	if (compare_data(label, out, len, test_data, test_data_len) == -1)
194 		goto done;
195 
196 	EC_GROUP_free(group_b);
197 	if ((group_b = d2i_ECPKParameters_bio(bio_mem, NULL)) == NULL) {
198 		fprintf(stderr, "FAIL: d2i_ECPKParameters_bio failed\n");
199 		goto done;
200 	}
201 
202 	if (EC_GROUP_cmp(group_a, group_b, NULL) != 0) {
203 		fprintf(stderr, "FAIL: EC_GROUPs do not match!\n");
204 		goto done;
205 	}
206 
207 	failure = 0;
208 
209  done:
210 	BIO_free_all(bio_mem);
211 	EC_GROUP_free(group_a);
212 	EC_GROUP_free(group_b);
213 	free(out);
214 
215 	return failure;
216 }
217 
218 static int
219 ec_group_pkparameters_named_curve_test(void)
220 {
221 	return ec_group_pkparameters_test("ECPKPARAMETERS named curve",
222 	    NID_X9_62_prime256v1, OPENSSL_EC_NAMED_CURVE,
223 	    ec_secp256r1_pkparameters_named_curve,
224 	    sizeof(ec_secp256r1_pkparameters_named_curve));
225 }
226 
227 static int
228 ec_group_pkparameters_parameters_test(void)
229 {
230 	return ec_group_pkparameters_test("ECPKPARAMETERS parameters",
231 	    NID_X9_62_prime256v1, OPENSSL_EC_EXPLICIT_CURVE,
232 	    ec_secp256r1_pkparameters_parameters,
233 	    sizeof(ec_secp256r1_pkparameters_parameters));
234 }
235 
236 static int
237 ec_group_pkparameters_correct_padding_test(void)
238 {
239 	return ec_group_pkparameters_test("ECPKPARAMETERS parameters",
240 	    NID_secp256k1, OPENSSL_EC_EXPLICIT_CURVE,
241 	    ec_secp256k1_pkparameters_parameters,
242 	    sizeof(ec_secp256k1_pkparameters_parameters));
243 }
244 
245 static EC_GROUP *
246 ec_group_simple_from_builtin(const EC_GROUP *group, int nid, BN_CTX *ctx)
247 {
248 	EC_GROUP *simple_group;
249 	BIGNUM *p, *a, *b, *x, *y, *order, *cofactor;
250 	const EC_POINT *generator;
251 	EC_POINT *simple_generator = NULL;
252 
253 	BN_CTX_start(ctx);
254 
255 	if ((p = BN_CTX_get(ctx)) == NULL)
256 		errx(1, "BN_CTX_get");
257 	if ((a = BN_CTX_get(ctx)) == NULL)
258 		errx(1, "BN_CTX_get");
259 	if ((b = BN_CTX_get(ctx)) == NULL)
260 		errx(1, "BN_CTX_get");
261 
262 	if ((x = BN_CTX_get(ctx)) == NULL)
263 		errx(1, "BN_CTX_get");
264 	if ((y = BN_CTX_get(ctx)) == NULL)
265 		errx(1, "BN_CTX_get");
266 
267 	if ((order = BN_CTX_get(ctx)) == NULL)
268 		errx(1, "BN_CTX_get");
269 	if ((cofactor = BN_CTX_get(ctx)) == NULL)
270 		errx(1, "BN_CTX_get");
271 
272 	if (!EC_GROUP_get_curve(group, p, a, b, ctx))
273 		errx(1, "EC_GROUP_get_curve");
274 	if (!EC_GROUP_get_order(group, order, ctx))
275 		errx(1, "EC_GROUP_get_order");
276 	if (!EC_GROUP_get_cofactor(group, cofactor, ctx))
277 		errx(1, "EC_GROUP_get_cofactor");
278 	if ((generator = EC_GROUP_get0_generator(group)) == NULL)
279 		errx(1, "EC_GROUP_get0_generator");
280 	if (!EC_POINT_get_affine_coordinates(group, generator, x, y, ctx))
281 		errx(1, "EC_POINT_get_affine_coordinates");
282 
283 	if ((simple_group = EC_GROUP_new(EC_GFp_simple_method())) == NULL)
284 		errx(1, "EC_GROUP_new");
285 	if (!EC_GROUP_set_curve(simple_group, p, a, b, ctx))
286 		errx(1, "EC_GROUP_set_curve");
287 	EC_GROUP_set_curve_name(simple_group, nid);
288 
289 	if ((simple_generator = EC_POINT_new(simple_group)) == NULL)
290 		errx(1, "EC_POINT_new");
291 	if (!EC_POINT_set_compressed_coordinates(simple_group, simple_generator,
292 	    x, BN_is_odd(y), ctx))
293 		errx(1, "EC_POINT_set_affine_coordinates");
294 	if (!EC_GROUP_set_generator(simple_group, simple_generator, order,
295 	    cofactor))
296 		errx(1, "EC_GROUP_set_generator");
297 
298 	BN_CTX_end(ctx);
299 
300 	EC_POINT_free(simple_generator);
301 
302 	return simple_group;
303 }
304 
305 static int
306 ec_group_roundtrip_curve(const EC_GROUP *group, const char *descr, int nid)
307 {
308 	EC_GROUP *new_group = NULL;
309 	unsigned char *der = NULL, *new_der = NULL;
310 	int der_len = 0, new_der_len = 0;
311 	const unsigned char *p;
312 	int failed = 1;
313 
314 	der = NULL;
315 	if ((der_len = i2d_ECPKParameters(group, &der)) <= 0)
316 		errx(1, "failed to serialize %s %d", descr, nid);
317 
318 	p = der;
319 	if ((new_group = d2i_ECPKParameters(NULL, &p, der_len)) == NULL)
320 		errx(1, "failed to deserialize %s %d", descr, nid);
321 
322 	new_der = NULL;
323 	if ((new_der_len = i2d_ECPKParameters(new_group, &new_der)) <= 0)
324 		errx(1, "failed to serialize new %s %d", descr, nid);
325 
326 	if (compare_data(__func__, der, der_len, new_der, new_der_len) == -1) {
327 		fprintf(stderr, "FAIL: new and old der for %s %d\n", descr, nid);
328 		goto err;
329 	}
330 
331 	if (EC_GROUP_method_of(group) == EC_GFp_mont_method()) {
332 		if (EC_GROUP_cmp(group, new_group, NULL) != 0) {
333 			fprintf(stderr, "FAIL: %s %d groups mismatch\n", descr, nid);
334 			goto err;
335 		}
336 	}
337 	if (EC_GROUP_get_asn1_flag(group) != EC_GROUP_get_asn1_flag(new_group)) {
338 		fprintf(stderr, "FAIL: %s %d asn1_flag %x != %x\n", descr, nid,
339 		    EC_GROUP_get_asn1_flag(group),
340 		    EC_GROUP_get_asn1_flag(new_group));
341 		goto err;
342 	}
343 	if (EC_GROUP_get_point_conversion_form(group) !=
344 	    EC_GROUP_get_point_conversion_form(new_group)) {
345 		fprintf(stderr, "FAIL: %s %d form %02x != %02x\n", descr, nid,
346 		    EC_GROUP_get_point_conversion_form(group),
347 		    EC_GROUP_get_point_conversion_form(new_group));
348 		goto err;
349 	}
350 
351 	failed = 0;
352 
353  err:
354 	EC_GROUP_free(new_group);
355 	freezero(der, der_len);
356 	freezero(new_der, new_der_len);
357 
358 	return failed;
359 }
360 
361 static int
362 ec_group_roundtrip_group(EC_GROUP *group, int nid)
363 {
364 	int failed = 1;
365 
366 	if (EC_GROUP_get_asn1_flag(group) != OPENSSL_EC_NAMED_CURVE) {
367 		fprintf(stderr, "FAIL: ASN.1 flag not set for %d\n", nid);
368 		goto err;
369 	}
370 	if (EC_GROUP_get_point_conversion_form(group) !=
371 	    POINT_CONVERSION_UNCOMPRESSED) {
372 		fprintf(stderr, "FAIL: %d has point conversion form %02x\n",
373 		    nid, EC_GROUP_get_point_conversion_form(group));
374 		goto err;
375 	}
376 
377 	failed = 0;
378 
379 	failed |= ec_group_roundtrip_curve(group, "named", nid);
380 
381 	EC_GROUP_set_asn1_flag(group, 0);
382 	failed |= ec_group_roundtrip_curve(group, "explicit", nid);
383 
384 	EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_COMPRESSED);
385 	failed |= ec_group_roundtrip_curve(group, "compressed", nid);
386 
387 	EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_HYBRID);
388 	failed |= ec_group_roundtrip_curve(group, "hybrid", nid);
389 
390  err:
391 	return failed;
392 }
393 
394 static int
395 ec_group_roundtrip_builtin_curve(const EC_builtin_curve *curve, BN_CTX *ctx)
396 {
397 	EC_GROUP *group = NULL, *simple_group = NULL;
398 	int failed = 0;
399 
400 	if ((group = EC_GROUP_new_by_curve_name(curve->nid)) == NULL)
401 		errx(1, "failed to instantiate curve %d", curve->nid);
402 
403 	if (!EC_GROUP_check(group, NULL)) {
404 		fprintf(stderr, "FAIL: EC_GROUP_check(%d) failed\n", curve->nid);
405 		goto err;
406 	}
407 
408 	if ((simple_group = ec_group_simple_from_builtin(group, curve->nid,
409 	    ctx)) == NULL)
410 		errx(1, "failed to instantiate simple group %d", curve->nid);
411 
412 	if (!EC_GROUP_check(group, NULL)) {
413 		fprintf(stderr, "FAIL: EC_GROUP_check(%d) failed\n", curve->nid);
414 		goto err;
415 	}
416 
417 	failed |= ec_group_roundtrip_group(group, curve->nid);
418 	failed |= ec_group_roundtrip_group(simple_group, curve->nid);
419 
420  err:
421 	EC_GROUP_free(group);
422 	EC_GROUP_free(simple_group);
423 
424 	return failed;
425 }
426 
427 static int
428 ec_group_roundtrip_builtin_curves(void)
429 {
430 	BN_CTX *ctx = NULL;
431 	EC_builtin_curve *all_curves = NULL;
432 	size_t curve_id, ncurves;
433 	int failed = 0;
434 
435 	if ((ctx = BN_CTX_new()) == NULL)
436 		errx(1, "BN_CTX_new");
437 
438 	ncurves = EC_get_builtin_curves(NULL, 0);
439 	if ((all_curves = calloc(ncurves, sizeof(*all_curves))) == NULL)
440 		err(1, "calloc builtin curves");
441 	EC_get_builtin_curves(all_curves, ncurves);
442 
443 	for (curve_id = 0; curve_id < ncurves; curve_id++)
444 		failed |= ec_group_roundtrip_builtin_curve(&all_curves[curve_id], ctx);
445 
446 	free(all_curves);
447 	BN_CTX_free(ctx);
448 
449 	return failed;
450 }
451 
452 struct curve {
453 	const char *descr;
454 	const char *oid;
455 	const char *sn;
456 	const char *ln;
457 	const char *p;
458 	const char *a;
459 	const char *b;
460 	const char *order;
461 	const char *cofactor;
462 	const char *x;
463 	const char *y;
464 	int known_named_curve;
465 	const char *named;
466 	size_t named_len;
467 	const char *param;
468 	size_t param_len;
469 };
470 
471 /*
472  * From draft-ietf-lwig-curve-representation-23, Appendix E.3
473  */
474 
475 static const uint8_t ec_wei25519_pkparameters_named_curve[] = {
476 	0x06, 0x03, 0x2b, 0x65, 0x6c,
477 };
478 
479 static const uint8_t ec_wei25519_pkparameters_parameters[] = {
480 	0x30, 0x81, 0xde, 0x02, 0x01, 0x01, 0x30, 0x2b,
481 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
482 	0x01, 0x02, 0x20, 0x7f, 0xff, 0xff, 0xff, 0xff,
483 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
484 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
485 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
486 	0xff, 0xff, 0xed, 0x30, 0x44, 0x04, 0x20, 0x2a,
487 	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
488 	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
489 	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
490 	0xaa, 0xaa, 0x98, 0x49, 0x14, 0xa1, 0x44, 0x04,
491 	0x20, 0x7b, 0x42, 0x5e, 0xd0, 0x97, 0xb4, 0x25,
492 	0xed, 0x09, 0x7b, 0x42, 0x5e, 0xd0, 0x97, 0xb4,
493 	0x25, 0xed, 0x09, 0x7b, 0x42, 0x5e, 0xd0, 0x97,
494 	0xb4, 0x26, 0x0b, 0x5e, 0x9c, 0x77, 0x10, 0xc8,
495 	0x64, 0x04, 0x41, 0x04, 0x2a, 0xaa, 0xaa, 0xaa,
496 	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
497 	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
498 	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
499 	0xaa, 0xad, 0x24, 0x5a, 0x20, 0xae, 0x19, 0xa1,
500 	0xb8, 0xa0, 0x86, 0xb4, 0xe0, 0x1e, 0xdd, 0x2c,
501 	0x77, 0x48, 0xd1, 0x4c, 0x92, 0x3d, 0x4d, 0x7e,
502 	0x6d, 0x7c, 0x61, 0xb2, 0x29, 0xe9, 0xc5, 0xa2,
503 	0x7e, 0xce, 0xd3, 0xd9, 0x02, 0x20, 0x10, 0x00,
504 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xde,
506 	0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6, 0x58, 0x12,
507 	0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed, 0x02, 0x01,
508 	0x08,
509 };
510 
511 static const struct curve wei25519 = {
512 	.descr = "short Weierstrass 25519",
513 	.oid = "1.3.101.108",
514 	.sn = "Wei25519",
515 	.p =	 "7fffffff" "ffffffff" "ffffffff" "ffffffff"
516 		 "ffffffff" "ffffffff" "ffffffff" "ffffffed",
517 	.a =	 "2aaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
518 		 "aaaaaaaa" "aaaaaaaa" "aaaaaa98" "4914a144",
519 	.b =	 "7b425ed0" "97b425ed" "097b425e" "d097b425"
520 		 "ed097b42" "5ed097b4" "260b5e9c" "7710c864",
521 	.x =	 "2aaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa"
522 		 "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaad245a",
523 	.y =	 "20ae19a1" "b8a086b4" "e01edd2c" "7748d14c"
524 		 "923d4d7e" "6d7c61b2" "29e9c5a2" "7eced3d9",
525 	.order = "10000000" "00000000" "00000000" "00000000"
526 		 "14def9de" "a2f79cd6" "5812631a" "5cf5d3ed",
527 	.cofactor = "8",
528 	.named = ec_wei25519_pkparameters_named_curve,
529 	.named_len = sizeof(ec_wei25519_pkparameters_named_curve),
530 	.param = ec_wei25519_pkparameters_parameters,
531 	.param_len = sizeof(ec_wei25519_pkparameters_parameters),
532 };
533 
534 /*
535  * From draft-ietf-lwig-curve-representation-23, Appendix G.3
536  */
537 
538 static const uint8_t ec_wei25519_2_pkparameters_parameters[] = {
539 	0x30, 0x81, 0xde, 0x02, 0x01, 0x01, 0x30, 0x2b,
540 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
541 	0x01, 0x02, 0x20, 0x7f, 0xff, 0xff, 0xff, 0xff,
542 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
543 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
544 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
545 	0xff, 0xff, 0xed, 0x30, 0x44, 0x04, 0x20, 0x00,
546 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04,
550 	0x20, 0x1a, 0xc1, 0xda, 0x05, 0xb5, 0x5b, 0xc1,
551 	0x46, 0x33, 0xbd, 0x39, 0xe4, 0x7f, 0x94, 0x30,
552 	0x2e, 0xf1, 0x98, 0x43, 0xdc, 0xf6, 0x69, 0x91,
553 	0x6f, 0x6a, 0x5d, 0xfd, 0x01, 0x65, 0x53, 0x8c,
554 	0xd1, 0x04, 0x41, 0x04, 0x17, 0xcf, 0xea, 0xc3,
555 	0x78, 0xae, 0xd6, 0x61, 0x31, 0x8e, 0x86, 0x34,
556 	0x58, 0x22, 0x75, 0xb6, 0xd9, 0xad, 0x4d, 0xef,
557 	0x07, 0x2e, 0xa1, 0x93, 0x5e, 0xe3, 0xc4, 0xe8,
558 	0x7a, 0x94, 0x0f, 0xfa, 0x0c, 0x08, 0xa9, 0x52,
559 	0xc5, 0x5d, 0xfa, 0xd6, 0x2c, 0x4f, 0x13, 0xf1,
560 	0xa8, 0xf6, 0x8d, 0xca, 0xdc, 0x5c, 0x33, 0x1d,
561 	0x29, 0x7a, 0x37, 0xb6, 0xf0, 0xd7, 0xfd, 0xcc,
562 	0x51, 0xe1, 0x6b, 0x4d, 0x02, 0x20, 0x10, 0x00,
563 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xde,
565 	0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6, 0x58, 0x12,
566 	0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed, 0x02, 0x01,
567 	0x08,
568 };
569 
570 static const struct curve wei25519_2 = {
571 	.descr = "short Weierstrass 25519.2",
572 	.oid = "1.3.101.108",
573 	.sn = "Wei25519",
574 	.p =	 "7fffffff" "ffffffff" "ffffffff" "ffffffff"
575 		 "ffffffff" "ffffffff" "ffffffff" "ffffffed",
576 	.a =	 "02",
577 	.b =	 "1ac1da05" "b55bc146" "33bd39e4" "7f94302e"
578 		 "f19843dc" "f669916f" "6a5dfd01" "65538cd1",
579 	.x =	 "17cfeac3" "78aed661" "318e8634" "582275b6"
580 		 "d9ad4def" "072ea193" "5ee3c4e8" "7a940ffa",
581 	.y =	 "0c08a952" "c55dfad6" "2c4f13f1" "a8f68dca"
582 		 "dc5c331d" "297a37b6" "f0d7fdcc" "51e16b4d",
583 	.order = "10000000" "00000000" "00000000" "00000000"
584 		 "14def9de" "a2f79cd6" "5812631a" "5cf5d3ed",
585 	.cofactor = "8",
586 	.named = ec_wei25519_pkparameters_named_curve,
587 	.named_len = sizeof(ec_wei25519_pkparameters_named_curve),
588 	.param = ec_wei25519_2_pkparameters_parameters,
589 	.param_len = sizeof(ec_wei25519_2_pkparameters_parameters),
590 };
591 
592 static const uint8_t ec_wei25519_3_pkparameters_parameters[] = {
593 	0x30, 0x81, 0xde, 0x02, 0x01, 0x01, 0x30, 0x2b,
594 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
595 	0x01, 0x02, 0x20, 0x7f, 0xff, 0xff, 0xff, 0xff,
596 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
597 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
598 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
599 	0xff, 0xff, 0xed, 0x30, 0x44, 0x04, 0x20, 0x7f,
600 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
601 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
602 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
603 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xea, 0x04,
604 	0x20, 0x41, 0xa3, 0xb6, 0xbf, 0xc6, 0x68, 0x77,
605 	0x8e, 0xbe, 0x29, 0x54, 0xa4, 0xb1, 0xdf, 0x36,
606 	0xd1, 0x48, 0x5e, 0xce, 0xf1, 0xea, 0x61, 0x42,
607 	0x95, 0x79, 0x6e, 0x10, 0x22, 0x40, 0x89, 0x1f,
608 	0xaa, 0x04, 0x41, 0x04, 0x77, 0x06, 0xc3, 0x7b,
609 	0x5a, 0x84, 0x12, 0x8a, 0x38, 0x84, 0xa5, 0xd7,
610 	0x18, 0x11, 0xf1, 0xb5, 0x5d, 0xa3, 0x23, 0x0f,
611 	0xfb, 0x17, 0xa8, 0xab, 0x0b, 0x32, 0xe4, 0x8d,
612 	0x31, 0xa6, 0x68, 0x5c, 0x0f, 0x60, 0x48, 0x0c,
613 	0x7a, 0x5c, 0x0e, 0x11, 0x40, 0x34, 0x0a, 0xdc,
614 	0x79, 0xd6, 0xa2, 0xbf, 0x0c, 0xb5, 0x7a, 0xd0,
615 	0x49, 0xd0, 0x25, 0xdc, 0x38, 0xd8, 0x0c, 0x77,
616 	0x98, 0x5f, 0x03, 0x29, 0x02, 0x20, 0x10, 0x00,
617 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xde,
619 	0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6, 0x58, 0x12,
620 	0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed, 0x02, 0x01,
621 	0x08,
622 };
623 
624 static const struct curve wei25519_3 = {
625 	.descr = "short Weierstrass 25519.-3",
626 	.oid = "1.3.101.108",
627 	.sn = "Wei25519",
628 	.p =	 "7fffffff" "ffffffff" "ffffffff" "ffffffff"
629 		 "ffffffff" "ffffffff" "ffffffff" "ffffffed",
630 	.a =	 "7fffffff" "ffffffff" "ffffffff" "ffffffff"
631 		 "ffffffff" "ffffffff" "ffffffff" "ffffffea",
632 	.b =	 "41a3b6bf" "c668778e" "be2954a4" "b1df36d1"
633 		 "485ecef1" "ea614295" "796e1022" "40891faa",
634 	.x =	 "7706c37b" "5a84128a" "3884a5d7" "1811f1b5"
635 		 "5da3230f" "fb17a8ab" "0b32e48d" "31a6685c",
636 	.y =	 "0f60480c" "7a5c0e11" "40340adc" "79d6a2bf"
637 		 "0cb57ad0" "49d025dc" "38d80c77" "985f0329",
638 	.order = "10000000" "00000000" "00000000" "00000000"
639 		 "14def9de" "a2f79cd6" "5812631a" "5cf5d3ed",
640 	.cofactor = "8",
641 	.named = ec_wei25519_pkparameters_named_curve,
642 	.named_len = sizeof(ec_wei25519_pkparameters_named_curve),
643 	.param = ec_wei25519_3_pkparameters_parameters,
644 	.param_len = sizeof(ec_wei25519_3_pkparameters_parameters),
645 };
646 
647 #if NEGATIVE_CURVE_COEFFICIENTS_ALLOWED
648 /* Same as wei25519_3 except for a. */
649 static const struct curve wei25519_3_neg = {
650 	.descr = "short Weierstrass 25519.-3 with negative a",
651 	.oid = "1.3.101.108",
652 	.sn = "Wei25519",
653 	.p =	 "7fffffff" "ffffffff" "ffffffff" "ffffffff"
654 		 "ffffffff" "ffffffff" "ffffffff" "ffffffed",
655 	.a =	 "-03",
656 	.b =	 "41a3b6bf" "c668778e" "be2954a4" "b1df36d1"
657 		 "485ecef1" "ea614295" "796e1022" "40891faa",
658 	.x =	 "7706c37b" "5a84128a" "3884a5d7" "1811f1b5"
659 		 "5da3230f" "fb17a8ab" "0b32e48d" "31a6685c",
660 	.y =	 "0f60480c" "7a5c0e11" "40340adc" "79d6a2bf"
661 		 "0cb57ad0" "49d025dc" "38d80c77" "985f0329",
662 	.order = "10000000" "00000000" "00000000" "00000000"
663 		 "14def9de" "a2f79cd6" "5812631a" "5cf5d3ed",
664 	.cofactor = "8",
665 	.named = ec_wei25519_pkparameters_named_curve,
666 	.named_len = sizeof(ec_wei25519_pkparameters_named_curve),
667 	.param = ec_wei25519_3_pkparameters_parameters,
668 	.param_len = sizeof(ec_wei25519_3_pkparameters_parameters),
669 };
670 #endif
671 
672 /*
673  * From draft-ietf-lwig-curve-representation-23, Appendix L.3
674  */
675 
676 static const uint8_t ec_secp256k1_m_pkparameters_named_curve[] = {
677 	0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x0a,
678 };
679 
680 static const uint8_t ec_secp256k1_m_pkparameters_parameters[] = {
681 	0x30, 0x81, 0xe0, 0x02, 0x01, 0x01, 0x30, 0x2c,
682 	0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
683 	0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff,
684 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
685 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
686 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
687 	0xff, 0xff, 0xfc, 0x2f, 0x30, 0x44, 0x04, 0x20,
688 	0xcf, 0xcd, 0x5c, 0x21, 0x75, 0xe2, 0xef, 0x7d,
689 	0xcc, 0xdc, 0xe7, 0x37, 0x77, 0x0b, 0x73, 0x81,
690 	0x5a, 0x2f, 0x13, 0xc5, 0x09, 0x03, 0x5c, 0xa2,
691 	0x54, 0xa1, 0x4a, 0xc9, 0xf0, 0x89, 0x74, 0xaf,
692 	0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 	0x06, 0xeb, 0x04, 0x41, 0x04, 0x3a, 0xca, 0x53,
697 	0x00, 0x95, 0x9f, 0xa1, 0xd0, 0xba, 0xf7, 0x8d,
698 	0xcf, 0xf7, 0x7a, 0x61, 0x6f, 0x39, 0x5e, 0x58,
699 	0x6d, 0x67, 0xac, 0xed, 0x0a, 0x88, 0x79, 0x81,
700 	0x29, 0x0c, 0x27, 0x91, 0x45, 0x95, 0x80, 0xfc,
701 	0xe5, 0x3a, 0x17, 0x0f, 0x4f, 0xb7, 0x44, 0x57,
702 	0x9f, 0xf3, 0xd6, 0x20, 0x86, 0x12, 0xcd, 0x6a,
703 	0x23, 0x3e, 0x2d, 0xe2, 0x37, 0xf9, 0x76, 0xc6,
704 	0xa7, 0x86, 0x11, 0xc8, 0x00, 0x02, 0x21, 0x00,
705 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
706 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
707 	0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
708 	0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
709 	0x02, 0x01, 0x01,
710 };
711 
712 static const struct curve secp256k1_m = {
713 	.descr = "short Weierstrass secp256k1.m",
714 	.oid =	 "1.3.132.0.10",
715 	.sn =	 SN_secp256k1,
716 	.p =	 "ffffffff" "ffffffff" "ffffffff" "ffffffff"
717 		 "ffffffff" "ffffffff" "fffffffe" "fffffc2f",
718 	.a =	 "cfcd5c21" "75e2ef7d" "ccdce737" "770b7381"
719 		 "5a2f13c5" "09035ca2" "54a14ac9" "f08974af",
720 	.b =	 "06eb",
721 	.x =	 "3aca5300" "959fa1d0" "baf78dcf" "f77a616f"
722 		 "395e586d" "67aced0a" "88798129" "0c279145",
723 	.y =	 "9580fce5" "3a170f4f" "b744579f" "f3d62086"
724 		 "12cd6a23" "3e2de237" "f976c6a7" "8611c800",
725 	.order = "ffffffff" "ffffffff" "ffffffff" "fffffffe"
726 		 "baaedce6" "af48a03b" "bfd25e8c" "d0364141",
727 	.cofactor = "1",
728 	.known_named_curve = 1,
729 	.named = ec_secp256k1_m_pkparameters_named_curve,
730 	.named_len = sizeof(ec_secp256k1_m_pkparameters_named_curve),
731 	.param = ec_secp256k1_m_pkparameters_parameters,
732 	.param_len = sizeof(ec_secp256k1_m_pkparameters_parameters),
733 };
734 
735 static EC_GROUP *
736 ec_group_from_curve_method(const struct curve *curve, const EC_METHOD *method,
737     BN_CTX *ctx)
738 {
739 	EC_GROUP *group;
740 	EC_POINT *generator = NULL;
741 	BIGNUM *p, *a, *b;
742 	BIGNUM *order, *x, *y;
743 
744 	BN_CTX_start(ctx);
745 
746 	if ((p = BN_CTX_get(ctx)) == NULL)
747 		errx(1, "BN_CTX_get");
748 	if ((a = BN_CTX_get(ctx)) == NULL)
749 		errx(1, "BN_CTX_get");
750 	if ((b = BN_CTX_get(ctx)) == NULL)
751 		errx(1, "BN_CTX_get");
752 
753 	if ((order = BN_CTX_get(ctx)) == NULL)
754 		errx(1, "BN_CTX_get");
755 	if ((x = BN_CTX_get(ctx)) == NULL)
756 		errx(1, "BN_CTX_get");
757 	if ((y = BN_CTX_get(ctx)) == NULL)
758 		errx(1, "BN_CTX_get");
759 
760 	if (BN_hex2bn(&p, curve->p) == 0)
761 		errx(1, "BN_hex2bn(p)");
762 	if (BN_hex2bn(&a, curve->a) == 0)
763 		errx(1, "BN_hex2bn(a)");
764 	if (BN_hex2bn(&b, curve->b) == 0)
765 		errx(1, "BN_hex2bn(b)");
766 
767 	if ((group = EC_GROUP_new(method)) == NULL)
768 		errx(1, "EC_GROUP_new");
769 
770 	if (!EC_GROUP_set_curve(group, p, a, b, ctx))
771 		errx(1, "EC_GROUP_set_curve");
772 
773 	if (BN_hex2bn(&x, curve->x) == 0)
774 		errx(1, "BN_hex2bn(x)");
775 	if (BN_hex2bn(&x, curve->x) == 0)
776 		errx(1, "BN_hex2bn(x)");
777 	if (BN_hex2bn(&y, curve->y) == 0)
778 		errx(1, "BN_hex2bn(y)");
779 
780 	if ((generator = EC_POINT_new(group)) == NULL)
781 		errx(1, "EC_POINT_new()");
782 
783 	if (!EC_POINT_set_affine_coordinates(group, generator, x, y, ctx)) {
784 		fprintf(stderr, "FAIL: %s EC_POINT_set_affine_coordinates\n",
785 		    curve->descr);
786 		ERR_print_errors_fp(stderr);
787 		goto err;
788 	}
789 
790 	if (BN_hex2bn(&order, curve->order) == 0)
791 		errx(1, "BN_hex2bn(order)");
792 
793 	/* Don't set cofactor to exercise the cofactor guessing code. */
794 	if (!EC_GROUP_set_generator(group, generator, order, NULL)) {
795 		fprintf(stderr, "FAIL: %s EC_GROUP_set_generator\n", curve->descr);
796 		ERR_print_errors_fp(stderr);
797 		goto err;
798 	}
799 
800 	EC_POINT_free(generator);
801 
802 	BN_CTX_end(ctx);
803 
804 	return group;
805 
806  err:
807 	BN_CTX_end(ctx);
808 
809 	EC_POINT_free(generator);
810 	EC_GROUP_free(group);
811 
812 	return NULL;
813 }
814 
815 static EC_GROUP *
816 ec_group_new(const struct curve *curve, const EC_METHOD *method, BN_CTX *ctx)
817 {
818 	EC_GROUP *group = NULL;
819 	BIGNUM *cofactor, *guessed_cofactor;
820 	int nid;
821 
822 	BN_CTX_start(ctx);
823 
824 	if ((nid = OBJ_txt2nid(curve->oid)) == NID_undef)
825 		nid = OBJ_create(curve->oid, curve->sn, curve->ln);
826 	if (nid == NID_undef) {
827 		fprintf(stderr, "FAIL: OBJ_create(%s)\n", curve->descr);
828 		goto err;
829 	}
830 
831 	if ((cofactor = BN_CTX_get(ctx)) == NULL)
832 		errx(1, "BN_CTX_get");
833 	if ((guessed_cofactor = BN_CTX_get(ctx)) == NULL)
834 		errx(1, "BN_CTX_get");
835 
836 	if (BN_hex2bn(&cofactor, curve->cofactor) == 0)
837 		errx(1, "BN_hex2bn(cofactor)");
838 
839 	if ((group = ec_group_from_curve_method(curve, method, ctx)) == NULL) {
840 		fprintf(stderr, "FAIL: %s ec_group_from_curve_method\n", curve->descr);
841 		ERR_print_errors_fp(stderr);
842 		goto err;
843 	}
844 
845 	if (!EC_GROUP_get_cofactor(group, guessed_cofactor, ctx)) {
846 		fprintf(stderr, "FAIL: %s EC_GROUP_get_cofactor\n", curve->descr);
847 		ERR_print_errors_fp(stderr);
848 		goto err;
849 	}
850 
851 	if (BN_cmp(cofactor, guessed_cofactor) != 0) {
852 		fprintf(stderr, "FAIL: %s cofactor: want ", curve->descr);
853 		BN_print_fp(stderr, cofactor);
854 		fprintf(stderr, ", got ");
855 		BN_print_fp(stderr, guessed_cofactor);
856 		fprintf(stderr, "\n");
857 		goto err;
858 	}
859 
860 	if (!EC_GROUP_check(group, ctx)) {
861 		fprintf(stderr, "FAIL: %s EC_GROUP_check\n", curve->descr);
862 		ERR_print_errors_fp(stderr);
863 		goto err;
864 	}
865 
866 	EC_GROUP_set_curve_name(group, nid);
867 
868 	BN_CTX_end(ctx);
869 
870 	return group;
871 
872  err:
873 	BN_CTX_end(ctx);
874 
875 	EC_GROUP_free(group);
876 
877 	return NULL;
878 }
879 
880 static int
881 ec_group_non_builtin_curve(const struct curve *curve, const EC_METHOD *method,
882     BN_CTX *ctx)
883 {
884 	EC_GROUP *group = NULL, *new_group = NULL;
885 	const unsigned char *pder;
886 	unsigned char *der = NULL;
887 #ifndef OPENSSL_SUPPRESS_DEPRECATED
888 	long error;
889 #endif
890 	int der_len = 0;
891 	int failed = 1;
892 
893 	ERR_clear_error();
894 	BN_CTX_start(ctx);
895 
896 	if ((group = ec_group_new(curve, method, ctx)) == NULL)
897 		goto err;
898 
899 	if (EC_GROUP_get_curve_name(group) == NID_undef) {
900 		fprintf(stderr, "FAIL: no curve name set for %s\n", curve->descr);
901 		goto err;
902 	}
903 
904 	EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
905 
906 	der = NULL;
907 	if ((der_len = i2d_ECPKParameters(group, &der)) <= 0) {
908 		fprintf(stderr, "FAIL: %s i2d_ECPKParameters (named)\n",
909 		    curve->descr);
910 		ERR_print_errors_fp(stderr);
911 		goto err;
912 	}
913 
914 	if (compare_data(curve->descr, der, der_len,
915 	    curve->named, curve->named_len) == -1)
916 		goto err;
917 
918 	freezero(der, der_len);
919 	der = NULL;
920 
921 	/* Explicit curve parameter encoding should work without NID set. */
922 	EC_GROUP_set_curve_name(group, NID_undef);
923 	EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
924 
925 	der = NULL;
926 	if ((der_len = i2d_ECPKParameters(group, &der)) <= 0) {
927 		fprintf(stderr, "FAIL: i2d_ECPKParameters (explicit) %s\n",
928 		    curve->descr);
929 		ERR_print_errors_fp(stderr);
930 		goto err;
931 	}
932 
933 	if (compare_data(curve->descr, der, der_len,
934 	    curve->param, curve->param_len) == -1)
935 		goto err;
936 
937 	freezero(der, der_len);
938 	der = NULL;
939 
940 	/* At this point we should have no error on the stack. */
941 	if (ERR_peek_last_error() != 0) {
942 		fprintf(stderr, "FAIL: %s unexpected error %lu\n", curve->descr,
943 		    ERR_peek_last_error());
944 		goto err;
945 	}
946 
947 	pder = curve->named;
948 	der_len = curve->named_len;
949 	new_group = d2i_ECPKParameters(NULL, &pder, der_len);
950 	if (!curve->known_named_curve && new_group != NULL) {
951 		fprintf(stderr, "FAIL: managed to decode unknown named curve %s\n",
952 		    curve->descr);
953 		goto err;
954 	}
955 	EC_GROUP_free(new_group);
956 	new_group = NULL;
957 #ifndef OPENSSL_SUPPRESS_DEPRECATED
958 	error = ERR_get_error();
959 	if (!curve->known_named_curve &&
960 	    ERR_GET_REASON(error) != EC_R_UNKNOWN_GROUP) {
961 		fprintf(stderr, "FAIL: %s unexpected error: want %d, got %d\n",
962 		    curve->descr, EC_R_UNKNOWN_GROUP, ERR_GET_REASON(error));
963 		goto err;
964 	}
965 #endif
966 
967 	ERR_clear_error();
968 
969 	pder = curve->param;
970 	der_len = curve->param_len;
971 	if ((new_group = d2i_ECPKParameters(NULL, &pder, der_len)) != NULL) {
972 		fprintf(stderr, "FAIL: managed to decode non-builtin parameters %s\n",
973 		    curve->descr);
974 		goto err;
975 	}
976 
977 #ifndef OPENSSL_SUPPRESS_DEPRECATED
978 	error = ERR_peek_last_error();
979 	if (ERR_GET_REASON(error) != EC_R_PKPARAMETERS2GROUP_FAILURE) {
980 		fprintf(stderr, "FAIL: %s unexpected error: want %d, got %d\n",
981 		    curve->descr, EC_R_UNKNOWN_GROUP, ERR_GET_REASON(error));
982 		goto err;
983 	}
984 #endif
985 
986 	failed = 0;
987 
988  err:
989 	BN_CTX_end(ctx);
990 
991 	EC_GROUP_free(group);
992 	EC_GROUP_free(new_group);
993 
994 	freezero(der, der_len);
995 
996 	return failed;
997 }
998 
999 static int
1000 ec_group_non_builtin_curves(void)
1001 {
1002 	BN_CTX *ctx;
1003 	int failed = 0;
1004 
1005 	if ((ctx = BN_CTX_new()) == NULL)
1006 		errx(1, "BN_CTX_new");
1007 
1008 	failed |= ec_group_non_builtin_curve(&wei25519, EC_GFp_mont_method(), ctx);
1009 	failed |= ec_group_non_builtin_curve(&wei25519, EC_GFp_simple_method(), ctx);
1010 
1011 	failed |= ec_group_non_builtin_curve(&wei25519_2, EC_GFp_mont_method(), ctx);
1012 	failed |= ec_group_non_builtin_curve(&wei25519_2, EC_GFp_simple_method(), ctx);
1013 
1014 	failed |= ec_group_non_builtin_curve(&wei25519_3, EC_GFp_mont_method(), ctx);
1015 	failed |= ec_group_non_builtin_curve(&wei25519_3, EC_GFp_simple_method(), ctx);
1016 
1017 #if NEGATIVE_CURVE_COEFFICIENTS_ALLOWED
1018 	failed |= ec_group_non_builtin_curve(&wei25519_3_neg, EC_GFp_mont_method(), ctx);
1019 	failed |= ec_group_non_builtin_curve(&wei25519_3_neg, EC_GFp_simple_method(), ctx);
1020 #endif
1021 
1022 	failed |= ec_group_non_builtin_curve(&secp256k1_m, EC_GFp_mont_method(), ctx);
1023 	failed |= ec_group_non_builtin_curve(&secp256k1_m, EC_GFp_simple_method(), ctx);
1024 
1025 	BN_CTX_free(ctx);
1026 
1027 	return failed;
1028 }
1029 
1030 static const struct ec_private_key {
1031 	const char *name;
1032 	size_t der_len;
1033 	uint8_t der[256];
1034 	const char *hex;
1035 	int oct_len;
1036 	uint8_t oct[256];
1037 } ec_private_keys[] = {
1038 	{
1039 		.name = "secp224k1",
1040 		.der_len = 107,
1041 		.der = {
1042 			0x30, 0x69, 0x02, 0x01, 0x01, 0x04, 0x1d, 0x00,
1043 			0x32, 0x2b, 0x6d, 0xe3, 0x62, 0x60, 0xda, 0xb2,
1044 			0x62, 0x0a, 0x38, 0x3e, 0xd3, 0x8c, 0x70, 0x9e,
1045 			0x76, 0x38, 0xac, 0x26, 0x17, 0xa9, 0x00, 0xdf,
1046 			0xfb, 0x1e, 0xf3, 0xbd, 0xa0, 0x07, 0x06, 0x05,
1047 			0x2b, 0x81, 0x04, 0x00, 0x20, 0xa1, 0x3c, 0x03,
1048 			0x3a, 0x00, 0x04, 0x51, 0xc4, 0x69, 0xdf, 0x2d,
1049 			0x49, 0x7b, 0x05, 0x6c, 0x12, 0x5f, 0x9a, 0x83,
1050 			0x51, 0x7d, 0xf3, 0x4a, 0x6c, 0xe1, 0x3a, 0xea,
1051 			0x44, 0x35, 0x3e, 0x7a, 0xa4, 0x40, 0xdf, 0xc4,
1052 			0x90, 0x18, 0xfc, 0x2f, 0x5d, 0x4b, 0x12, 0x37,
1053 			0x87, 0x4d, 0x2a, 0xf8, 0xbd, 0x29, 0xfb, 0x13,
1054 			0x34, 0xef, 0xfb, 0x04, 0xa1, 0x28, 0x7d, 0x51,
1055 			0xbe, 0xe7, 0x0b,
1056 		},
1057 		.hex =	"0451C469DF2D497B"
1058 			"056C125F9A83517D"
1059 			"F34A6CE13AEA4435"
1060 			"3E7AA440DFC49018"
1061 			"FC2F5D4B1237874D"
1062 			"2AF8BD29FB1334EF"
1063 			"FB04A1287D51BEE7"
1064 			"0B",
1065 		.oct_len = 57,
1066 		.oct = {
1067 			0x04, 0x51, 0xc4, 0x69, 0xdf, 0x2d, 0x49, 0x7b,
1068 			0x05, 0x6c, 0x12, 0x5f, 0x9a, 0x83, 0x51, 0x7d,
1069 			0xf3, 0x4a, 0x6c, 0xe1, 0x3a, 0xea, 0x44, 0x35,
1070 			0x3e, 0x7a, 0xa4, 0x40, 0xdf, 0xc4, 0x90, 0x18,
1071 			0xfc, 0x2f, 0x5d, 0x4b, 0x12, 0x37, 0x87, 0x4d,
1072 			0x2a, 0xf8, 0xbd, 0x29, 0xfb, 0x13, 0x34, 0xef,
1073 			0xfb, 0x04, 0xa1, 0x28, 0x7d, 0x51, 0xbe, 0xe7,
1074 			0x0b,
1075 		},
1076 	},
1077 	{
1078 		.name = "secp224r1",
1079 		.der_len = 106,
1080 		.der = {
1081 			0x30, 0x68, 0x02, 0x01, 0x01, 0x04, 0x1c, 0x76,
1082 			0x9b, 0x2f, 0x62, 0xff, 0x5f, 0x84, 0x6c, 0x7e,
1083 			0x90, 0xda, 0xfb, 0x70, 0x62, 0xc1, 0xb9, 0xa2,
1084 			0xc9, 0xf7, 0x1b, 0x76, 0x7f, 0xbb, 0xb1, 0xd4,
1085 			0xa4, 0xa0, 0x42, 0xa0, 0x07, 0x06, 0x05, 0x2b,
1086 			0x81, 0x04, 0x00, 0x21, 0xa1, 0x3c, 0x03, 0x3a,
1087 			0x00, 0x04, 0x94, 0x84, 0xb0, 0xcd, 0x65, 0xef,
1088 			0xc5, 0x5d, 0xc9, 0xe4, 0x91, 0x71, 0xcb, 0xc7,
1089 			0xf1, 0x8e, 0x44, 0x39, 0xc2, 0xd3, 0x07, 0xf0,
1090 			0x6c, 0xb6, 0xef, 0x77, 0xc0, 0x84, 0x30, 0x2c,
1091 			0xd2, 0xf2, 0xf0, 0xb5, 0xb6, 0x6f, 0x0a, 0xf4,
1092 			0x43, 0xab, 0x5e, 0x5d, 0xd8, 0x97, 0xbf, 0xab,
1093 			0xf4, 0x2d, 0x34, 0x25, 0xee, 0x4c, 0xec, 0xfb,
1094 			0x4d, 0x0b,
1095 		},
1096 		.hex =	"049484B0CD65EFC5"
1097 			"5DC9E49171CBC7F1"
1098 			"8E4439C2D307F06C"
1099 			"B6EF77C084302CD2"
1100 			"F2F0B5B66F0AF443"
1101 			"AB5E5DD897BFABF4"
1102 			"2D3425EE4CECFB4D"
1103 			"0B",
1104 		.oct_len = 57,
1105 		.oct = {
1106 			0x04, 0x94, 0x84, 0xb0, 0xcd, 0x65, 0xef, 0xc5,
1107 			0x5d, 0xc9, 0xe4, 0x91, 0x71, 0xcb, 0xc7, 0xf1,
1108 			0x8e, 0x44, 0x39, 0xc2, 0xd3, 0x07, 0xf0, 0x6c,
1109 			0xb6, 0xef, 0x77, 0xc0, 0x84, 0x30, 0x2c, 0xd2,
1110 			0xf2, 0xf0, 0xb5, 0xb6, 0x6f, 0x0a, 0xf4, 0x43,
1111 			0xab, 0x5e, 0x5d, 0xd8, 0x97, 0xbf, 0xab, 0xf4,
1112 			0x2d, 0x34, 0x25, 0xee, 0x4c, 0xec, 0xfb, 0x4d,
1113 			0x0b,
1114 		},
1115 	},
1116 	{
1117 		.name = "secp256k1",
1118 		.der_len = 118,
1119 		.der = {
1120 			0x30, 0x74, 0x02, 0x01, 0x01, 0x04, 0x20, 0xf2,
1121 			0xe5, 0x5c, 0x24, 0x66, 0x01, 0x2b, 0x95, 0x96,
1122 			0xbf, 0xbd, 0x0e, 0x33, 0x3d, 0xfd, 0x8a, 0x22,
1123 			0x79, 0x12, 0xc5, 0x93, 0x28, 0x1b, 0x74, 0x39,
1124 			0x61, 0x80, 0x1c, 0x17, 0xb1, 0x36, 0xab, 0xa0,
1125 			0x07, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x0a,
1126 			0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x9f, 0xd2,
1127 			0xbe, 0xcc, 0xf8, 0x00, 0xe8, 0xd0, 0x40, 0x73,
1128 			0x11, 0xb9, 0x34, 0x76, 0x68, 0xb2, 0x6b, 0x88,
1129 			0xea, 0xa6, 0x64, 0x37, 0xe7, 0x06, 0xdf, 0x9f,
1130 			0x20, 0xb8, 0xc3, 0x7f, 0x9f, 0x8f, 0xbc, 0x80,
1131 			0x65, 0xe9, 0x73, 0xcb, 0x1d, 0xa1, 0xfa, 0x34,
1132 			0x23, 0x66, 0xb9, 0x47, 0x89, 0xe9, 0x08, 0x92,
1133 			0x5e, 0xb5, 0x37, 0x44, 0x40, 0x1c, 0x34, 0x6c,
1134 			0xf2, 0xdb, 0x44, 0x71, 0x26, 0xeb,
1135 		},
1136 		.hex =	"049FD2BECCF800E8"
1137 			"D0407311B9347668"
1138 			"B26B88EAA66437E7"
1139 			"06DF9F20B8C37F9F"
1140 			"8FBC8065E973CB1D"
1141 			"A1FA342366B94789"
1142 			"E908925EB5374440"
1143 			"1C346CF2DB447126"
1144 			"EB",
1145 		.oct_len = 65,
1146 		.oct = {
1147 			0x04, 0x9f, 0xd2, 0xbe, 0xcc, 0xf8, 0x00, 0xe8,
1148 			0xd0, 0x40, 0x73, 0x11, 0xb9, 0x34, 0x76, 0x68,
1149 			0xb2, 0x6b, 0x88, 0xea, 0xa6, 0x64, 0x37, 0xe7,
1150 			0x06, 0xdf, 0x9f, 0x20, 0xb8, 0xc3, 0x7f, 0x9f,
1151 			0x8f, 0xbc, 0x80, 0x65, 0xe9, 0x73, 0xcb, 0x1d,
1152 			0xa1, 0xfa, 0x34, 0x23, 0x66, 0xb9, 0x47, 0x89,
1153 			0xe9, 0x08, 0x92, 0x5e, 0xb5, 0x37, 0x44, 0x40,
1154 			0x1c, 0x34, 0x6c, 0xf2, 0xdb, 0x44, 0x71, 0x26,
1155 			0xeb,
1156 		},
1157 	},
1158 	{
1159 		.name = "secp384r1",
1160 		.der_len = 167,
1161 		.der = {
1162 			0x30, 0x81, 0xa4, 0x02, 0x01, 0x01, 0x04, 0x30,
1163 			0xa0, 0xd3, 0x78, 0x23, 0x51, 0xe1, 0x20, 0x5c,
1164 			0xbe, 0x84, 0x11, 0x2f, 0x82, 0x55, 0xfc, 0xd1,
1165 			0x5d, 0xae, 0xfc, 0x72, 0x60, 0x50, 0x3c, 0x2d,
1166 			0x70, 0xb4, 0x00, 0xe2, 0xe6, 0x0a, 0xdf, 0xc5,
1167 			0x56, 0xe6, 0xb8, 0x69, 0xf8, 0xad, 0xf5, 0xfc,
1168 			0x95, 0xb3, 0x5b, 0x3d, 0xda, 0x6c, 0x5f, 0x74,
1169 			0xa0, 0x07, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00,
1170 			0x22, 0xa1, 0x64, 0x03, 0x62, 0x00, 0x04, 0xce,
1171 			0x9a, 0x3b, 0x4b, 0x01, 0xe6, 0xc4, 0x5a, 0xfa,
1172 			0x97, 0x03, 0xc1, 0xce, 0x18, 0xd5, 0x6c, 0x47,
1173 			0x27, 0x4d, 0x6c, 0x9a, 0xbd, 0x47, 0xab, 0x20,
1174 			0x0f, 0x99, 0x83, 0x19, 0x8b, 0xcb, 0x18, 0xd7,
1175 			0xa3, 0xb2, 0xe7, 0x3b, 0xd0, 0xf1, 0xf3, 0x29,
1176 			0xb2, 0x6d, 0x38, 0xd6, 0xcc, 0x8e, 0x5e, 0xf0,
1177 			0xb2, 0xb9, 0xbd, 0x85, 0x2c, 0xab, 0x4b, 0xb6,
1178 			0x9d, 0x98, 0xa1, 0xce, 0xf1, 0x8a, 0xdb, 0x92,
1179 			0x75, 0x7d, 0xf7, 0x82, 0x4c, 0x0a, 0xc7, 0x3b,
1180 			0x52, 0x6e, 0x97, 0xc6, 0x23, 0xc9, 0x6f, 0x3f,
1181 			0xe5, 0xd2, 0xa2, 0x79, 0x47, 0xb0, 0x6e, 0x5f,
1182 			0x85, 0x39, 0x94, 0x57, 0xbf, 0x54, 0x76,
1183 		},
1184 		.hex =	"04CE9A3B4B01E6C4"
1185 			"5AFA9703C1CE18D5"
1186 			"6C47274D6C9ABD47"
1187 			"AB200F9983198BCB"
1188 			"18D7A3B2E73BD0F1"
1189 			"F329B26D38D6CC8E"
1190 			"5EF0B2B9BD852CAB"
1191 			"4BB69D98A1CEF18A"
1192 			"DB92757DF7824C0A"
1193 			"C73B526E97C623C9"
1194 			"6F3FE5D2A27947B0"
1195 			"6E5F85399457BF54"
1196 			"76",
1197 		.oct_len = 97,
1198 		.oct = {
1199 			0x04, 0xce, 0x9a, 0x3b, 0x4b, 0x01, 0xe6, 0xc4,
1200 			0x5a, 0xfa, 0x97, 0x03, 0xc1, 0xce, 0x18, 0xd5,
1201 			0x6c, 0x47, 0x27, 0x4d, 0x6c, 0x9a, 0xbd, 0x47,
1202 			0xab, 0x20, 0x0f, 0x99, 0x83, 0x19, 0x8b, 0xcb,
1203 			0x18, 0xd7, 0xa3, 0xb2, 0xe7, 0x3b, 0xd0, 0xf1,
1204 			0xf3, 0x29, 0xb2, 0x6d, 0x38, 0xd6, 0xcc, 0x8e,
1205 			0x5e, 0xf0, 0xb2, 0xb9, 0xbd, 0x85, 0x2c, 0xab,
1206 			0x4b, 0xb6, 0x9d, 0x98, 0xa1, 0xce, 0xf1, 0x8a,
1207 			0xdb, 0x92, 0x75, 0x7d, 0xf7, 0x82, 0x4c, 0x0a,
1208 			0xc7, 0x3b, 0x52, 0x6e, 0x97, 0xc6, 0x23, 0xc9,
1209 			0x6f, 0x3f, 0xe5, 0xd2, 0xa2, 0x79, 0x47, 0xb0,
1210 			0x6e, 0x5f, 0x85, 0x39, 0x94, 0x57, 0xbf, 0x54,
1211 			0x76,
1212 		},
1213 	},
1214 	{
1215 		.name = "secp521r1",
1216 		.der_len = 223,
1217 		.der = {
1218 			0x30, 0x81, 0xdc, 0x02, 0x01, 0x01, 0x04, 0x42,
1219 			0x01, 0x6e, 0xff, 0x5d, 0x18, 0x50, 0x5b, 0x09,
1220 			0xf8, 0x38, 0x10, 0x6c, 0x54, 0x19, 0x59, 0xdb,
1221 			0x30, 0xc5, 0x60, 0x28, 0xb1, 0x7f, 0xba, 0x22,
1222 			0x06, 0x4d, 0x8a, 0x69, 0x53, 0xb0, 0xc5, 0x8f,
1223 			0x17, 0x4d, 0x51, 0xc6, 0x2f, 0x41, 0x4e, 0xf0,
1224 			0xab, 0xb4, 0x3a, 0x8f, 0x00, 0x6f, 0x32, 0xe7,
1225 			0xe6, 0x56, 0xb7, 0xe9, 0xb1, 0xcd, 0x3a, 0x93,
1226 			0xe6, 0x8f, 0xe6, 0x60, 0xb6, 0x80, 0xbd, 0x02,
1227 			0xfb, 0x90, 0xa0, 0x07, 0x06, 0x05, 0x2b, 0x81,
1228 			0x04, 0x00, 0x23, 0xa1, 0x81, 0x89, 0x03, 0x81,
1229 			0x86, 0x00, 0x04, 0x01, 0xd2, 0xc3, 0x78, 0x41,
1230 			0xb1, 0x86, 0x24, 0xca, 0x6d, 0x80, 0x5c, 0x97,
1231 			0xcf, 0x96, 0xf0, 0x87, 0xb4, 0x25, 0xbe, 0x37,
1232 			0x9a, 0xf3, 0xe5, 0x4a, 0x70, 0xd1, 0xe6, 0x36,
1233 			0x9e, 0x69, 0xcc, 0xfb, 0x83, 0xd6, 0xa1, 0x62,
1234 			0x6d, 0xa8, 0xe6, 0xca, 0xe7, 0x0e, 0x24, 0xe6,
1235 			0x26, 0xcd, 0xc0, 0x0d, 0x2a, 0x01, 0x81, 0x6a,
1236 			0xd6, 0x94, 0xf2, 0x90, 0xcd, 0x26, 0x68, 0x28,
1237 			0x2c, 0x57, 0xd3, 0xf0, 0x37, 0x00, 0xbc, 0x5e,
1238 			0xfa, 0xf9, 0x36, 0xcd, 0x0f, 0xeb, 0x4f, 0x82,
1239 			0x17, 0x6a, 0xa0, 0x73, 0xd2, 0x48, 0xfc, 0xfb,
1240 			0xf0, 0x54, 0xc3, 0x23, 0x29, 0x76, 0xc7, 0x21,
1241 			0x98, 0x09, 0x29, 0x8b, 0xce, 0x6e, 0x6b, 0xe3,
1242 			0x97, 0x94, 0xb2, 0x30, 0xaa, 0xf6, 0x43, 0x5c,
1243 			0x15, 0xd7, 0xb8, 0xdb, 0x06, 0x92, 0xa8, 0x36,
1244 			0x8f, 0x89, 0xb6, 0x39, 0x2c, 0x2c, 0x23, 0x0a,
1245 			0xb6, 0x95, 0x9c, 0x6b, 0xce, 0xc4, 0x8e,
1246 		},
1247 		.hex =	"0401D2C37841B186"
1248 			"24CA6D805C97CF96"
1249 			"F087B425BE379AF3"
1250 			"E54A70D1E6369E69"
1251 			"CCFB83D6A1626DA8"
1252 			"E6CAE70E24E626CD"
1253 			"C00D2A01816AD694"
1254 			"F290CD2668282C57"
1255 			"D3F03700BC5EFAF9"
1256 			"36CD0FEB4F82176A"
1257 			"A073D248FCFBF054"
1258 			"C3232976C7219809"
1259 			"298BCE6E6BE39794"
1260 			"B230AAF6435C15D7"
1261 			"B8DB0692A8368F89"
1262 			"B6392C2C230AB695"
1263 			"9C6BCEC48E",
1264 		.oct_len = 133,
1265 		.oct = {
1266 			0x04, 0x01, 0xd2, 0xc3, 0x78, 0x41, 0xb1, 0x86,
1267 			0x24, 0xca, 0x6d, 0x80, 0x5c, 0x97, 0xcf, 0x96,
1268 			0xf0, 0x87, 0xb4, 0x25, 0xbe, 0x37, 0x9a, 0xf3,
1269 			0xe5, 0x4a, 0x70, 0xd1, 0xe6, 0x36, 0x9e, 0x69,
1270 			0xcc, 0xfb, 0x83, 0xd6, 0xa1, 0x62, 0x6d, 0xa8,
1271 			0xe6, 0xca, 0xe7, 0x0e, 0x24, 0xe6, 0x26, 0xcd,
1272 			0xc0, 0x0d, 0x2a, 0x01, 0x81, 0x6a, 0xd6, 0x94,
1273 			0xf2, 0x90, 0xcd, 0x26, 0x68, 0x28, 0x2c, 0x57,
1274 			0xd3, 0xf0, 0x37, 0x00, 0xbc, 0x5e, 0xfa, 0xf9,
1275 			0x36, 0xcd, 0x0f, 0xeb, 0x4f, 0x82, 0x17, 0x6a,
1276 			0xa0, 0x73, 0xd2, 0x48, 0xfc, 0xfb, 0xf0, 0x54,
1277 			0xc3, 0x23, 0x29, 0x76, 0xc7, 0x21, 0x98, 0x09,
1278 			0x29, 0x8b, 0xce, 0x6e, 0x6b, 0xe3, 0x97, 0x94,
1279 			0xb2, 0x30, 0xaa, 0xf6, 0x43, 0x5c, 0x15, 0xd7,
1280 			0xb8, 0xdb, 0x06, 0x92, 0xa8, 0x36, 0x8f, 0x89,
1281 			0xb6, 0x39, 0x2c, 0x2c, 0x23, 0x0a, 0xb6, 0x95,
1282 			0x9c, 0x6b, 0xce, 0xc4, 0x8e,
1283 		},
1284 	},
1285 	{
1286 		.name = "prime239v1",
1287 		.der_len = 115,
1288 		.der = {
1289 			0x30, 0x71, 0x02, 0x01, 0x01, 0x04, 0x1e, 0x6e,
1290 			0x26, 0x5e, 0xde, 0x5b, 0x67, 0xd6, 0x38, 0x52,
1291 			0xe7, 0x1e, 0x8d, 0x44, 0xb1, 0xfb, 0xf8, 0xaf,
1292 			0xf9, 0x94, 0x2c, 0xe2, 0x0d, 0xa8, 0x5f, 0x03,
1293 			0x67, 0x53, 0x7b, 0x8b, 0x2e, 0xa0, 0x0a, 0x06,
1294 			0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01,
1295 			0x04, 0xa1, 0x40, 0x03, 0x3e, 0x00, 0x04, 0x33,
1296 			0xc6, 0xe5, 0x8a, 0xc1, 0x8b, 0x7c, 0x96, 0x19,
1297 			0xc9, 0xe1, 0x54, 0x7f, 0x81, 0x9e, 0x59, 0x62,
1298 			0xec, 0xc0, 0x1e, 0xe5, 0x53, 0xd5, 0xae, 0x6b,
1299 			0xd3, 0xe0, 0x09, 0x07, 0xc5, 0x27, 0x81, 0xa6,
1300 			0x8d, 0x39, 0x8e, 0xfe, 0x01, 0xc2, 0x1d, 0xda,
1301 			0xde, 0x7b, 0xdc, 0x76, 0x27, 0x17, 0xf9, 0x6f,
1302 			0xe3, 0x04, 0xef, 0x5d, 0x65, 0x75, 0x98, 0x7f,
1303 			0x2d, 0xd0, 0x68,
1304 		},
1305 		.hex =	"0433C6E58AC18B7C"
1306 			"9619C9E1547F819E"
1307 			"5962ECC01EE553D5"
1308 			"AE6BD3E00907C527"
1309 			"81A68D398EFE01C2"
1310 			"1DDADE7BDC762717"
1311 			"F96FE304EF5D6575"
1312 			"987F2DD068",
1313 		.oct_len = 61,
1314 		.oct = {
1315 			0x04, 0x33, 0xc6, 0xe5, 0x8a, 0xc1, 0x8b, 0x7c,
1316 			0x96, 0x19, 0xc9, 0xe1, 0x54, 0x7f, 0x81, 0x9e,
1317 			0x59, 0x62, 0xec, 0xc0, 0x1e, 0xe5, 0x53, 0xd5,
1318 			0xae, 0x6b, 0xd3, 0xe0, 0x09, 0x07, 0xc5, 0x27,
1319 			0x81, 0xa6, 0x8d, 0x39, 0x8e, 0xfe, 0x01, 0xc2,
1320 			0x1d, 0xda, 0xde, 0x7b, 0xdc, 0x76, 0x27, 0x17,
1321 			0xf9, 0x6f, 0xe3, 0x04, 0xef, 0x5d, 0x65, 0x75,
1322 			0x98, 0x7f, 0x2d, 0xd0, 0x68,
1323 		},
1324 	},
1325 	{
1326 		.name = "prime239v2",
1327 		.der_len = 115,
1328 		.der = {
1329 			0x30, 0x71, 0x02, 0x01, 0x01, 0x04, 0x1e, 0x30,
1330 			0x2f, 0x01, 0x10, 0xe9, 0x09, 0x15, 0xdd, 0xe3,
1331 			0xdd, 0xae, 0xcb, 0x9d, 0x3a, 0x58, 0x92, 0x02,
1332 			0x1e, 0x6e, 0x02, 0x57, 0xa8, 0x36, 0x0b, 0x20,
1333 			0x0b, 0x7e, 0xf4, 0xad, 0x0b, 0xa0, 0x0a, 0x06,
1334 			0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01,
1335 			0x05, 0xa1, 0x40, 0x03, 0x3e, 0x00, 0x04, 0x3c,
1336 			0x10, 0x27, 0x7b, 0xac, 0xdf, 0x86, 0xc9, 0x4f,
1337 			0xf8, 0x39, 0x87, 0x02, 0x39, 0xaf, 0x41, 0xbc,
1338 			0x4b, 0x67, 0xd8, 0x5e, 0x04, 0x96, 0x84, 0xb5,
1339 			0x60, 0x50, 0x48, 0x6a, 0x20, 0x1d, 0x2b, 0x7e,
1340 			0x9f, 0xaf, 0xf8, 0x8e, 0x7e, 0xa4, 0xcd, 0x00,
1341 			0xad, 0xb1, 0xad, 0x22, 0x69, 0x32, 0x10, 0x6c,
1342 			0xe0, 0xcc, 0xdd, 0x45, 0xd8, 0xa6, 0x29, 0x2f,
1343 			0xad, 0x6b, 0xf9,
1344 		},
1345 		.hex =	"043C10277BACDF86"
1346 			"C94FF839870239AF"
1347 			"41BC4B67D85E0496"
1348 			"84B56050486A201D"
1349 			"2B7E9FAFF88E7EA4"
1350 			"CD00ADB1AD226932"
1351 			"106CE0CCDD45D8A6"
1352 			"292FAD6BF9",
1353 		.oct_len = 61,
1354 		.oct = {
1355 			0x04, 0x3c, 0x10, 0x27, 0x7b, 0xac, 0xdf, 0x86,
1356 			0xc9, 0x4f, 0xf8, 0x39, 0x87, 0x02, 0x39, 0xaf,
1357 			0x41, 0xbc, 0x4b, 0x67, 0xd8, 0x5e, 0x04, 0x96,
1358 			0x84, 0xb5, 0x60, 0x50, 0x48, 0x6a, 0x20, 0x1d,
1359 			0x2b, 0x7e, 0x9f, 0xaf, 0xf8, 0x8e, 0x7e, 0xa4,
1360 			0xcd, 0x00, 0xad, 0xb1, 0xad, 0x22, 0x69, 0x32,
1361 			0x10, 0x6c, 0xe0, 0xcc, 0xdd, 0x45, 0xd8, 0xa6,
1362 			0x29, 0x2f, 0xad, 0x6b, 0xf9,
1363 		},
1364 	},
1365 	{
1366 		.name = "prime239v3",
1367 		.der_len = 115,
1368 		.der = {
1369 			0x30, 0x71, 0x02, 0x01, 0x01, 0x04, 0x1e, 0x26,
1370 			0x3f, 0x23, 0x4c, 0xe7, 0xbd, 0xa8, 0xe4, 0xfe,
1371 			0x7c, 0xf6, 0x18, 0x6a, 0xb2, 0xa6, 0x39, 0x15,
1372 			0x6d, 0x72, 0xe8, 0x9e, 0x3f, 0x0f, 0x10, 0x1e,
1373 			0xe5, 0xdf, 0xac, 0xe8, 0x2f, 0xa0, 0x0a, 0x06,
1374 			0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01,
1375 			0x06, 0xa1, 0x40, 0x03, 0x3e, 0x00, 0x04, 0x37,
1376 			0xba, 0x07, 0x7f, 0xd9, 0x46, 0x5a, 0x33, 0x03,
1377 			0x31, 0x77, 0x38, 0xef, 0xee, 0xcc, 0x3d, 0xe1,
1378 			0xaa, 0x57, 0xe3, 0x8d, 0xb7, 0xcd, 0xe3, 0x01,
1379 			0xf4, 0xd6, 0x75, 0x49, 0x72, 0x61, 0x4c, 0xbf,
1380 			0xc0, 0x1f, 0x8b, 0x5f, 0x98, 0x9b, 0xa7, 0xe5,
1381 			0x6a, 0xb7, 0xfe, 0x63, 0xdb, 0xb0, 0x40, 0xcb,
1382 			0x26, 0x81, 0x2a, 0x91, 0x14, 0x0f, 0xc7, 0x31,
1383 			0x13, 0x78, 0x16,
1384 		},
1385 		.hex =	"0437BA077FD9465A"
1386 			"3303317738EFEECC"
1387 			"3DE1AA57E38DB7CD"
1388 			"E301F4D675497261"
1389 			"4CBFC01F8B5F989B"
1390 			"A7E56AB7FE63DBB0"
1391 			"40CB26812A91140F"
1392 			"C731137816",
1393 		.oct_len = 61,
1394 		.oct = {
1395 			0x04, 0x37, 0xba, 0x07, 0x7f, 0xd9, 0x46, 0x5a,
1396 			0x33, 0x03, 0x31, 0x77, 0x38, 0xef, 0xee, 0xcc,
1397 			0x3d, 0xe1, 0xaa, 0x57, 0xe3, 0x8d, 0xb7, 0xcd,
1398 			0xe3, 0x01, 0xf4, 0xd6, 0x75, 0x49, 0x72, 0x61,
1399 			0x4c, 0xbf, 0xc0, 0x1f, 0x8b, 0x5f, 0x98, 0x9b,
1400 			0xa7, 0xe5, 0x6a, 0xb7, 0xfe, 0x63, 0xdb, 0xb0,
1401 			0x40, 0xcb, 0x26, 0x81, 0x2a, 0x91, 0x14, 0x0f,
1402 			0xc7, 0x31, 0x13, 0x78, 0x16,
1403 		},
1404 	},
1405 	{
1406 		.name = "prime256v1",
1407 		.der_len = 121,
1408 		.der = {
1409 			0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x6c,
1410 			0x83, 0x81, 0x90, 0x65, 0x7b, 0x45, 0x98, 0x66,
1411 			0x4b, 0x91, 0x8e, 0xcf, 0x71, 0x61, 0x22, 0xb6,
1412 			0xd6, 0x93, 0x74, 0x84, 0xa3, 0xc6, 0x44, 0x71,
1413 			0x25, 0xc5, 0xef, 0x77, 0x52, 0xd2, 0x32, 0xa0,
1414 			0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
1415 			0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00,
1416 			0x04, 0x96, 0x8a, 0xc3, 0x66, 0x1e, 0xf7, 0xcf,
1417 			0xf6, 0xcc, 0x4e, 0x73, 0xae, 0xe2, 0x64, 0xc4,
1418 			0x56, 0x5f, 0x2d, 0xfe, 0xde, 0xac, 0x92, 0xbe,
1419 			0x10, 0x40, 0x37, 0xce, 0x24, 0x12, 0x30, 0x19,
1420 			0x08, 0x66, 0xcf, 0x90, 0xc9, 0x37, 0x03, 0xd1,
1421 			0xd5, 0x8d, 0xaa, 0x18, 0x2a, 0xbc, 0xed, 0x82,
1422 			0x32, 0xc9, 0x43, 0x4b, 0x98, 0x7f, 0xdc, 0xb1,
1423 			0x0b, 0xa6, 0xdd, 0x16, 0xc5, 0x8d, 0x5a, 0xcf,
1424 			0xe3,
1425 		},
1426 		.hex =	"04968AC3661EF7CF"
1427 			"F6CC4E73AEE264C4"
1428 			"565F2DFEDEAC92BE"
1429 			"104037CE24123019"
1430 			"0866CF90C93703D1"
1431 			"D58DAA182ABCED82"
1432 			"32C9434B987FDCB1"
1433 			"0BA6DD16C58D5ACF"
1434 			"E3",
1435 		.oct_len = 65,
1436 		.oct = {
1437 			0x04, 0x96, 0x8a, 0xc3, 0x66, 0x1e, 0xf7, 0xcf,
1438 			0xf6, 0xcc, 0x4e, 0x73, 0xae, 0xe2, 0x64, 0xc4,
1439 			0x56, 0x5f, 0x2d, 0xfe, 0xde, 0xac, 0x92, 0xbe,
1440 			0x10, 0x40, 0x37, 0xce, 0x24, 0x12, 0x30, 0x19,
1441 			0x08, 0x66, 0xcf, 0x90, 0xc9, 0x37, 0x03, 0xd1,
1442 			0xd5, 0x8d, 0xaa, 0x18, 0x2a, 0xbc, 0xed, 0x82,
1443 			0x32, 0xc9, 0x43, 0x4b, 0x98, 0x7f, 0xdc, 0xb1,
1444 			0x0b, 0xa6, 0xdd, 0x16, 0xc5, 0x8d, 0x5a, 0xcf,
1445 			0xe3,
1446 		},
1447 	},
1448 	{
1449 		.name = "brainpoolP224r1",
1450 		.der_len = 110,
1451 		.der = {
1452 			0x30, 0x6c, 0x02, 0x01, 0x01, 0x04, 0x1c, 0xae,
1453 			0x9c, 0xe1, 0x9c, 0xaf, 0xbd, 0x9d, 0xec, 0x9a,
1454 			0xe4, 0xdc, 0x5a, 0x9f, 0xdb, 0x0d, 0x51, 0x65,
1455 			0xe2, 0x49, 0xa7, 0x35, 0xea, 0xbc, 0x8b, 0x4a,
1456 			0x27, 0xfd, 0xa8, 0xa0, 0x0b, 0x06, 0x09, 0x2b,
1457 			0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x05,
1458 			0xa1, 0x3c, 0x03, 0x3a, 0x00, 0x04, 0x30, 0x88,
1459 			0x20, 0xb3, 0x47, 0x2e, 0x40, 0x1e, 0x68, 0xae,
1460 			0xe1, 0x00, 0x58, 0xa2, 0x4b, 0xb9, 0xac, 0xf7,
1461 			0x5d, 0xc1, 0xee, 0xf5, 0xfb, 0xdd, 0x34, 0xae,
1462 			0xbe, 0x3c, 0x93, 0xdd, 0xc2, 0xd8, 0x3a, 0x9a,
1463 			0x72, 0x65, 0x41, 0xac, 0xcc, 0x25, 0x6a, 0xcf,
1464 			0x71, 0x50, 0x6b, 0xed, 0xe3, 0xc5, 0xd4, 0xe9,
1465 			0x1b, 0x59, 0x92, 0xa4, 0xa8, 0x81,
1466 		},
1467 		.hex =	"04308820B3472E40"
1468 			"1E68AEE10058A24B"
1469 			"B9ACF75DC1EEF5FB"
1470 			"DD34AEBE3C93DDC2"
1471 			"D83A9A726541ACCC"
1472 			"256ACF71506BEDE3"
1473 			"C5D4E91B5992A4A8"
1474 			"81",
1475 		.oct_len = 57,
1476 		.oct = {
1477 			0x04, 0x30, 0x88, 0x20, 0xb3, 0x47, 0x2e, 0x40,
1478 			0x1e, 0x68, 0xae, 0xe1, 0x00, 0x58, 0xa2, 0x4b,
1479 			0xb9, 0xac, 0xf7, 0x5d, 0xc1, 0xee, 0xf5, 0xfb,
1480 			0xdd, 0x34, 0xae, 0xbe, 0x3c, 0x93, 0xdd, 0xc2,
1481 			0xd8, 0x3a, 0x9a, 0x72, 0x65, 0x41, 0xac, 0xcc,
1482 			0x25, 0x6a, 0xcf, 0x71, 0x50, 0x6b, 0xed, 0xe3,
1483 			0xc5, 0xd4, 0xe9, 0x1b, 0x59, 0x92, 0xa4, 0xa8,
1484 			0x81,
1485 		},
1486 	},
1487 	{
1488 		.name = "brainpoolP224t1",
1489 		.der_len = 110,
1490 		.der = {
1491 			0x30, 0x6c, 0x02, 0x01, 0x01, 0x04, 0x1c, 0xc0,
1492 			0x10, 0xc2, 0xf4, 0xab, 0xbb, 0x00, 0xa0, 0x14,
1493 			0x62, 0x13, 0x24, 0xc2, 0x8d, 0x9e, 0x78, 0x92,
1494 			0x24, 0x3b, 0xa8, 0xd0, 0xf1, 0x06, 0x69, 0x77,
1495 			0x1d, 0x9d, 0x6c, 0xa0, 0x0b, 0x06, 0x09, 0x2b,
1496 			0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x06,
1497 			0xa1, 0x3c, 0x03, 0x3a, 0x00, 0x04, 0x0b, 0xbf,
1498 			0x95, 0xea, 0x8b, 0xa8, 0x24, 0x94, 0x68, 0x54,
1499 			0x69, 0xd9, 0x55, 0xa5, 0x36, 0x34, 0xf1, 0x4a,
1500 			0x45, 0xf9, 0x9f, 0x66, 0x7b, 0x5d, 0xc9, 0x8b,
1501 			0x0a, 0x7a, 0x5d, 0xef, 0x25, 0x9a, 0xa3, 0x86,
1502 			0xe1, 0x98, 0x1b, 0x5b, 0xe3, 0xe3, 0x55, 0xa0,
1503 			0x59, 0xb2, 0xfd, 0xe7, 0xdf, 0x41, 0xff, 0x4f,
1504 			0x36, 0xe9, 0x56, 0xe9, 0x07, 0xc2,
1505 		},
1506 		.hex =	"040BBF95EA8BA824"
1507 			"94685469D955A536"
1508 			"34F14A45F99F667B"
1509 			"5DC98B0A7A5DEF25"
1510 			"9AA386E1981B5BE3"
1511 			"E355A059B2FDE7DF"
1512 			"41FF4F36E956E907"
1513 			"C2",
1514 		.oct_len = 57,
1515 		.oct = {
1516 			0x04, 0x0b, 0xbf, 0x95, 0xea, 0x8b, 0xa8, 0x24,
1517 			0x94, 0x68, 0x54, 0x69, 0xd9, 0x55, 0xa5, 0x36,
1518 			0x34, 0xf1, 0x4a, 0x45, 0xf9, 0x9f, 0x66, 0x7b,
1519 			0x5d, 0xc9, 0x8b, 0x0a, 0x7a, 0x5d, 0xef, 0x25,
1520 			0x9a, 0xa3, 0x86, 0xe1, 0x98, 0x1b, 0x5b, 0xe3,
1521 			0xe3, 0x55, 0xa0, 0x59, 0xb2, 0xfd, 0xe7, 0xdf,
1522 			0x41, 0xff, 0x4f, 0x36, 0xe9, 0x56, 0xe9, 0x07,
1523 			0xc2,
1524 		},
1525 	},
1526 	{
1527 		.name = "brainpoolP256r1",
1528 		.der_len = 122,
1529 		.der = {
1530 			0x30, 0x78, 0x02, 0x01, 0x01, 0x04, 0x20, 0x98,
1531 			0x48, 0x86, 0x7a, 0x5b, 0x60, 0xb9, 0xba, 0xab,
1532 			0xa2, 0x34, 0x55, 0x43, 0x17, 0xbc, 0xfd, 0xc2,
1533 			0x18, 0xc9, 0xa8, 0x4b, 0x28, 0xbe, 0x5e, 0xa0,
1534 			0x37, 0xab, 0x0d, 0xe0, 0x54, 0x65, 0x87, 0xa0,
1535 			0x0b, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02,
1536 			0x08, 0x01, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42,
1537 			0x00, 0x04, 0x08, 0xd7, 0x77, 0xf5, 0x10, 0xa9,
1538 			0x83, 0xd9, 0xdf, 0xfd, 0x40, 0xe4, 0x42, 0xce,
1539 			0xd8, 0x3b, 0x9b, 0xef, 0xe6, 0x4d, 0x4e, 0xca,
1540 			0x2d, 0xea, 0xe6, 0x69, 0xfe, 0xd3, 0xa9, 0x3f,
1541 			0x30, 0xfa, 0x7e, 0xa7, 0x14, 0x9d, 0x37, 0x77,
1542 			0xc5, 0xcc, 0x1e, 0x32, 0xf6, 0xce, 0x17, 0x91,
1543 			0x1b, 0xeb, 0xa3, 0x8f, 0xce, 0x70, 0x55, 0xc1,
1544 			0xcf, 0xe3, 0x38, 0xa0, 0xb7, 0x95, 0x85, 0x26,
1545 			0xf5, 0xb2,
1546 		},
1547 		.hex =	"0408D777F510A983"
1548 			"D9DFFD40E442CED8"
1549 			"3B9BEFE64D4ECA2D"
1550 			"EAE669FED3A93F30"
1551 			"FA7EA7149D3777C5"
1552 			"CC1E32F6CE17911B"
1553 			"EBA38FCE7055C1CF"
1554 			"E338A0B7958526F5"
1555 			"B2",
1556 		.oct_len = 65,
1557 		.oct = {
1558 			0x04, 0x08, 0xd7, 0x77, 0xf5, 0x10, 0xa9, 0x83,
1559 			0xd9, 0xdf, 0xfd, 0x40, 0xe4, 0x42, 0xce, 0xd8,
1560 			0x3b, 0x9b, 0xef, 0xe6, 0x4d, 0x4e, 0xca, 0x2d,
1561 			0xea, 0xe6, 0x69, 0xfe, 0xd3, 0xa9, 0x3f, 0x30,
1562 			0xfa, 0x7e, 0xa7, 0x14, 0x9d, 0x37, 0x77, 0xc5,
1563 			0xcc, 0x1e, 0x32, 0xf6, 0xce, 0x17, 0x91, 0x1b,
1564 			0xeb, 0xa3, 0x8f, 0xce, 0x70, 0x55, 0xc1, 0xcf,
1565 			0xe3, 0x38, 0xa0, 0xb7, 0x95, 0x85, 0x26, 0xf5,
1566 			0xb2,
1567 		},
1568 	},
1569 	{
1570 		.name = "brainpoolP256t1",
1571 		.der_len = 122,
1572 		.der = {
1573 			0x30, 0x78, 0x02, 0x01, 0x01, 0x04, 0x20, 0x21,
1574 			0xb0, 0x02, 0x6c, 0xac, 0x68, 0xe7, 0xaf, 0xb6,
1575 			0x8b, 0xb9, 0xe6, 0x68, 0xec, 0x2a, 0xfa, 0x55,
1576 			0xb0, 0xd4, 0x23, 0xaa, 0xb9, 0xfb, 0x7c, 0xf5,
1577 			0xd1, 0x2f, 0x61, 0x52, 0x19, 0xc0, 0x19, 0xa0,
1578 			0x0b, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02,
1579 			0x08, 0x01, 0x01, 0x08, 0xa1, 0x44, 0x03, 0x42,
1580 			0x00, 0x04, 0x7b, 0x1d, 0x55, 0x29, 0x0b, 0x0a,
1581 			0x0d, 0x02, 0x7a, 0x1d, 0x72, 0x53, 0xc1, 0x84,
1582 			0xb9, 0x90, 0x00, 0xb9, 0x45, 0xe5, 0xa5, 0xd4,
1583 			0xee, 0xd6, 0x9a, 0x1d, 0xb0, 0x3a, 0x91, 0xa8,
1584 			0x95, 0x56, 0x58, 0x32, 0xcb, 0xf3, 0x28, 0x95,
1585 			0xa6, 0x82, 0x46, 0xe6, 0x0a, 0x33, 0x00, 0xd1,
1586 			0x0c, 0x61, 0xac, 0x1e, 0xa0, 0xb0, 0xad, 0x3a,
1587 			0xbd, 0x1e, 0x53, 0x8d, 0x26, 0x96, 0xab, 0x44,
1588 			0x6b, 0x84,
1589 		},
1590 		.hex =	"047B1D55290B0A0D"
1591 			"027A1D7253C184B9"
1592 			"9000B945E5A5D4EE"
1593 			"D69A1DB03A91A895"
1594 			"565832CBF32895A6"
1595 			"8246E60A3300D10C"
1596 			"61AC1EA0B0AD3ABD"
1597 			"1E538D2696AB446B"
1598 			"84",
1599 		.oct_len = 65,
1600 		.oct = {
1601 			0x04, 0x7b, 0x1d, 0x55, 0x29, 0x0b, 0x0a, 0x0d,
1602 			0x02, 0x7a, 0x1d, 0x72, 0x53, 0xc1, 0x84, 0xb9,
1603 			0x90, 0x00, 0xb9, 0x45, 0xe5, 0xa5, 0xd4, 0xee,
1604 			0xd6, 0x9a, 0x1d, 0xb0, 0x3a, 0x91, 0xa8, 0x95,
1605 			0x56, 0x58, 0x32, 0xcb, 0xf3, 0x28, 0x95, 0xa6,
1606 			0x82, 0x46, 0xe6, 0x0a, 0x33, 0x00, 0xd1, 0x0c,
1607 			0x61, 0xac, 0x1e, 0xa0, 0xb0, 0xad, 0x3a, 0xbd,
1608 			0x1e, 0x53, 0x8d, 0x26, 0x96, 0xab, 0x44, 0x6b,
1609 			0x84,
1610 		},
1611 	},
1612 	{
1613 		.name = "brainpoolP320r1",
1614 		.der_len = 147,
1615 		.der = {
1616 			0x30, 0x81, 0x90, 0x02, 0x01, 0x01, 0x04, 0x28,
1617 			0x1f, 0x7e, 0x6e, 0x51, 0x13, 0x87, 0x9b, 0x09,
1618 			0x2b, 0x3f, 0x1c, 0x39, 0x0f, 0x9f, 0x48, 0x79,
1619 			0x48, 0xa1, 0x44, 0xe0, 0x5c, 0x73, 0x2a, 0x6c,
1620 			0x6e, 0x60, 0x59, 0xd0, 0xf6, 0x6f, 0x32, 0x0e,
1621 			0x6b, 0x2b, 0x0c, 0xf2, 0x39, 0xbd, 0x42, 0xaf,
1622 			0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03,
1623 			0x02, 0x08, 0x01, 0x01, 0x09, 0xa1, 0x54, 0x03,
1624 			0x52, 0x00, 0x04, 0xa3, 0x37, 0x85, 0xe2, 0xf2,
1625 			0x5f, 0xa1, 0x71, 0xa6, 0x75, 0xfe, 0xa1, 0xea,
1626 			0x66, 0x35, 0x7a, 0x53, 0x71, 0x24, 0x83, 0xcd,
1627 			0xc9, 0x5d, 0x3f, 0x43, 0xc4, 0x97, 0x6d, 0xcc,
1628 			0x0c, 0xed, 0x9a, 0x51, 0x51, 0x7d, 0x1e, 0xd0,
1629 			0xea, 0xd2, 0x8c, 0x36, 0xb0, 0x93, 0x62, 0xeb,
1630 			0x26, 0xda, 0xe1, 0xef, 0xc7, 0x1a, 0xfa, 0x0c,
1631 			0xea, 0x84, 0x7a, 0xf1, 0x50, 0x2c, 0xee, 0xf1,
1632 			0xb3, 0xcc, 0xb7, 0xa0, 0x98, 0x5d, 0xde, 0xc2,
1633 			0x54, 0xcc, 0x11, 0x2a, 0x84, 0xc6, 0x79, 0x10,
1634 			0x7b, 0x20, 0x26,
1635 		},
1636 		.hex =	"04A33785E2F25FA1"
1637 			"71A675FEA1EA6635"
1638 			"7A53712483CDC95D"
1639 			"3F43C4976DCC0CED"
1640 			"9A51517D1ED0EAD2"
1641 			"8C36B09362EB26DA"
1642 			"E1EFC71AFA0CEA84"
1643 			"7AF1502CEEF1B3CC"
1644 			"B7A0985DDEC254CC"
1645 			"112A84C679107B20"
1646 			"26",
1647 		.oct_len = 81,
1648 		.oct = {
1649 			0x04, 0xa3, 0x37, 0x85, 0xe2, 0xf2, 0x5f, 0xa1,
1650 			0x71, 0xa6, 0x75, 0xfe, 0xa1, 0xea, 0x66, 0x35,
1651 			0x7a, 0x53, 0x71, 0x24, 0x83, 0xcd, 0xc9, 0x5d,
1652 			0x3f, 0x43, 0xc4, 0x97, 0x6d, 0xcc, 0x0c, 0xed,
1653 			0x9a, 0x51, 0x51, 0x7d, 0x1e, 0xd0, 0xea, 0xd2,
1654 			0x8c, 0x36, 0xb0, 0x93, 0x62, 0xeb, 0x26, 0xda,
1655 			0xe1, 0xef, 0xc7, 0x1a, 0xfa, 0x0c, 0xea, 0x84,
1656 			0x7a, 0xf1, 0x50, 0x2c, 0xee, 0xf1, 0xb3, 0xcc,
1657 			0xb7, 0xa0, 0x98, 0x5d, 0xde, 0xc2, 0x54, 0xcc,
1658 			0x11, 0x2a, 0x84, 0xc6, 0x79, 0x10, 0x7b, 0x20,
1659 			0x26,
1660 		},
1661 	},
1662 	{
1663 		.name = "brainpoolP320t1",
1664 		.der_len = 147,
1665 		.der = {
1666 			0x30, 0x81, 0x90, 0x02, 0x01, 0x01, 0x04, 0x28,
1667 			0x4a, 0x8a, 0x25, 0xd9, 0xfa, 0x04, 0x8f, 0x6b,
1668 			0xd5, 0xa3, 0x83, 0xd6, 0xf2, 0xca, 0x82, 0xd5,
1669 			0xe2, 0x8e, 0x3f, 0xe6, 0x07, 0xcd, 0xa2, 0x22,
1670 			0xa0, 0x3f, 0x0a, 0x7c, 0x09, 0x0f, 0x9f, 0xf4,
1671 			0xe3, 0x59, 0x4b, 0x43, 0x0c, 0xfd, 0x5a, 0x96,
1672 			0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03,
1673 			0x02, 0x08, 0x01, 0x01, 0x0a, 0xa1, 0x54, 0x03,
1674 			0x52, 0x00, 0x04, 0x3d, 0x8c, 0x4c, 0xbb, 0x30,
1675 			0x3f, 0xa0, 0x84, 0x61, 0x43, 0x50, 0x23, 0x70,
1676 			0xe3, 0x70, 0xb6, 0x4d, 0x89, 0xc8, 0x95, 0xa0,
1677 			0x09, 0xae, 0xfc, 0x55, 0x9c, 0x2f, 0xef, 0x16,
1678 			0xc0, 0x72, 0x3c, 0x3e, 0x07, 0xa1, 0xbb, 0xd8,
1679 			0x8a, 0xfa, 0xaf, 0x9f, 0xaf, 0x07, 0x7c, 0x15,
1680 			0x4d, 0x75, 0x6b, 0xf5, 0x25, 0x65, 0x5b, 0xc4,
1681 			0x78, 0x59, 0x22, 0xe5, 0x92, 0x5c, 0xc2, 0x8f,
1682 			0xdc, 0x97, 0x59, 0x82, 0xc5, 0x0d, 0x24, 0x70,
1683 			0x03, 0xbe, 0xa5, 0x05, 0x88, 0x16, 0x47, 0x9f,
1684 			0xe5, 0x3b, 0xb8,
1685 		},
1686 		.hex =	"043D8C4CBB303FA0"
1687 			"846143502370E370"
1688 			"B64D89C895A009AE"
1689 			"FC559C2FEF16C072"
1690 			"3C3E07A1BBD88AFA"
1691 			"AF9FAF077C154D75"
1692 			"6BF525655BC47859"
1693 			"22E5925CC28FDC97"
1694 			"5982C50D247003BE"
1695 			"A5058816479FE53B"
1696 			"B8",
1697 		.oct_len = 81,
1698 		.oct = {
1699 			0x04, 0x3d, 0x8c, 0x4c, 0xbb, 0x30, 0x3f, 0xa0,
1700 			0x84, 0x61, 0x43, 0x50, 0x23, 0x70, 0xe3, 0x70,
1701 			0xb6, 0x4d, 0x89, 0xc8, 0x95, 0xa0, 0x09, 0xae,
1702 			0xfc, 0x55, 0x9c, 0x2f, 0xef, 0x16, 0xc0, 0x72,
1703 			0x3c, 0x3e, 0x07, 0xa1, 0xbb, 0xd8, 0x8a, 0xfa,
1704 			0xaf, 0x9f, 0xaf, 0x07, 0x7c, 0x15, 0x4d, 0x75,
1705 			0x6b, 0xf5, 0x25, 0x65, 0x5b, 0xc4, 0x78, 0x59,
1706 			0x22, 0xe5, 0x92, 0x5c, 0xc2, 0x8f, 0xdc, 0x97,
1707 			0x59, 0x82, 0xc5, 0x0d, 0x24, 0x70, 0x03, 0xbe,
1708 			0xa5, 0x05, 0x88, 0x16, 0x47, 0x9f, 0xe5, 0x3b,
1709 			0xb8,
1710 		},
1711 	},
1712 	{
1713 		.name = "brainpoolP384r1",
1714 		.der_len = 171,
1715 		.der = {
1716 			0x30, 0x81, 0xa8, 0x02, 0x01, 0x01, 0x04, 0x30,
1717 			0x02, 0x57, 0xb6, 0xfe, 0x31, 0xda, 0x87, 0xcd,
1718 			0x68, 0x2a, 0x67, 0x98, 0xd1, 0x72, 0x5c, 0xd8,
1719 			0x2e, 0x25, 0xf9, 0x39, 0x36, 0x3b, 0x93, 0x98,
1720 			0x79, 0x81, 0xc0, 0x7e, 0xa3, 0x44, 0x99, 0xd8,
1721 			0xe5, 0x07, 0x1f, 0xea, 0xa1, 0x66, 0x60, 0x00,
1722 			0x29, 0x84, 0xa3, 0x35, 0xdd, 0x64, 0x96, 0x93,
1723 			0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03,
1724 			0x02, 0x08, 0x01, 0x01, 0x0b, 0xa1, 0x64, 0x03,
1725 			0x62, 0x00, 0x04, 0x4f, 0x79, 0xe0, 0xe7, 0xf9,
1726 			0x57, 0x33, 0xf9, 0x9d, 0x6a, 0x5c, 0x00, 0x6e,
1727 			0xb8, 0xbc, 0xe6, 0x4f, 0x70, 0x1d, 0x73, 0x02,
1728 			0x5c, 0x87, 0xa1, 0x88, 0xea, 0xe3, 0x57, 0x5c,
1729 			0x1a, 0x27, 0x40, 0xcf, 0xcc, 0x6f, 0x7e, 0x6d,
1730 			0xfd, 0x96, 0x0b, 0xaa, 0xc5, 0x02, 0x92, 0x10,
1731 			0x6d, 0x7e, 0xd5, 0x17, 0xda, 0xab, 0x52, 0x9b,
1732 			0xcd, 0x87, 0x08, 0x64, 0x2a, 0x61, 0x03, 0xc9,
1733 			0xfe, 0x97, 0x79, 0xf0, 0x5c, 0x84, 0x72, 0x50,
1734 			0x53, 0x95, 0x56, 0x7a, 0x97, 0xce, 0x36, 0x13,
1735 			0x23, 0x78, 0x31, 0x82, 0x36, 0x07, 0x45, 0xad,
1736 			0x92, 0x00, 0xaf, 0x3d, 0xe8, 0x5a, 0x7d, 0x7b,
1737 			0x63, 0xc2, 0xde,
1738 		},
1739 		.hex =	"044F79E0E7F95733"
1740 			"F99D6A5C006EB8BC"
1741 			"E64F701D73025C87"
1742 			"A188EAE3575C1A27"
1743 			"40CFCC6F7E6DFD96"
1744 			"0BAAC50292106D7E"
1745 			"D517DAAB529BCD87"
1746 			"08642A6103C9FE97"
1747 			"79F05C8472505395"
1748 			"567A97CE36132378"
1749 			"3182360745AD9200"
1750 			"AF3DE85A7D7B63C2"
1751 			"DE",
1752 		.oct_len = 97,
1753 		.oct = {
1754 			0x04, 0x4f, 0x79, 0xe0, 0xe7, 0xf9, 0x57, 0x33,
1755 			0xf9, 0x9d, 0x6a, 0x5c, 0x00, 0x6e, 0xb8, 0xbc,
1756 			0xe6, 0x4f, 0x70, 0x1d, 0x73, 0x02, 0x5c, 0x87,
1757 			0xa1, 0x88, 0xea, 0xe3, 0x57, 0x5c, 0x1a, 0x27,
1758 			0x40, 0xcf, 0xcc, 0x6f, 0x7e, 0x6d, 0xfd, 0x96,
1759 			0x0b, 0xaa, 0xc5, 0x02, 0x92, 0x10, 0x6d, 0x7e,
1760 			0xd5, 0x17, 0xda, 0xab, 0x52, 0x9b, 0xcd, 0x87,
1761 			0x08, 0x64, 0x2a, 0x61, 0x03, 0xc9, 0xfe, 0x97,
1762 			0x79, 0xf0, 0x5c, 0x84, 0x72, 0x50, 0x53, 0x95,
1763 			0x56, 0x7a, 0x97, 0xce, 0x36, 0x13, 0x23, 0x78,
1764 			0x31, 0x82, 0x36, 0x07, 0x45, 0xad, 0x92, 0x00,
1765 			0xaf, 0x3d, 0xe8, 0x5a, 0x7d, 0x7b, 0x63, 0xc2,
1766 			0xde,
1767 		},
1768 	},
1769 	{
1770 		.name = "brainpoolP384t1",
1771 		.der_len = 171,
1772 		.der = {
1773 			0x30, 0x81, 0xa8, 0x02, 0x01, 0x01, 0x04, 0x30,
1774 			0x35, 0xea, 0xbc, 0x66, 0xd4, 0xa9, 0xc0, 0xe1,
1775 			0xcd, 0xd4, 0xe5, 0xb1, 0xac, 0x8f, 0x66, 0x82,
1776 			0x56, 0xc1, 0xbd, 0xf2, 0xf5, 0x30, 0x95, 0xab,
1777 			0x30, 0xaa, 0xc0, 0xc3, 0x07, 0xca, 0x97, 0xc9,
1778 			0x53, 0x45, 0xd3, 0xff, 0xbf, 0xfe, 0xdf, 0x39,
1779 			0x32, 0x40, 0xe0, 0x45, 0x15, 0xa7, 0x22, 0x5f,
1780 			0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03,
1781 			0x02, 0x08, 0x01, 0x01, 0x0c, 0xa1, 0x64, 0x03,
1782 			0x62, 0x00, 0x04, 0x85, 0xdb, 0x57, 0x4b, 0x71,
1783 			0xb1, 0x65, 0x93, 0x51, 0x83, 0x7c, 0xb3, 0x24,
1784 			0x07, 0x6b, 0x7b, 0x57, 0x33, 0x73, 0x3a, 0xa6,
1785 			0x14, 0x86, 0x83, 0xa8, 0x88, 0x81, 0xf2, 0x90,
1786 			0xdf, 0x93, 0x4f, 0x67, 0x41, 0xef, 0xcb, 0x35,
1787 			0x14, 0xad, 0x4c, 0x67, 0x0b, 0xdb, 0x86, 0x03,
1788 			0x5e, 0x6d, 0x5e, 0x7e, 0x4b, 0x0f, 0x73, 0x9e,
1789 			0x73, 0x50, 0x86, 0x29, 0x09, 0x7c, 0x38, 0xfc,
1790 			0xbe, 0xaf, 0x59, 0x9c, 0x69, 0xdf, 0xb4, 0x60,
1791 			0x14, 0x3e, 0xb2, 0x1a, 0x72, 0x86, 0x57, 0xcb,
1792 			0x6b, 0x42, 0x20, 0x67, 0x7f, 0xbc, 0xa8, 0x57,
1793 			0x88, 0x76, 0x72, 0x9a, 0xb4, 0xea, 0xc0, 0x48,
1794 			0x01, 0x5d, 0x8e,
1795 		},
1796 		.hex =	"0485DB574B71B165"
1797 			"9351837CB324076B"
1798 			"7B5733733AA61486"
1799 			"83A88881F290DF93"
1800 			"4F6741EFCB3514AD"
1801 			"4C670BDB86035E6D"
1802 			"5E7E4B0F739E7350"
1803 			"8629097C38FCBEAF"
1804 			"599C69DFB460143E"
1805 			"B21A728657CB6B42"
1806 			"20677FBCA8578876"
1807 			"729AB4EAC048015D"
1808 			"8E",
1809 		.oct_len = 97,
1810 		.oct = {
1811 			0x04, 0x85, 0xdb, 0x57, 0x4b, 0x71, 0xb1, 0x65,
1812 			0x93, 0x51, 0x83, 0x7c, 0xb3, 0x24, 0x07, 0x6b,
1813 			0x7b, 0x57, 0x33, 0x73, 0x3a, 0xa6, 0x14, 0x86,
1814 			0x83, 0xa8, 0x88, 0x81, 0xf2, 0x90, 0xdf, 0x93,
1815 			0x4f, 0x67, 0x41, 0xef, 0xcb, 0x35, 0x14, 0xad,
1816 			0x4c, 0x67, 0x0b, 0xdb, 0x86, 0x03, 0x5e, 0x6d,
1817 			0x5e, 0x7e, 0x4b, 0x0f, 0x73, 0x9e, 0x73, 0x50,
1818 			0x86, 0x29, 0x09, 0x7c, 0x38, 0xfc, 0xbe, 0xaf,
1819 			0x59, 0x9c, 0x69, 0xdf, 0xb4, 0x60, 0x14, 0x3e,
1820 			0xb2, 0x1a, 0x72, 0x86, 0x57, 0xcb, 0x6b, 0x42,
1821 			0x20, 0x67, 0x7f, 0xbc, 0xa8, 0x57, 0x88, 0x76,
1822 			0x72, 0x9a, 0xb4, 0xea, 0xc0, 0x48, 0x01, 0x5d,
1823 			0x8e,
1824 		},
1825 	},
1826 	{
1827 		.name = "brainpoolP512r1",
1828 		.der_len = 221,
1829 		.der = {
1830 			0x30, 0x81, 0xda, 0x02, 0x01, 0x01, 0x04, 0x40,
1831 			0x7e, 0x04, 0x7d, 0xab, 0x42, 0xc6, 0xdb, 0x95,
1832 			0xfb, 0x22, 0x0b, 0xe4, 0x09, 0xff, 0x4a, 0x1e,
1833 			0x7b, 0x42, 0x62, 0x82, 0x41, 0xf4, 0x1e, 0xc2,
1834 			0x1f, 0x9e, 0x52, 0xea, 0xce, 0x1b, 0x75, 0x07,
1835 			0x7c, 0xaf, 0x49, 0xdf, 0xf3, 0x20, 0xfa, 0x88,
1836 			0x23, 0xc4, 0x5e, 0x6d, 0x82, 0x45, 0x32, 0x19,
1837 			0x04, 0x4a, 0x3d, 0x80, 0xa1, 0xa8, 0x99, 0x09,
1838 			0xce, 0x78, 0xde, 0x32, 0x18, 0xf4, 0x83, 0x2c,
1839 			0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03,
1840 			0x02, 0x08, 0x01, 0x01, 0x0d, 0xa1, 0x81, 0x85,
1841 			0x03, 0x81, 0x82, 0x00, 0x04, 0x1e, 0x99, 0xea,
1842 			0x54, 0xb6, 0x1a, 0x4f, 0x44, 0x25, 0xf4, 0xf8,
1843 			0xbe, 0x33, 0x7c, 0xd1, 0x62, 0x35, 0xf5, 0xd1,
1844 			0x8e, 0x9f, 0xae, 0xa8, 0x8f, 0x6d, 0x61, 0x27,
1845 			0x2d, 0x2a, 0xb1, 0x96, 0x48, 0x6d, 0xb2, 0x63,
1846 			0x05, 0x9f, 0xec, 0xa1, 0xcd, 0x65, 0x45, 0xc8,
1847 			0xcd, 0xf1, 0xa4, 0xba, 0x20, 0xb7, 0xe4, 0xc7,
1848 			0x92, 0x3c, 0x1f, 0x16, 0xf4, 0x5b, 0x75, 0xe4,
1849 			0x2a, 0x2e, 0x44, 0x72, 0x65, 0x63, 0xc3, 0x78,
1850 			0x54, 0x50, 0xcb, 0x50, 0xe0, 0xbe, 0xe7, 0x6f,
1851 			0x2a, 0xdc, 0x24, 0x7b, 0xf8, 0x4b, 0xa8, 0xe2,
1852 			0x1b, 0x27, 0x00, 0x2d, 0xe8, 0x99, 0xdc, 0x5f,
1853 			0xa4, 0x43, 0xa8, 0xf7, 0xb1, 0x55, 0xea, 0xd7,
1854 			0x02, 0x09, 0x08, 0x97, 0x5f, 0x21, 0x1e, 0x16,
1855 			0xa0, 0xd8, 0x27, 0xe4, 0x5e, 0x3a, 0xa5, 0x51,
1856 			0x68, 0xe7, 0x19, 0xc1, 0x7d, 0xb6, 0x9d, 0xb9,
1857 			0xc6, 0xc2, 0x1b, 0x48, 0x7f,
1858 		},
1859 		.hex =	"041E99EA54B61A4F"
1860 			"4425F4F8BE337CD1"
1861 			"6235F5D18E9FAEA8"
1862 			"8F6D61272D2AB196"
1863 			"486DB263059FECA1"
1864 			"CD6545C8CDF1A4BA"
1865 			"20B7E4C7923C1F16"
1866 			"F45B75E42A2E4472"
1867 			"6563C3785450CB50"
1868 			"E0BEE76F2ADC247B"
1869 			"F84BA8E21B27002D"
1870 			"E899DC5FA443A8F7"
1871 			"B155EAD702090897"
1872 			"5F211E16A0D827E4"
1873 			"5E3AA55168E719C1"
1874 			"7DB69DB9C6C21B48"
1875 			"7F",
1876 		.oct_len = 129,
1877 		.oct = {
1878 			0x04, 0x1e, 0x99, 0xea, 0x54, 0xb6, 0x1a, 0x4f,
1879 			0x44, 0x25, 0xf4, 0xf8, 0xbe, 0x33, 0x7c, 0xd1,
1880 			0x62, 0x35, 0xf5, 0xd1, 0x8e, 0x9f, 0xae, 0xa8,
1881 			0x8f, 0x6d, 0x61, 0x27, 0x2d, 0x2a, 0xb1, 0x96,
1882 			0x48, 0x6d, 0xb2, 0x63, 0x05, 0x9f, 0xec, 0xa1,
1883 			0xcd, 0x65, 0x45, 0xc8, 0xcd, 0xf1, 0xa4, 0xba,
1884 			0x20, 0xb7, 0xe4, 0xc7, 0x92, 0x3c, 0x1f, 0x16,
1885 			0xf4, 0x5b, 0x75, 0xe4, 0x2a, 0x2e, 0x44, 0x72,
1886 			0x65, 0x63, 0xc3, 0x78, 0x54, 0x50, 0xcb, 0x50,
1887 			0xe0, 0xbe, 0xe7, 0x6f, 0x2a, 0xdc, 0x24, 0x7b,
1888 			0xf8, 0x4b, 0xa8, 0xe2, 0x1b, 0x27, 0x00, 0x2d,
1889 			0xe8, 0x99, 0xdc, 0x5f, 0xa4, 0x43, 0xa8, 0xf7,
1890 			0xb1, 0x55, 0xea, 0xd7, 0x02, 0x09, 0x08, 0x97,
1891 			0x5f, 0x21, 0x1e, 0x16, 0xa0, 0xd8, 0x27, 0xe4,
1892 			0x5e, 0x3a, 0xa5, 0x51, 0x68, 0xe7, 0x19, 0xc1,
1893 			0x7d, 0xb6, 0x9d, 0xb9, 0xc6, 0xc2, 0x1b, 0x48,
1894 			0x7f,
1895 		},
1896 	},
1897 	{
1898 		.name = "brainpoolP512t1",
1899 		.der_len = 221,
1900 		.der = {
1901 			0x30, 0x81, 0xda, 0x02, 0x01, 0x01, 0x04, 0x40,
1902 			0xa0, 0xcb, 0xab, 0x2e, 0xdb, 0xb0, 0x17, 0x53,
1903 			0x91, 0x23, 0x8c, 0x86, 0x29, 0x8b, 0x33, 0x27,
1904 			0x27, 0x86, 0x71, 0xdd, 0x9f, 0x92, 0x8a, 0x8a,
1905 			0x28, 0xac, 0x1f, 0x4b, 0x67, 0x8d, 0xd3, 0x7a,
1906 			0x71, 0xd9, 0x95, 0x3c, 0xc2, 0x48, 0x9a, 0x1e,
1907 			0x75, 0xcf, 0x33, 0x6f, 0xdc, 0x88, 0x8c, 0x29,
1908 			0x1d, 0x41, 0xf8, 0xe1, 0xb3, 0x8f, 0xf9, 0x9e,
1909 			0x13, 0x14, 0xbc, 0x4f, 0xa5, 0x8e, 0x06, 0xba,
1910 			0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03,
1911 			0x02, 0x08, 0x01, 0x01, 0x0e, 0xa1, 0x81, 0x85,
1912 			0x03, 0x81, 0x82, 0x00, 0x04, 0x5b, 0x2b, 0x47,
1913 			0x83, 0x61, 0xea, 0x80, 0x14, 0x85, 0x06, 0xe7,
1914 			0x03, 0xbd, 0x24, 0x04, 0x47, 0x5d, 0x33, 0x4e,
1915 			0xde, 0x0c, 0x92, 0x09, 0x54, 0x77, 0x53, 0x0e,
1916 			0x33, 0x30, 0x73, 0xc0, 0xc0, 0x6a, 0xf2, 0xb5,
1917 			0xb5, 0xd4, 0xd3, 0x02, 0x2f, 0x20, 0xe2, 0x88,
1918 			0xb2, 0x07, 0x4a, 0x9f, 0x90, 0xbf, 0xba, 0xb5,
1919 			0x3d, 0xc4, 0x5b, 0x65, 0x76, 0xb5, 0xe5, 0xa1,
1920 			0x7d, 0x63, 0x39, 0x57, 0xaa, 0x1d, 0x1f, 0x99,
1921 			0x52, 0x43, 0x5d, 0x0b, 0x58, 0xa6, 0x51, 0x1e,
1922 			0x6f, 0x7b, 0x9e, 0x2f, 0x45, 0x5a, 0x2d, 0x6f,
1923 			0xaa, 0x2b, 0xfc, 0xe1, 0x9f, 0x78, 0x11, 0x70,
1924 			0x80, 0xf8, 0xfe, 0x51, 0x45, 0x12, 0xbf, 0x79,
1925 			0xd8, 0xaf, 0x05, 0x59, 0x14, 0x01, 0x81, 0x9c,
1926 			0x12, 0x5c, 0x8d, 0x4d, 0xed, 0xc7, 0x44, 0x61,
1927 			0x68, 0x0f, 0x3f, 0x34, 0xee, 0x90, 0x4e, 0xab,
1928 			0x80, 0x7c, 0x41, 0xd7, 0x8f,
1929 		},
1930 		.hex =	"045B2B478361EA80"
1931 			"148506E703BD2404"
1932 			"475D334EDE0C9209"
1933 			"5477530E333073C0"
1934 			"C06AF2B5B5D4D302"
1935 			"2F20E288B2074A9F"
1936 			"90BFBAB53DC45B65"
1937 			"76B5E5A17D633957"
1938 			"AA1D1F9952435D0B"
1939 			"58A6511E6F7B9E2F"
1940 			"455A2D6FAA2BFCE1"
1941 			"9F78117080F8FE51"
1942 			"4512BF79D8AF0559"
1943 			"1401819C125C8D4D"
1944 			"EDC74461680F3F34"
1945 			"EE904EAB807C41D7"
1946 			"8F",
1947 		.oct_len = 129,
1948 		.oct = {
1949 			0x04, 0x5b, 0x2b, 0x47, 0x83, 0x61, 0xea, 0x80,
1950 			0x14, 0x85, 0x06, 0xe7, 0x03, 0xbd, 0x24, 0x04,
1951 			0x47, 0x5d, 0x33, 0x4e, 0xde, 0x0c, 0x92, 0x09,
1952 			0x54, 0x77, 0x53, 0x0e, 0x33, 0x30, 0x73, 0xc0,
1953 			0xc0, 0x6a, 0xf2, 0xb5, 0xb5, 0xd4, 0xd3, 0x02,
1954 			0x2f, 0x20, 0xe2, 0x88, 0xb2, 0x07, 0x4a, 0x9f,
1955 			0x90, 0xbf, 0xba, 0xb5, 0x3d, 0xc4, 0x5b, 0x65,
1956 			0x76, 0xb5, 0xe5, 0xa1, 0x7d, 0x63, 0x39, 0x57,
1957 			0xaa, 0x1d, 0x1f, 0x99, 0x52, 0x43, 0x5d, 0x0b,
1958 			0x58, 0xa6, 0x51, 0x1e, 0x6f, 0x7b, 0x9e, 0x2f,
1959 			0x45, 0x5a, 0x2d, 0x6f, 0xaa, 0x2b, 0xfc, 0xe1,
1960 			0x9f, 0x78, 0x11, 0x70, 0x80, 0xf8, 0xfe, 0x51,
1961 			0x45, 0x12, 0xbf, 0x79, 0xd8, 0xaf, 0x05, 0x59,
1962 			0x14, 0x01, 0x81, 0x9c, 0x12, 0x5c, 0x8d, 0x4d,
1963 			0xed, 0xc7, 0x44, 0x61, 0x68, 0x0f, 0x3f, 0x34,
1964 			0xee, 0x90, 0x4e, 0xab, 0x80, 0x7c, 0x41, 0xd7,
1965 			0x8f,
1966 		},
1967 	},
1968 	{
1969 		.name = "FRP256v1",
1970 		.der_len = 123,
1971 		.der = {
1972 			0x30, 0x79, 0x02, 0x01, 0x01, 0x04, 0x20, 0x66,
1973 			0xe4, 0xdb, 0x37, 0x46, 0x8d, 0xa1, 0xc8, 0x20,
1974 			0x0d, 0xdf, 0xcb, 0x3b, 0x5c, 0x5b, 0x84, 0xe1,
1975 			0x89, 0xed, 0x30, 0x37, 0xaa, 0xfa, 0xb2, 0x5b,
1976 			0xf4, 0xf6, 0x13, 0x66, 0xfe, 0xfc, 0x7c, 0xa0,
1977 			0x0c, 0x06, 0x0a, 0x2a, 0x81, 0x7a, 0x01, 0x81,
1978 			0x5f, 0x65, 0x82, 0x00, 0x01, 0xa1, 0x44, 0x03,
1979 			0x42, 0x00, 0x04, 0x17, 0xc7, 0xae, 0x1b, 0xe4,
1980 			0xc6, 0xd6, 0x3a, 0xcf, 0x6b, 0x7e, 0x43, 0x29,
1981 			0x9f, 0xdc, 0xc2, 0xa3, 0x90, 0x53, 0x62, 0x42,
1982 			0x6e, 0xa3, 0xa4, 0xca, 0xd3, 0xf6, 0x53, 0x53,
1983 			0xd4, 0xa6, 0x1f, 0xa8, 0x03, 0x1f, 0x6d, 0xd4,
1984 			0x75, 0x77, 0x23, 0xf7, 0x92, 0xa4, 0x7c, 0x5a,
1985 			0x4c, 0xc7, 0xc6, 0x96, 0x54, 0x62, 0x94, 0x9b,
1986 			0xa7, 0xe0, 0x31, 0x1c, 0x4d, 0x1c, 0xa8, 0x2a,
1987 			0x51, 0x11, 0x24,
1988 		},
1989 		.hex =	"0417C7AE1BE4C6D6"
1990 			"3ACF6B7E43299FDC"
1991 			"C2A3905362426EA3"
1992 			"A4CAD3F65353D4A6"
1993 			"1FA8031F6DD47577"
1994 			"23F792A47C5A4CC7"
1995 			"C6965462949BA7E0"
1996 			"311C4D1CA82A5111"
1997 			"24",
1998 		.oct_len = 65,
1999 		.oct = {
2000 			0x04, 0x17, 0xc7, 0xae, 0x1b, 0xe4, 0xc6, 0xd6,
2001 			0x3a, 0xcf, 0x6b, 0x7e, 0x43, 0x29, 0x9f, 0xdc,
2002 			0xc2, 0xa3, 0x90, 0x53, 0x62, 0x42, 0x6e, 0xa3,
2003 			0xa4, 0xca, 0xd3, 0xf6, 0x53, 0x53, 0xd4, 0xa6,
2004 			0x1f, 0xa8, 0x03, 0x1f, 0x6d, 0xd4, 0x75, 0x77,
2005 			0x23, 0xf7, 0x92, 0xa4, 0x7c, 0x5a, 0x4c, 0xc7,
2006 			0xc6, 0x96, 0x54, 0x62, 0x94, 0x9b, 0xa7, 0xe0,
2007 			0x31, 0x1c, 0x4d, 0x1c, 0xa8, 0x2a, 0x51, 0x11,
2008 			0x24,
2009 		},
2010 	},
2011 };
2012 
2013 #define N_EC_PRIVATE_KEYS (sizeof(ec_private_keys) / sizeof(ec_private_keys[0]))
2014 
2015 static EC_KEY *
2016 ec_key_check_sanity(const struct ec_private_key *key)
2017 {
2018 	EC_KEY *ec_key;
2019 	const unsigned char *p;
2020 	unsigned char *der = NULL;
2021 	int der_len = 0;
2022 	unsigned int flags;
2023 	uint8_t form;
2024 
2025 	p = key->der;
2026 	if ((ec_key = d2i_ECPrivateKey(NULL, &p, key->der_len)) == NULL) {
2027 		fprintf(stderr, "FAIL: d2i_ECPrivateKey for %s\n", key->name);
2028 		goto err;
2029 	}
2030 
2031 	if ((flags = EC_KEY_get_enc_flags(ec_key)) != 0) {
2032 		fprintf(stderr, "FAIL: EC_KEY_get_enc_flags() returned %x for %s\n",
2033 		    flags, key->name);
2034 		goto err;
2035 	}
2036 	if ((form = EC_KEY_get_conv_form(ec_key)) != POINT_CONVERSION_UNCOMPRESSED) {
2037 		fprintf(stderr, "FAIL: got conversion form %02x, want %02x\n",
2038 		    form, POINT_CONVERSION_UNCOMPRESSED);
2039 		goto err;
2040 	}
2041 
2042 	ERR_clear_error();
2043 	if (!EC_KEY_check_key(ec_key)) {
2044 		fprintf(stderr, "FAIL: EC_KEY_check_key() for %s\n", key->name);
2045 		ERR_print_errors_fp(stderr);
2046 		goto err;
2047 	}
2048 
2049 	der = NULL;
2050 	if ((der_len = i2d_ECPrivateKey(ec_key, &der)) <= 0) {
2051 		fprintf(stderr, "FAIL: i2d_ECPrivateKey() for %s\n", key->name);
2052 		der_len = 0;
2053 		goto err;
2054 	}
2055 
2056 	if (compare_data(key->name, der, der_len, key->der, key->der_len) == -1)
2057 		goto err;
2058 
2059 	freezero(der, der_len);
2060 	der = NULL;
2061 
2062 	return ec_key;
2063 
2064  err:
2065 	EC_KEY_free(ec_key);
2066 	freezero(der, der_len);
2067 
2068 	return NULL;
2069 }
2070 
2071 static int
2072 ec_key_test_point_encoding(const struct ec_private_key *key, const EC_KEY *ec_key)
2073 {
2074 	const EC_GROUP *group;
2075 	const EC_POINT *ec_public_point;
2076 	char *hex = NULL;
2077 	unsigned char *ostr = NULL;
2078 	int hex_len = 0, ostr_len = 0;
2079 	int failed = 1;
2080 
2081 	if ((group = EC_KEY_get0_group(ec_key)) == NULL) {
2082 		fprintf(stderr, "FAIL: EC_KEY_get0_group() for %s\n", key->name);
2083 		goto err;
2084 	}
2085 	if ((ec_public_point = EC_KEY_get0_public_key(ec_key)) == NULL) {
2086 		fprintf(stderr, "FAIL: EC_KEY_get0_public_key() for %s\n", key->name);
2087 		goto err;
2088 	}
2089 
2090 	if ((hex = EC_POINT_point2hex(group, ec_public_point,
2091 	    POINT_CONVERSION_UNCOMPRESSED, NULL)) == NULL) {
2092 		fprintf(stderr, "FAIL: EC_POINT_point2hex() for %s\n", key->name);
2093 		goto err;
2094 	}
2095 
2096 	if ((hex_len = strlen(hex)) != 2 * key->oct_len) {
2097 		fprintf(stderr, "FAIL: hex_len: %d, oct_len %d for %s\n",
2098 		    hex_len, key->oct_len, key->name);
2099 		goto err;
2100 	}
2101 
2102 	if (compare_data(key->name, hex, hex_len, key->hex, hex_len) == -1) {
2103 		fprintf(stderr, "FAIL: EC_POINT_point2hex() comparison for %s\n",
2104 		    key->name);
2105 		goto err;
2106 	}
2107 
2108 	if ((ostr_len = i2o_ECPublicKey(ec_key, &ostr)) <= 0) {
2109 		fprintf(stderr, "FAIL: i2o_ECPublicKey for %s\n", key->name);
2110 		goto err;
2111 	}
2112 
2113 	if (compare_data(key->name, ostr, ostr_len, key->oct, key->oct_len) == -1) {
2114 		fprintf(stderr, "FAIL: i2o_ECPublicKey comparison for %s\n",
2115 		    key->name);
2116 		goto err;
2117 	}
2118 
2119 	failed = 0;
2120 
2121  err:
2122 	free(hex);
2123 	freezero(ostr, ostr_len);
2124 
2125 	return failed;
2126 }
2127 
2128 static int
2129 ec_key_test_point_versus_bn(const struct ec_private_key *key, const EC_KEY *ec_key)
2130 {
2131 	const EC_GROUP *group;
2132 	const EC_POINT *ec_public_point;
2133 	EC_POINT *point = NULL;
2134 	BIGNUM *hex_bn = NULL, *point_bn = NULL;
2135 	int rv;
2136 	int failed = 1;
2137 
2138 	if ((group = EC_KEY_get0_group(ec_key)) == NULL) {
2139 		fprintf(stderr, "FAIL: EC_KEY_get0_group() for %s\n", key->name);
2140 		goto err;
2141 	}
2142 	if ((ec_public_point = EC_KEY_get0_public_key(ec_key)) == NULL) {
2143 		fprintf(stderr, "FAIL: EC_KEY_get0_public_key() for %s\n", key->name);
2144 		goto err;
2145 	}
2146 
2147 	/*
2148 	 * Check that point2bn matches hex2bn.
2149 	 */
2150 
2151 	if ((point_bn = BN_new()) == NULL)
2152 		err(1, "BN_new()");
2153 	if (EC_POINT_point2bn(group, ec_public_point,
2154 	    POINT_CONVERSION_UNCOMPRESSED, point_bn, NULL) == NULL) {
2155 		fprintf(stderr, "FAIL: EC_POINT_point2bn() for %s\n", key->name);
2156 		goto err;
2157 	}
2158 
2159 	if (BN_hex2bn(&hex_bn, key->hex) == 0) {
2160 		fprintf(stderr, "FAIL: BN_hex2bn() for %s\n", key->name);
2161 		goto err;
2162 	}
2163 
2164 	if (BN_cmp(hex_bn, point_bn) != 0) {
2165 		fprintf(stderr, "FAIL: mismatch between "
2166 		    "hex point and curve point for %s\n", key->name);
2167 		goto err;
2168 	}
2169 
2170 	/*
2171 	 * Translate back to a point on the curve.
2172 	 */
2173 
2174 	if ((point = EC_POINT_hex2point(group, key->hex, NULL, NULL)) == NULL) {
2175 		fprintf(stderr, "FAIL: EC_POINT_hex2point() failed for %s\n",
2176 		    key->name);
2177 		goto err;
2178 	}
2179 
2180 	if ((rv = EC_POINT_cmp(group, ec_public_point, point, NULL)) != 0) {
2181 		fprintf(stderr, "FAIL: EC_POINT_cmp() returned %d for %s\n",
2182 		    rv, key->name);
2183 		goto err;
2184 	}
2185 
2186 	/*
2187 	 * Invalidate the point by doubling and inverting it. Then see if
2188 	 * point reuse works.
2189 	 */
2190 
2191 	if (!EC_POINT_dbl(group, point, point, NULL)) {
2192 		fprintf(stderr, "FAIL: EC_POINT_dbl() failed for %s\n",
2193 		    key->name);
2194 		goto err;
2195 	}
2196 	if (!EC_POINT_invert(group, point, NULL)) {
2197 		fprintf(stderr, "FAIL: EC_POINT_invert() failed for %s\n",
2198 		    key->name);
2199 		goto err;
2200 	}
2201 	if (!EC_POINT_is_on_curve(group, point, NULL)) {
2202 		fprintf(stderr, "FAIL: EC_POINT_is_on_curve() failed for %s\n",
2203 		    key->name);
2204 		goto err;
2205 	}
2206 	if (EC_POINT_is_at_infinity(group, point)) {
2207 		fprintf(stderr, "FAIL: EC_POINT_is_at_infinity() is true for %s\n",
2208 		    key->name);
2209 		goto err;
2210 	}
2211 
2212 	/* The points are now different. */
2213 	if ((rv = EC_POINT_cmp(group, ec_public_point, point, NULL)) == 0) {
2214 		fprintf(stderr, "FAIL: EC_POINT_cmp() returned %d for %s\n",
2215 		    rv, key->name);
2216 		goto err;
2217 	}
2218 
2219 	if (EC_POINT_hex2point(group, key->hex, point, NULL) == NULL) {
2220 		fprintf(stderr, "FAIL: EC_POINT_hex2point() 2 failed for %s\n",
2221 		    key->name);
2222 		goto err;
2223 	}
2224 
2225 	/* And after reuse they should be the same again. */
2226 	if ((rv = EC_POINT_cmp(group, ec_public_point, point, NULL)) != 0) {
2227 		fprintf(stderr, "FAIL: EC_POINT_cmp() returned %d for %s\n",
2228 		    rv, key->name);
2229 		goto err;
2230 	}
2231 
2232 	failed = 0;
2233 
2234  err:
2235 	BN_free(hex_bn);
2236 	BN_free(point_bn);
2237 	EC_POINT_free(point);
2238 
2239 	return failed;
2240 }
2241 
2242 static int
2243 ec_key_test_i2o_and_o2i(const struct ec_private_key *key, const EC_KEY *ec_key_orig)
2244 {
2245 	EC_KEY *ec_key = NULL, *ec_pub_key = NULL;
2246 	const unsigned char *p;
2247 	unsigned char *ostr = NULL;
2248 	int ostr_len = 0;
2249 	uint8_t form;
2250 	int rv;
2251 	int failed = 1;
2252 
2253 	if ((ec_key = EC_KEY_dup(ec_key_orig)) == NULL) {
2254 		fprintf(stderr, "FAIL: EC_KEY_dup failed for %s", key->name);
2255 		goto err;
2256 	}
2257 
2258 	EC_KEY_set_conv_form(ec_key, POINT_CONVERSION_COMPRESSED);
2259 
2260 	ostr = NULL;
2261 	if ((ostr_len = i2o_ECPublicKey(ec_key, &ostr)) <= 0) {
2262 		fprintf(stderr, "FAIL: i2o_ECPublicKey for %s\n", key->name);
2263 		ostr_len = 0;
2264 		goto err;
2265 	}
2266 
2267 	if ((ec_pub_key = EC_KEY_new()) == NULL)
2268 		errx(1, "EC_KEY_new");
2269 	if (!EC_KEY_set_group(ec_pub_key, EC_KEY_get0_group(ec_key))) {
2270 		fprintf(stderr, "FAIL: EC_KEY_set_group() for %s\n", key->name);
2271 		goto err;
2272 	}
2273 
2274 	if ((form = EC_KEY_get_conv_form(ec_pub_key)) != POINT_CONVERSION_UNCOMPRESSED) {
2275 		fprintf(stderr, "FAIL: EC_KEY_get_conv_form() for %s:\n"
2276 		    "got %02x, want %02x\n", key->name, form, POINT_CONVERSION_UNCOMPRESSED);
2277 		goto err;
2278 	}
2279 
2280 	/* Need to pass in the public key to tell o2i about the group... */
2281 	p = ostr;
2282 	if (o2i_ECPublicKey(&ec_pub_key, &p, ostr_len) == NULL) {
2283 		fprintf(stderr, "FAIL: o2i_ECPublicKey() for %s\n", key->name);
2284 		goto err;
2285 	}
2286 
2287 	if ((form = EC_KEY_get_conv_form(ec_pub_key)) != POINT_CONVERSION_COMPRESSED) {
2288 		fprintf(stderr, "FAIL: EC_KEY_get_conv_form() for %s:\n"
2289 		    "got %02x, want %02x\n", key->name, form, POINT_CONVERSION_COMPRESSED);
2290 		goto err;
2291 	}
2292 
2293 	if ((rv = EC_POINT_cmp(EC_KEY_get0_group(ec_pub_key),
2294 	    EC_KEY_get0_public_key(ec_pub_key), EC_KEY_get0_public_key(ec_key),
2295 	    NULL)) != 0) {
2296 		fprintf(stderr, "FAIL: EC_POINT_cmp() returned %d for %s\n",
2297 		    rv, key->name);
2298 		goto err;
2299 	}
2300 
2301 	failed = 0;
2302 
2303  err:
2304 	EC_KEY_free(ec_key);
2305 	EC_KEY_free(ec_pub_key);
2306 	freezero(ostr, ostr_len);
2307 
2308 	return failed;
2309 }
2310 
2311 static int
2312 ec_key_test_hybrid_roundtrip(const struct ec_private_key *key,
2313     const EC_KEY *ec_key_orig)
2314 {
2315 	EC_KEY *ec_key = NULL, *ec_pub_key = NULL;
2316 	const unsigned char *p;
2317 	unsigned char *der = NULL;
2318 	int der_len = 0;
2319 	unsigned int flags;
2320 	int rv;
2321 	uint8_t form;
2322 	int failed = 1;
2323 
2324 	if ((ec_key = EC_KEY_new()) == NULL)
2325 		errx(1, "EC_KEY_new()");
2326 
2327 	if (EC_KEY_copy(ec_key, ec_key_orig) == NULL) {
2328 		fprintf(stderr, "FAIL: failed to kopy EC_KEY for %s\n", key->name);
2329 		goto err;
2330 	}
2331 
2332 	EC_KEY_set_conv_form(ec_key, POINT_CONVERSION_HYBRID);
2333 	EC_KEY_set_enc_flags(ec_key, EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY);
2334 
2335 	if ((der_len = i2d_ECPrivateKey(ec_key, &der)) <= 0) {
2336 		fprintf(stderr, "FAIL: i2d_ECPrivateKey(2) for %s\n", key->name);
2337 		der_len = 0;
2338 		goto err;
2339 	}
2340 
2341 	if ((ec_pub_key = EC_KEY_new()) == NULL)
2342 		errx(1, "EC_KEY_new");
2343 	if (!EC_KEY_set_group(ec_pub_key, EC_KEY_get0_group(ec_key))) {
2344 		fprintf(stderr, "FAIL: EC_KEY_set_group() for %s\n", key->name);
2345 		goto err;
2346 	}
2347 	/* Change away from the default to see if it changed below. */
2348 	EC_KEY_set_conv_form(ec_pub_key, POINT_CONVERSION_COMPRESSED);
2349 
2350 	if ((flags = EC_KEY_get_enc_flags(ec_pub_key)) != 0) {
2351 		fprintf(stderr, "FAIL: EC_KEY_get_enc_flags() returned %x for %s\n",
2352 		    flags, key->name);
2353 		goto err;
2354 	}
2355 
2356 	p = der;
2357 	if (d2i_ECPrivateKey(&ec_pub_key, &p, der_len) == NULL) {
2358 		fprintf(stderr, "FAIL: d2i_ECPrivateKey for public %s\n", key->name);
2359 		goto err;
2360 	}
2361 
2362 	/* For reasons of inconsistency, only EC_PKEY_NO_PUBKEY is set. */
2363 	if ((flags = EC_KEY_get_enc_flags(ec_pub_key)) != EC_PKEY_NO_PUBKEY) {
2364 		fprintf(stderr, "FAIL: EC_KEY_get_enc_flags() for public %s: "
2365 		    " got %x, want %x\n", key->name, flags, EC_PKEY_NO_PUBKEY);
2366 		goto err;
2367 	}
2368 
2369 	/* We had to compute the public key, so point conversion form is unchanged. */
2370 	if ((form = EC_KEY_get_conv_form(ec_pub_key)) != POINT_CONVERSION_COMPRESSED) {
2371 		fprintf(stderr, "FAIL: EC_KEY_get_conv_form() not compressed for %s:\n"
2372 		    "got %02x, want %02x\n", key->name, form, POINT_CONVERSION_COMPRESSED);
2373 		goto err;
2374 	}
2375 
2376 	if ((rv = EC_POINT_cmp(EC_KEY_get0_group(ec_pub_key),
2377 	    EC_KEY_get0_public_key(ec_pub_key), EC_KEY_get0_public_key(ec_key),
2378 	    NULL)) != 0) {
2379 		fprintf(stderr, "FAIL: EC_POINT_cmp() returned %d for %s "
2380 		    "after DER roundtrip\n", rv, key->name);
2381 		goto err;
2382 	}
2383 
2384 	failed = 0;
2385 
2386  err:
2387 	EC_KEY_free(ec_key);
2388 	EC_KEY_free(ec_pub_key);
2389 	freezero(der, der_len);
2390 
2391 	return failed;
2392 }
2393 
2394 static int
2395 ec_key_test_parameter_roundtrip(const struct ec_private_key *key,
2396     EC_KEY *ec_key)
2397 {
2398 	EC_KEY *ec_pub_key = NULL;
2399 	const unsigned char *p;
2400 	unsigned char *der = NULL;
2401 	int der_len = 0;
2402 	int rv;
2403 	int failed = 1;
2404 
2405 	if ((der_len = i2d_ECParameters(ec_key, &der)) <= 0) {
2406 		fprintf(stderr, "FAIL: i2d_ECParameters returned %d for %s\n",
2407 		    der_len, key->name);
2408 		goto err;
2409 	}
2410 
2411 	/* See if we leak on reuse, whether the curve is right or not. */
2412 	if ((ec_pub_key = EC_KEY_new_by_curve_name(NID_secp256k1)) == NULL)
2413 		errx(1, "EC_KEY_new_by_curve_name");
2414 
2415 	p = der;
2416 	if (d2i_ECParameters(&ec_pub_key, &p, der_len) == NULL) {
2417 		fprintf(stderr, "FAIL: d2i_ECParameters for %s\n", key->name);
2418 		goto err;
2419 	}
2420 
2421 	if ((rv = EC_GROUP_cmp(EC_KEY_get0_group(ec_key),
2422 	    EC_KEY_get0_group(ec_pub_key), NULL)) != 0) {
2423 		fprintf(stderr, "FAIL: EC_GROUP_cmp returned %d for %s\n",
2424 		    rv, key->name);
2425 		goto err;
2426 	}
2427 
2428 	failed = 0;
2429 
2430  err:
2431 	EC_KEY_free(ec_pub_key);
2432 	freezero(der, der_len);
2433 
2434 	return failed;
2435 }
2436 
2437 static int
2438 ec_group_check_private_key(const struct ec_private_key *key)
2439 {
2440 	EC_KEY *ec_key = NULL;
2441 	int failed = 0;
2442 
2443 	if ((ec_key = ec_key_check_sanity(key)) == NULL) {
2444 		fprintf(stderr, "FAIL: ec_key_check_sanity() for %s\n", key->name);
2445 		failed = 1;
2446 		goto err;
2447 	}
2448 
2449 	failed |= ec_key_test_point_encoding(key, ec_key);
2450 	failed |= ec_key_test_point_versus_bn(key, ec_key);
2451 	failed |= ec_key_test_i2o_and_o2i(key, ec_key);
2452 	failed |= ec_key_test_hybrid_roundtrip(key, ec_key);
2453 	failed |= ec_key_test_parameter_roundtrip(key, ec_key);
2454 
2455  err:
2456 	EC_KEY_free(ec_key);
2457 
2458 	return failed;
2459 }
2460 
2461 static int
2462 ec_group_check_private_keys(void)
2463 {
2464 	size_t i;
2465 	int failed = 0;
2466 
2467 	for (i = 0; i < N_EC_PRIVATE_KEYS; i++)
2468 		failed |= ec_group_check_private_key(&ec_private_keys[i]);
2469 
2470 	return failed;
2471 }
2472 
2473 int
2474 main(int argc, char **argv)
2475 {
2476 	int failed = 0;
2477 
2478 	failed |= ec_group_pkparameters_named_curve_test();
2479 	failed |= ec_group_pkparameters_parameters_test();
2480 	failed |= ec_group_pkparameters_correct_padding_test();
2481 	failed |= ec_group_roundtrip_builtin_curves();
2482 	failed |= ec_group_non_builtin_curves();
2483 	failed |= ec_group_check_private_keys();
2484 
2485 	return failed;
2486 }
2487