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