1 /*
2 * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4 *
5 * Licensed under the OpenSSL license (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11 #include "internal/nelem.h"
12 #include "testutil.h"
13
14 #ifndef OPENSSL_NO_EC
15 # include <openssl/ec.h>
16 # ifndef OPENSSL_NO_ENGINE
17 # include <openssl/engine.h>
18 # endif
19 # include <openssl/err.h>
20 # include <openssl/obj_mac.h>
21 # include <openssl/objects.h>
22 # include <openssl/rand.h>
23 # include <openssl/bn.h>
24 # include <openssl/opensslconf.h>
25
26 static size_t crv_len = 0;
27 static EC_builtin_curve *curves = NULL;
28
29 /* test multiplication with group order, long and negative scalars */
group_order_tests(EC_GROUP * group)30 static int group_order_tests(EC_GROUP *group)
31 {
32 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
33 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
34 const EC_POINT *G = NULL;
35 BN_CTX *ctx = NULL;
36 int i = 0, r = 0;
37
38 if (!TEST_ptr(n1 = BN_new())
39 || !TEST_ptr(n2 = BN_new())
40 || !TEST_ptr(order = BN_new())
41 || !TEST_ptr(ctx = BN_CTX_new())
42 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
43 || !TEST_ptr(P = EC_POINT_new(group))
44 || !TEST_ptr(Q = EC_POINT_new(group))
45 || !TEST_ptr(R = EC_POINT_new(group))
46 || !TEST_ptr(S = EC_POINT_new(group)))
47 goto err;
48
49 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
50 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
51 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
52 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
53 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
54 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
55 || !TEST_true(EC_POINT_copy(P, G))
56 || !TEST_true(BN_one(n1))
57 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
58 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
59 || !TEST_true(BN_sub(n1, order, n1))
60 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
61 || !TEST_true(EC_POINT_invert(group, Q, ctx))
62 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
63 goto err;
64
65 for (i = 1; i <= 2; i++) {
66 const BIGNUM *scalars[6];
67 const EC_POINT *points[6];
68
69 if (!TEST_true(BN_set_word(n1, i))
70 /*
71 * If i == 1, P will be the predefined generator for which
72 * EC_GROUP_precompute_mult has set up precomputation.
73 */
74 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
75 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
76 || !TEST_true(BN_one(n1))
77 /* n1 = 1 - order */
78 || !TEST_true(BN_sub(n1, n1, order))
79 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
80 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
81
82 /* n2 = 1 + order */
83 || !TEST_true(BN_add(n2, order, BN_value_one()))
84 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
85 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
86
87 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
88 || !TEST_true(BN_mul(n2, n1, n2, ctx))
89 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
90 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
91 goto err;
92
93 /* n2 = order^2 - 1 */
94 BN_set_negative(n2, 0);
95 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
96 /* Add P to verify the result. */
97 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
98 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
99
100 /* Exercise EC_POINTs_mul, including corner cases. */
101 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
102 goto err;
103
104 scalars[0] = scalars[1] = BN_value_one();
105 points[0] = points[1] = P;
106
107 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
108 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
109 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
110 goto err;
111
112 scalars[0] = n1;
113 points[0] = Q; /* => infinity */
114 scalars[1] = n2;
115 points[1] = P; /* => -P */
116 scalars[2] = n1;
117 points[2] = Q; /* => infinity */
118 scalars[3] = n2;
119 points[3] = Q; /* => infinity */
120 scalars[4] = n1;
121 points[4] = P; /* => P */
122 scalars[5] = n2;
123 points[5] = Q; /* => infinity */
124 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
125 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
126 goto err;
127 }
128
129 r = 1;
130 err:
131 if (r == 0 && i != 0)
132 TEST_info(i == 1 ? "allowing precomputation" :
133 "without precomputation");
134 EC_POINT_free(P);
135 EC_POINT_free(Q);
136 EC_POINT_free(R);
137 EC_POINT_free(S);
138 BN_free(n1);
139 BN_free(n2);
140 BN_free(order);
141 BN_CTX_free(ctx);
142 return r;
143 }
144
prime_field_tests(void)145 static int prime_field_tests(void)
146 {
147 BN_CTX *ctx = NULL;
148 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
149 EC_GROUP *group = NULL, *tmp = NULL;
150 EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
151 *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
152 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
153 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
154 const EC_POINT *points[4];
155 const BIGNUM *scalars[4];
156 unsigned char buf[100];
157 size_t len, r = 0;
158 int k;
159
160 if (!TEST_ptr(ctx = BN_CTX_new())
161 || !TEST_ptr(p = BN_new())
162 || !TEST_ptr(a = BN_new())
163 || !TEST_ptr(b = BN_new())
164 || !TEST_true(BN_hex2bn(&p, "17"))
165 || !TEST_true(BN_hex2bn(&a, "1"))
166 || !TEST_true(BN_hex2bn(&b, "1"))
167 /*
168 * applications should use EC_GROUP_new_curve_GFp so
169 * that the library gets to choose the EC_METHOD
170 */
171 || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
172 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
173 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
174 || !TEST_true(EC_GROUP_copy(tmp, group)))
175 goto err;
176 EC_GROUP_free(group);
177 group = tmp;
178 tmp = NULL;
179
180 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
181 goto err;
182
183 TEST_info("Curve defined by Weierstrass equation");
184 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
185 test_output_bignum("a", a);
186 test_output_bignum("b", b);
187 test_output_bignum("p", p);
188
189 buf[0] = 0;
190 if (!TEST_ptr(P = EC_POINT_new(group))
191 || !TEST_ptr(Q = EC_POINT_new(group))
192 || !TEST_ptr(R = EC_POINT_new(group))
193 || !TEST_true(EC_POINT_set_to_infinity(group, P))
194 || !TEST_true(EC_POINT_is_at_infinity(group, P))
195 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
196 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
197 || !TEST_true(EC_POINT_is_at_infinity(group, P))
198 || !TEST_ptr(x = BN_new())
199 || !TEST_ptr(y = BN_new())
200 || !TEST_ptr(z = BN_new())
201 || !TEST_ptr(yplusone = BN_new())
202 || !TEST_true(BN_hex2bn(&x, "D"))
203 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
204 goto err;
205
206 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
207 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
208 goto err;
209 TEST_info("Point is not on curve");
210 test_output_bignum("x", x);
211 test_output_bignum("y", y);
212 goto err;
213 }
214
215 TEST_note("A cyclic subgroup:");
216 k = 100;
217 do {
218 if (!TEST_int_ne(k--, 0))
219 goto err;
220
221 if (EC_POINT_is_at_infinity(group, P)) {
222 TEST_note(" point at infinity");
223 } else {
224 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
225 ctx)))
226 goto err;
227
228 test_output_bignum("x", x);
229 test_output_bignum("y", y);
230 }
231
232 if (!TEST_true(EC_POINT_copy(R, P))
233 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
234 goto err;
235
236 } while (!EC_POINT_is_at_infinity(group, P));
237
238 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
239 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
240 goto err;
241
242 len =
243 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
244 sizeof(buf), ctx);
245 if (!TEST_size_t_ne(len, 0)
246 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
247 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
248 goto err;
249 test_output_memory("Generator as octet string, compressed form:",
250 buf, len);
251
252 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
253 buf, sizeof(buf), ctx);
254 if (!TEST_size_t_ne(len, 0)
255 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
256 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
257 goto err;
258 test_output_memory("Generator as octet string, uncompressed form:",
259 buf, len);
260
261 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
262 buf, sizeof(buf), ctx);
263 if (!TEST_size_t_ne(len, 0)
264 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
265 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
266 goto err;
267 test_output_memory("Generator as octet string, hybrid form:",
268 buf, len);
269
270 if (!TEST_true(EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z,
271 ctx)))
272 goto err;
273 TEST_info("A representation of the inverse of that generator in");
274 TEST_note("Jacobian projective coordinates");
275 test_output_bignum("x", x);
276 test_output_bignum("y", y);
277 test_output_bignum("z", z);
278
279 if (!TEST_true(EC_POINT_invert(group, P, ctx))
280 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
281
282 /*
283 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
284 * 2000) -- not a NIST curve, but commonly used
285 */
286
287 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
288 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
289 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
290 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
291 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
292 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
293 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
294 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
295 || !TEST_true(BN_hex2bn(&x, "4A96B568"
296 "8EF573284664698968C38BB913CBFC82"))
297 || !TEST_true(BN_hex2bn(&y, "23a62855"
298 "3168947d59dcc912042351377ac5fb32"))
299 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
300 /*
301 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
302 * and therefore setting the coordinates should fail.
303 */
304 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
305 ctx))
306 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
307 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
308 || !TEST_true(BN_hex2bn(&z, "0100000000"
309 "000000000001F4C8F927AED3CA752257"))
310 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
311 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
312 goto err;
313 TEST_info("SEC2 curve secp160r1 -- Generator");
314 test_output_bignum("x", x);
315 test_output_bignum("y", y);
316 /* G_y value taken from the standard: */
317 if (!TEST_true(BN_hex2bn(&z, "23a62855"
318 "3168947d59dcc912042351377ac5fb32"))
319 || !TEST_BN_eq(y, z)
320 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
321 || !group_order_tests(group)
322 || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))
323 || !TEST_true(EC_GROUP_copy(P_160, group))
324
325 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
326
327 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
328 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
329 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
330 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
331 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
332 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
333 "0FA7E9AB72243049FEB8DEECC146B9B1"))
334 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
335 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
336 "7CBF20EB43A18800F4FF0AFD82FF1012"))
337 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
338 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
339 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
340 "FFFFFFFF99DEF836146BC9B1B4D22831"))
341 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
342 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
343 goto err;
344
345 TEST_info("NIST curve P-192 -- Generator");
346 test_output_bignum("x", x);
347 test_output_bignum("y", y);
348 /* G_y value taken from the standard: */
349 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
350 "631011ED6B24CDD573F977A11E794811"))
351 || !TEST_BN_eq(y, z)
352 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
353 /*
354 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
355 * and therefore setting the coordinates should fail.
356 */
357 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
358 ctx))
359 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
360 || !group_order_tests(group)
361 || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))
362 || !TEST_true(EC_GROUP_copy(P_192, group))
363
364 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
365
366 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
367 "FFFFFFFF000000000000000000000001"))
368 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
369 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
370 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
371 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
372 "5044B0B7D7BFD8BA270B39432355FFB4"))
373 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
374 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
375 "4A03C1D356C21122343280D6115C1D21"))
376 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
377 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
378 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
379 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
380 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
381 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
382 goto err;
383
384 TEST_info("NIST curve P-224 -- Generator");
385 test_output_bignum("x", x);
386 test_output_bignum("y", y);
387 /* G_y value taken from the standard: */
388 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
389 "CD4375A05A07476444D5819985007E34"))
390 || !TEST_BN_eq(y, z)
391 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
392 /*
393 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
394 * and therefore setting the coordinates should fail.
395 */
396 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
397 ctx))
398 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
399 || !group_order_tests(group)
400 || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
401 || !TEST_true(EC_GROUP_copy(P_224, group))
402
403 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
404
405 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
406 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
407 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
408 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
409 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
410 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
411 "651D06B0CC53B0F63BCE3C3E27D2604B"))
412 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
413
414 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
415 "77037D812DEB33A0F4A13945D898C296"))
416 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
417 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
418 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
419 "BCE6FAADA7179E84F3B9CAC2FC632551"))
420 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
421 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
422 goto err;
423
424 TEST_info("NIST curve P-256 -- Generator");
425 test_output_bignum("x", x);
426 test_output_bignum("y", y);
427 /* G_y value taken from the standard: */
428 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
429 "2BCE33576B315ECECBB6406837BF51F5"))
430 || !TEST_BN_eq(y, z)
431 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
432 /*
433 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
434 * and therefore setting the coordinates should fail.
435 */
436 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
437 ctx))
438 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
439 || !group_order_tests(group)
440 || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
441 || !TEST_true(EC_GROUP_copy(P_256, group))
442
443 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
444
445 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
446 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
447 "FFFFFFFF0000000000000000FFFFFFFF"))
448 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
449 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
450 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
451 "FFFFFFFF0000000000000000FFFFFFFC"))
452 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
453 "181D9C6EFE8141120314088F5013875A"
454 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
455 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
456
457 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
458 "6E1D3B628BA79B9859F741E082542A38"
459 "5502F25DBF55296C3A545E3872760AB7"))
460 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
461 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
462 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
463 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
464 "581A0DB248B0A77AECEC196ACCC52973"))
465 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
466 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
467 goto err;
468
469 TEST_info("NIST curve P-384 -- Generator");
470 test_output_bignum("x", x);
471 test_output_bignum("y", y);
472 /* G_y value taken from the standard: */
473 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
474 "F8F41DBD289A147CE9DA3113B5F0B8C0"
475 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
476 || !TEST_BN_eq(y, z)
477 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
478 /*
479 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
480 * and therefore setting the coordinates should fail.
481 */
482 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
483 ctx))
484 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
485 || !group_order_tests(group)
486 || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
487 || !TEST_true(EC_GROUP_copy(P_384, group))
488
489 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
490 || !TEST_true(BN_hex2bn(&p, "1FF"
491 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
492 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
493 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
494 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
495 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
496 || !TEST_true(BN_hex2bn(&a, "1FF"
497 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
500 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
501 || !TEST_true(BN_hex2bn(&b, "051"
502 "953EB9618E1C9A1F929A21A0B68540EE"
503 "A2DA725B99B315F3B8B489918EF109E1"
504 "56193951EC7E937B1652C0BD3BB1BF07"
505 "3573DF883D2C34F1EF451FD46B503F00"))
506 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
507 || !TEST_true(BN_hex2bn(&x, "C6"
508 "858E06B70404E9CD9E3ECB662395B442"
509 "9C648139053FB521F828AF606B4D3DBA"
510 "A14B5E77EFE75928FE1DC127A2FFA8DE"
511 "3348B3C1856A429BF97E7E31C2E5BD66"))
512 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
513 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
514 || !TEST_true(BN_hex2bn(&z, "1FF"
515 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
516 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
517 "51868783BF2F966B7FCC0148F709A5D0"
518 "3BB5C9B8899C47AEBB6FB71E91386409"))
519 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
520 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
521 goto err;
522
523 TEST_info("NIST curve P-521 -- Generator");
524 test_output_bignum("x", x);
525 test_output_bignum("y", y);
526 /* G_y value taken from the standard: */
527 if (!TEST_true(BN_hex2bn(&z, "118"
528 "39296A789A3BC0045C8A5FB42C7D1BD9"
529 "98F54449579B446817AFBD17273E662C"
530 "97EE72995EF42640C550B9013FAD0761"
531 "353C7086A272C24088BE94769FD16650"))
532 || !TEST_BN_eq(y, z)
533 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
534 /*
535 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
536 * and therefore setting the coordinates should fail.
537 */
538 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
539 ctx))
540 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
541 || !group_order_tests(group)
542 || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
543 || !TEST_true(EC_GROUP_copy(P_521, group))
544
545 /* more tests using the last curve */
546
547 /* Restore the point that got mangled in the (x, y + 1) test. */
548 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
549 || !TEST_true(EC_POINT_copy(Q, P))
550 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
551 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
552 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
553 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
554 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
555 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
556 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
557 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
558 goto err;
559 points[0] = Q;
560 points[1] = Q;
561 points[2] = Q;
562 points[3] = Q;
563
564 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
565 || !TEST_true(BN_add(y, z, BN_value_one()))
566 || !TEST_BN_even(y)
567 || !TEST_true(BN_rshift1(y, y)))
568 goto err;
569 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
570 scalars[1] = y;
571
572 TEST_note("combined multiplication ...");
573
574 /* z is still the group order */
575 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
576 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
577 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
578 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
579 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
580 || !TEST_true(BN_add(z, z, y)))
581 goto err;
582 BN_set_negative(z, 1);
583 scalars[0] = y;
584 scalars[1] = z; /* z = -(order + y) */
585
586 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
587 || !TEST_true(EC_POINT_is_at_infinity(group, P))
588 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
589 || !TEST_true(BN_add(z, x, y)))
590 goto err;
591 BN_set_negative(z, 1);
592 scalars[0] = x;
593 scalars[1] = y;
594 scalars[2] = z; /* z = -(x+y) */
595
596 if (!TEST_ptr(scalar3 = BN_new()))
597 goto err;
598 BN_zero(scalar3);
599 scalars[3] = scalar3;
600
601 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
602 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
603 goto err;
604
605 TEST_note(" ok\n");
606
607
608 r = 1;
609 err:
610 BN_CTX_free(ctx);
611 BN_free(p);
612 BN_free(a);
613 BN_free(b);
614 EC_GROUP_free(group);
615 EC_GROUP_free(tmp);
616 EC_POINT_free(P);
617 EC_POINT_free(Q);
618 EC_POINT_free(R);
619 BN_free(x);
620 BN_free(y);
621 BN_free(z);
622 BN_free(yplusone);
623 BN_free(scalar3);
624
625 EC_GROUP_free(P_160);
626 EC_GROUP_free(P_192);
627 EC_GROUP_free(P_224);
628 EC_GROUP_free(P_256);
629 EC_GROUP_free(P_384);
630 EC_GROUP_free(P_521);
631 return r;
632 }
633
634 # ifndef OPENSSL_NO_EC2M
635
636 static struct c2_curve_test {
637 const char *name;
638 const char *p;
639 const char *a;
640 const char *b;
641 const char *x;
642 const char *y;
643 int ybit;
644 const char *order;
645 const char *cof;
646 int degree;
647 } char2_curve_tests[] = {
648 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
649 {
650 "NIST curve K-163",
651 "0800000000000000000000000000000000000000C9",
652 "1",
653 "1",
654 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
655 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
656 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
657 },
658 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
659 {
660 "NIST curve B-163",
661 "0800000000000000000000000000000000000000C9",
662 "1",
663 "020A601907B8C953CA1481EB10512F78744A3205FD",
664 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
665 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
666 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
667 },
668 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
669 {
670 "NIST curve K-233",
671 "020000000000000000000000000000000000000004000000000000000001",
672 "0",
673 "1",
674 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
675 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
676 0,
677 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
678 "4", 233
679 },
680 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
681 {
682 "NIST curve B-233",
683 "020000000000000000000000000000000000000004000000000000000001",
684 "000000000000000000000000000000000000000000000000000000000001",
685 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
686 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
687 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
688 1,
689 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
690 "2", 233
691 },
692 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
693 {
694 "NIST curve K-283",
695 "08000000"
696 "00000000000000000000000000000000000000000000000000000000000010A1",
697 "0",
698 "1",
699 "0503213F"
700 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
701 "01CCDA38"
702 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
703 0,
704 "01FFFFFF"
705 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
706 "4", 283
707 },
708 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
709 {
710 "NIST curve B-283",
711 "08000000"
712 "00000000000000000000000000000000000000000000000000000000000010A1",
713 "00000000"
714 "0000000000000000000000000000000000000000000000000000000000000001",
715 "027B680A"
716 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
717 "05F93925"
718 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
719 "03676854"
720 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
721 1,
722 "03FFFFFF"
723 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
724 "2", 283
725 },
726 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
727 {
728 "NIST curve K-409",
729 "0200000000000000000000000000000000000000"
730 "0000000000000000000000000000000000000000008000000000000000000001",
731 "0",
732 "1",
733 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
734 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
735 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
736 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
737 1,
738 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
739 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
740 "4", 409
741 },
742 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
743 {
744 "NIST curve B-409",
745 "0200000000000000000000000000000000000000"
746 "0000000000000000000000000000000000000000008000000000000000000001",
747 "0000000000000000000000000000000000000000"
748 "0000000000000000000000000000000000000000000000000000000000000001",
749 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
750 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
751 "015D4860D088DDB3496B0C6064756260441CDE4A"
752 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
753 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
754 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
755 1,
756 "0100000000000000000000000000000000000000"
757 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
758 "2", 409
759 },
760 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
761 {
762 "NIST curve K-571",
763 "800000000000000"
764 "0000000000000000000000000000000000000000000000000000000000000000"
765 "0000000000000000000000000000000000000000000000000000000000000425",
766 "0",
767 "1",
768 "026EB7A859923FBC"
769 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
770 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
771 "0349DC807F4FBF37"
772 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
773 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
774 0,
775 "0200000000000000"
776 "00000000000000000000000000000000000000000000000000000000131850E1"
777 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
778 "4", 571
779 },
780 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
781 {
782 "NIST curve B-571",
783 "800000000000000"
784 "0000000000000000000000000000000000000000000000000000000000000000"
785 "0000000000000000000000000000000000000000000000000000000000000425",
786 "0000000000000000"
787 "0000000000000000000000000000000000000000000000000000000000000000"
788 "0000000000000000000000000000000000000000000000000000000000000001",
789 "02F40E7E2221F295"
790 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
791 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
792 "0303001D34B85629"
793 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
794 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
795 "037BF27342DA639B"
796 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
797 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
798 1,
799 "03FFFFFFFFFFFFFF"
800 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
801 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
802 "2", 571
803 }
804 };
805
char2_curve_test(int n)806 static int char2_curve_test(int n)
807 {
808 int r = 0;
809 BN_CTX *ctx = NULL;
810 BIGNUM *p = NULL, *a = NULL, *b = NULL;
811 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
812 EC_GROUP *group = NULL, *variable = NULL;
813 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
814 const EC_POINT *points[3];
815 const BIGNUM *scalars[3];
816 struct c2_curve_test *const test = char2_curve_tests + n;
817
818 if (!TEST_ptr(ctx = BN_CTX_new())
819 || !TEST_ptr(p = BN_new())
820 || !TEST_ptr(a = BN_new())
821 || !TEST_ptr(b = BN_new())
822 || !TEST_ptr(x = BN_new())
823 || !TEST_ptr(y = BN_new())
824 || !TEST_ptr(z = BN_new())
825 || !TEST_ptr(yplusone = BN_new())
826 || !TEST_true(BN_hex2bn(&p, test->p))
827 || !TEST_true(BN_hex2bn(&a, test->a))
828 || !TEST_true(BN_hex2bn(&b, test->b))
829 || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method()))
830 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
831 || !TEST_ptr(P = EC_POINT_new(group))
832 || !TEST_ptr(Q = EC_POINT_new(group))
833 || !TEST_ptr(R = EC_POINT_new(group))
834 || !TEST_true(BN_hex2bn(&x, test->x))
835 || !TEST_true(BN_hex2bn(&y, test->y))
836 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
837 goto err;
838
839 /* Change test based on whether binary point compression is enabled or not. */
840 # ifdef OPENSSL_EC_BIN_PT_COMP
841 /*
842 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
843 * and therefore setting the coordinates should fail.
844 */
845 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
846 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
847 test->y_bit,
848 ctx))
849 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
850 || !TEST_true(BN_hex2bn(&z, test->order))
851 || !TEST_true(BN_hex2bn(&cof, test->cof))
852 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
853 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
854 goto err;
855 TEST_info("%s -- Generator", test->name);
856 test_output_bignum("x", x);
857 test_output_bignum("y", y);
858 /* G_y value taken from the standard: */
859 if (!TEST_true(BN_hex2bn(&z, test->y))
860 || !TEST_BN_eq(y, z))
861 goto err;
862 # else
863 /*
864 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
865 * and therefore setting the coordinates should fail.
866 */
867 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
868 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
869 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
870 || !TEST_true(BN_hex2bn(&z, test->order))
871 || !TEST_true(BN_hex2bn(&cof, test->cof))
872 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
873 goto err;
874 TEST_info("%s -- Generator:", test->name);
875 test_output_bignum("x", x);
876 test_output_bignum("y", y);
877 # endif
878
879 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
880 || !group_order_tests(group)
881 || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group)))
882 || !TEST_true(EC_GROUP_copy(variable, group)))
883 goto err;
884
885 /* more tests using the last curve */
886 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
887 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
888 || !TEST_true(EC_POINT_copy(Q, P))
889 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
890 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
891 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
892 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
893 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
894 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
895 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
896 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
897 goto err;
898
899 points[0] = Q;
900 points[1] = Q;
901 points[2] = Q;
902
903 if (!TEST_true(BN_add(y, z, BN_value_one()))
904 || !TEST_BN_even(y)
905 || !TEST_true(BN_rshift1(y, y)))
906 goto err;
907 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
908 scalars[1] = y;
909
910 TEST_note("combined multiplication ...");
911
912 /* z is still the group order */
913 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
914 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
915 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
916 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
917 goto err;
918
919 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
920 || !TEST_true(BN_add(z, z, y)))
921 goto err;
922 BN_set_negative(z, 1);
923 scalars[0] = y;
924 scalars[1] = z; /* z = -(order + y) */
925
926 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
927 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
928 goto err;
929
930 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
931 || !TEST_true(BN_add(z, x, y)))
932 goto err;
933 BN_set_negative(z, 1);
934 scalars[0] = x;
935 scalars[1] = y;
936 scalars[2] = z; /* z = -(x+y) */
937
938 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
939 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
940 goto err;;
941 }
942
943 r = 1;
944 err:
945 BN_CTX_free(ctx);
946 BN_free(p);
947 BN_free(a);
948 BN_free(b);
949 BN_free(x);
950 BN_free(y);
951 BN_free(z);
952 BN_free(yplusone);
953 BN_free(cof);
954 EC_POINT_free(P);
955 EC_POINT_free(Q);
956 EC_POINT_free(R);
957 EC_GROUP_free(group);
958 EC_GROUP_free(variable);
959 return r;
960 }
961
char2_field_tests(void)962 static int char2_field_tests(void)
963 {
964 BN_CTX *ctx = NULL;
965 BIGNUM *p = NULL, *a = NULL, *b = NULL;
966 EC_GROUP *group = NULL, *tmp = NULL;
967 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
968 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
969 unsigned char buf[100];
970 size_t len;
971 int k, r = 0;
972
973 if (!TEST_ptr(ctx = BN_CTX_new())
974 || !TEST_ptr(p = BN_new())
975 || !TEST_ptr(a = BN_new())
976 || !TEST_ptr(b = BN_new())
977 || !TEST_true(BN_hex2bn(&p, "13"))
978 || !TEST_true(BN_hex2bn(&a, "3"))
979 || !TEST_true(BN_hex2bn(&b, "1")))
980 goto err;
981
982 group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
983 * EC_GROUP_new_curve_GF2m
984 * so that the library gets
985 * to choose the EC_METHOD */
986 if (!TEST_ptr(group)
987 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
988 || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
989 || !TEST_true(EC_GROUP_copy(tmp, group)))
990 goto err;
991 EC_GROUP_free(group);
992 group = tmp;
993 tmp = NULL;
994
995 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
996 goto err;
997
998 TEST_info("Curve defined by Weierstrass equation");
999 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
1000 test_output_bignum("a", a);
1001 test_output_bignum("b", b);
1002 test_output_bignum("p", p);
1003
1004 if (!TEST_ptr(P = EC_POINT_new(group))
1005 || !TEST_ptr(Q = EC_POINT_new(group))
1006 || !TEST_ptr(R = EC_POINT_new(group))
1007 || !TEST_true(EC_POINT_set_to_infinity(group, P))
1008 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1009 goto err;
1010
1011 buf[0] = 0;
1012 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
1013 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
1014 || !TEST_true(EC_POINT_is_at_infinity(group, P))
1015 || !TEST_ptr(x = BN_new())
1016 || !TEST_ptr(y = BN_new())
1017 || !TEST_ptr(z = BN_new())
1018 || !TEST_ptr(cof = BN_new())
1019 || !TEST_ptr(yplusone = BN_new())
1020 || !TEST_true(BN_hex2bn(&x, "6"))
1021 /* Change test based on whether binary point compression is enabled or not. */
1022 # ifdef OPENSSL_EC_BIN_PT_COMP
1023 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
1024 # else
1025 || !TEST_true(BN_hex2bn(&y, "8"))
1026 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
1027 # endif
1028 )
1029 goto err;
1030 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
1031 /* Change test based on whether binary point compression is enabled or not. */
1032 # ifdef OPENSSL_EC_BIN_PT_COMP
1033 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
1034 goto err;
1035 # endif
1036 TEST_info("Point is not on curve");
1037 test_output_bignum("x", x);
1038 test_output_bignum("y", y);
1039 goto err;
1040 }
1041
1042 TEST_note("A cyclic subgroup:");
1043 k = 100;
1044 do {
1045 if (!TEST_int_ne(k--, 0))
1046 goto err;
1047
1048 if (EC_POINT_is_at_infinity(group, P))
1049 TEST_note(" point at infinity");
1050 else {
1051 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1052 ctx)))
1053 goto err;
1054
1055 test_output_bignum("x", x);
1056 test_output_bignum("y", y);
1057 }
1058
1059 if (!TEST_true(EC_POINT_copy(R, P))
1060 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1061 goto err;
1062 }
1063 while (!EC_POINT_is_at_infinity(group, P));
1064
1065 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1066 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1067 goto err;
1068
1069 /* Change test based on whether binary point compression is enabled or not. */
1070 # ifdef OPENSSL_EC_BIN_PT_COMP
1071 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
1072 buf, sizeof(buf), ctx);
1073 if (!TEST_size_t_ne(len, 0)
1074 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1075 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1076 goto err;
1077 test_output_memory("Generator as octet string, compressed form:",
1078 buf, len);
1079 # endif
1080
1081 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
1082 buf, sizeof(buf), ctx);
1083 if (!TEST_size_t_ne(len, 0)
1084 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1085 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1086 goto err;
1087 test_output_memory("Generator as octet string, uncompressed form:",
1088 buf, len);
1089
1090 /* Change test based on whether binary point compression is enabled or not. */
1091 # ifdef OPENSSL_EC_BIN_PT_COMP
1092 len =
1093 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
1094 ctx);
1095 if (!TEST_size_t_ne(len, 0)
1096 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1097 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1098 goto err;
1099 test_output_memory("Generator as octet string, hybrid form:",
1100 buf, len);
1101 # endif
1102
1103 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1104 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1105 goto err;
1106
1107 TEST_note("\n");
1108
1109 r = 1;
1110 err:
1111 BN_CTX_free(ctx);
1112 BN_free(p);
1113 BN_free(a);
1114 BN_free(b);
1115 EC_GROUP_free(group);
1116 EC_GROUP_free(tmp);
1117 EC_POINT_free(P);
1118 EC_POINT_free(Q);
1119 EC_POINT_free(R);
1120 BN_free(x);
1121 BN_free(y);
1122 BN_free(z);
1123 BN_free(cof);
1124 BN_free(yplusone);
1125 return r;
1126 }
1127
hybrid_point_encoding_test(void)1128 static int hybrid_point_encoding_test(void)
1129 {
1130 BIGNUM *x = NULL, *y = NULL;
1131 EC_GROUP *group = NULL;
1132 EC_POINT *point = NULL;
1133 unsigned char *buf = NULL;
1134 size_t len;
1135 int r = 0;
1136
1137 if (!TEST_true(BN_dec2bn(&x, "0"))
1138 || !TEST_true(BN_dec2bn(&y, "1"))
1139 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_sect571k1))
1140 || !TEST_ptr(point = EC_POINT_new(group))
1141 || !TEST_true(EC_POINT_set_affine_coordinates(group, point, x, y, NULL))
1142 || !TEST_size_t_ne(0, (len = EC_POINT_point2oct(group,
1143 point,
1144 POINT_CONVERSION_HYBRID,
1145 NULL,
1146 0,
1147 NULL)))
1148 || !TEST_ptr(buf = OPENSSL_malloc(len))
1149 || !TEST_size_t_eq(len, EC_POINT_point2oct(group,
1150 point,
1151 POINT_CONVERSION_HYBRID,
1152 buf,
1153 len,
1154 NULL)))
1155 goto err;
1156
1157 r = 1;
1158
1159 /* buf contains a valid hybrid point, check that we can decode it. */
1160 if (!TEST_true(EC_POINT_oct2point(group, point, buf, len, NULL)))
1161 r = 0;
1162
1163 /* Flip the y_bit and verify that the invalid encoding is rejected. */
1164 buf[0] ^= 1;
1165 if (!TEST_false(EC_POINT_oct2point(group, point, buf, len, NULL)))
1166 r = 0;
1167
1168 err:
1169 BN_free(x);
1170 BN_free(y);
1171 EC_GROUP_free(group);
1172 EC_POINT_free(point);
1173 OPENSSL_free(buf);
1174 return r;
1175 }
1176 #endif
1177
internal_curve_test(int n)1178 static int internal_curve_test(int n)
1179 {
1180 EC_GROUP *group = NULL;
1181 int nid = curves[n].nid;
1182
1183 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1184 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1185 OBJ_nid2sn(nid));
1186 return 0;
1187 }
1188 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1189 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1190 EC_GROUP_free(group);
1191 return 0;
1192 }
1193 EC_GROUP_free(group);
1194 return 1;
1195 }
1196
internal_curve_test_method(int n)1197 static int internal_curve_test_method(int n)
1198 {
1199 int r, nid = curves[n].nid;
1200 EC_GROUP *group;
1201
1202 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1203 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1204 return 0;
1205 }
1206 r = group_order_tests(group);
1207 EC_GROUP_free(group);
1208 return r;
1209 }
1210
1211 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
1212 /*
1213 * nistp_test_params contains magic numbers for testing our optimized
1214 * implementations of several NIST curves with characteristic > 3.
1215 */
1216 struct nistp_test_params {
1217 const EC_METHOD *(*meth) (void);
1218 int degree;
1219 /*
1220 * Qx, Qy and D are taken from
1221 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
1222 * Otherwise, values are standard curve parameters from FIPS 180-3
1223 */
1224 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1225 };
1226
1227 static const struct nistp_test_params nistp_tests_params[] = {
1228 {
1229 /* P-224 */
1230 EC_GFp_nistp224_method,
1231 224,
1232 /* p */
1233 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1234 /* a */
1235 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1236 /* b */
1237 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1238 /* Qx */
1239 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1240 /* Qy */
1241 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1242 /* Gx */
1243 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1244 /* Gy */
1245 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1246 /* order */
1247 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1248 /* d */
1249 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1250 },
1251 {
1252 /* P-256 */
1253 EC_GFp_nistp256_method,
1254 256,
1255 /* p */
1256 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1257 /* a */
1258 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1259 /* b */
1260 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1261 /* Qx */
1262 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1263 /* Qy */
1264 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1265 /* Gx */
1266 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1267 /* Gy */
1268 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1269 /* order */
1270 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1271 /* d */
1272 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1273 },
1274 {
1275 /* P-521 */
1276 EC_GFp_nistp521_method,
1277 521,
1278 /* p */
1279 "1ff"
1280 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1281 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1282 /* a */
1283 "1ff"
1284 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1285 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
1286 /* b */
1287 "051"
1288 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1289 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
1290 /* Qx */
1291 "0098"
1292 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1293 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
1294 /* Qy */
1295 "0164"
1296 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1297 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
1298 /* Gx */
1299 "c6"
1300 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1301 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
1302 /* Gy */
1303 "118"
1304 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1305 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
1306 /* order */
1307 "1ff"
1308 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1309 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
1310 /* d */
1311 "0100"
1312 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1313 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
1314 },
1315 };
1316
nistp_single_test(int idx)1317 static int nistp_single_test(int idx)
1318 {
1319 const struct nistp_test_params *test = nistp_tests_params + idx;
1320 BN_CTX *ctx = NULL;
1321 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1322 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1323 EC_GROUP *NISTP = NULL;
1324 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1325 int r = 0;
1326
1327 TEST_note("NIST curve P-%d (optimised implementation):",
1328 test->degree);
1329 if (!TEST_ptr(ctx = BN_CTX_new())
1330 || !TEST_ptr(p = BN_new())
1331 || !TEST_ptr(a = BN_new())
1332 || !TEST_ptr(b = BN_new())
1333 || !TEST_ptr(x = BN_new())
1334 || !TEST_ptr(y = BN_new())
1335 || !TEST_ptr(m = BN_new())
1336 || !TEST_ptr(n = BN_new())
1337 || !TEST_ptr(order = BN_new())
1338 || !TEST_ptr(yplusone = BN_new())
1339
1340 || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
1341 || !TEST_true(BN_hex2bn(&p, test->p))
1342 || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
1343 || !TEST_true(BN_hex2bn(&a, test->a))
1344 || !TEST_true(BN_hex2bn(&b, test->b))
1345 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
1346 || !TEST_ptr(G = EC_POINT_new(NISTP))
1347 || !TEST_ptr(P = EC_POINT_new(NISTP))
1348 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1349 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1350 || !TEST_true(BN_hex2bn(&x, test->Qx))
1351 || !TEST_true(BN_hex2bn(&y, test->Qy))
1352 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
1353 /*
1354 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1355 * and therefore setting the coordinates should fail.
1356 */
1357 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1358 yplusone, ctx))
1359 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1360 ctx))
1361 || !TEST_true(BN_hex2bn(&x, test->Gx))
1362 || !TEST_true(BN_hex2bn(&y, test->Gy))
1363 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
1364 || !TEST_true(BN_hex2bn(&order, test->order))
1365 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1366 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1367 goto err;
1368
1369 TEST_note("NIST test vectors ... ");
1370 if (!TEST_true(BN_hex2bn(&n, test->d)))
1371 goto err;
1372 /* fixed point multiplication */
1373 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1374 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1375 goto err;
1376 /* random point multiplication */
1377 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1378 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1379
1380 /* set generator to P = 2*G, where G is the standard generator */
1381 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1382 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1383 /* set the scalar to m=n/2, where n is the NIST test scalar */
1384 || !TEST_true(BN_rshift(m, n, 1)))
1385 goto err;
1386
1387 /* test the non-standard generator */
1388 /* fixed point multiplication */
1389 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1390 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1391 goto err;
1392 /* random point multiplication */
1393 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1394 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1395
1396 /*
1397 * We have not performed precomputation so have_precompute mult should be
1398 * false
1399 */
1400 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
1401
1402 /* now repeat all tests with precomputation */
1403 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
1404 || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
1405 goto err;
1406
1407 /* fixed point multiplication */
1408 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
1409 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1410 goto err;
1411 /* random point multiplication */
1412 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
1413 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
1414
1415 /* reset generator */
1416 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1417 goto err;
1418 /* fixed point multiplication */
1419 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
1420 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1421 goto err;
1422 /* random point multiplication */
1423 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
1424 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1425 goto err;
1426
1427 /* regression test for felem_neg bug */
1428 if (!TEST_true(BN_set_word(m, 32))
1429 || !TEST_true(BN_set_word(n, 31))
1430 || !TEST_true(EC_POINT_copy(P, G))
1431 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1432 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1433 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1434 goto err;
1435
1436 r = group_order_tests(NISTP);
1437 err:
1438 EC_GROUP_free(NISTP);
1439 EC_POINT_free(G);
1440 EC_POINT_free(P);
1441 EC_POINT_free(Q);
1442 EC_POINT_free(Q_CHECK);
1443 BN_free(n);
1444 BN_free(m);
1445 BN_free(p);
1446 BN_free(a);
1447 BN_free(b);
1448 BN_free(x);
1449 BN_free(y);
1450 BN_free(order);
1451 BN_free(yplusone);
1452 BN_CTX_free(ctx);
1453 return r;
1454 }
1455
1456 /*
1457 * Tests a point known to cause an incorrect underflow in an old version of
1458 * ecp_nist521.c
1459 */
underflow_test(void)1460 static int underflow_test(void)
1461 {
1462 BN_CTX *ctx = NULL;
1463 EC_GROUP *grp = NULL;
1464 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
1465 BIGNUM *x1 = NULL, *y1 = NULL, *z1 = NULL, *x2 = NULL, *y2 = NULL;
1466 BIGNUM *k = NULL;
1467 int testresult = 0;
1468 const char *x1str =
1469 "1534f0077fffffe87e9adcfe000000000000000000003e05a21d2400002e031b1f4"
1470 "b80000c6fafa4f3c1288798d624a247b5e2ffffffffffffffefe099241900004";
1471 const char *p521m1 =
1472 "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1473 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe";
1474
1475 ctx = BN_CTX_new();
1476 if (!TEST_ptr(ctx))
1477 return 0;
1478
1479 BN_CTX_start(ctx);
1480 x1 = BN_CTX_get(ctx);
1481 y1 = BN_CTX_get(ctx);
1482 z1 = BN_CTX_get(ctx);
1483 x2 = BN_CTX_get(ctx);
1484 y2 = BN_CTX_get(ctx);
1485 k = BN_CTX_get(ctx);
1486 if (!TEST_ptr(k))
1487 goto err;
1488
1489 grp = EC_GROUP_new_by_curve_name(NID_secp521r1);
1490 P = EC_POINT_new(grp);
1491 Q = EC_POINT_new(grp);
1492 R = EC_POINT_new(grp);
1493 if (!TEST_ptr(grp) || !TEST_ptr(P) || !TEST_ptr(Q) || !TEST_ptr(R))
1494 goto err;
1495
1496 if (!TEST_int_gt(BN_hex2bn(&x1, x1str), 0)
1497 || !TEST_int_gt(BN_hex2bn(&y1, p521m1), 0)
1498 || !TEST_int_gt(BN_hex2bn(&z1, p521m1), 0)
1499 || !TEST_int_gt(BN_hex2bn(&k, "02"), 0)
1500 || !TEST_true(EC_POINT_set_Jprojective_coordinates_GFp(grp, P, x1,
1501 y1, z1, ctx))
1502 || !TEST_true(EC_POINT_mul(grp, Q, NULL, P, k, ctx))
1503 || !TEST_true(EC_POINT_get_affine_coordinates(grp, Q, x1, y1, ctx))
1504 || !TEST_true(EC_POINT_dbl(grp, R, P, ctx))
1505 || !TEST_true(EC_POINT_get_affine_coordinates(grp, R, x2, y2, ctx)))
1506 goto err;
1507
1508 if (!TEST_int_eq(BN_cmp(x1, x2), 0)
1509 || !TEST_int_eq(BN_cmp(y1, y2), 0))
1510 goto err;
1511
1512 testresult = 1;
1513
1514 err:
1515 BN_CTX_end(ctx);
1516 EC_POINT_free(P);
1517 EC_POINT_free(Q);
1518 EC_POINT_free(R);
1519 EC_GROUP_free(grp);
1520 BN_CTX_free(ctx);
1521
1522 return testresult;
1523 }
1524 # endif
1525
1526 static const unsigned char p521_named[] = {
1527 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1528 };
1529
1530 static const unsigned char p521_explicit[] = {
1531 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1532 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1533 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1534 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1535 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1536 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1537 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1538 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1539 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1540 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1541 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1542 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1543 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1544 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1545 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1546 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1547 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1548 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1549 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1550 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1551 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1552 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1553 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1554 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1555 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1556 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1557 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1558 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1559 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1560 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1561 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1562 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1563 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1564 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1565 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1566 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1567 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1568 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1569 };
1570
1571 /*
1572 * Sometime we cannot compare nids for equality, as the built-in curve table
1573 * includes aliases with different names for the same curve.
1574 *
1575 * This function returns TRUE (1) if the checked nids are identical, or if they
1576 * alias to the same curve. FALSE (0) otherwise.
1577 */
1578 static ossl_inline
are_ec_nids_compatible(int n1d,int n2d)1579 int are_ec_nids_compatible(int n1d, int n2d)
1580 {
1581 int ret = 0;
1582 switch (n1d) {
1583 # ifndef OPENSSL_NO_EC2M
1584 case NID_sect113r1:
1585 case NID_wap_wsg_idm_ecid_wtls4:
1586 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1587 break;
1588 case NID_sect163k1:
1589 case NID_wap_wsg_idm_ecid_wtls3:
1590 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1591 break;
1592 case NID_sect233k1:
1593 case NID_wap_wsg_idm_ecid_wtls10:
1594 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1595 break;
1596 case NID_sect233r1:
1597 case NID_wap_wsg_idm_ecid_wtls11:
1598 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1599 break;
1600 case NID_X9_62_c2pnb163v1:
1601 case NID_wap_wsg_idm_ecid_wtls5:
1602 ret = (n2d == NID_X9_62_c2pnb163v1
1603 || n2d == NID_wap_wsg_idm_ecid_wtls5);
1604 break;
1605 # endif /* OPENSSL_NO_EC2M */
1606 case NID_secp112r1:
1607 case NID_wap_wsg_idm_ecid_wtls6:
1608 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1609 break;
1610 case NID_secp160r2:
1611 case NID_wap_wsg_idm_ecid_wtls7:
1612 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1613 break;
1614 # ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
1615 case NID_secp224r1:
1616 case NID_wap_wsg_idm_ecid_wtls12:
1617 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1618 break;
1619 # else
1620 /*
1621 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1622 * that is associated with a specialized method.
1623 */
1624 case NID_wap_wsg_idm_ecid_wtls12:
1625 ret = (n2d == NID_secp224r1);
1626 break;
1627 # endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
1628
1629 default:
1630 ret = (n1d == n2d);
1631 }
1632 return ret;
1633 }
1634
1635 /*
1636 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1637 * EC_GROUP for built-in curves.
1638 *
1639 * Note that it is possible to retrieve an alternative alias that does not match
1640 * the original nid.
1641 *
1642 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1643 */
check_named_curve_from_ecparameters(int id)1644 static int check_named_curve_from_ecparameters(int id)
1645 {
1646 int ret = 0, nid, tnid;
1647 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1648 const EC_POINT *group_gen = NULL;
1649 EC_POINT *other_gen = NULL;
1650 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1651 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1652 const BIGNUM *group_order = NULL;
1653 BIGNUM *other_order = NULL;
1654 BN_CTX *bn_ctx = NULL;
1655 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1656 static size_t invalid_seed_len = sizeof(invalid_seed);
1657 ECPARAMETERS *params = NULL, *other_params = NULL;
1658 EC_GROUP *g_ary[8] = {NULL};
1659 EC_GROUP **g_next = &g_ary[0];
1660 ECPARAMETERS *p_ary[8] = {NULL};
1661 ECPARAMETERS **p_next = &p_ary[0];
1662
1663 /* Do some setup */
1664 nid = curves[id].nid;
1665 TEST_note("Curve %s", OBJ_nid2sn(nid));
1666 if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1667 return ret;
1668 BN_CTX_start(bn_ctx);
1669
1670 if (/* Allocations */
1671 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1672 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1673 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1674 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1675 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1676 /* Generate reference group and params */
1677 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1678 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1679 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1680 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1681 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1682 /* compute `other_*` values */
1683 || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1684 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1685 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1686 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1687 other_gen_x, other_gen_y, bn_ctx))
1688 || !TEST_true(BN_copy(other_order, group_order))
1689 || !TEST_true(BN_add_word(other_order, 1))
1690 || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1691 || !TEST_true(BN_add_word(other_cofactor, 1)))
1692 goto err;
1693
1694 EC_POINT_free(other_gen);
1695 other_gen = NULL;
1696
1697 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1698 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1699 other_gen_x, other_gen_y,
1700 bn_ctx)))
1701 goto err;
1702
1703 /*
1704 * ###########################
1705 * # Actual tests start here #
1706 * ###########################
1707 */
1708
1709 /*
1710 * Creating a group from built-in explicit parameters returns a
1711 * "named" EC_GROUP
1712 */
1713 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1714 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1715 goto err;
1716 /*
1717 * We cannot always guarantee the names match, as the built-in table
1718 * contains aliases for the same curve with different names.
1719 */
1720 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1721 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1722 goto err;
1723 }
1724 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1725 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1726 goto err;
1727
1728 /*
1729 * An invalid seed in the parameters should be ignored: expect a "named"
1730 * group.
1731 */
1732 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1733 invalid_seed_len)
1734 || !TEST_ptr(other_params = *p_next++ =
1735 EC_GROUP_get_ecparameters(tmpg, NULL))
1736 || !TEST_ptr(tgroup = *g_next++ =
1737 EC_GROUP_new_from_ecparameters(other_params))
1738 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1739 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1740 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1741 OPENSSL_EC_EXPLICIT_CURVE)) {
1742 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1743 goto err;
1744 }
1745
1746 /*
1747 * A null seed in the parameters should be ignored, as it is optional:
1748 * expect a "named" group.
1749 */
1750 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1751 || !TEST_ptr(other_params = *p_next++ =
1752 EC_GROUP_get_ecparameters(tmpg, NULL))
1753 || !TEST_ptr(tgroup = *g_next++ =
1754 EC_GROUP_new_from_ecparameters(other_params))
1755 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1756 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1757 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1758 OPENSSL_EC_EXPLICIT_CURVE)) {
1759 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1760 goto err;
1761 }
1762
1763 /*
1764 * Check that changing any of the generator parameters does not yield a
1765 * match with the built-in curves
1766 */
1767 if (/* Other gen, same group order & cofactor */
1768 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1769 group_cofactor))
1770 || !TEST_ptr(other_params = *p_next++ =
1771 EC_GROUP_get_ecparameters(tmpg, NULL))
1772 || !TEST_ptr(tgroup = *g_next++ =
1773 EC_GROUP_new_from_ecparameters(other_params))
1774 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1775 /* Same gen & cofactor, different order */
1776 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1777 group_cofactor))
1778 || !TEST_ptr(other_params = *p_next++ =
1779 EC_GROUP_get_ecparameters(tmpg, NULL))
1780 || !TEST_ptr(tgroup = *g_next++ =
1781 EC_GROUP_new_from_ecparameters(other_params))
1782 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1783 /* The order is not an optional field, so this should fail */
1784 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1785 group_cofactor))
1786 /* Check that a wrong cofactor is ignored, and we still match */
1787 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1788 other_cofactor))
1789 || !TEST_ptr(other_params = *p_next++ =
1790 EC_GROUP_get_ecparameters(tmpg, NULL))
1791 || !TEST_ptr(tgroup = *g_next++ =
1792 EC_GROUP_new_from_ecparameters(other_params))
1793 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1794 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1795 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1796 OPENSSL_EC_EXPLICIT_CURVE)
1797 /* Check that if the cofactor is not set then it still matches */
1798 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1799 NULL))
1800 || !TEST_ptr(other_params = *p_next++ =
1801 EC_GROUP_get_ecparameters(tmpg, NULL))
1802 || !TEST_ptr(tgroup = *g_next++ =
1803 EC_GROUP_new_from_ecparameters(other_params))
1804 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1805 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1806 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1807 OPENSSL_EC_EXPLICIT_CURVE)
1808 /* check that restoring the generator passes */
1809 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1810 group_cofactor))
1811 || !TEST_ptr(other_params = *p_next++ =
1812 EC_GROUP_get_ecparameters(tmpg, NULL))
1813 || !TEST_ptr(tgroup = *g_next++ =
1814 EC_GROUP_new_from_ecparameters(other_params))
1815 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1816 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1817 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1818 OPENSSL_EC_EXPLICIT_CURVE))
1819 goto err;
1820
1821 ret = 1;
1822 err:
1823 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
1824 EC_GROUP_free(*g_next);
1825 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
1826 ECPARAMETERS_free(*p_next);
1827 ECPARAMETERS_free(params);
1828 EC_POINT_free(other_gen);
1829 EC_GROUP_free(tmpg);
1830 EC_GROUP_free(group);
1831 BN_CTX_end(bn_ctx);
1832 BN_CTX_free(bn_ctx);
1833 return ret;
1834 }
1835
parameter_test(void)1836 static int parameter_test(void)
1837 {
1838 EC_GROUP *group = NULL, *group2 = NULL;
1839 ECPARAMETERS *ecparameters = NULL;
1840 unsigned char *buf = NULL;
1841 int r = 0, len;
1842
1843 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp112r1))
1844 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1845 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1846 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1847 goto err;
1848
1849 EC_GROUP_free(group);
1850 group = NULL;
1851
1852 /* Test the named curve encoding, which should be default. */
1853 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1854 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1855 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1856 goto err;
1857
1858 OPENSSL_free(buf);
1859 buf = NULL;
1860
1861 /*
1862 * Test the explicit encoding. P-521 requires correctly zero-padding the
1863 * curve coefficients.
1864 */
1865 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1866 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1867 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
1868 goto err;
1869
1870 r = 1;
1871 err:
1872 EC_GROUP_free(group);
1873 EC_GROUP_free(group2);
1874 ECPARAMETERS_free(ecparameters);
1875 OPENSSL_free(buf);
1876 return r;
1877 }
1878
1879 /*-
1880 * random 256-bit explicit parameters curve, cofactor absent
1881 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
1882 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
1883 */
1884 static const unsigned char params_cf_pass[] = {
1885 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
1886 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
1887 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
1888 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
1889 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
1890 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
1891 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
1892 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
1893 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
1894 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
1895 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
1896 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
1897 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
1898 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
1899 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
1900 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
1901 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
1902 0x14, 0xa8, 0x2f, 0x4f
1903 };
1904
1905 /*-
1906 * random 256-bit explicit parameters curve, cofactor absent
1907 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
1908 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
1909 */
1910 static const unsigned char params_cf_fail[] = {
1911 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
1912 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
1913 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
1914 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
1915 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
1916 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
1917 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
1918 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
1919 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
1920 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
1921 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
1922 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
1923 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
1924 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
1925 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
1926 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
1927 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
1928 0x34, 0xa2, 0x21, 0x01
1929 };
1930
1931 /*-
1932 * Test two random 256-bit explicit parameters curves with absent cofactor.
1933 * The two curves are chosen to roughly straddle the bounds at which the lib
1934 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
1935 *
1936 * - params_cf_pass: order is sufficiently close to p to compute cofactor
1937 * - params_cf_fail: order is too far away from p to compute cofactor
1938 *
1939 * For standards-compliant curves, cofactor is chosen as small as possible.
1940 * So you can see neither of these curves are fit for cryptographic use.
1941 *
1942 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
1943 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
1944 * will always succeed in computing the cofactor. Neither of these curves
1945 * conform to that -- this is just robustness testing.
1946 */
cofactor_range_test(void)1947 static int cofactor_range_test(void)
1948 {
1949 EC_GROUP *group = NULL;
1950 BIGNUM *cf = NULL;
1951 int ret = 0;
1952 const unsigned char *b1 = (const unsigned char *)params_cf_fail;
1953 const unsigned char *b2 = (const unsigned char *)params_cf_pass;
1954
1955 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
1956 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
1957 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
1958 sizeof(params_cf_pass)))
1959 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
1960 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
1961 goto err;
1962 ret = 1;
1963 err:
1964 BN_free(cf);
1965 EC_GROUP_free(group);
1966 return ret;
1967 }
1968
1969 /*-
1970 * For named curves, test that:
1971 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
1972 * - a nonsensical cofactor throws an error (negative test)
1973 * - nonsensical orders throw errors (negative tests)
1974 */
cardinality_test(int n)1975 static int cardinality_test(int n)
1976 {
1977 int ret = 0;
1978 int nid = curves[n].nid;
1979 BN_CTX *ctx = NULL;
1980 EC_GROUP *g1 = NULL, *g2 = NULL;
1981 EC_POINT *g2_gen = NULL;
1982 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
1983 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
1984
1985 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
1986
1987 if (!TEST_ptr(ctx = BN_CTX_new())
1988 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))
1989 || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) {
1990 EC_GROUP_free(g1);
1991 EC_GROUP_free(g2);
1992 BN_CTX_free(ctx);
1993 return 0;
1994 }
1995
1996 BN_CTX_start(ctx);
1997 g1_p = BN_CTX_get(ctx);
1998 g1_a = BN_CTX_get(ctx);
1999 g1_b = BN_CTX_get(ctx);
2000 g1_x = BN_CTX_get(ctx);
2001 g1_y = BN_CTX_get(ctx);
2002 g1_order = BN_CTX_get(ctx);
2003 g1_cf = BN_CTX_get(ctx);
2004
2005 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
2006 /* pull out the explicit curve parameters */
2007 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
2008 || !TEST_true(EC_POINT_get_affine_coordinates(g1,
2009 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
2010 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
2011 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
2012 /* construct g2 manually with g1 parameters */
2013 || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx))
2014 || !TEST_ptr(g2_gen = EC_POINT_new(g2))
2015 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
2016 /* pass NULL cofactor: lib should compute it */
2017 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2018 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2019 || !TEST_BN_eq(g1_cf, g2_cf)
2020 /* pass zero cofactor: lib should compute it */
2021 || !TEST_true(BN_set_word(g2_cf, 0))
2022 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2023 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2024 || !TEST_BN_eq(g1_cf, g2_cf)
2025 /* negative test for invalid cofactor */
2026 || !TEST_true(BN_set_word(g2_cf, 0))
2027 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2028 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2029 /* negative test for NULL order */
2030 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
2031 /* negative test for zero order */
2032 || !TEST_true(BN_set_word(g1_order, 0))
2033 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2034 /* negative test for negative order */
2035 || !TEST_true(BN_set_word(g2_cf, 0))
2036 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
2037 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2038 /* negative test for too large order */
2039 || !TEST_true(BN_lshift(g1_order, g1_p, 2))
2040 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
2041 goto err;
2042 ret = 1;
2043 err:
2044 EC_POINT_free(g2_gen);
2045 EC_GROUP_free(g1);
2046 EC_GROUP_free(g2);
2047 BN_CTX_end(ctx);
2048 BN_CTX_free(ctx);
2049 return ret;
2050 }
2051
2052 /*
2053 * Helper for ec_point_hex2point_test
2054 *
2055 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2056 * (group,P) pair.
2057 *
2058 * If P is NULL use point at infinity.
2059 */
2060 static ossl_inline
ec_point_hex2point_test_helper(const EC_GROUP * group,const EC_POINT * P,point_conversion_form_t form,BN_CTX * bnctx)2061 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2062 point_conversion_form_t form,
2063 BN_CTX *bnctx)
2064 {
2065 int ret = 0;
2066 EC_POINT *Q = NULL, *Pinf = NULL;
2067 char *hex = NULL;
2068
2069 if (P == NULL) {
2070 /* If P is NULL use point at infinity. */
2071 if (!TEST_ptr(Pinf = EC_POINT_new(group))
2072 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2073 goto err;
2074 P = Pinf;
2075 }
2076
2077 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2078 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2079 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2080 goto err;
2081
2082 /*
2083 * The next check is most likely superfluous, as EC_POINT_cmp should already
2084 * cover this.
2085 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2086 * so we include it anyway!
2087 */
2088 if (Pinf != NULL
2089 && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2090 goto err;
2091
2092 ret = 1;
2093
2094 err:
2095 EC_POINT_free(Pinf);
2096 OPENSSL_free(hex);
2097 EC_POINT_free(Q);
2098
2099 return ret;
2100 }
2101
2102 /*
2103 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2104 */
ec_point_hex2point_test(int id)2105 static int ec_point_hex2point_test(int id)
2106 {
2107 int ret = 0, nid;
2108 EC_GROUP *group = NULL;
2109 const EC_POINT *G = NULL;
2110 EC_POINT *P = NULL;
2111 BN_CTX * bnctx = NULL;
2112
2113 /* Do some setup */
2114 nid = curves[id].nid;
2115 if (!TEST_ptr(bnctx = BN_CTX_new())
2116 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2117 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2118 || !TEST_ptr(P = EC_POINT_dup(G, group)))
2119 goto err;
2120
2121 if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2122 POINT_CONVERSION_COMPRESSED,
2123 bnctx))
2124 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2125 POINT_CONVERSION_COMPRESSED,
2126 bnctx))
2127 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2128 POINT_CONVERSION_UNCOMPRESSED,
2129 bnctx))
2130 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2131 POINT_CONVERSION_UNCOMPRESSED,
2132 bnctx))
2133 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2134 POINT_CONVERSION_HYBRID,
2135 bnctx))
2136 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2137 POINT_CONVERSION_HYBRID,
2138 bnctx)))
2139 goto err;
2140
2141 ret = 1;
2142
2143 err:
2144 EC_POINT_free(P);
2145 EC_GROUP_free(group);
2146 BN_CTX_free(bnctx);
2147
2148 return ret;
2149 }
2150
2151 /*
2152 * check the EC_METHOD respects the supplied EC_GROUP_set_generator G
2153 */
custom_generator_test(int id)2154 static int custom_generator_test(int id)
2155 {
2156 int ret = 0, nid, bsize;
2157 EC_GROUP *group = NULL;
2158 EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL;
2159 BN_CTX *ctx = NULL;
2160 BIGNUM *k = NULL;
2161 unsigned char *b1 = NULL, *b2 = NULL;
2162
2163 /* Do some setup */
2164 nid = curves[id].nid;
2165 TEST_note("Curve %s", OBJ_nid2sn(nid));
2166 if (!TEST_ptr(ctx = BN_CTX_new()))
2167 return 0;
2168
2169 BN_CTX_start(ctx);
2170
2171 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)))
2172 goto err;
2173
2174 /* expected byte length of encoded points */
2175 bsize = (EC_GROUP_get_degree(group) + 7) / 8;
2176 bsize = 2 * bsize + 1;
2177
2178 if (!TEST_ptr(k = BN_CTX_get(ctx))
2179 /* fetch a testing scalar k != 0,1 */
2180 || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1,
2181 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
2182 /* make k even */
2183 || !TEST_true(BN_clear_bit(k, 0))
2184 || !TEST_ptr(G2 = EC_POINT_new(group))
2185 || !TEST_ptr(Q1 = EC_POINT_new(group))
2186 /* Q1 := kG */
2187 || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx))
2188 /* pull out the bytes of that */
2189 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2190 POINT_CONVERSION_UNCOMPRESSED, NULL,
2191 0, ctx), bsize)
2192 || !TEST_ptr(b1 = OPENSSL_malloc(bsize))
2193 || !TEST_int_eq(EC_POINT_point2oct(group, Q1,
2194 POINT_CONVERSION_UNCOMPRESSED, b1,
2195 bsize, ctx), bsize)
2196 /* new generator is G2 := 2G */
2197 || !TEST_true(EC_POINT_dbl(group, G2, EC_GROUP_get0_generator(group),
2198 ctx))
2199 || !TEST_true(EC_GROUP_set_generator(group, G2,
2200 EC_GROUP_get0_order(group),
2201 EC_GROUP_get0_cofactor(group)))
2202 || !TEST_ptr(Q2 = EC_POINT_new(group))
2203 || !TEST_true(BN_rshift1(k, k))
2204 /* Q2 := k/2 G2 */
2205 || !TEST_true(EC_POINT_mul(group, Q2, k, NULL, NULL, ctx))
2206 || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
2207 POINT_CONVERSION_UNCOMPRESSED, NULL,
2208 0, ctx), bsize)
2209 || !TEST_ptr(b2 = OPENSSL_malloc(bsize))
2210 || !TEST_int_eq(EC_POINT_point2oct(group, Q2,
2211 POINT_CONVERSION_UNCOMPRESSED, b2,
2212 bsize, ctx), bsize)
2213 /* Q1 = kG = k/2 G2 = Q2 should hold */
2214 || !TEST_int_eq(CRYPTO_memcmp(b1, b2, bsize), 0))
2215 goto err;
2216
2217 ret = 1;
2218
2219 err:
2220 BN_CTX_end(ctx);
2221 EC_POINT_free(Q1);
2222 EC_POINT_free(Q2);
2223 EC_POINT_free(G2);
2224 EC_GROUP_free(group);
2225 BN_CTX_free(ctx);
2226 OPENSSL_free(b1);
2227 OPENSSL_free(b2);
2228
2229 return ret;
2230 }
2231
2232 #endif /* OPENSSL_NO_EC */
2233
setup_tests(void)2234 int setup_tests(void)
2235 {
2236 #ifndef OPENSSL_NO_EC
2237 crv_len = EC_get_builtin_curves(NULL, 0);
2238 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2239 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
2240 return 0;
2241
2242 ADD_TEST(parameter_test);
2243 ADD_TEST(cofactor_range_test);
2244 ADD_ALL_TESTS(cardinality_test, crv_len);
2245 ADD_TEST(prime_field_tests);
2246 # ifndef OPENSSL_NO_EC2M
2247 ADD_TEST(hybrid_point_encoding_test);
2248 ADD_TEST(char2_field_tests);
2249 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
2250 # endif
2251 # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
2252 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
2253 ADD_TEST(underflow_test);
2254 # endif
2255 ADD_ALL_TESTS(internal_curve_test, crv_len);
2256 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
2257
2258 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
2259 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
2260 ADD_ALL_TESTS(custom_generator_test, crv_len);
2261 #endif /* OPENSSL_NO_EC */
2262 return 1;
2263 }
2264
cleanup_tests(void)2265 void cleanup_tests(void)
2266 {
2267 #ifndef OPENSSL_NO_EC
2268 OPENSSL_free(curves);
2269 #endif
2270 }
2271