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