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