Use .cnf for config files, not .conf
[openssl.git] / test / ec_internal_test.c
1 /*
2  * Copyright 2019 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 /*
11  * Low level APIs are deprecated for public use, but still ok for internal use.
12  */
13 #include "internal/deprecated.h"
14
15 #include "internal/nelem.h"
16 #include "testutil.h"
17 #include <openssl/ec.h>
18 #include "ec_local.h"
19 #include <openssl/objects.h>
20
21 static size_t crv_len = 0;
22 static EC_builtin_curve *curves = NULL;
23
24 /* sanity checks field_inv function pointer in EC_METHOD */
25 static int group_field_tests(const EC_GROUP *group, BN_CTX *ctx)
26 {
27     BIGNUM *a = NULL, *b = NULL, *c = NULL;
28     int ret = 0;
29
30     if (group->meth->field_inv == NULL || group->meth->field_mul == NULL)
31         return 1;
32
33     BN_CTX_start(ctx);
34     a = BN_CTX_get(ctx);
35     b = BN_CTX_get(ctx);
36     if (!TEST_ptr(c = BN_CTX_get(ctx))
37         /* 1/1 = 1 */
38         || !TEST_true(group->meth->field_inv(group, b, BN_value_one(), ctx))
39         || !TEST_true(BN_is_one(b))
40         /* (1/a)*a = 1 */
41         || !TEST_true(BN_pseudo_rand(a, BN_num_bits(group->field) - 1,
42                                      BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
43         || !TEST_true(group->meth->field_inv(group, b, a, ctx))
44         || (group->meth->field_encode &&
45             !TEST_true(group->meth->field_encode(group, a, a, ctx)))
46         || (group->meth->field_encode &&
47             !TEST_true(group->meth->field_encode(group, b, b, ctx)))
48         || !TEST_true(group->meth->field_mul(group, c, a, b, ctx))
49         || (group->meth->field_decode &&
50             !TEST_true(group->meth->field_decode(group, c, c, ctx)))
51         || !TEST_true(BN_is_one(c)))
52         goto err;
53
54     /* 1/0 = error */
55     BN_zero(a);
56     if (!TEST_false(group->meth->field_inv(group, b, a, 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         /* 1/p = error */
61         || !TEST_false(group->meth->field_inv(group, b, group->field, ctx))
62         || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC)
63         || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) ==
64                       EC_R_CANNOT_INVERT))
65         goto err;
66
67     ERR_clear_error();
68     ret = 1;
69  err:
70     BN_CTX_end(ctx);
71     return ret;
72 }
73
74 /* wrapper for group_field_tests for explicit curve params and EC_METHOD */
75 static int field_tests(const EC_METHOD *meth, const unsigned char *params,
76                        int len)
77 {
78     BN_CTX *ctx = NULL;
79     BIGNUM *p = NULL, *a = NULL, *b = NULL;
80     EC_GROUP *group = NULL;
81     int ret = 0;
82
83     if (!TEST_ptr(ctx = BN_CTX_new()))
84         return 0;
85
86     BN_CTX_start(ctx);
87     p = BN_CTX_get(ctx);
88     a = BN_CTX_get(ctx);
89     if (!TEST_ptr(b = BN_CTX_get(ctx))
90         || !TEST_ptr(group = EC_GROUP_new(meth))
91         || !TEST_true(BN_bin2bn(params, len, p))
92         || !TEST_true(BN_bin2bn(params + len, len, a))
93         || !TEST_true(BN_bin2bn(params + 2 * len, len, b))
94         || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
95         || !group_field_tests(group, ctx))
96         goto err;
97     ret = 1;
98
99  err:
100     BN_CTX_end(ctx);
101     BN_CTX_free(ctx);
102     if (group != NULL)
103         EC_GROUP_free(group);
104     return ret;
105 }
106
107 /* NIST prime curve P-256 */
108 static const unsigned char params_p256[] = {
109     /* p */
110     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
111     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
112     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
113     /* a */
114     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
115     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
116     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
117     /* b */
118     0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
119     0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
120     0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B
121 };
122
123 #ifndef OPENSSL_NO_EC2M
124 /* NIST binary curve B-283 */
125 static const unsigned char params_b283[] = {
126     /* p */
127     0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
130     /* a */
131     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
134     /* b */
135     0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A,
136     0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2,
137     0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5
138 };
139 #endif
140
141 /* test EC_GFp_simple_method directly */
142 static int field_tests_ecp_simple(void)
143 {
144     TEST_info("Testing EC_GFp_simple_method()\n");
145     return field_tests(EC_GFp_simple_method(), params_p256,
146                        sizeof(params_p256) / 3);
147 }
148
149 /* test EC_GFp_mont_method directly */
150 static int field_tests_ecp_mont(void)
151 {
152     TEST_info("Testing EC_GFp_mont_method()\n");
153     return field_tests(EC_GFp_mont_method(), params_p256,
154                        sizeof(params_p256) / 3);
155 }
156
157 #ifndef OPENSSL_NO_EC2M
158 /* test EC_GF2m_simple_method directly */
159 static int field_tests_ec2_simple(void)
160 {
161     TEST_info("Testing EC_GF2m_simple_method()\n");
162     return field_tests(EC_GF2m_simple_method(), params_b283,
163                        sizeof(params_b283) / 3);
164 }
165 #endif
166
167 /* test default method for a named curve */
168 static int field_tests_default(int n)
169 {
170     BN_CTX *ctx = NULL;
171     EC_GROUP *group = NULL;
172     int nid = curves[n].nid;
173     int ret = 0;
174
175     TEST_info("Testing curve %s\n", OBJ_nid2sn(nid));
176
177     if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
178         || !TEST_ptr(ctx = BN_CTX_new())
179         || !group_field_tests(group, ctx))
180         goto err;
181
182     ret = 1;
183  err:
184     if (group != NULL)
185         EC_GROUP_free(group);
186     if (ctx != NULL)
187         BN_CTX_free(ctx);
188     return ret;
189 }
190
191 int setup_tests(void)
192 {
193     crv_len = EC_get_builtin_curves(NULL, 0);
194     if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
195         || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
196         return 0;
197
198     ADD_TEST(field_tests_ecp_simple);
199     ADD_TEST(field_tests_ecp_mont);
200 #ifndef OPENSSL_NO_EC2M
201     ADD_TEST(field_tests_ec2_simple);
202 #endif
203     ADD_ALL_TESTS(field_tests_default, crv_len);
204     return 1;
205 }
206
207 void cleanup_tests(void)
208 {
209     OPENSSL_free(curves);
210 }