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