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