Imported Upstream version 1.1.1i
[platform/upstream/openssl1.1.git] / test / ec_internal_test.c
1 /*
2  * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include "internal/nelem.h"
11 #include "testutil.h"
12 #include <openssl/ec.h>
13 #include "ec_local.h"
14 #include <openssl/objects.h>
15
16 static size_t crv_len = 0;
17 static EC_builtin_curve *curves = NULL;
18
19 /* sanity checks field_inv function pointer in EC_METHOD */
20 static int group_field_tests(const EC_GROUP *group, BN_CTX *ctx)
21 {
22     BIGNUM *a = NULL, *b = NULL, *c = NULL;
23     int ret = 0;
24
25     if (group->meth->field_inv == NULL || group->meth->field_mul == NULL)
26         return 1;
27
28     BN_CTX_start(ctx);
29     a = BN_CTX_get(ctx);
30     b = BN_CTX_get(ctx);
31     if (!TEST_ptr(c = BN_CTX_get(ctx))
32         /* 1/1 = 1 */
33         || !TEST_true(group->meth->field_inv(group, b, BN_value_one(), ctx))
34         || !TEST_true(BN_is_one(b))
35         /* (1/a)*a = 1 */
36         || !TEST_true(BN_pseudo_rand(a, BN_num_bits(group->field) - 1,
37                                      BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
38         || !TEST_true(group->meth->field_inv(group, b, a, ctx))
39         || (group->meth->field_encode &&
40             !TEST_true(group->meth->field_encode(group, a, a, ctx)))
41         || (group->meth->field_encode &&
42             !TEST_true(group->meth->field_encode(group, b, b, ctx)))
43         || !TEST_true(group->meth->field_mul(group, c, a, b, ctx))
44         || (group->meth->field_decode &&
45             !TEST_true(group->meth->field_decode(group, c, c, ctx)))
46         || !TEST_true(BN_is_one(c)))
47         goto err;
48
49     /* 1/0 = error */
50     BN_zero(a);
51     if (!TEST_false(group->meth->field_inv(group, b, a, ctx))
52         || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC)
53         || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) ==
54                       EC_R_CANNOT_INVERT)
55         /* 1/p = error */
56         || !TEST_false(group->meth->field_inv(group, b, group->field, ctx))
57         || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC)
58         || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) ==
59                       EC_R_CANNOT_INVERT))
60         goto err;
61
62     ERR_clear_error();
63     ret = 1;
64  err:
65     BN_CTX_end(ctx);
66     return ret;
67 }
68
69 /* wrapper for group_field_tests for explicit curve params and EC_METHOD */
70 static int field_tests(const EC_METHOD *meth, const unsigned char *params,
71                        int len)
72 {
73     BN_CTX *ctx = NULL;
74     BIGNUM *p = NULL, *a = NULL, *b = NULL;
75     EC_GROUP *group = NULL;
76     int ret = 0;
77
78     if (!TEST_ptr(ctx = BN_CTX_new()))
79         return 0;
80
81     BN_CTX_start(ctx);
82     p = BN_CTX_get(ctx);
83     a = BN_CTX_get(ctx);
84     if (!TEST_ptr(b = BN_CTX_get(ctx))
85         || !TEST_ptr(group = EC_GROUP_new(meth))
86         || !TEST_true(BN_bin2bn(params, len, p))
87         || !TEST_true(BN_bin2bn(params + len, len, a))
88         || !TEST_true(BN_bin2bn(params + 2 * len, len, b))
89         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
90         || !group_field_tests(group, ctx))
91         goto err;
92     ret = 1;
93
94  err:
95     BN_CTX_end(ctx);
96     BN_CTX_free(ctx);
97     if (group != NULL)
98         EC_GROUP_free(group);
99     return ret;
100 }
101
102 /* NIST prime curve P-256 */
103 static const unsigned char params_p256[] = {
104     /* p */
105     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
106     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
107     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
108     /* a */
109     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
110     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
111     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
112     /* b */
113     0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
114     0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
115     0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B
116 };
117
118 #ifndef OPENSSL_NO_EC2M
119 /* NIST binary curve B-283 */
120 static const unsigned char params_b283[] = {
121     /* p */
122     0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
125     /* a */
126     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
129     /* b */
130     0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A,
131     0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2,
132     0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5
133 };
134 #endif
135
136 /* test EC_GFp_simple_method directly */
137 static int field_tests_ecp_simple(void)
138 {
139     TEST_info("Testing EC_GFp_simple_method()\n");
140     return field_tests(EC_GFp_simple_method(), params_p256,
141                        sizeof(params_p256) / 3);
142 }
143
144 /* test EC_GFp_mont_method directly */
145 static int field_tests_ecp_mont(void)
146 {
147     TEST_info("Testing EC_GFp_mont_method()\n");
148     return field_tests(EC_GFp_mont_method(), params_p256,
149                        sizeof(params_p256) / 3);
150 }
151
152 #ifndef OPENSSL_NO_EC2M
153 /* test EC_GF2m_simple_method directly */
154 static int field_tests_ec2_simple(void)
155 {
156     TEST_info("Testing EC_GF2m_simple_method()\n");
157     return field_tests(EC_GF2m_simple_method(), params_b283,
158                        sizeof(params_b283) / 3);
159 }
160 #endif
161
162 /* test default method for a named curve */
163 static int field_tests_default(int n)
164 {
165     BN_CTX *ctx = NULL;
166     EC_GROUP *group = NULL;
167     int nid = curves[n].nid;
168     int ret = 0;
169
170     TEST_info("Testing curve %s\n", OBJ_nid2sn(nid));
171
172     if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
173         || !TEST_ptr(ctx = BN_CTX_new())
174         || !group_field_tests(group, ctx))
175         goto err;
176
177     ret = 1;
178  err:
179     if (group != NULL)
180         EC_GROUP_free(group);
181     if (ctx != NULL)
182         BN_CTX_free(ctx);
183     return ret;
184 }
185
186 /*
187  * Tests behavior of the decoded_from_explicit_params flag and API
188  */
189 static int decoded_flag_test(void)
190 {
191     EC_GROUP *grp;
192     EC_GROUP *grp_copy = NULL;
193     ECPARAMETERS *ecparams = NULL;
194     ECPKPARAMETERS *ecpkparams = NULL;
195     EC_KEY *key = NULL;
196     unsigned char *encodedparams = NULL;
197     const unsigned char *encp;
198     int encodedlen;
199     int testresult = 0;
200
201     /* Test EC_GROUP_new not setting the flag */
202     grp = EC_GROUP_new(EC_GFp_simple_method());
203     if (!TEST_ptr(grp)
204         || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
205         goto err;
206     EC_GROUP_free(grp);
207
208     /* Test EC_GROUP_new_by_curve_name not setting the flag */
209     grp = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
210     if (!TEST_ptr(grp)
211         || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
212         goto err;
213
214     /* Test EC_GROUP_new_from_ecparameters not setting the flag */
215     if (!TEST_ptr(ecparams = EC_GROUP_get_ecparameters(grp, NULL))
216         || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecparameters(ecparams))
217         || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
218         goto err;
219     EC_GROUP_free(grp_copy);
220     grp_copy = NULL;
221     ECPARAMETERS_free(ecparams);
222     ecparams = NULL;
223
224     /* Test EC_GROUP_new_from_ecpkparameters not setting the flag */
225     if (!TEST_int_eq(EC_GROUP_get_asn1_flag(grp), OPENSSL_EC_NAMED_CURVE)
226         || !TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
227         || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
228         || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0)
229         || !TEST_ptr(key = EC_KEY_new())
230     /* Test EC_KEY_decoded_from_explicit_params on key without a group */
231         || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), -1)
232         || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
233     /* Test EC_KEY_decoded_from_explicit_params negative case */
234         || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 0))
235         goto err;
236     EC_GROUP_free(grp_copy);
237     grp_copy = NULL;
238     ECPKPARAMETERS_free(ecpkparams);
239     ecpkparams = NULL;
240
241     /* Test d2i_ECPKParameters with named params not setting the flag */
242     if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
243         || !TEST_ptr(encp = encodedparams)
244         || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
245         || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
246         goto err;
247     EC_GROUP_free(grp_copy);
248     grp_copy = NULL;
249     OPENSSL_free(encodedparams);
250     encodedparams = NULL;
251
252     /* Asn1 flag stays set to explicit with EC_GROUP_new_from_ecpkparameters */
253     EC_GROUP_set_asn1_flag(grp, OPENSSL_EC_EXPLICIT_CURVE);
254     if (!TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
255         || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
256         || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
257         || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
258         goto err;
259     EC_GROUP_free(grp_copy);
260     grp_copy = NULL;
261
262     /* Test d2i_ECPKParameters with explicit params setting the flag */
263     if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
264         || !TEST_ptr(encp = encodedparams)
265         || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
266         || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
267         || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 1)
268         || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
269     /* Test EC_KEY_decoded_from_explicit_params positive case */
270         || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 1))
271         goto err;
272
273     testresult = 1;
274
275  err:
276     EC_KEY_free(key);
277     EC_GROUP_free(grp);
278     EC_GROUP_free(grp_copy);
279     ECPARAMETERS_free(ecparams);
280     ECPKPARAMETERS_free(ecpkparams);
281     OPENSSL_free(encodedparams);
282
283     return testresult;
284 }
285
286 int setup_tests(void)
287 {
288     crv_len = EC_get_builtin_curves(NULL, 0);
289     if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
290         || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
291         return 0;
292
293     ADD_TEST(field_tests_ecp_simple);
294     ADD_TEST(field_tests_ecp_mont);
295 #ifndef OPENSSL_NO_EC2M
296     ADD_TEST(field_tests_ec2_simple);
297 #endif
298     ADD_ALL_TESTS(field_tests_default, crv_len);
299     ADD_TEST(decoded_flag_test);
300     return 1;
301 }
302
303 void cleanup_tests(void)
304 {
305     OPENSSL_free(curves);
306 }