blob: 8b737149d860e8e81ddeb7723035375db83431fb [file] [log] [blame]
Bodo Möller35b73a12002-08-02 14:28:37 +00001/*
Tomas Mrazf377e582021-01-20 12:59:53 +01002 * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
Rich Salzaa8f3d72017-06-15 10:16:46 -04003 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
Rich Salz440e5d82016-05-17 14:20:24 -04004 *
Richard Levitte909f1a22018-12-06 13:05:25 +01005 * Licensed under the Apache License 2.0 (the "License"). You may not use
Rich Salz440e5d82016-05-17 14:20:24 -04006 * 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
Bodo Möller35b73a12002-08-02 14:28:37 +00009 */
Rich Salz440e5d82016-05-17 14:20:24 -040010
Billy Brumley4fcd15c2020-05-13 07:33:59 +030011/*
Shane Lontis5b5eea42020-10-15 13:41:59 +100012 * EC_KEY low level APIs are deprecated for public use, but still ok for
13 * internal use.
Billy Brumley4fcd15c2020-05-13 07:33:59 +030014 */
Shane Lontis5b5eea42020-10-15 13:41:59 +100015#include "internal/deprecated.h"
Billy Brumley4fcd15c2020-05-13 07:33:59 +030016
Shane Lontis8402cd52019-03-21 20:09:02 +100017#include <string.h>
Rich Salz176db6d2017-08-22 08:35:43 -040018#include "internal/nelem.h"
Pauli2db85ac2017-04-28 14:06:11 +100019#include "testutil.h"
Emilia Kasper2f0ca542017-02-28 14:13:40 +010020
Tomas Mrazf377e582021-01-20 12:59:53 +010021#include <openssl/ec.h>
22#ifndef OPENSSL_NO_ENGINE
23# include <openssl/engine.h>
24#endif
25#include <openssl/err.h>
26#include <openssl/obj_mac.h>
27#include <openssl/objects.h>
28#include <openssl/rand.h>
29#include <openssl/bn.h>
30#include <openssl/opensslconf.h>
31#include "openssl/core_names.h"
32#include "openssl/param_build.h"
33#include "openssl/evp.h"
Bodo Möllerbb62a8b2001-03-08 19:14:52 +000034
Pauli2db85ac2017-04-28 14:06:11 +100035static size_t crv_len = 0;
36static EC_builtin_curve *curves = NULL;
Bodo Möller652ae062003-07-22 10:39:10 +000037
Bodo Möller04daec82010-08-26 14:29:55 +000038/* test multiplication with group order, long and negative scalars */
Pauli2db85ac2017-04-28 14:06:11 +100039static int group_order_tests(EC_GROUP *group)
Matt Caswell0f113f32015-01-22 03:40:55 +000040{
Pauli2db85ac2017-04-28 14:06:11 +100041 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
42 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
Billy Brumley66b0bca2018-07-08 01:27:34 +030043 const EC_POINT *G = NULL;
Pauli2db85ac2017-04-28 14:06:11 +100044 BN_CTX *ctx = NULL;
45 int i = 0, r = 0;
Bodo Möllereb8ef242010-08-27 12:07:35 +000046
Pauli2db85ac2017-04-28 14:06:11 +100047 if (!TEST_ptr(n1 = BN_new())
48 || !TEST_ptr(n2 = BN_new())
49 || !TEST_ptr(order = BN_new())
50 || !TEST_ptr(ctx = BN_CTX_new())
Billy Brumley66b0bca2018-07-08 01:27:34 +030051 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
Pauli2db85ac2017-04-28 14:06:11 +100052 || !TEST_ptr(P = EC_POINT_new(group))
53 || !TEST_ptr(Q = EC_POINT_new(group))
54 || !TEST_ptr(R = EC_POINT_new(group))
55 || !TEST_ptr(S = EC_POINT_new(group)))
56 goto err;
57
58 if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
59 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
60 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
Tomas Mrazf377e582021-01-20 12:59:53 +010061#ifndef OPENSSL_NO_DEPRECATED_3_0
Pauli2db85ac2017-04-28 14:06:11 +100062 || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
Tomas Mrazf377e582021-01-20 12:59:53 +010063#endif
Pauli2db85ac2017-04-28 14:06:11 +100064 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
Billy Brumley66b0bca2018-07-08 01:27:34 +030065 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
66 || !TEST_true(EC_POINT_copy(P, G))
67 || !TEST_true(BN_one(n1))
68 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
69 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
70 || !TEST_true(BN_sub(n1, order, n1))
71 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
72 || !TEST_true(EC_POINT_invert(group, Q, ctx))
73 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +100074 goto err;
75
Matt Caswell0f113f32015-01-22 03:40:55 +000076 for (i = 1; i <= 2; i++) {
Tomas Mrazf377e582021-01-20 12:59:53 +010077#ifndef OPENSSL_NO_DEPRECATED_3_0
Matt Caswell0f113f32015-01-22 03:40:55 +000078 const BIGNUM *scalars[6];
79 const EC_POINT *points[6];
Tomas Mrazf377e582021-01-20 12:59:53 +010080#endif
Bodo Moeller0fe73d62014-08-01 17:18:14 +020081
Pauli2db85ac2017-04-28 14:06:11 +100082 if (!TEST_true(BN_set_word(n1, i))
83 /*
84 * If i == 1, P will be the predefined generator for which
85 * EC_GROUP_precompute_mult has set up precomputation.
86 */
87 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
Billy Brumley66b0bca2018-07-08 01:27:34 +030088 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +100089 || !TEST_true(BN_one(n1))
90 /* n1 = 1 - order */
91 || !TEST_true(BN_sub(n1, n1, order))
92 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
93 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
Bodo Moeller0fe73d62014-08-01 17:18:14 +020094
Pauli2db85ac2017-04-28 14:06:11 +100095 /* n2 = 1 + order */
96 || !TEST_true(BN_add(n2, order, BN_value_one()))
97 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
98 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
Bodo Moeller0fe73d62014-08-01 17:18:14 +020099
Pauli2db85ac2017-04-28 14:06:11 +1000100 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
101 || !TEST_true(BN_mul(n2, n1, n2, ctx))
102 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
103 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
104 goto err;
Bodo Moeller0fe73d62014-08-01 17:18:14 +0200105
Matt Caswell0f113f32015-01-22 03:40:55 +0000106 /* n2 = order^2 - 1 */
107 BN_set_negative(n2, 0);
Pauli2db85ac2017-04-28 14:06:11 +1000108 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
109 /* Add P to verify the result. */
110 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
111 || !TEST_true(EC_POINT_is_at_infinity(group, Q))
Pauli2db85ac2017-04-28 14:06:11 +1000112 || !TEST_false(EC_POINT_is_at_infinity(group, P)))
113 goto err;
Andy Polyakov50e34aa2016-02-21 21:05:50 +0100114
Tomas Mrazf377e582021-01-20 12:59:53 +0100115#ifndef OPENSSL_NO_DEPRECATED_3_0
Billy Brumley4fcd15c2020-05-13 07:33:59 +0300116 /* Exercise EC_POINTs_mul, including corner cases. */
Andy Polyakov50e34aa2016-02-21 21:05:50 +0100117 scalars[0] = scalars[1] = BN_value_one();
118 points[0] = points[1] = P;
119
Pauli2db85ac2017-04-28 14:06:11 +1000120 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
121 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
122 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
123 goto err;
Andy Polyakov50e34aa2016-02-21 21:05:50 +0100124
Matt Caswell0f113f32015-01-22 03:40:55 +0000125 scalars[0] = n1;
126 points[0] = Q; /* => infinity */
127 scalars[1] = n2;
128 points[1] = P; /* => -P */
129 scalars[2] = n1;
130 points[2] = Q; /* => infinity */
131 scalars[3] = n2;
132 points[3] = Q; /* => infinity */
133 scalars[4] = n1;
134 points[4] = P; /* => P */
135 scalars[5] = n2;
136 points[5] = Q; /* => infinity */
Pauli2db85ac2017-04-28 14:06:11 +1000137 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
138 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
139 goto err;
Tomas Mrazf377e582021-01-20 12:59:53 +0100140#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000141 }
Bodo Moeller0fe73d62014-08-01 17:18:14 +0200142
Pauli2db85ac2017-04-28 14:06:11 +1000143 r = 1;
144err:
145 if (r == 0 && i != 0)
146 TEST_info(i == 1 ? "allowing precomputation" :
147 "without precomputation");
Matt Caswell0f113f32015-01-22 03:40:55 +0000148 EC_POINT_free(P);
149 EC_POINT_free(Q);
Andy Polyakov50e34aa2016-02-21 21:05:50 +0100150 EC_POINT_free(R);
151 EC_POINT_free(S);
Matt Caswell0f113f32015-01-22 03:40:55 +0000152 BN_free(n1);
153 BN_free(n2);
154 BN_free(order);
155 BN_CTX_free(ctx);
Pauli2db85ac2017-04-28 14:06:11 +1000156 return r;
Matt Caswell0f113f32015-01-22 03:40:55 +0000157}
Bodo Möller04daec82010-08-26 14:29:55 +0000158
Pauli2db85ac2017-04-28 14:06:11 +1000159static int prime_field_tests(void)
Matt Caswell0f113f32015-01-22 03:40:55 +0000160{
161 BN_CTX *ctx = NULL;
Pauli2db85ac2017-04-28 14:06:11 +1000162 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
Billy Brumley23ccae82020-05-27 13:30:04 +0300163 EC_GROUP *group = NULL;
Pauli2db85ac2017-04-28 14:06:11 +1000164 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
165 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
Tomas Mrazf377e582021-01-20 12:59:53 +0100166#ifndef OPENSSL_NO_DEPRECATED_3_0
Pauli2db85ac2017-04-28 14:06:11 +1000167 const EC_POINT *points[4];
168 const BIGNUM *scalars[4];
Tomas Mrazf377e582021-01-20 12:59:53 +0100169#endif
Matt Caswell0f113f32015-01-22 03:40:55 +0000170 unsigned char buf[100];
Pauli37916462017-06-12 10:01:17 +1000171 size_t len, r = 0;
Matt Caswell0f113f32015-01-22 03:40:55 +0000172 int k;
Bodo Mölleradfe54b2001-03-08 11:59:48 +0000173
Pauli2db85ac2017-04-28 14:06:11 +1000174 if (!TEST_ptr(ctx = BN_CTX_new())
175 || !TEST_ptr(p = BN_new())
176 || !TEST_ptr(a = BN_new())
177 || !TEST_ptr(b = BN_new())
178 || !TEST_true(BN_hex2bn(&p, "17"))
179 || !TEST_true(BN_hex2bn(&a, "1"))
180 || !TEST_true(BN_hex2bn(&b, "1"))
Billy Brumley23ccae82020-05-27 13:30:04 +0300181 || !TEST_ptr(group = EC_GROUP_new_curve_GFp(p, a, b, ctx))
182 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000183 goto err;
Bodo Möller48fe4d62001-03-10 23:18:35 +0000184
Pauli37916462017-06-12 10:01:17 +1000185 TEST_info("Curve defined by Weierstrass equation");
186 TEST_note(" y^2 = x^3 + a*x + b (mod p)");
187 test_output_bignum("a", a);
188 test_output_bignum("b", b);
189 test_output_bignum("p", p);
Bodo Möllerbb62a8b2001-03-08 19:14:52 +0000190
Matt Caswell0f113f32015-01-22 03:40:55 +0000191 buf[0] = 0;
Pauli2db85ac2017-04-28 14:06:11 +1000192 if (!TEST_ptr(P = EC_POINT_new(group))
193 || !TEST_ptr(Q = EC_POINT_new(group))
194 || !TEST_ptr(R = EC_POINT_new(group))
195 || !TEST_true(EC_POINT_set_to_infinity(group, P))
196 || !TEST_true(EC_POINT_is_at_infinity(group, P))
197 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
198 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
199 || !TEST_true(EC_POINT_is_at_infinity(group, P))
200 || !TEST_ptr(x = BN_new())
201 || !TEST_ptr(y = BN_new())
202 || !TEST_ptr(z = BN_new())
203 || !TEST_ptr(yplusone = BN_new())
204 || !TEST_true(BN_hex2bn(&x, "D"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100205 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000206 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +0000207
Pauli2db85ac2017-04-28 14:06:11 +1000208 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
Matt Caswell9cc570d2018-07-30 16:40:18 +0100209 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000210 goto err;
Pauli37916462017-06-12 10:01:17 +1000211 TEST_info("Point is not on curve");
212 test_output_bignum("x", x);
213 test_output_bignum("y", y);
Pauli2db85ac2017-04-28 14:06:11 +1000214 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +0000215 }
216
Pauli37916462017-06-12 10:01:17 +1000217 TEST_note("A cyclic subgroup:");
Matt Caswell0f113f32015-01-22 03:40:55 +0000218 k = 100;
219 do {
Pauli2db85ac2017-04-28 14:06:11 +1000220 if (!TEST_int_ne(k--, 0))
221 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +0000222
Pauli2db85ac2017-04-28 14:06:11 +1000223 if (EC_POINT_is_at_infinity(group, P)) {
Pauli37916462017-06-12 10:01:17 +1000224 TEST_note(" point at infinity");
Pauli2db85ac2017-04-28 14:06:11 +1000225 } else {
Matt Caswell9cc570d2018-07-30 16:40:18 +0100226 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
227 ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000228 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +0000229
Pauli37916462017-06-12 10:01:17 +1000230 test_output_bignum("x", x);
231 test_output_bignum("y", y);
Matt Caswell0f113f32015-01-22 03:40:55 +0000232 }
233
Pauli2db85ac2017-04-28 14:06:11 +1000234 if (!TEST_true(EC_POINT_copy(R, P))
235 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
236 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +0000237
Pauli2db85ac2017-04-28 14:06:11 +1000238 } while (!EC_POINT_is_at_infinity(group, P));
Matt Caswell0f113f32015-01-22 03:40:55 +0000239
Pauli2db85ac2017-04-28 14:06:11 +1000240 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
241 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
242 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +0000243
244 len =
245 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
Rich Salzcbe29642017-12-07 13:39:34 -0500246 sizeof(buf), ctx);
Pauli2db85ac2017-04-28 14:06:11 +1000247 if (!TEST_size_t_ne(len, 0)
248 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
249 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
250 goto err;
Pauli37916462017-06-12 10:01:17 +1000251 test_output_memory("Generator as octet string, compressed form:",
252 buf, len);
Matt Caswell0f113f32015-01-22 03:40:55 +0000253
Pauli2db85ac2017-04-28 14:06:11 +1000254 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
Rich Salzcbe29642017-12-07 13:39:34 -0500255 buf, sizeof(buf), ctx);
Pauli2db85ac2017-04-28 14:06:11 +1000256 if (!TEST_size_t_ne(len, 0)
257 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
258 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
259 goto err;
Pauli37916462017-06-12 10:01:17 +1000260 test_output_memory("Generator as octet string, uncompressed form:",
261 buf, len);
Matt Caswell0f113f32015-01-22 03:40:55 +0000262
Pauli2db85ac2017-04-28 14:06:11 +1000263 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,
Rich Salzcbe29642017-12-07 13:39:34 -0500264 buf, sizeof(buf), ctx);
Pauli2db85ac2017-04-28 14:06:11 +1000265 if (!TEST_size_t_ne(len, 0)
266 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
267 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
268 goto err;
Pauli37916462017-06-12 10:01:17 +1000269 test_output_memory("Generator as octet string, hybrid form:",
270 buf, len);
Matt Caswell0f113f32015-01-22 03:40:55 +0000271
Pauli2db85ac2017-04-28 14:06:11 +1000272 if (!TEST_true(EC_POINT_invert(group, P, ctx))
273 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
Bodo Möllerbb62a8b2001-03-08 19:14:52 +0000274
Matt Caswell0f113f32015-01-22 03:40:55 +0000275 /*
276 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
277 * 2000) -- not a NIST curve, but commonly used
278 */
Bodo Möllerbb62a8b2001-03-08 19:14:52 +0000279
Pauli2db85ac2017-04-28 14:06:11 +1000280 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF"
281 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
Kurt Roeckx42619392019-10-06 17:21:16 +0200282 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
Pauli2db85ac2017-04-28 14:06:11 +1000283 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF"
284 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
285 || !TEST_true(BN_hex2bn(&b, "1C97BEFC"
286 "54BD7A8B65ACF89F81D4D4ADC565FA45"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100287 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000288 || !TEST_true(BN_hex2bn(&x, "4A96B568"
289 "8EF573284664698968C38BB913CBFC82"))
290 || !TEST_true(BN_hex2bn(&y, "23a62855"
291 "3168947d59dcc912042351377ac5fb32"))
292 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
Emilia Kasper1e2012b2016-06-03 14:42:04 +0200293 /*
294 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
295 * and therefore setting the coordinates should fail.
296 */
Matt Caswell9cc570d2018-07-30 16:40:18 +0100297 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
298 ctx))
299 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000300 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
301 || !TEST_true(BN_hex2bn(&z, "0100000000"
302 "000000000001F4C8F927AED3CA752257"))
303 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100304 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000305 goto err;
Pauli37916462017-06-12 10:01:17 +1000306 TEST_info("SEC2 curve secp160r1 -- Generator");
307 test_output_bignum("x", x);
308 test_output_bignum("y", y);
Matt Caswell0f113f32015-01-22 03:40:55 +0000309 /* G_y value taken from the standard: */
Pauli2db85ac2017-04-28 14:06:11 +1000310 if (!TEST_true(BN_hex2bn(&z, "23a62855"
311 "3168947d59dcc912042351377ac5fb32"))
Paulidc352c12017-05-08 12:09:41 +1000312 || !TEST_BN_eq(y, z)
Pauli2db85ac2017-04-28 14:06:11 +1000313 || !TEST_int_eq(EC_GROUP_get_degree(group), 160)
314 || !group_order_tests(group)
Bodo Möller48fe4d62001-03-10 23:18:35 +0000315
Matt Caswell0f113f32015-01-22 03:40:55 +0000316 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
Bodo Möller652ae062003-07-22 10:39:10 +0000317
Pauli2db85ac2017-04-28 14:06:11 +1000318 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF"
319 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
Kurt Roeckx42619392019-10-06 17:21:16 +0200320 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
Pauli2db85ac2017-04-28 14:06:11 +1000321 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF"
322 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
323 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7"
324 "0FA7E9AB72243049FEB8DEECC146B9B1"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100325 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000326 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6"
327 "7CBF20EB43A18800F4FF0AFD82FF1012"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100328 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000329 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
330 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF"
331 "FFFFFFFF99DEF836146BC9B1B4D22831"))
332 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100333 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000334 goto err;
Bodo Möller652ae062003-07-22 10:39:10 +0000335
Pauli37916462017-06-12 10:01:17 +1000336 TEST_info("NIST curve P-192 -- Generator");
337 test_output_bignum("x", x);
338 test_output_bignum("y", y);
Matt Caswell0f113f32015-01-22 03:40:55 +0000339 /* G_y value taken from the standard: */
Pauli2db85ac2017-04-28 14:06:11 +1000340 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78"
341 "631011ED6B24CDD573F977A11E794811"))
Paulidc352c12017-05-08 12:09:41 +1000342 || !TEST_BN_eq(y, z)
Pauli2db85ac2017-04-28 14:06:11 +1000343 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
Emilia Kasper1e2012b2016-06-03 14:42:04 +0200344 /*
345 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
346 * and therefore setting the coordinates should fail.
347 */
Matt Caswell9cc570d2018-07-30 16:40:18 +0100348 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
349 ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000350 || !TEST_int_eq(EC_GROUP_get_degree(group), 192)
351 || !group_order_tests(group)
Bodo Möller48fe4d62001-03-10 23:18:35 +0000352
Matt Caswell0f113f32015-01-22 03:40:55 +0000353 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
Bodo Möller48fe4d62001-03-10 23:18:35 +0000354
Pauli2db85ac2017-04-28 14:06:11 +1000355 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF"
356 "FFFFFFFF000000000000000000000001"))
Kurt Roeckx42619392019-10-06 17:21:16 +0200357 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
Pauli2db85ac2017-04-28 14:06:11 +1000358 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF"
359 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
360 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256"
361 "5044B0B7D7BFD8BA270B39432355FFB4"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100362 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000363 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9"
364 "4A03C1D356C21122343280D6115C1D21"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100365 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000366 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
367 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF"
368 "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
369 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100370 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000371 goto err;
Bodo Möller7793f302002-08-02 13:42:24 +0000372
Pauli37916462017-06-12 10:01:17 +1000373 TEST_info("NIST curve P-224 -- Generator");
374 test_output_bignum("x", x);
375 test_output_bignum("y", y);
Matt Caswell0f113f32015-01-22 03:40:55 +0000376 /* G_y value taken from the standard: */
Pauli2db85ac2017-04-28 14:06:11 +1000377 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6"
378 "CD4375A05A07476444D5819985007E34"))
Paulidc352c12017-05-08 12:09:41 +1000379 || !TEST_BN_eq(y, z)
Pauli2db85ac2017-04-28 14:06:11 +1000380 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
Emilia Kasper1e2012b2016-06-03 14:42:04 +0200381 /*
382 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
383 * and therefore setting the coordinates should fail.
384 */
Matt Caswell9cc570d2018-07-30 16:40:18 +0100385 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
386 ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000387 || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
388 || !group_order_tests(group)
Bodo Möller48fe4d62001-03-10 23:18:35 +0000389
Matt Caswell0f113f32015-01-22 03:40:55 +0000390 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
Bodo Möller38374912001-03-11 12:27:24 +0000391
Pauli2db85ac2017-04-28 14:06:11 +1000392 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
393 "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
Kurt Roeckx42619392019-10-06 17:21:16 +0200394 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
Pauli2db85ac2017-04-28 14:06:11 +1000395 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
396 "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
397 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
398 "651D06B0CC53B0F63BCE3C3E27D2604B"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100399 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
Bodo Möller48fe4d62001-03-10 23:18:35 +0000400
Pauli2db85ac2017-04-28 14:06:11 +1000401 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
402 "77037D812DEB33A0F4A13945D898C296"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100403 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000404 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
405 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
406 "BCE6FAADA7179E84F3B9CAC2FC632551"))
407 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100408 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000409 goto err;
Bodo Möller48fe4d62001-03-10 23:18:35 +0000410
Pauli37916462017-06-12 10:01:17 +1000411 TEST_info("NIST curve P-256 -- Generator");
412 test_output_bignum("x", x);
413 test_output_bignum("y", y);
Matt Caswell0f113f32015-01-22 03:40:55 +0000414 /* G_y value taken from the standard: */
Pauli2db85ac2017-04-28 14:06:11 +1000415 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
416 "2BCE33576B315ECECBB6406837BF51F5"))
Paulidc352c12017-05-08 12:09:41 +1000417 || !TEST_BN_eq(y, z)
Pauli2db85ac2017-04-28 14:06:11 +1000418 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
Emilia Kasper1e2012b2016-06-03 14:42:04 +0200419 /*
420 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
421 * and therefore setting the coordinates should fail.
422 */
Matt Caswell9cc570d2018-07-30 16:40:18 +0100423 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
424 ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000425 || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
426 || !group_order_tests(group)
Bodo Möller48fe4d62001-03-10 23:18:35 +0000427
Matt Caswell0f113f32015-01-22 03:40:55 +0000428 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
Bodo Möller48fe4d62001-03-10 23:18:35 +0000429
Pauli2db85ac2017-04-28 14:06:11 +1000430 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
431 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
432 "FFFFFFFF0000000000000000FFFFFFFF"))
Kurt Roeckx42619392019-10-06 17:21:16 +0200433 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
Pauli2db85ac2017-04-28 14:06:11 +1000434 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
435 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
436 "FFFFFFFF0000000000000000FFFFFFFC"))
437 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
438 "181D9C6EFE8141120314088F5013875A"
439 "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100440 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
Bodo Möller48fe4d62001-03-10 23:18:35 +0000441
Pauli2db85ac2017-04-28 14:06:11 +1000442 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
443 "6E1D3B628BA79B9859F741E082542A38"
444 "5502F25DBF55296C3A545E3872760AB7"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100445 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000446 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
447 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
448 "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
449 "581A0DB248B0A77AECEC196ACCC52973"))
450 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100451 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000452 goto err;
Bodo Möller48fe4d62001-03-10 23:18:35 +0000453
Pauli37916462017-06-12 10:01:17 +1000454 TEST_info("NIST curve P-384 -- Generator");
455 test_output_bignum("x", x);
456 test_output_bignum("y", y);
Matt Caswell0f113f32015-01-22 03:40:55 +0000457 /* G_y value taken from the standard: */
Pauli2db85ac2017-04-28 14:06:11 +1000458 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
459 "F8F41DBD289A147CE9DA3113B5F0B8C0"
460 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
Paulidc352c12017-05-08 12:09:41 +1000461 || !TEST_BN_eq(y, z)
Pauli2db85ac2017-04-28 14:06:11 +1000462 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
Emilia Kasper1e2012b2016-06-03 14:42:04 +0200463 /*
464 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
465 * and therefore setting the coordinates should fail.
466 */
Matt Caswell9cc570d2018-07-30 16:40:18 +0100467 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
468 ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000469 || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
470 || !group_order_tests(group)
Bodo Möller48fe4d62001-03-10 23:18:35 +0000471
Matt Caswell0f113f32015-01-22 03:40:55 +0000472 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
Pauli2db85ac2017-04-28 14:06:11 +1000473 || !TEST_true(BN_hex2bn(&p, "1FF"
474 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
475 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
476 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
477 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
Kurt Roeckx42619392019-10-06 17:21:16 +0200478 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
Pauli2db85ac2017-04-28 14:06:11 +1000479 || !TEST_true(BN_hex2bn(&a, "1FF"
480 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
481 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
482 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
483 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
484 || !TEST_true(BN_hex2bn(&b, "051"
485 "953EB9618E1C9A1F929A21A0B68540EE"
486 "A2DA725B99B315F3B8B489918EF109E1"
487 "56193951EC7E937B1652C0BD3BB1BF07"
488 "3573DF883D2C34F1EF451FD46B503F00"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100489 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000490 || !TEST_true(BN_hex2bn(&x, "C6"
491 "858E06B70404E9CD9E3ECB662395B442"
492 "9C648139053FB521F828AF606B4D3DBA"
493 "A14B5E77EFE75928FE1DC127A2FFA8DE"
494 "3348B3C1856A429BF97E7E31C2E5BD66"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100495 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000496 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
497 || !TEST_true(BN_hex2bn(&z, "1FF"
498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
500 "51868783BF2F966B7FCC0148F709A5D0"
501 "3BB5C9B8899C47AEBB6FB71E91386409"))
502 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100503 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000504 goto err;
Bodo Möller48fe4d62001-03-10 23:18:35 +0000505
Pauli37916462017-06-12 10:01:17 +1000506 TEST_info("NIST curve P-521 -- Generator");
507 test_output_bignum("x", x);
508 test_output_bignum("y", y);
Matt Caswell0f113f32015-01-22 03:40:55 +0000509 /* G_y value taken from the standard: */
Pauli2db85ac2017-04-28 14:06:11 +1000510 if (!TEST_true(BN_hex2bn(&z, "118"
511 "39296A789A3BC0045C8A5FB42C7D1BD9"
512 "98F54449579B446817AFBD17273E662C"
513 "97EE72995EF42640C550B9013FAD0761"
514 "353C7086A272C24088BE94769FD16650"))
Paulidc352c12017-05-08 12:09:41 +1000515 || !TEST_BN_eq(y, z)
Pauli2db85ac2017-04-28 14:06:11 +1000516 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
Emilia Kasper1e2012b2016-06-03 14:42:04 +0200517 /*
518 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
519 * and therefore setting the coordinates should fail.
520 */
Matt Caswell9cc570d2018-07-30 16:40:18 +0100521 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
522 ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000523 || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
524 || !group_order_tests(group)
Bodo Möller48fe4d62001-03-10 23:18:35 +0000525
Matt Caswell0f113f32015-01-22 03:40:55 +0000526 /* more tests using the last curve */
Bodo Möller48fe4d62001-03-10 23:18:35 +0000527
Emilia Kasper1e2012b2016-06-03 14:42:04 +0200528 /* Restore the point that got mangled in the (x, y + 1) test. */
Matt Caswell9cc570d2018-07-30 16:40:18 +0100529 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000530 || !TEST_true(EC_POINT_copy(Q, P))
531 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
532 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
533 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
534 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
535 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
536 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
537 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
538 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
539 goto err;
Billy Brumley4fcd15c2020-05-13 07:33:59 +0300540
Tomas Mrazf377e582021-01-20 12:59:53 +0100541#ifndef OPENSSL_NO_DEPRECATED_3_0
Billy Brumley4fcd15c2020-05-13 07:33:59 +0300542 TEST_note("combined multiplication ...");
Pauli2db85ac2017-04-28 14:06:11 +1000543 points[0] = Q;
544 points[1] = Q;
545 points[2] = Q;
546 points[3] = Q;
Emilia Kasper1e2012b2016-06-03 14:42:04 +0200547
Pauli2db85ac2017-04-28 14:06:11 +1000548 if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
549 || !TEST_true(BN_add(y, z, BN_value_one()))
Paulidc352c12017-05-08 12:09:41 +1000550 || !TEST_BN_even(y)
Pauli2db85ac2017-04-28 14:06:11 +1000551 || !TEST_true(BN_rshift1(y, y)))
552 goto err;
Billy Brumley4fcd15c2020-05-13 07:33:59 +0300553
Pauli2db85ac2017-04-28 14:06:11 +1000554 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
555 scalars[1] = y;
Bodo Möller48fe4d62001-03-10 23:18:35 +0000556
Pauli2db85ac2017-04-28 14:06:11 +1000557 /* z is still the group order */
558 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
559 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
560 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
561 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
Rich Salz5ecff872017-06-21 13:55:02 +0100562 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
Pauli2db85ac2017-04-28 14:06:11 +1000563 || !TEST_true(BN_add(z, z, y)))
564 goto err;
565 BN_set_negative(z, 1);
566 scalars[0] = y;
567 scalars[1] = z; /* z = -(order + y) */
Bodo Möller48fe4d62001-03-10 23:18:35 +0000568
Pauli2db85ac2017-04-28 14:06:11 +1000569 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
570 || !TEST_true(EC_POINT_is_at_infinity(group, P))
Rich Salz5ecff872017-06-21 13:55:02 +0100571 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
Pauli2db85ac2017-04-28 14:06:11 +1000572 || !TEST_true(BN_add(z, x, y)))
573 goto err;
574 BN_set_negative(z, 1);
575 scalars[0] = x;
576 scalars[1] = y;
577 scalars[2] = z; /* z = -(x+y) */
Bodo Möller48fe4d62001-03-10 23:18:35 +0000578
Pauli2db85ac2017-04-28 14:06:11 +1000579 if (!TEST_ptr(scalar3 = BN_new()))
580 goto err;
581 BN_zero(scalar3);
582 scalars[3] = scalar3;
Bodo Möller48fe4d62001-03-10 23:18:35 +0000583
Pauli2db85ac2017-04-28 14:06:11 +1000584 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
585 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
586 goto err;
Tomas Mrazf377e582021-01-20 12:59:53 +0100587#endif
Pauli37916462017-06-12 10:01:17 +1000588 TEST_note(" ok\n");
Pauli2db85ac2017-04-28 14:06:11 +1000589 r = 1;
590err:
Rich Salz23a1d5e2015-04-30 21:37:06 -0400591 BN_CTX_free(ctx);
Matt Caswell0f113f32015-01-22 03:40:55 +0000592 BN_free(p);
593 BN_free(a);
594 BN_free(b);
595 EC_GROUP_free(group);
596 EC_POINT_free(P);
597 EC_POINT_free(Q);
598 EC_POINT_free(R);
599 BN_free(x);
600 BN_free(y);
601 BN_free(z);
Emilia Kasper1e2012b2016-06-03 14:42:04 +0200602 BN_free(yplusone);
Pauli2db85ac2017-04-28 14:06:11 +1000603 BN_free(scalar3);
Pauli2db85ac2017-04-28 14:06:11 +1000604 return r;
Matt Caswell0f113f32015-01-22 03:40:55 +0000605}
Bodo Möller7793f302002-08-02 13:42:24 +0000606
Tomas Mrazf377e582021-01-20 12:59:53 +0100607#ifndef OPENSSL_NO_EC2M
Bodo Möller7793f302002-08-02 13:42:24 +0000608
Pauli2db85ac2017-04-28 14:06:11 +1000609static struct c2_curve_test {
610 const char *name;
611 const char *p;
612 const char *a;
613 const char *b;
614 const char *x;
615 const char *y;
616 int ybit;
617 const char *order;
618 const char *cof;
619 int degree;
620} char2_curve_tests[] = {
621 /* Curve K-163 (FIPS PUB 186-2, App. 6) */
622 {
623 "NIST curve K-163",
624 "0800000000000000000000000000000000000000C9",
625 "1",
626 "1",
627 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
628 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
629 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163
630 },
631 /* Curve B-163 (FIPS PUB 186-2, App. 6) */
632 {
633 "NIST curve B-163",
634 "0800000000000000000000000000000000000000C9",
635 "1",
636 "020A601907B8C953CA1481EB10512F78744A3205FD",
637 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
638 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
639 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163
640 },
641 /* Curve K-233 (FIPS PUB 186-2, App. 6) */
642 {
643 "NIST curve K-233",
644 "020000000000000000000000000000000000000004000000000000000001",
645 "0",
646 "1",
647 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
648 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
649 0,
650 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
651 "4", 233
652 },
653 /* Curve B-233 (FIPS PUB 186-2, App. 6) */
654 {
655 "NIST curve B-233",
656 "020000000000000000000000000000000000000004000000000000000001",
657 "000000000000000000000000000000000000000000000000000000000001",
658 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
659 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
660 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
661 1,
662 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
663 "2", 233
664 },
665 /* Curve K-283 (FIPS PUB 186-2, App. 6) */
666 {
667 "NIST curve K-283",
668 "08000000"
669 "00000000000000000000000000000000000000000000000000000000000010A1",
670 "0",
671 "1",
672 "0503213F"
673 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
674 "01CCDA38"
675 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
676 0,
677 "01FFFFFF"
678 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
679 "4", 283
680 },
681 /* Curve B-283 (FIPS PUB 186-2, App. 6) */
682 {
683 "NIST curve B-283",
684 "08000000"
685 "00000000000000000000000000000000000000000000000000000000000010A1",
686 "00000000"
687 "0000000000000000000000000000000000000000000000000000000000000001",
688 "027B680A"
689 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
690 "05F93925"
691 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
692 "03676854"
693 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
694 1,
695 "03FFFFFF"
696 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
697 "2", 283
698 },
699 /* Curve K-409 (FIPS PUB 186-2, App. 6) */
700 {
701 "NIST curve K-409",
702 "0200000000000000000000000000000000000000"
703 "0000000000000000000000000000000000000000008000000000000000000001",
704 "0",
705 "1",
706 "0060F05F658F49C1AD3AB1890F7184210EFD0987"
707 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
708 "01E369050B7C4E42ACBA1DACBF04299C3460782F"
709 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
710 1,
711 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
712 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
713 "4", 409
714 },
715 /* Curve B-409 (FIPS PUB 186-2, App. 6) */
716 {
717 "NIST curve B-409",
718 "0200000000000000000000000000000000000000"
719 "0000000000000000000000000000000000000000008000000000000000000001",
720 "0000000000000000000000000000000000000000"
721 "0000000000000000000000000000000000000000000000000000000000000001",
722 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E"
723 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
724 "015D4860D088DDB3496B0C6064756260441CDE4A"
725 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
726 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5"
727 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
728 1,
729 "0100000000000000000000000000000000000000"
730 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
731 "2", 409
732 },
733 /* Curve K-571 (FIPS PUB 186-2, App. 6) */
734 {
735 "NIST curve K-571",
736 "800000000000000"
737 "0000000000000000000000000000000000000000000000000000000000000000"
738 "0000000000000000000000000000000000000000000000000000000000000425",
739 "0",
740 "1",
741 "026EB7A859923FBC"
742 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6"
743 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
744 "0349DC807F4FBF37"
745 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7"
746 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
747 0,
748 "0200000000000000"
749 "00000000000000000000000000000000000000000000000000000000131850E1"
750 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
751 "4", 571
752 },
753 /* Curve B-571 (FIPS PUB 186-2, App. 6) */
754 {
755 "NIST curve B-571",
756 "800000000000000"
757 "0000000000000000000000000000000000000000000000000000000000000000"
758 "0000000000000000000000000000000000000000000000000000000000000425",
759 "0000000000000000"
760 "0000000000000000000000000000000000000000000000000000000000000000"
761 "0000000000000000000000000000000000000000000000000000000000000001",
762 "02F40E7E2221F295"
763 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933"
764 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
765 "0303001D34B85629"
766 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293"
767 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
768 "037BF27342DA639B"
769 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57"
770 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
771 1,
772 "03FFFFFFFFFFFFFF"
773 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18"
774 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
775 "2", 571
776 }
777};
778
779static int char2_curve_test(int n)
780{
781 int r = 0;
782 BN_CTX *ctx = NULL;
783 BIGNUM *p = NULL, *a = NULL, *b = NULL;
784 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
Billy Brumley23ccae82020-05-27 13:30:04 +0300785 EC_GROUP *group = NULL;
Pauli2db85ac2017-04-28 14:06:11 +1000786 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
Billy Brumley4fcd15c2020-05-13 07:33:59 +0300787# ifndef OPENSSL_NO_DEPRECATED_3_0
Pauli2db85ac2017-04-28 14:06:11 +1000788 const EC_POINT *points[3];
789 const BIGNUM *scalars[3];
Billy Brumley4fcd15c2020-05-13 07:33:59 +0300790# endif
Pauli2db85ac2017-04-28 14:06:11 +1000791 struct c2_curve_test *const test = char2_curve_tests + n;
792
793 if (!TEST_ptr(ctx = BN_CTX_new())
794 || !TEST_ptr(p = BN_new())
795 || !TEST_ptr(a = BN_new())
796 || !TEST_ptr(b = BN_new())
797 || !TEST_ptr(x = BN_new())
798 || !TEST_ptr(y = BN_new())
799 || !TEST_ptr(z = BN_new())
800 || !TEST_ptr(yplusone = BN_new())
801 || !TEST_true(BN_hex2bn(&p, test->p))
802 || !TEST_true(BN_hex2bn(&a, test->a))
803 || !TEST_true(BN_hex2bn(&b, test->b))
Billy Brumley23ccae82020-05-27 13:30:04 +0300804 || !TEST_true(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000805 || !TEST_ptr(P = EC_POINT_new(group))
806 || !TEST_ptr(Q = EC_POINT_new(group))
807 || !TEST_ptr(R = EC_POINT_new(group))
808 || !TEST_true(BN_hex2bn(&x, test->x))
809 || !TEST_true(BN_hex2bn(&y, test->y))
810 || !TEST_true(BN_add(yplusone, y, BN_value_one())))
811 goto err;
812
813/* Change test based on whether binary point compression is enabled or not. */
814# ifdef OPENSSL_EC_BIN_PT_COMP
815 /*
816 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
817 * and therefore setting the coordinates should fail.
818 */
Matt Caswell9cc570d2018-07-30 16:40:18 +0100819 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
820 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x,
821 test->y_bit,
822 ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000823 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
824 || !TEST_true(BN_hex2bn(&z, test->order))
825 || !TEST_true(BN_hex2bn(&cof, test->cof))
826 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100827 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000828 goto err;
Pauli37916462017-06-12 10:01:17 +1000829 TEST_info("%s -- Generator", test->name);
830 test_output_bignum("x", x);
831 test_output_bignum("y", y);
Pauli2db85ac2017-04-28 14:06:11 +1000832 /* G_y value taken from the standard: */
833 if (!TEST_true(BN_hex2bn(&z, test->y))
Paulidc352c12017-05-08 12:09:41 +1000834 || !TEST_BN_eq(y, z))
Pauli2db85ac2017-04-28 14:06:11 +1000835 goto err;
836# else
837 /*
838 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
839 * and therefore setting the coordinates should fail.
840 */
Matt Caswell9cc570d2018-07-30 16:40:18 +0100841 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx))
842 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000843 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
844 || !TEST_true(BN_hex2bn(&z, test->order))
845 || !TEST_true(BN_hex2bn(&cof, test->cof))
846 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)))
847 goto err;
Pauli37916462017-06-12 10:01:17 +1000848 TEST_info("%s -- Generator:", test->name);
849 test_output_bignum("x", x);
850 test_output_bignum("y", y);
Pauli2db85ac2017-04-28 14:06:11 +1000851# endif
852
853 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree)
Billy Brumley23ccae82020-05-27 13:30:04 +0300854 || !group_order_tests(group))
Pauli2db85ac2017-04-28 14:06:11 +1000855 goto err;
856
857 /* more tests using the last curve */
858 if (n == OSSL_NELEM(char2_curve_tests) - 1) {
Matt Caswell9cc570d2018-07-30 16:40:18 +0100859 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
Pauli2db85ac2017-04-28 14:06:11 +1000860 || !TEST_true(EC_POINT_copy(Q, P))
861 || !TEST_false(EC_POINT_is_at_infinity(group, Q))
862 || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
863 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
864 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */
865 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
866 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
867 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */
868 || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
869 goto err;
870
Billy Brumley4fcd15c2020-05-13 07:33:59 +0300871# ifndef OPENSSL_NO_DEPRECATED_3_0
872 TEST_note("combined multiplication ...");
Pauli2db85ac2017-04-28 14:06:11 +1000873 points[0] = Q;
874 points[1] = Q;
875 points[2] = Q;
876
877 if (!TEST_true(BN_add(y, z, BN_value_one()))
Paulidc352c12017-05-08 12:09:41 +1000878 || !TEST_BN_even(y)
Pauli2db85ac2017-04-28 14:06:11 +1000879 || !TEST_true(BN_rshift1(y, y)))
880 goto err;
881 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
882 scalars[1] = y;
883
Pauli2db85ac2017-04-28 14:06:11 +1000884 /* z is still the group order */
885 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
886 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
887 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
888 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)))
889 goto err;
890
Rich Salz5ecff872017-06-21 13:55:02 +0100891 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
Pauli2db85ac2017-04-28 14:06:11 +1000892 || !TEST_true(BN_add(z, z, y)))
893 goto err;
894 BN_set_negative(z, 1);
895 scalars[0] = y;
896 scalars[1] = z; /* z = -(order + y) */
897
898 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
899 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
900 goto err;
901
Rich Salz5ecff872017-06-21 13:55:02 +0100902 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
Pauli2db85ac2017-04-28 14:06:11 +1000903 || !TEST_true(BN_add(z, x, y)))
904 goto err;
905 BN_set_negative(z, 1);
906 scalars[0] = x;
907 scalars[1] = y;
908 scalars[2] = z; /* z = -(x+y) */
909
910 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
911 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
Billy Brumley4fcd15c2020-05-13 07:33:59 +0300912 goto err;
913# endif
Pauli2db85ac2017-04-28 14:06:11 +1000914 }
915
916 r = 1;
917err:
918 BN_CTX_free(ctx);
919 BN_free(p);
920 BN_free(a);
921 BN_free(b);
922 BN_free(x);
923 BN_free(y);
924 BN_free(z);
925 BN_free(yplusone);
926 BN_free(cof);
927 EC_POINT_free(P);
928 EC_POINT_free(Q);
929 EC_POINT_free(R);
930 EC_GROUP_free(group);
Pauli2db85ac2017-04-28 14:06:11 +1000931 return r;
932}
933
934static int char2_field_tests(void)
Matt Caswell0f113f32015-01-22 03:40:55 +0000935{
936 BN_CTX *ctx = NULL;
Pauli2db85ac2017-04-28 14:06:11 +1000937 BIGNUM *p = NULL, *a = NULL, *b = NULL;
Billy Brumley23ccae82020-05-27 13:30:04 +0300938 EC_GROUP *group = NULL;
Pauli2db85ac2017-04-28 14:06:11 +1000939 EC_POINT *P = NULL, *Q = NULL, *R = NULL;
940 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL;
Matt Caswell0f113f32015-01-22 03:40:55 +0000941 unsigned char buf[100];
Pauli37916462017-06-12 10:01:17 +1000942 size_t len;
Pauli2db85ac2017-04-28 14:06:11 +1000943 int k, r = 0;
Bodo Möller7793f302002-08-02 13:42:24 +0000944
Pauli2db85ac2017-04-28 14:06:11 +1000945 if (!TEST_ptr(ctx = BN_CTX_new())
946 || !TEST_ptr(p = BN_new())
947 || !TEST_ptr(a = BN_new())
948 || !TEST_ptr(b = BN_new())
949 || !TEST_true(BN_hex2bn(&p, "13"))
950 || !TEST_true(BN_hex2bn(&a, "3"))
951 || !TEST_true(BN_hex2bn(&b, "1")))
952 goto err;
Bodo Möller7793f302002-08-02 13:42:24 +0000953
Billy Brumley23ccae82020-05-27 13:30:04 +0300954 if (!TEST_ptr(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx))
955 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000956 goto err;
Bodo Möller7793f302002-08-02 13:42:24 +0000957
Pauli37916462017-06-12 10:01:17 +1000958 TEST_info("Curve defined by Weierstrass equation");
959 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)");
960 test_output_bignum("a", a);
961 test_output_bignum("b", b);
962 test_output_bignum("p", p);
Bodo Möller7793f302002-08-02 13:42:24 +0000963
Pauli2db85ac2017-04-28 14:06:11 +1000964 if (!TEST_ptr(P = EC_POINT_new(group))
965 || !TEST_ptr(Q = EC_POINT_new(group))
966 || !TEST_ptr(R = EC_POINT_new(group))
967 || !TEST_true(EC_POINT_set_to_infinity(group, P))
968 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
969 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +0000970
971 buf[0] = 0;
Pauli2db85ac2017-04-28 14:06:11 +1000972 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))
973 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))
974 || !TEST_true(EC_POINT_is_at_infinity(group, P))
975 || !TEST_ptr(x = BN_new())
976 || !TEST_ptr(y = BN_new())
977 || !TEST_ptr(z = BN_new())
978 || !TEST_ptr(cof = BN_new())
979 || !TEST_ptr(yplusone = BN_new())
980 || !TEST_true(BN_hex2bn(&x, "6"))
Bodo Möller7793f302002-08-02 13:42:24 +0000981/* Change test based on whether binary point compression is enabled or not. */
Tomas Mrazf377e582021-01-20 12:59:53 +0100982# ifdef OPENSSL_EC_BIN_PT_COMP
Matt Caswell9cc570d2018-07-30 16:40:18 +0100983 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))
Tomas Mrazf377e582021-01-20 12:59:53 +0100984# else
Pauli2db85ac2017-04-28 14:06:11 +1000985 || !TEST_true(BN_hex2bn(&y, "8"))
Matt Caswell9cc570d2018-07-30 16:40:18 +0100986 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx))
Tomas Mrazf377e582021-01-20 12:59:53 +0100987# endif
Pauli2db85ac2017-04-28 14:06:11 +1000988 )
989 goto err;
990 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {
Bodo Möller7793f302002-08-02 13:42:24 +0000991/* Change test based on whether binary point compression is enabled or not. */
Tomas Mrazf377e582021-01-20 12:59:53 +0100992# ifdef OPENSSL_EC_BIN_PT_COMP
Matt Caswell9cc570d2018-07-30 16:40:18 +0100993 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))
Pauli2db85ac2017-04-28 14:06:11 +1000994 goto err;
Tomas Mrazf377e582021-01-20 12:59:53 +0100995# endif
Pauli37916462017-06-12 10:01:17 +1000996 TEST_info("Point is not on curve");
997 test_output_bignum("x", x);
998 test_output_bignum("y", y);
Pauli2db85ac2017-04-28 14:06:11 +1000999 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001000 }
Bodo Möller7793f302002-08-02 13:42:24 +00001001
Pauli37916462017-06-12 10:01:17 +10001002 TEST_note("A cyclic subgroup:");
Matt Caswell0f113f32015-01-22 03:40:55 +00001003 k = 100;
1004 do {
Pauli2db85ac2017-04-28 14:06:11 +10001005 if (!TEST_int_ne(k--, 0))
1006 goto err;
Bodo Möller7793f302002-08-02 13:42:24 +00001007
Matt Caswell0f113f32015-01-22 03:40:55 +00001008 if (EC_POINT_is_at_infinity(group, P))
Pauli37916462017-06-12 10:01:17 +10001009 TEST_note(" point at infinity");
Matt Caswell0f113f32015-01-22 03:40:55 +00001010 else {
Matt Caswell9cc570d2018-07-30 16:40:18 +01001011 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,
1012 ctx)))
Pauli2db85ac2017-04-28 14:06:11 +10001013 goto err;
Bodo Möller7793f302002-08-02 13:42:24 +00001014
Pauli37916462017-06-12 10:01:17 +10001015 test_output_bignum("x", x);
1016 test_output_bignum("y", y);
Matt Caswell0f113f32015-01-22 03:40:55 +00001017 }
Bodo Möller7793f302002-08-02 13:42:24 +00001018
Pauli2db85ac2017-04-28 14:06:11 +10001019 if (!TEST_true(EC_POINT_copy(R, P))
1020 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))
1021 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001022 }
1023 while (!EC_POINT_is_at_infinity(group, P));
1024
Pauli2db85ac2017-04-28 14:06:11 +10001025 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))
1026 || !TEST_true(EC_POINT_is_at_infinity(group, P)))
1027 goto err;
Bodo Möller7793f302002-08-02 13:42:24 +00001028
1029/* Change test based on whether binary point compression is enabled or not. */
Tomas Mrazf377e582021-01-20 12:59:53 +01001030# ifdef OPENSSL_EC_BIN_PT_COMP
Pauli2db85ac2017-04-28 14:06:11 +10001031 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED,
Rich Salzcbe29642017-12-07 13:39:34 -05001032 buf, sizeof(buf), ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001033 if (!TEST_size_t_ne(len, 0)
1034 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1035 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1036 goto err;
Pauli37916462017-06-12 10:01:17 +10001037 test_output_memory("Generator as octet string, compressed form:",
1038 buf, len);
Tomas Mrazf377e582021-01-20 12:59:53 +01001039# endif
Matt Caswell0f113f32015-01-22 03:40:55 +00001040
Pauli2db85ac2017-04-28 14:06:11 +10001041 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,
Rich Salzcbe29642017-12-07 13:39:34 -05001042 buf, sizeof(buf), ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001043 if (!TEST_size_t_ne(len, 0)
1044 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1045 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1046 goto err;
Pauli37916462017-06-12 10:01:17 +10001047 test_output_memory("Generator as octet string, uncompressed form:",
1048 buf, len);
Matt Caswell0f113f32015-01-22 03:40:55 +00001049
Bodo Möller7793f302002-08-02 13:42:24 +00001050/* Change test based on whether binary point compression is enabled or not. */
Tomas Mrazf377e582021-01-20 12:59:53 +01001051# ifdef OPENSSL_EC_BIN_PT_COMP
Matt Caswell0f113f32015-01-22 03:40:55 +00001052 len =
Rich Salzcbe29642017-12-07 13:39:34 -05001053 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf),
Matt Caswell0f113f32015-01-22 03:40:55 +00001054 ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001055 if (!TEST_size_t_ne(len, 0)
1056 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))
1057 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))
1058 goto err;
Pauli37916462017-06-12 10:01:17 +10001059 test_output_memory("Generator as octet string, hybrid form:",
1060 buf, len);
Tomas Mrazf377e582021-01-20 12:59:53 +01001061# endif
Bodo Möller7793f302002-08-02 13:42:24 +00001062
Pauli2db85ac2017-04-28 14:06:11 +10001063 if (!TEST_true(EC_POINT_invert(group, P, ctx))
1064 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)))
1065 goto err;
Bodo Möller7793f302002-08-02 13:42:24 +00001066
Pauli37916462017-06-12 10:01:17 +10001067 TEST_note("\n");
Bodo Möller7793f302002-08-02 13:42:24 +00001068
Pauli2db85ac2017-04-28 14:06:11 +10001069 r = 1;
1070err:
Rich Salz23a1d5e2015-04-30 21:37:06 -04001071 BN_CTX_free(ctx);
Matt Caswell0f113f32015-01-22 03:40:55 +00001072 BN_free(p);
1073 BN_free(a);
1074 BN_free(b);
1075 EC_GROUP_free(group);
1076 EC_POINT_free(P);
1077 EC_POINT_free(Q);
1078 EC_POINT_free(R);
1079 BN_free(x);
1080 BN_free(y);
1081 BN_free(z);
1082 BN_free(cof);
Emilia Kasper1e2012b2016-06-03 14:42:04 +02001083 BN_free(yplusone);
Pauli2db85ac2017-04-28 14:06:11 +10001084 return r;
Matt Caswell0f113f32015-01-22 03:40:55 +00001085}
Tomas Mrazf377e582021-01-20 12:59:53 +01001086#endif
Bodo Möller7793f302002-08-02 13:42:24 +00001087
Pauli2db85ac2017-04-28 14:06:11 +10001088static int internal_curve_test(int n)
Matt Caswell0f113f32015-01-22 03:40:55 +00001089{
Pauli2db85ac2017-04-28 14:06:11 +10001090 EC_GROUP *group = NULL;
1091 int nid = curves[n].nid;
Bodo Möllerd742bd82002-11-11 10:25:12 +00001092
Pauli2db85ac2017-04-28 14:06:11 +10001093 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1094 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1095 OBJ_nid2sn(nid));
1096 return 0;
Matt Caswell0f113f32015-01-22 03:40:55 +00001097 }
Pauli2db85ac2017-04-28 14:06:11 +10001098 if (!TEST_true(EC_GROUP_check(group, NULL))) {
1099 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
Matt Caswell0f113f32015-01-22 03:40:55 +00001100 EC_GROUP_free(group);
Pauli2db85ac2017-04-28 14:06:11 +10001101 return 0;
Matt Caswell0f113f32015-01-22 03:40:55 +00001102 }
Pauli2db85ac2017-04-28 14:06:11 +10001103 EC_GROUP_free(group);
1104 return 1;
1105}
Billy Brumley920ed8c2016-01-27 17:29:32 +02001106
Pauli2db85ac2017-04-28 14:06:11 +10001107static int internal_curve_test_method(int n)
1108{
1109 int r, nid = curves[n].nid;
1110 EC_GROUP *group;
Billy Brumley920ed8c2016-01-27 17:29:32 +02001111
Pauli2db85ac2017-04-28 14:06:11 +10001112 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
1113 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
1114 return 0;
1115 }
1116 r = group_order_tests(group);
1117 EC_GROUP_free(group);
1118 return r;
Matt Caswell0f113f32015-01-22 03:40:55 +00001119}
Bodo Möller3e00b4c2011-10-18 19:43:16 +00001120
David Asraffa1f0302019-02-07 11:51:39 +02001121static int group_field_test(void)
1122{
1123 int r = 1;
1124 BIGNUM *secp521r1_field = NULL;
1125 BIGNUM *sect163r2_field = NULL;
1126 EC_GROUP *secp521r1_group = NULL;
1127 EC_GROUP *sect163r2_group = NULL;
1128
1129 BN_hex2bn(&secp521r1_field,
1130 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1131 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1132 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1133 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
1134 "FFFF");
1135
1136
1137 BN_hex2bn(&sect163r2_field,
1138 "08000000000000000000000000000000"
1139 "00000000C9");
1140
1141 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1);
1142 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group)))
1143 r = 0;
1144
1145 # ifndef OPENSSL_NO_EC2M
1146 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2);
1147 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group)))
1148 r = 0;
1149 # endif
1150
1151 EC_GROUP_free(secp521r1_group);
1152 EC_GROUP_free(sect163r2_group);
1153 BN_free(secp521r1_field);
1154 BN_free(sect163r2_field);
1155 return r;
1156}
1157
Matt Caswell0f113f32015-01-22 03:40:55 +00001158/*
Billy Brumley23ccae82020-05-27 13:30:04 +03001159 * nistp_test_params contains magic numbers for testing
1160 * several NIST curves with characteristic > 3.
Matt Caswell0f113f32015-01-22 03:40:55 +00001161 */
1162struct nistp_test_params {
Billy Brumley23ccae82020-05-27 13:30:04 +03001163 const int nid;
Matt Caswell0f113f32015-01-22 03:40:55 +00001164 int degree;
1165 /*
1166 * Qx, Qy and D are taken from
Matt Caswell79caf5d2015-12-19 14:38:17 +00001167 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
Matt Caswell0f113f32015-01-22 03:40:55 +00001168 * Otherwise, values are standard curve parameters from FIPS 180-3
1169 */
1170 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
1171};
1172
1173static const struct nistp_test_params nistp_tests_params[] = {
1174 {
1175 /* P-224 */
Billy Brumley23ccae82020-05-27 13:30:04 +03001176 NID_secp224r1,
Matt Caswell0f113f32015-01-22 03:40:55 +00001177 224,
1178 /* p */
1179 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
1180 /* a */
1181 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
1182 /* b */
1183 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
1184 /* Qx */
1185 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
1186 /* Qy */
1187 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
1188 /* Gx */
1189 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
1190 /* Gy */
1191 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
1192 /* order */
1193 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
1194 /* d */
1195 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
1196 },
1197 {
1198 /* P-256 */
Billy Brumley23ccae82020-05-27 13:30:04 +03001199 NID_X9_62_prime256v1,
Matt Caswell0f113f32015-01-22 03:40:55 +00001200 256,
1201 /* p */
1202 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
1203 /* a */
1204 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
1205 /* b */
1206 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
1207 /* Qx */
1208 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
1209 /* Qy */
1210 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
1211 /* Gx */
1212 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
1213 /* Gy */
1214 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
1215 /* order */
1216 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
1217 /* d */
1218 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
1219 },
1220 {
1221 /* P-521 */
Billy Brumley23ccae82020-05-27 13:30:04 +03001222 NID_secp521r1,
Matt Caswell0f113f32015-01-22 03:40:55 +00001223 521,
1224 /* p */
Pauli2db85ac2017-04-28 14:06:11 +10001225 "1ff"
1226 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1227 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
Matt Caswell0f113f32015-01-22 03:40:55 +00001228 /* a */
Pauli2db85ac2017-04-28 14:06:11 +10001229 "1ff"
1230 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1231 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
Matt Caswell0f113f32015-01-22 03:40:55 +00001232 /* b */
Pauli2db85ac2017-04-28 14:06:11 +10001233 "051"
1234 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
1235 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
Matt Caswell0f113f32015-01-22 03:40:55 +00001236 /* Qx */
Pauli2db85ac2017-04-28 14:06:11 +10001237 "0098"
1238 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
1239 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
Matt Caswell0f113f32015-01-22 03:40:55 +00001240 /* Qy */
Pauli2db85ac2017-04-28 14:06:11 +10001241 "0164"
1242 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
1243 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
Matt Caswell0f113f32015-01-22 03:40:55 +00001244 /* Gx */
Pauli2db85ac2017-04-28 14:06:11 +10001245 "c6"
1246 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
1247 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
Matt Caswell0f113f32015-01-22 03:40:55 +00001248 /* Gy */
Pauli2db85ac2017-04-28 14:06:11 +10001249 "118"
1250 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
1251 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
Matt Caswell0f113f32015-01-22 03:40:55 +00001252 /* order */
Pauli2db85ac2017-04-28 14:06:11 +10001253 "1ff"
1254 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
1255 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
Matt Caswell0f113f32015-01-22 03:40:55 +00001256 /* d */
Pauli2db85ac2017-04-28 14:06:11 +10001257 "0100"
1258 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
1259 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
Matt Caswell0f113f32015-01-22 03:40:55 +00001260 },
1261};
Bodo Möller3e00b4c2011-10-18 19:43:16 +00001262
Pauli2db85ac2017-04-28 14:06:11 +10001263static int nistp_single_test(int idx)
Matt Caswell0f113f32015-01-22 03:40:55 +00001264{
Pauli2db85ac2017-04-28 14:06:11 +10001265 const struct nistp_test_params *test = nistp_tests_params + idx;
1266 BN_CTX *ctx = NULL;
1267 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
1268 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
1269 EC_GROUP *NISTP = NULL;
1270 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
1271 int r = 0;
Bodo Möllere0d61322011-10-19 08:59:53 +00001272
Pauli37916462017-06-12 10:01:17 +10001273 TEST_note("NIST curve P-%d (optimised implementation):",
1274 test->degree);
Pauli2db85ac2017-04-28 14:06:11 +10001275 if (!TEST_ptr(ctx = BN_CTX_new())
1276 || !TEST_ptr(p = BN_new())
1277 || !TEST_ptr(a = BN_new())
1278 || !TEST_ptr(b = BN_new())
1279 || !TEST_ptr(x = BN_new())
1280 || !TEST_ptr(y = BN_new())
1281 || !TEST_ptr(m = BN_new())
1282 || !TEST_ptr(n = BN_new())
1283 || !TEST_ptr(order = BN_new())
1284 || !TEST_ptr(yplusone = BN_new())
Bodo Möllereb8ef242010-08-27 12:07:35 +00001285
Billy Brumley23ccae82020-05-27 13:30:04 +03001286 || !TEST_ptr(NISTP = EC_GROUP_new_by_curve_name(test->nid))
Pauli2db85ac2017-04-28 14:06:11 +10001287 || !TEST_true(BN_hex2bn(&p, test->p))
Kurt Roeckx42619392019-10-06 17:21:16 +02001288 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL))
Pauli2db85ac2017-04-28 14:06:11 +10001289 || !TEST_true(BN_hex2bn(&a, test->a))
1290 || !TEST_true(BN_hex2bn(&b, test->b))
Matt Caswell9cc570d2018-07-30 16:40:18 +01001291 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
Pauli2db85ac2017-04-28 14:06:11 +10001292 || !TEST_ptr(G = EC_POINT_new(NISTP))
1293 || !TEST_ptr(P = EC_POINT_new(NISTP))
1294 || !TEST_ptr(Q = EC_POINT_new(NISTP))
1295 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
1296 || !TEST_true(BN_hex2bn(&x, test->Qx))
1297 || !TEST_true(BN_hex2bn(&y, test->Qy))
1298 || !TEST_true(BN_add(yplusone, y, BN_value_one()))
Emilia Kasper1e2012b2016-06-03 14:42:04 +02001299 /*
1300 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
1301 * and therefore setting the coordinates should fail.
1302 */
Matt Caswell9cc570d2018-07-30 16:40:18 +01001303 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
1304 yplusone, ctx))
1305 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
1306 ctx))
Pauli2db85ac2017-04-28 14:06:11 +10001307 || !TEST_true(BN_hex2bn(&x, test->Gx))
1308 || !TEST_true(BN_hex2bn(&y, test->Gy))
Matt Caswell9cc570d2018-07-30 16:40:18 +01001309 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
Pauli2db85ac2017-04-28 14:06:11 +10001310 || !TEST_true(BN_hex2bn(&order, test->order))
1311 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
1312 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
1313 goto err;
Bodo Möller04daec82010-08-26 14:29:55 +00001314
Pauli37916462017-06-12 10:01:17 +10001315 TEST_note("NIST test vectors ... ");
Pauli2db85ac2017-04-28 14:06:11 +10001316 if (!TEST_true(BN_hex2bn(&n, test->d)))
1317 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001318 /* fixed point multiplication */
1319 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001320 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1321 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001322 /* random point multiplication */
1323 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001324 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
Bodo Möller04daec82010-08-26 14:29:55 +00001325
Pauli2db85ac2017-04-28 14:06:11 +10001326 /* set generator to P = 2*G, where G is the standard generator */
1327 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
1328 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
1329 /* set the scalar to m=n/2, where n is the NIST test scalar */
1330 || !TEST_true(BN_rshift(m, n, 1)))
1331 goto err;
Bodo Möller04daec82010-08-26 14:29:55 +00001332
Matt Caswell0f113f32015-01-22 03:40:55 +00001333 /* test the non-standard generator */
1334 /* fixed point multiplication */
1335 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001336 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1337 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001338 /* random point multiplication */
1339 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001340 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
Tomas Mrazf377e582021-01-20 12:59:53 +01001341#ifndef OPENSSL_NO_DEPRECATED_3_0
Billy Brumley6b4eb932020-05-17 16:09:00 +03001342 /* We have not performed precomp so this should be false */
Pauli2db85ac2017-04-28 14:06:11 +10001343 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
Billy Brumley6b4eb932020-05-17 16:09:00 +03001344 /* now repeat all tests with precomputation */
Pauli2db85ac2017-04-28 14:06:11 +10001345 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
Tomas Mrazf377e582021-01-20 12:59:53 +01001346#endif
Billy Brumley6b4eb932020-05-17 16:09:00 +03001347 )
Pauli2db85ac2017-04-28 14:06:11 +10001348 goto err;
Bodo Möller04daec82010-08-26 14:29:55 +00001349
Matt Caswell0f113f32015-01-22 03:40:55 +00001350 /* fixed point multiplication */
1351 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001352 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1353 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001354 /* random point multiplication */
1355 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001356 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
Bodo Möller04daec82010-08-26 14:29:55 +00001357
Matt Caswell0f113f32015-01-22 03:40:55 +00001358 /* reset generator */
Pauli2db85ac2017-04-28 14:06:11 +10001359 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
1360 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001361 /* fixed point multiplication */
1362 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001363 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1364 goto err;
Matt Caswell0f113f32015-01-22 03:40:55 +00001365 /* random point multiplication */
1366 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001367 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
1368 goto err;
Bodo Möller04daec82010-08-26 14:29:55 +00001369
David Benjamindc55e4f2018-03-28 12:21:45 -04001370 /* regression test for felem_neg bug */
1371 if (!TEST_true(BN_set_word(m, 32))
1372 || !TEST_true(BN_set_word(n, 31))
1373 || !TEST_true(EC_POINT_copy(P, G))
1374 || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
1375 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
1376 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
1377 goto err;
1378
Billy Brumley23ccae82020-05-27 13:30:04 +03001379 r = 1;
Pauli2db85ac2017-04-28 14:06:11 +10001380err:
Matt Caswell0f113f32015-01-22 03:40:55 +00001381 EC_GROUP_free(NISTP);
1382 EC_POINT_free(G);
1383 EC_POINT_free(P);
1384 EC_POINT_free(Q);
1385 EC_POINT_free(Q_CHECK);
1386 BN_free(n);
1387 BN_free(m);
1388 BN_free(p);
1389 BN_free(a);
1390 BN_free(b);
1391 BN_free(x);
1392 BN_free(y);
1393 BN_free(order);
Emilia Kasper1e2012b2016-06-03 14:42:04 +02001394 BN_free(yplusone);
Matt Caswell0f113f32015-01-22 03:40:55 +00001395 BN_CTX_free(ctx);
Pauli2db85ac2017-04-28 14:06:11 +10001396 return r;
Matt Caswell0f113f32015-01-22 03:40:55 +00001397}
Bodo Möller04daec82010-08-26 14:29:55 +00001398
David Benjaminfc6f5792018-05-20 14:33:49 -04001399static const unsigned char p521_named[] = {
1400 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
1401};
1402
1403static const unsigned char p521_explicit[] = {
1404 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
1405 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
1406 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
1412 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1413 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1414 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1415 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1416 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1417 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
1418 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
1419 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
1420 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
1421 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
1422 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
1423 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
1424 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
1425 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
1426 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
1427 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
1428 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
1429 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
1430 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
1431 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
1432 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
1433 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
1434 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
1435 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
1436 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1437 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1438 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
1439 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
1440 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
1441 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
1442};
1443
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001444/*
1445 * This test validates a named curve's group parameters using
1446 * EC_GROUP_check_named_curve(). It also checks that modifying any of the
1447 * group parameters results in the curve not being valid.
1448 */
1449static int check_named_curve_test(int id)
Shane Lontis8402cd52019-03-21 20:09:02 +10001450{
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001451 int ret = 0, nid, field_nid, has_seed;
1452 EC_GROUP *group = NULL, *gtest = NULL;
Shane Lontis8402cd52019-03-21 20:09:02 +10001453 const EC_POINT *group_gen = NULL;
1454 EC_POINT *other_gen = NULL;
1455 BIGNUM *group_p = NULL, *group_a = NULL, *group_b = NULL;
1456 BIGNUM *other_p = NULL, *other_a = NULL, *other_b = NULL;
1457 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1458 BIGNUM *other_order = NULL;
1459 const BIGNUM *group_order = NULL;
1460 BN_CTX *bn_ctx = NULL;
1461 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1462 static size_t invalid_seed_len = sizeof(invalid_seed);
1463
1464 /* Do some setup */
1465 nid = curves[id].nid;
1466 if (!TEST_ptr(bn_ctx = BN_CTX_new())
1467 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1468 || !TEST_ptr(gtest = EC_GROUP_dup(group))
1469 || !TEST_ptr(group_p = BN_new())
1470 || !TEST_ptr(group_a = BN_new())
1471 || !TEST_ptr(group_b = BN_new())
1472 || !TEST_ptr(group_cofactor = BN_new())
1473 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1474 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1475 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1476 || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL))
1477 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1478 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1479 || !TEST_ptr(other_order = BN_dup(group_order))
1480 || !TEST_true(BN_add_word(other_order, 1))
1481 || !TEST_ptr(other_a = BN_dup(group_a))
1482 || !TEST_true(BN_add_word(other_a, 1))
1483 || !TEST_ptr(other_b = BN_dup(group_b))
1484 || !TEST_true(BN_add_word(other_b, 1))
1485 || !TEST_ptr(other_cofactor = BN_dup(group_cofactor))
1486 || !TEST_true(BN_add_word(other_cofactor, 1)))
1487 goto err;
1488
Shane Lontis37f03b92019-04-02 10:55:00 +10001489 /* Determine if the built-in curve has a seed field set */
Shane Lontis8402cd52019-03-21 20:09:02 +10001490 has_seed = (EC_GROUP_get_seed_len(group) > 0);
Billy Brumley23ccae82020-05-27 13:30:04 +03001491 field_nid = EC_GROUP_get_field_type(group);
Shane Lontis8402cd52019-03-21 20:09:02 +10001492 if (field_nid == NID_X9_62_characteristic_two_field) {
1493 if (!TEST_ptr(other_p = BN_dup(group_p))
1494 || !TEST_true(BN_lshift1(other_p, other_p)))
1495 goto err;
1496 } else {
1497 if (!TEST_ptr(other_p = BN_dup(group_p)))
1498 goto err;
1499 /*
1500 * Just choosing any arbitrary prime does not work..
1501 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a
1502 * nist prime. So only select one of these as an alternate prime.
1503 */
1504 if (!TEST_ptr(BN_copy(other_p,
1505 BN_ucmp(BN_get0_nist_prime_192(), other_p) == 0 ?
1506 BN_get0_nist_prime_256() :
1507 BN_get0_nist_prime_192())))
1508 goto err;
1509 }
1510
1511 /* Passes because this is a valid curve */
Matt Caswella9612d62019-07-03 17:30:03 +01001512 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)
Shane Lontis8402cd52019-03-21 20:09:02 +10001513 /* Only NIST curves pass */
Matt Caswella9612d62019-07-03 17:30:03 +01001514 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 1, NULL),
Shane Lontis8402cd52019-03-21 20:09:02 +10001515 EC_curve_nid2nist(nid) != NULL ? nid : NID_undef))
1516 goto err;
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001517
1518 /* Fail if the curve name doesn't match the parameters */
Shane Lontis8402cd52019-03-21 20:09:02 +10001519 EC_GROUP_set_curve_name(group, nid + 1);
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001520 ERR_set_mark();
Matt Caswella9612d62019-07-03 17:30:03 +01001521 if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0, NULL), 0))
Shane Lontis8402cd52019-03-21 20:09:02 +10001522 goto err;
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001523 ERR_pop_to_mark();
1524
1525 /* Restore curve name and ensure it's passing */
Shane Lontis8402cd52019-03-21 20:09:02 +10001526 EC_GROUP_set_curve_name(group, nid);
Matt Caswella9612d62019-07-03 17:30:03 +01001527 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001528 goto err;
Shane Lontis8402cd52019-03-21 20:09:02 +10001529
1530 if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len),
1531 invalid_seed_len))
1532 goto err;
1533
1534 if (has_seed) {
1535 /*
Shane Lontis37f03b92019-04-02 10:55:00 +10001536 * If the built-in curve has a seed and we set the seed to another value
Shane Lontis8402cd52019-03-21 20:09:02 +10001537 * then it will fail the check.
1538 */
Matt Caswella9612d62019-07-03 17:30:03 +01001539 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), 0))
Shane Lontis8402cd52019-03-21 20:09:02 +10001540 goto err;
1541 } else {
1542 /*
Shane Lontis37f03b92019-04-02 10:55:00 +10001543 * If the built-in curve does not have a seed then setting the seed will
Shane Lontis8402cd52019-03-21 20:09:02 +10001544 * pass the check (as the seed is optional).
1545 */
Matt Caswella9612d62019-07-03 17:30:03 +01001546 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
Shane Lontis8402cd52019-03-21 20:09:02 +10001547 goto err;
1548 }
1549 /* Pass if the seed is unknown (as it is optional) */
1550 if (!TEST_int_eq(EC_GROUP_set_seed(group, NULL, 0), 1)
Matt Caswella9612d62019-07-03 17:30:03 +01001551 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid))
Shane Lontis8402cd52019-03-21 20:09:02 +10001552 goto err;
1553
1554 /* Check that a duped group passes */
Matt Caswella9612d62019-07-03 17:30:03 +01001555 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
Shane Lontis8402cd52019-03-21 20:09:02 +10001556 goto err;
1557
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001558 /* check that changing any generator parameter fails */
Shane Lontis8402cd52019-03-21 20:09:02 +10001559 if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order,
1560 group_cofactor))
Matt Caswella9612d62019-07-03 17:30:03 +01001561 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
Shane Lontis8402cd52019-03-21 20:09:02 +10001562 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order,
1563 group_cofactor))
Matt Caswella9612d62019-07-03 17:30:03 +01001564 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
Shane Lontis8402cd52019-03-21 20:09:02 +10001565 /* The order is not an optional field, so this should fail */
Nicola Tuveribfed4fc2019-09-09 04:00:37 +03001566 || !TEST_false(EC_GROUP_set_generator(gtest, group_gen, NULL,
1567 group_cofactor))
Shane Lontis8402cd52019-03-21 20:09:02 +10001568 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1569 other_cofactor))
Matt Caswella9612d62019-07-03 17:30:03 +01001570 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)
Shane Lontis8402cd52019-03-21 20:09:02 +10001571 /* Check that if the cofactor is not set then it still passes */
1572 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1573 NULL))
Matt Caswella9612d62019-07-03 17:30:03 +01001574 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)
Shane Lontis8402cd52019-03-21 20:09:02 +10001575 /* check that restoring the generator passes */
1576 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order,
1577 group_cofactor))
Matt Caswella9612d62019-07-03 17:30:03 +01001578 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
Nicola Tuveri8d4f1502019-03-31 16:26:33 +03001579 goto err;
1580
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001581 /*
Nicola Tuveri8d4f1502019-03-31 16:26:33 +03001582 * check that changing any curve parameter fails
1583 *
1584 * Setting arbitrary p, a or b might fail for some EC_GROUPs
1585 * depending on the internal EC_METHOD implementation, hence run
1586 * these tests conditionally to the success of EC_GROUP_set_curve().
1587 */
1588 ERR_set_mark();
1589 if (EC_GROUP_set_curve(gtest, other_p, group_a, group_b, NULL)) {
Matt Caswella9612d62019-07-03 17:30:03 +01001590 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
Nicola Tuveri8d4f1502019-03-31 16:26:33 +03001591 goto err;
1592 } else {
1593 /* clear the error stack if EC_GROUP_set_curve() failed */
1594 ERR_pop_to_mark();
1595 ERR_set_mark();
1596 }
1597 if (EC_GROUP_set_curve(gtest, group_p, other_a, group_b, NULL)) {
Matt Caswella9612d62019-07-03 17:30:03 +01001598 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
Nicola Tuveri8d4f1502019-03-31 16:26:33 +03001599 goto err;
1600 } else {
1601 /* clear the error stack if EC_GROUP_set_curve() failed */
1602 ERR_pop_to_mark();
1603 ERR_set_mark();
1604 }
1605 if (EC_GROUP_set_curve(gtest, group_p, group_a, other_b, NULL)) {
Matt Caswella9612d62019-07-03 17:30:03 +01001606 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0))
Nicola Tuveri8d4f1502019-03-31 16:26:33 +03001607 goto err;
1608 } else {
1609 /* clear the error stack if EC_GROUP_set_curve() failed */
1610 ERR_pop_to_mark();
1611 ERR_set_mark();
1612 }
1613 ERR_pop_to_mark();
1614
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001615 /* Check that restoring the curve parameters passes */
Nicola Tuveri8d4f1502019-03-31 16:26:33 +03001616 if (!TEST_true(EC_GROUP_set_curve(gtest, group_p, group_a, group_b, NULL))
Matt Caswella9612d62019-07-03 17:30:03 +01001617 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid))
Shane Lontis8402cd52019-03-21 20:09:02 +10001618 goto err;
1619
1620 ret = 1;
1621err:
1622 BN_free(group_p);
1623 BN_free(other_p);
1624 BN_free(group_a);
1625 BN_free(other_a);
1626 BN_free(group_b);
1627 BN_free(other_b);
1628 BN_free(group_cofactor);
1629 BN_free(other_cofactor);
1630 BN_free(other_order);
1631 EC_POINT_free(other_gen);
Shane Lontis8402cd52019-03-21 20:09:02 +10001632 EC_GROUP_free(gtest);
1633 EC_GROUP_free(group);
1634 BN_CTX_free(bn_ctx);
1635 return ret;
1636}
1637
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001638/*
1639 * This checks the lookup capability of EC_GROUP_check_named_curve()
1640 * when the given group was created with explicit parameters.
1641 *
1642 * It is possible to retrieve an alternative alias that does not match
1643 * the original nid in this case.
1644 */
1645static int check_named_curve_lookup_test(int id)
1646{
1647 int ret = 0, nid, rv = 0;
1648 EC_GROUP *g = NULL , *ga = NULL;
1649 ECPARAMETERS *p = NULL, *pa = NULL;
1650 BN_CTX *ctx = NULL;
1651
1652 /* Do some setup */
1653 nid = curves[id].nid;
1654 if (!TEST_ptr(ctx = BN_CTX_new())
1655 || !TEST_ptr(g = EC_GROUP_new_by_curve_name(nid))
1656 || !TEST_ptr(p = EC_GROUP_get_ecparameters(g, NULL)))
1657 goto err;
1658
1659 /* replace with group from explicit parameters */
1660 EC_GROUP_free(g);
1661 if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p)))
1662 goto err;
1663
Matt Caswella9612d62019-07-03 17:30:03 +01001664 if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0, NULL), 0))
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03001665 goto err;
1666 if (rv != nid) {
1667 /*
1668 * Found an alias:
1669 * fail if the returned nid is not an alias of the original group.
1670 *
1671 * The comparison here is done by comparing two explicit
1672 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the
1673 * comparison happens with unnamed EC_GROUPs using the same
1674 * EC_METHODs.
1675 */
1676 if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv))
1677 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL)))
1678 goto err;
1679
1680 /* replace with group from explicit parameters, then compare */
1681 EC_GROUP_free(ga);
1682 if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa))
1683 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0))
1684 goto err;
1685 }
1686
1687 ret = 1;
1688
1689 err:
1690 EC_GROUP_free(g);
1691 EC_GROUP_free(ga);
1692 ECPARAMETERS_free(p);
1693 ECPARAMETERS_free(pa);
1694 BN_CTX_free(ctx);
1695
1696 return ret;
1697}
1698
Nicola Tuveribacaa612019-09-07 18:05:31 +03001699/*
1700 * Sometime we cannot compare nids for equality, as the built-in curve table
1701 * includes aliases with different names for the same curve.
1702 *
1703 * This function returns TRUE (1) if the checked nids are identical, or if they
1704 * alias to the same curve. FALSE (0) otherwise.
1705 */
1706static ossl_inline
1707int are_ec_nids_compatible(int n1d, int n2d)
1708{
1709 int ret = 0;
1710 switch (n1d) {
Tomas Mrazf377e582021-01-20 12:59:53 +01001711#ifndef OPENSSL_NO_EC2M
Nicola Tuveribacaa612019-09-07 18:05:31 +03001712 case NID_sect113r1:
1713 case NID_wap_wsg_idm_ecid_wtls4:
1714 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4);
1715 break;
1716 case NID_sect163k1:
1717 case NID_wap_wsg_idm_ecid_wtls3:
1718 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3);
1719 break;
1720 case NID_sect233k1:
1721 case NID_wap_wsg_idm_ecid_wtls10:
1722 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10);
1723 break;
1724 case NID_sect233r1:
1725 case NID_wap_wsg_idm_ecid_wtls11:
1726 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11);
1727 break;
1728 case NID_X9_62_c2pnb163v1:
1729 case NID_wap_wsg_idm_ecid_wtls5:
1730 ret = (n2d == NID_X9_62_c2pnb163v1
1731 || n2d == NID_wap_wsg_idm_ecid_wtls5);
1732 break;
Tomas Mrazf377e582021-01-20 12:59:53 +01001733#endif /* OPENSSL_NO_EC2M */
Nicola Tuveribacaa612019-09-07 18:05:31 +03001734 case NID_secp112r1:
1735 case NID_wap_wsg_idm_ecid_wtls6:
1736 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6);
1737 break;
1738 case NID_secp160r2:
1739 case NID_wap_wsg_idm_ecid_wtls7:
1740 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7);
1741 break;
Tomas Mrazf377e582021-01-20 12:59:53 +01001742#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
Nicola Tuveribacaa612019-09-07 18:05:31 +03001743 case NID_secp224r1:
1744 case NID_wap_wsg_idm_ecid_wtls12:
1745 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12);
1746 break;
Tomas Mrazf377e582021-01-20 12:59:53 +01001747#else
Nicola Tuveribacaa612019-09-07 18:05:31 +03001748 /*
1749 * For SEC P-224 we want to ensure that the SECP nid is returned, as
1750 * that is associated with a specialized method.
1751 */
1752 case NID_wap_wsg_idm_ecid_wtls12:
1753 ret = (n2d == NID_secp224r1);
1754 break;
Tomas Mrazf377e582021-01-20 12:59:53 +01001755#endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
Nicola Tuveribacaa612019-09-07 18:05:31 +03001756
1757 default:
1758 ret = (n1d == n2d);
1759 }
1760 return ret;
1761}
1762
1763/*
1764 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named"
1765 * EC_GROUP for built-in curves.
1766 *
1767 * Note that it is possible to retrieve an alternative alias that does not match
1768 * the original nid.
1769 *
1770 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set.
1771 */
1772static int check_named_curve_from_ecparameters(int id)
1773{
1774 int ret = 0, nid, tnid;
1775 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL;
1776 const EC_POINT *group_gen = NULL;
1777 EC_POINT *other_gen = NULL;
1778 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL;
1779 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL;
1780 const BIGNUM *group_order = NULL;
1781 BIGNUM *other_order = NULL;
1782 BN_CTX *bn_ctx = NULL;
1783 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED";
1784 static size_t invalid_seed_len = sizeof(invalid_seed);
1785 ECPARAMETERS *params = NULL, *other_params = NULL;
1786 EC_GROUP *g_ary[8] = {NULL};
1787 EC_GROUP **g_next = &g_ary[0];
1788 ECPARAMETERS *p_ary[8] = {NULL};
1789 ECPARAMETERS **p_next = &p_ary[0];
1790
1791 /* Do some setup */
1792 nid = curves[id].nid;
1793 TEST_note("Curve %s", OBJ_nid2sn(nid));
1794 if (!TEST_ptr(bn_ctx = BN_CTX_new()))
1795 return ret;
1796 BN_CTX_start(bn_ctx);
1797
1798 if (/* Allocations */
1799 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx))
1800 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx))
1801 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx))
1802 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx))
1803 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx))
1804 /* Generate reference group and params */
1805 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
1806 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL))
1807 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group))
1808 || !TEST_ptr(group_order = EC_GROUP_get0_order(group))
1809 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL))
1810 /* compute `other_*` values */
1811 || !TEST_ptr(tmpg = EC_GROUP_dup(group))
1812 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group))
1813 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL))
1814 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen,
1815 other_gen_x, other_gen_y, bn_ctx))
1816 || !TEST_true(BN_copy(other_order, group_order))
1817 || !TEST_true(BN_add_word(other_order, 1))
1818 || !TEST_true(BN_copy(other_cofactor, group_cofactor))
1819 || !TEST_true(BN_add_word(other_cofactor, 1)))
1820 goto err;
1821
1822 EC_POINT_free(other_gen);
1823 other_gen = NULL;
1824
1825 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg))
1826 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen,
1827 other_gen_x, other_gen_y,
1828 bn_ctx)))
1829 goto err;
1830
1831 /*
1832 * ###########################
1833 * # Actual tests start here #
1834 * ###########################
1835 */
1836
1837 /*
1838 * Creating a group from built-in explicit parameters returns a
1839 * "named" EC_GROUP
1840 */
1841 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params))
1842 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef))
1843 goto err;
1844 /*
1845 * We cannot always guarantee the names match, as the built-in table
1846 * contains aliases for the same curve with different names.
1847 */
1848 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) {
1849 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1850 goto err;
1851 }
1852 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */
1853 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE))
1854 goto err;
1855
1856 /*
1857 * An invalid seed in the parameters should be ignored: expect a "named"
1858 * group.
1859 */
1860 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len),
1861 invalid_seed_len)
1862 || !TEST_ptr(other_params = *p_next++ =
1863 EC_GROUP_get_ecparameters(tmpg, NULL))
1864 || !TEST_ptr(tgroup = *g_next++ =
1865 EC_GROUP_new_from_ecparameters(other_params))
1866 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1867 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1868 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1869 OPENSSL_EC_EXPLICIT_CURVE)) {
1870 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1871 goto err;
1872 }
1873
1874 /*
1875 * A null seed in the parameters should be ignored, as it is optional:
1876 * expect a "named" group.
1877 */
1878 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1)
1879 || !TEST_ptr(other_params = *p_next++ =
1880 EC_GROUP_get_ecparameters(tmpg, NULL))
1881 || !TEST_ptr(tgroup = *g_next++ =
1882 EC_GROUP_new_from_ecparameters(other_params))
1883 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1884 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1885 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1886 OPENSSL_EC_EXPLICIT_CURVE)) {
1887 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid));
1888 goto err;
1889 }
1890
1891 /*
1892 * Check that changing any of the generator parameters does not yield a
1893 * match with the built-in curves
1894 */
1895 if (/* Other gen, same group order & cofactor */
1896 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order,
1897 group_cofactor))
1898 || !TEST_ptr(other_params = *p_next++ =
1899 EC_GROUP_get_ecparameters(tmpg, NULL))
1900 || !TEST_ptr(tgroup = *g_next++ =
1901 EC_GROUP_new_from_ecparameters(other_params))
1902 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1903 /* Same gen & cofactor, different order */
1904 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order,
1905 group_cofactor))
1906 || !TEST_ptr(other_params = *p_next++ =
1907 EC_GROUP_get_ecparameters(tmpg, NULL))
1908 || !TEST_ptr(tgroup = *g_next++ =
1909 EC_GROUP_new_from_ecparameters(other_params))
1910 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1911 /* The order is not an optional field, so this should fail */
1912 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL,
1913 group_cofactor))
1914 /* Check that a wrong cofactor is ignored, and we still match */
1915 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1916 other_cofactor))
1917 || !TEST_ptr(other_params = *p_next++ =
1918 EC_GROUP_get_ecparameters(tmpg, NULL))
1919 || !TEST_ptr(tgroup = *g_next++ =
1920 EC_GROUP_new_from_ecparameters(other_params))
1921 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1922 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1923 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1924 OPENSSL_EC_EXPLICIT_CURVE)
1925 /* Check that if the cofactor is not set then it still matches */
1926 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1927 NULL))
1928 || !TEST_ptr(other_params = *p_next++ =
1929 EC_GROUP_get_ecparameters(tmpg, NULL))
1930 || !TEST_ptr(tgroup = *g_next++ =
1931 EC_GROUP_new_from_ecparameters(other_params))
1932 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1933 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1934 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1935 OPENSSL_EC_EXPLICIT_CURVE)
1936 /* check that restoring the generator passes */
1937 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order,
1938 group_cofactor))
1939 || !TEST_ptr(other_params = *p_next++ =
1940 EC_GROUP_get_ecparameters(tmpg, NULL))
1941 || !TEST_ptr(tgroup = *g_next++ =
1942 EC_GROUP_new_from_ecparameters(other_params))
1943 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)
1944 || !TEST_true(are_ec_nids_compatible(nid, tnid))
1945 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup),
1946 OPENSSL_EC_EXPLICIT_CURVE))
1947 goto err;
1948
1949 ret = 1;
1950err:
1951 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++)
1952 EC_GROUP_free(*g_next);
1953 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++)
1954 ECPARAMETERS_free(*p_next);
1955 ECPARAMETERS_free(params);
1956 EC_POINT_free(other_gen);
1957 EC_GROUP_free(tmpg);
1958 EC_GROUP_free(group);
1959 BN_CTX_end(bn_ctx);
1960 BN_CTX_free(bn_ctx);
1961 return ret;
1962}
1963
1964
Pauli2db85ac2017-04-28 14:06:11 +10001965static int parameter_test(void)
Kazuki Yamaguchi0110a472016-08-06 22:24:44 +09001966{
Pauli2db85ac2017-04-28 14:06:11 +10001967 EC_GROUP *group = NULL, *group2 = NULL;
1968 ECPARAMETERS *ecparameters = NULL;
David Benjaminfc6f5792018-05-20 14:33:49 -04001969 unsigned char *buf = NULL;
1970 int r = 0, len;
Kazuki Yamaguchi0110a472016-08-06 22:24:44 +09001971
Nicola Tuverif5b7f992019-07-28 16:13:30 +03001972 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1))
David Benjaminfc6f5792018-05-20 14:33:49 -04001973 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
1974 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
1975 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
1976 goto err;
Kazuki Yamaguchi0110a472016-08-06 22:24:44 +09001977
1978 EC_GROUP_free(group);
David Benjaminfc6f5792018-05-20 14:33:49 -04001979 group = NULL;
1980
1981 /* Test the named curve encoding, which should be default. */
1982 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
1983 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1984 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
1985 goto err;
1986
1987 OPENSSL_free(buf);
1988 buf = NULL;
1989
1990 /*
1991 * Test the explicit encoding. P-521 requires correctly zero-padding the
1992 * curve coefficients.
1993 */
1994 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
1995 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
1996 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
1997 goto err;
1998
1999 r = 1;
2000err:
2001 EC_GROUP_free(group);
Kazuki Yamaguchi0110a472016-08-06 22:24:44 +09002002 EC_GROUP_free(group2);
2003 ECPARAMETERS_free(ecparameters);
David Benjaminfc6f5792018-05-20 14:33:49 -04002004 OPENSSL_free(buf);
Pauli2db85ac2017-04-28 14:06:11 +10002005 return r;
Kazuki Yamaguchi0110a472016-08-06 22:24:44 +09002006}
Shane Lontis5173cdd2019-03-23 13:12:08 +10002007
Billy Brumley6b4152f2019-09-02 15:03:26 +03002008/*-
Billy Brumley1d3cd982019-09-09 11:29:09 +03002009 * random 256-bit explicit parameters curve, cofactor absent
2010 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit)
2011 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit)
2012 */
2013static const unsigned char params_cf_pass[] = {
2014 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2015 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5,
2016 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2017 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2018 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5,
2019 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d,
2020 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93,
2021 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc,
2022 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27,
2023 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23,
2024 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77,
2025 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b,
2026 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4,
2027 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9,
2028 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a,
2029 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c,
2030 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96,
2031 0x14, 0xa8, 0x2f, 0x4f
2032};
2033
2034/*-
2035 * random 256-bit explicit parameters curve, cofactor absent
2036 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit)
2037 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit)
2038 */
2039static const unsigned char params_cf_fail[] = {
2040 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86,
2041 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37,
2042 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2043 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2044 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37,
2045 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b,
2046 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0,
2047 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09,
2048 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d,
2049 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02,
2050 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59,
2051 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11,
2052 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24,
2053 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70,
2054 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73,
2055 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04,
2056 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e,
2057 0x34, 0xa2, 0x21, 0x01
2058};
2059
2060/*-
2061 * Test two random 256-bit explicit parameters curves with absent cofactor.
2062 * The two curves are chosen to roughly straddle the bounds at which the lib
2063 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that:
2064 *
2065 * - params_cf_pass: order is sufficiently close to p to compute cofactor
2066 * - params_cf_fail: order is too far away from p to compute cofactor
2067 *
2068 * For standards-compliant curves, cofactor is chosen as small as possible.
2069 * So you can see neither of these curves are fit for cryptographic use.
2070 *
2071 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2:
2072 * h <= 2**(t/8) where t is the security level of the curve, for which the lib
2073 * will always succeed in computing the cofactor. Neither of these curves
2074 * conform to that -- this is just robustness testing.
2075 */
2076static int cofactor_range_test(void)
2077{
2078 EC_GROUP *group = NULL;
2079 BIGNUM *cf = NULL;
2080 int ret = 0;
2081 const unsigned char *b1 = (const unsigned char *)params_cf_fail;
2082 const unsigned char *b2 = (const unsigned char *)params_cf_pass;
2083
2084 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail)))
2085 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group))
2086 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2,
2087 sizeof(params_cf_pass)))
2088 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0)
2089 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group)))
2090 goto err;
2091 ret = 1;
2092 err:
2093 BN_free(cf);
2094 EC_GROUP_free(group);
2095 return ret;
2096}
2097
2098/*-
Billy Brumley6b4152f2019-09-02 15:03:26 +03002099 * For named curves, test that:
2100 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
2101 * - a nonsensical cofactor throws an error (negative test)
2102 * - nonsensical orders throw errors (negative tests)
2103 */
2104static int cardinality_test(int n)
2105{
Billy Brumley23ccae82020-05-27 13:30:04 +03002106 int ret = 0, is_binary = 0;
Billy Brumley6b4152f2019-09-02 15:03:26 +03002107 int nid = curves[n].nid;
2108 BN_CTX *ctx = NULL;
2109 EC_GROUP *g1 = NULL, *g2 = NULL;
2110 EC_POINT *g2_gen = NULL;
2111 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL,
2112 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL;
2113
Nicola Tuveri65936a52019-09-09 03:52:00 +03002114 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid));
Billy Brumley6b4152f2019-09-02 15:03:26 +03002115
2116 if (!TEST_ptr(ctx = BN_CTX_new())
Billy Brumley23ccae82020-05-27 13:30:04 +03002117 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))) {
Billy Brumley6b4152f2019-09-02 15:03:26 +03002118 BN_CTX_free(ctx);
2119 return 0;
2120 }
2121
Billy Brumley23ccae82020-05-27 13:30:04 +03002122 is_binary = (EC_GROUP_get_field_type(g1) == NID_X9_62_characteristic_two_field);
2123
Billy Brumley6b4152f2019-09-02 15:03:26 +03002124 BN_CTX_start(ctx);
2125 g1_p = BN_CTX_get(ctx);
2126 g1_a = BN_CTX_get(ctx);
2127 g1_b = BN_CTX_get(ctx);
2128 g1_x = BN_CTX_get(ctx);
2129 g1_y = BN_CTX_get(ctx);
2130 g1_order = BN_CTX_get(ctx);
2131 g1_cf = BN_CTX_get(ctx);
2132
2133 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx))
2134 /* pull out the explicit curve parameters */
2135 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx))
2136 || !TEST_true(EC_POINT_get_affine_coordinates(g1,
2137 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx))
2138 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1)))
2139 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx))
2140 /* construct g2 manually with g1 parameters */
Tomas Mrazf377e582021-01-20 12:59:53 +01002141#ifndef OPENSSL_NO_EC2M
Billy Brumley23ccae82020-05-27 13:30:04 +03002142 || !TEST_ptr(g2 = (is_binary) ?
2143 EC_GROUP_new_curve_GF2m(g1_p, g1_a, g1_b, ctx) :
2144 EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx))
Tomas Mrazf377e582021-01-20 12:59:53 +01002145#else
Billy Brumley23ccae82020-05-27 13:30:04 +03002146 || !TEST_int_eq(0, is_binary)
2147 || !TEST_ptr(g2 = EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx))
Tomas Mrazf377e582021-01-20 12:59:53 +01002148#endif
Billy Brumley6b4152f2019-09-02 15:03:26 +03002149 || !TEST_ptr(g2_gen = EC_POINT_new(g2))
2150 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx))
2151 /* pass NULL cofactor: lib should compute it */
2152 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
2153 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2154 || !TEST_BN_eq(g1_cf, g2_cf)
2155 /* pass zero cofactor: lib should compute it */
2156 || !TEST_true(BN_set_word(g2_cf, 0))
2157 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
2158 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx))
2159 || !TEST_BN_eq(g1_cf, g2_cf)
2160 /* negative test for invalid cofactor */
2161 || !TEST_true(BN_set_word(g2_cf, 0))
2162 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
Billy Brumley5041ea32019-09-06 17:26:08 +03002163 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf))
Billy Brumley6b4152f2019-09-02 15:03:26 +03002164 /* negative test for NULL order */
Billy Brumley5041ea32019-09-06 17:26:08 +03002165 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL))
Billy Brumley6b4152f2019-09-02 15:03:26 +03002166 /* negative test for zero order */
2167 || !TEST_true(BN_set_word(g1_order, 0))
Billy Brumley5041ea32019-09-06 17:26:08 +03002168 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
Billy Brumley6b4152f2019-09-02 15:03:26 +03002169 /* negative test for negative order */
2170 || !TEST_true(BN_set_word(g2_cf, 0))
2171 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one()))
Billy Brumley5041ea32019-09-06 17:26:08 +03002172 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))
Billy Brumley6b4152f2019-09-02 15:03:26 +03002173 /* negative test for too large order */
2174 || !TEST_true(BN_lshift(g1_order, g1_p, 2))
Billy Brumley5041ea32019-09-06 17:26:08 +03002175 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)))
Billy Brumley6b4152f2019-09-02 15:03:26 +03002176 goto err;
2177 ret = 1;
2178 err:
2179 EC_POINT_free(g2_gen);
2180 EC_GROUP_free(g1);
2181 EC_GROUP_free(g2);
2182 BN_CTX_end(ctx);
2183 BN_CTX_free(ctx);
2184 return ret;
2185}
2186
Shane Lontis5173cdd2019-03-23 13:12:08 +10002187static int check_ec_key_field_public_range_test(int id)
2188{
2189 int ret = 0, type = 0;
2190 const EC_POINT *pub = NULL;
2191 const EC_GROUP *group = NULL;
Shane Lontis5173cdd2019-03-23 13:12:08 +10002192 const BIGNUM *field = NULL;
2193 BIGNUM *x = NULL, *y = NULL;
2194 EC_KEY *key = NULL;
2195
Nicola Tuveribfed4fc2019-09-09 04:00:37 +03002196 if (!TEST_ptr(x = BN_new())
2197 || !TEST_ptr(y = BN_new())
2198 || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid))
2199 || !TEST_ptr(group = EC_KEY_get0_group(key))
Nicola Tuveribfed4fc2019-09-09 04:00:37 +03002200 || !TEST_ptr(field = EC_GROUP_get0_field(group))
2201 || !TEST_int_gt(EC_KEY_generate_key(key), 0)
2202 || !TEST_int_gt(EC_KEY_check_key(key), 0)
2203 || !TEST_ptr(pub = EC_KEY_get0_public_key(key))
2204 || !TEST_int_gt(EC_POINT_get_affine_coordinates(group, pub, x, y,
2205 NULL), 0))
Shane Lontis5173cdd2019-03-23 13:12:08 +10002206 goto err;
2207
2208 /*
2209 * Make the public point out of range by adding the field (which will still
2210 * be the same point on the curve). The add is different for char2 fields.
2211 */
Billy Brumley23ccae82020-05-27 13:30:04 +03002212 type = EC_GROUP_get_field_type(group);
Matt Caswella5cf1982019-04-19 11:17:44 +01002213#ifndef OPENSSL_NO_EC2M
Shane Lontis5173cdd2019-03-23 13:12:08 +10002214 if (type == NID_X9_62_characteristic_two_field) {
2215 /* test for binary curves */
2216 if (!TEST_true(BN_GF2m_add(x, x, field)))
2217 goto err;
Matt Caswella5cf1982019-04-19 11:17:44 +01002218 } else
2219#endif
2220 if (type == NID_X9_62_prime_field) {
Shane Lontis5173cdd2019-03-23 13:12:08 +10002221 /* test for prime curves */
2222 if (!TEST_true(BN_add(x, x, field)))
2223 goto err;
2224 } else {
2225 /* this should never happen */
2226 TEST_error("Unsupported EC_METHOD field_type");
2227 goto err;
2228 }
2229 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key, x, y), 0))
2230 goto err;
2231
2232 ret = 1;
2233err:
2234 BN_free(x);
2235 BN_free(y);
2236 EC_KEY_free(key);
2237 return ret;
2238}
Nicola Tuveri35ed0292019-11-01 22:09:40 +02002239
2240/*
2241 * Helper for ec_point_hex2point_test
2242 *
2243 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given
2244 * (group,P) pair.
2245 *
2246 * If P is NULL use point at infinity.
2247 */
2248static ossl_inline
2249int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P,
2250 point_conversion_form_t form,
2251 BN_CTX *bnctx)
2252{
2253 int ret = 0;
2254 EC_POINT *Q = NULL, *Pinf = NULL;
2255 char *hex = NULL;
2256
2257 if (P == NULL) {
2258 /* If P is NULL use point at infinity. */
2259 if (!TEST_ptr(Pinf = EC_POINT_new(group))
2260 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf)))
2261 goto err;
2262 P = Pinf;
2263 }
2264
2265 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx))
2266 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx))
2267 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx)))
2268 goto err;
2269
2270 /*
2271 * The next check is most likely superfluous, as EC_POINT_cmp should already
2272 * cover this.
2273 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity,
2274 * so we include it anyway!
2275 */
2276 if (Pinf != NULL
2277 && !TEST_true(EC_POINT_is_at_infinity(group, Q)))
2278 goto err;
2279
2280 ret = 1;
2281
2282 err:
2283 EC_POINT_free(Pinf);
2284 OPENSSL_free(hex);
2285 EC_POINT_free(Q);
2286
2287 return ret;
2288}
2289
2290/*
2291 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex()
2292 */
2293static int ec_point_hex2point_test(int id)
2294{
2295 int ret = 0, nid;
2296 EC_GROUP *group = NULL;
2297 const EC_POINT *G = NULL;
2298 EC_POINT *P = NULL;
2299 BN_CTX * bnctx = NULL;
2300
2301 /* Do some setup */
2302 nid = curves[id].nid;
2303 if (!TEST_ptr(bnctx = BN_CTX_new())
2304 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
2305 || !TEST_ptr(G = EC_GROUP_get0_generator(group))
2306 || !TEST_ptr(P = EC_POINT_dup(G, group)))
2307 goto err;
2308
2309 if (!TEST_true(ec_point_hex2point_test_helper(group, P,
2310 POINT_CONVERSION_COMPRESSED,
2311 bnctx))
2312 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2313 POINT_CONVERSION_COMPRESSED,
2314 bnctx))
2315 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2316 POINT_CONVERSION_UNCOMPRESSED,
2317 bnctx))
2318 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2319 POINT_CONVERSION_UNCOMPRESSED,
2320 bnctx))
2321 || !TEST_true(ec_point_hex2point_test_helper(group, P,
2322 POINT_CONVERSION_HYBRID,
2323 bnctx))
2324 || !TEST_true(ec_point_hex2point_test_helper(group, NULL,
2325 POINT_CONVERSION_HYBRID,
2326 bnctx)))
2327 goto err;
2328
2329 ret = 1;
2330
2331 err:
2332 EC_POINT_free(P);
2333 EC_GROUP_free(group);
2334 BN_CTX_free(bnctx);
2335
2336 return ret;
2337}
2338
Shane Lontisc0f39de2020-08-22 14:55:41 +10002339static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx,
2340 unsigned char *gen, int gen_size)
2341{
2342 int ret = 0, i_out;
2343 EVP_PKEY_CTX *pctx = NULL;
2344 EVP_PKEY *pkeyparam = NULL;
2345 OSSL_PARAM_BLD *bld = NULL;
2346 const char *field_name;
2347 OSSL_PARAM *params = NULL;
2348 const OSSL_PARAM *gettable;
2349 BIGNUM *p, *a, *b;
2350 BIGNUM *p_out = NULL, *a_out = NULL, *b_out = NULL;
2351 BIGNUM *order_out = NULL, *cofactor_out = NULL;
2352 char name[80];
2353 unsigned char buf[1024];
2354 size_t buf_len, name_len;
2355#ifndef OPENSSL_NO_EC2M
2356 unsigned int k1 = 0, k2 = 0, k3 = 0;
2357 const char *basis_name = NULL;
2358#endif
2359
2360 p = BN_CTX_get(ctx);
2361 a = BN_CTX_get(ctx);
2362 b = BN_CTX_get(ctx);
2363
2364 if (!TEST_ptr(b)
2365 || !TEST_ptr(bld = OSSL_PARAM_BLD_new()))
2366 goto err;
2367
2368 if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) {
2369 field_name = SN_X9_62_prime_field;
2370 } else {
2371 field_name = SN_X9_62_characteristic_two_field;
2372#ifndef OPENSSL_NO_EC2M
2373 if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) {
2374 basis_name = SN_X9_62_tpBasis;
2375 if (!TEST_true(EC_GROUP_get_trinomial_basis(group, &k1)))
2376 goto err;
2377 } else {
2378 basis_name = SN_X9_62_ppBasis;
2379 if (!TEST_true(EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)))
2380 goto err;
2381 }
2382#endif /* OPENSSL_NO_EC2M */
2383 }
2384 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))
2385 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
2386 OSSL_PKEY_PARAM_EC_FIELD_TYPE, field_name, 0))
2387 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, p))
2388 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
2389 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b)))
2390 goto err;
2391
2392 if (EC_GROUP_get0_seed(group) != NULL) {
2393 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
2394 OSSL_PKEY_PARAM_EC_SEED, EC_GROUP_get0_seed(group),
2395 EC_GROUP_get_seed_len(group))))
2396 goto err;
2397 }
2398 if (EC_GROUP_get0_cofactor(group) != NULL) {
2399 if (!TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
2400 EC_GROUP_get0_cofactor(group))))
2401 goto err;
2402 }
2403
2404 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
2405 OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_size))
2406 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER,
2407 EC_GROUP_get0_order(group))))
2408 goto err;
2409
2410 if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))
2411 || !TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL))
Shane Lontis2db985b2021-02-05 13:55:50 +10002412 || !TEST_int_gt(EVP_PKEY_fromdata_init(pctx), 0)
2413 || !TEST_int_gt(EVP_PKEY_fromdata(pctx, &pkeyparam,
2414 EVP_PKEY_KEY_PARAMETERS, params), 0))
Shane Lontisc0f39de2020-08-22 14:55:41 +10002415 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);
Shane Lontis3f883c72021-04-07 13:45:19 +10002552 OSSL_PARAM_free(params);
Shane Lontisc0f39de2020-08-22 14:55:41 +10002553 OSSL_PARAM_BLD_free(bld);
2554 EVP_PKEY_free(pkeyparam);
2555 EVP_PKEY_CTX_free(pctx);
2556 return ret;
2557}
2558
Billy Brumleya01cae92020-06-09 13:16:15 +03002559/*
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 */
Nicola Tuvericfae32c2020-07-21 23:12:59 +03002583 bsize = (EC_GROUP_get_degree(group) + 7) / 8;
2584 bsize = 1 + 2 * bsize; /* UNCOMPRESSED_POINT format */
Billy Brumleya01cae92020-06-09 13:16:15 +03002585
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 */
Nicola Tuverif5384f02020-07-21 18:04:38 +03002622 || !TEST_mem_eq(b1, bsize, b2, bsize))
Billy Brumleya01cae92020-06-09 13:16:15 +03002623 goto err;
2624
Shane Lontisc0f39de2020-08-22 14:55:41 +10002625 if (!do_test_custom_explicit_fromdata(group, ctx, b1, bsize))
2626 goto err;
2627
Billy Brumleya01cae92020-06-09 13:16:15 +03002628 ret = 1;
2629
2630 err:
Billy Brumleya01cae92020-06-09 13:16:15 +03002631 EC_POINT_free(Q1);
2632 EC_POINT_free(Q2);
2633 EC_POINT_free(G2);
2634 EC_GROUP_free(group);
Shane Lontisc0f39de2020-08-22 14:55:41 +10002635 BN_CTX_end(ctx);
Billy Brumleya01cae92020-06-09 13:16:15 +03002636 BN_CTX_free(ctx);
2637 OPENSSL_free(b1);
2638 OPENSSL_free(b2);
2639
2640 return ret;
2641}
2642
Nicola Tuverif5384f02020-07-21 18:04:38 +03002643/*
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;
Tomas Mrazf377e582021-01-20 12:59:53 +01002682#ifdef OPENSSL_NO_EC2M
Nicola Tuverif5384f02020-07-21 18:04:38 +03002683 if (!is_prime) {
2684 ret = TEST_skip("binary curves not supported in this build");
2685 goto err;
2686 }
Tomas Mrazf377e582021-01-20 12:59:53 +01002687#endif
Nicola Tuverif5384f02020-07-21 18:04:38 +03002688
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 }
Tomas Mrazf377e582021-01-20 12:59:53 +01002724#ifndef OPENSSL_NO_EC2M
Nicola Tuverif5384f02020-07-21 18:04:38 +03002725 else {
2726 if (!TEST_ptr(altgroup = EC_GROUP_new_curve_GF2m(p, a, b, ctx)))
2727 goto err;
2728 }
Tomas Mrazf377e582021-01-20 12:59:53 +01002729#endif
Nicola Tuverif5384f02020-07-21 18:04:38 +03002730
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))
Shane Lontis2db985b2021-02-05 13:55:50 +10002873 || !TEST_true(EVP_PKEY_fromdata_init(pctx2))
2874 || !TEST_true(EVP_PKEY_fromdata(pctx2, &pkey1, EVP_PKEY_KEYPAIR,
2875 params1))
2876 || !TEST_true(EVP_PKEY_fromdata(pctx2, &pkey2, EVP_PKEY_PUBLIC_KEY,
2877 params2)))
Nicola Tuverif5384f02020-07-21 18:04:38 +03002878 goto err;
2879
2880 /* compute keyexchange once more using the provider keys */
2881 EVP_PKEY_CTX_free(pctx1);
2882 if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))
2883 || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1)
2884 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1)
2885 || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &t), 1)
2886 || !TEST_int_gt(bsize, t)
2887 || !TEST_int_le(sslen, t)
2888 || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &t), 1)
2889 /* compare with previous result */
2890 || !TEST_mem_eq(buf1, t, buf2, sslen))
2891 goto err;
2892
2893 ret = 1;
2894
2895 err:
2896 BN_CTX_end(ctx);
2897 BN_CTX_free(ctx);
2898 OSSL_PARAM_BLD_free(param_bld);
Shane Lontis3f883c72021-04-07 13:45:19 +10002899 OSSL_PARAM_free(params1);
2900 OSSL_PARAM_free(params2);
Nicola Tuverif5384f02020-07-21 18:04:38 +03002901 EC_POINT_free(Q1);
2902 EC_POINT_free(Q2);
2903 EC_POINT_free(G2);
2904 EC_GROUP_free(group);
2905 EC_GROUP_free(altgroup);
2906 OPENSSL_free(buf1);
2907 OPENSSL_free(buf2);
2908 OPENSSL_free(pub1);
2909 OPENSSL_free(pub2);
2910 EC_KEY_free(eckey1);
2911 EC_KEY_free(eckey2);
2912 EVP_PKEY_free(pkey1);
2913 EVP_PKEY_free(pkey2);
2914 EVP_PKEY_CTX_free(pctx1);
2915 EVP_PKEY_CTX_free(pctx2);
2916
2917 return ret;
2918}
2919
Pauliad887412017-07-18 11:48:27 +10002920int setup_tests(void)
Matt Caswell0f113f32015-01-22 03:40:55 +00002921{
Pauli2db85ac2017-04-28 14:06:11 +10002922 crv_len = EC_get_builtin_curves(NULL, 0);
2923 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
2924 || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
Pauliad887412017-07-18 11:48:27 +10002925 return 0;
Bodo Möller7793f302002-08-02 13:42:24 +00002926
Pauli2db85ac2017-04-28 14:06:11 +10002927 ADD_TEST(parameter_test);
Billy Brumley1d3cd982019-09-09 11:29:09 +03002928 ADD_TEST(cofactor_range_test);
Billy Brumley6b4152f2019-09-02 15:03:26 +03002929 ADD_ALL_TESTS(cardinality_test, crv_len);
Pauli2db85ac2017-04-28 14:06:11 +10002930 ADD_TEST(prime_field_tests);
Tomas Mrazf377e582021-01-20 12:59:53 +01002931#ifndef OPENSSL_NO_EC2M
Pauli2db85ac2017-04-28 14:06:11 +10002932 ADD_TEST(char2_field_tests);
2933 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
Tomas Mrazf377e582021-01-20 12:59:53 +01002934#endif
Pauli2db85ac2017-04-28 14:06:11 +10002935 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
Pauli2db85ac2017-04-28 14:06:11 +10002936 ADD_ALL_TESTS(internal_curve_test, crv_len);
2937 ADD_ALL_TESTS(internal_curve_test_method, crv_len);
David Asraffa1f0302019-02-07 11:51:39 +02002938 ADD_TEST(group_field_test);
Nicola Tuveriac2b52c2019-03-31 18:46:53 +03002939 ADD_ALL_TESTS(check_named_curve_test, crv_len);
2940 ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len);
Shane Lontis5173cdd2019-03-23 13:12:08 +10002941 ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len);
Nicola Tuveribacaa612019-09-07 18:05:31 +03002942 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len);
Nicola Tuveri35ed0292019-11-01 22:09:40 +02002943 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len);
Billy Brumleya01cae92020-06-09 13:16:15 +03002944 ADD_ALL_TESTS(custom_generator_test, crv_len);
Nicola Tuverif5384f02020-07-21 18:04:38 +03002945 ADD_ALL_TESTS(custom_params_test, crv_len);
Pauliad887412017-07-18 11:48:27 +10002946 return 1;
2947}
2948
2949void cleanup_tests(void)
2950{
2951 OPENSSL_free(curves);
Matt Caswell0f113f32015-01-22 03:40:55 +00002952}