]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - test_curves.c
tcl_tests: ca.try: Ignore openssl crl exit status for 'corrupted CRL' test
[openssl-gost/engine.git] / test_curves.c
1 /*
2  * Copyright (C) 2018 vt@altlinux.org. All Rights Reserved.
3  *
4  * Contents licensed under the terms of the OpenSSL license
5  * See https://www.openssl.org/source/license.html for details
6  */
7
8 #ifdef _MSC_VER
9 # pragma warning(push, 3)
10 # include <openssl/applink.c>
11 # pragma warning(pop)
12 #endif
13 #include "gost_lcl.h"
14 #include <openssl/evp.h>
15 #include <openssl/rand.h>
16 #include <openssl/err.h>
17 #include <openssl/asn1.h>
18 #include <openssl/obj_mac.h>
19 #include <openssl/ec.h>
20 #include <openssl/bn.h>
21 #include <string.h>
22
23 #define T(e) \
24     if (!(e)) { \
25         ERR_print_errors_fp(stderr); \
26         OpenSSLDie(__FILE__, __LINE__, #e); \
27     }
28
29 #define cRED    "\033[1;31m"
30 #define cDRED   "\033[0;31m"
31 #define cGREEN  "\033[1;32m"
32 #define cDGREEN "\033[0;32m"
33 #define cBLUE   "\033[1;34m"
34 #define cDBLUE  "\033[0;34m"
35 #define cNORM   "\033[m"
36 #define TEST_ASSERT(e) { \
37         test = e; \
38         if (test) \
39                 printf(cRED "  Test FAILED" cNORM "\n"); \
40         else \
41                 printf(cGREEN "  Test passed" cNORM "\n"); \
42 }
43
44 struct test_curve {
45     int nid;
46     const char *name;
47     int listed;
48 };
49
50 static struct test_curve test_curves[] = {
51 #if 2001
52     { NID_id_GostR3410_2001_TestParamSet, },
53 #endif
54     { NID_id_GostR3410_2001_CryptoPro_A_ParamSet },
55     { NID_id_GostR3410_2001_CryptoPro_B_ParamSet },
56     { NID_id_GostR3410_2001_CryptoPro_C_ParamSet },
57     { NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet },
58     { NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet },
59     { NID_id_tc26_gost_3410_2012_512_paramSetA, "id-tc26-gost-3410-2012-512-paramSetA", },
60     { NID_id_tc26_gost_3410_2012_512_paramSetB, "id-tc26-gost-3410-2012-512-paramSetB", },
61     { NID_id_tc26_gost_3410_2012_512_paramSetC, "id-tc26-gost-3410-2012-512-paramSetC", },
62     { NID_id_tc26_gost_3410_2012_256_paramSetA, "id-tc26-gost-3410-2012-256-paramSetA", },
63     { NID_id_tc26_gost_3410_2012_256_paramSetB, "id-tc26-gost-3410-2012-256-paramSetB", },
64     { NID_id_tc26_gost_3410_2012_256_paramSetC, "id-tc26-gost-3410-2012-256-paramSetC", },
65     { NID_id_tc26_gost_3410_2012_256_paramSetD, "id-tc26-gost-3410-2012-256-paramSetD", },
66     0,
67 };
68
69 static struct test_curve *get_test_curve(int nid)
70 {
71     int i;
72
73     for (i = 0; test_curves[i].nid; i++)
74         if (test_curves[i].nid == nid)
75             return &test_curves[i];
76     return NULL;
77 }
78
79 static void print_bn(const char *name, const BIGNUM *n)
80 {
81     printf("%3s = ", name);
82     BN_print_fp(stdout, n);
83     printf("\n");
84 }
85
86 // https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography
87 static int parameter_test(struct test_curve *tc)
88 {
89     const int nid = tc->nid;
90     int test;
91
92     printf(cBLUE "Test curve NID %d" cNORM, nid);
93     if (tc->name)
94         printf(cBLUE ": %s" cNORM, tc->name);
95     else if (OBJ_nid2sn(nid))
96         printf(cBLUE ": %s" cNORM, OBJ_nid2sn(nid));
97     printf("\n");
98
99     if (!OBJ_nid2obj(nid)) {
100         printf(cRED "NID %d not found" cNORM "\n", nid);
101         return 1;
102     }
103
104     /* nid resolves in both directions */
105     const char *sn, *ln;
106     T(sn = OBJ_nid2sn(nid));
107     T(ln = OBJ_nid2ln(nid));
108     if (tc->name)
109         T(!strcmp(tc->name, OBJ_nid2sn(nid)));
110     T(nid == OBJ_sn2nid(sn));
111     T(nid == OBJ_ln2nid(ln));
112
113     EC_KEY *ec;
114     T(ec = EC_KEY_new());
115     if (!fill_GOST_EC_params(ec, nid)) {
116         printf(cRED "fill_GOST_EC_params FAIL" cNORM "\n");
117         ERR_print_errors_fp(stderr);
118         return 1;
119     }
120
121     const EC_GROUP *group;
122     T(group = EC_KEY_get0_group(ec));
123
124     BN_CTX *ctx;
125     T(ctx = BN_CTX_new());
126     BIGNUM *p, *a, *b;
127     T(p = BN_new());
128     T(a = BN_new());
129     T(b = BN_new());
130     EC_GROUP_get_curve(group, p, a, b, ctx);
131     print_bn("p", p);
132     print_bn("a", a);
133     print_bn("b", b);
134     T(!BN_is_zero(p));
135     T(BN_is_odd(p)); /* Should be odd for F_p */
136     T(!BN_is_zero(a));
137     T(!BN_is_zero(b));
138
139     /* Check generator */
140     const EC_POINT *generator;
141     T(generator = EC_GROUP_get0_generator(group));
142     BIGNUM *x, *y;
143     T(x = BN_new());
144     T(y = BN_new());
145     T(EC_POINT_get_affine_coordinates(group, generator, x, y, ctx));
146     print_bn("x", x);
147     print_bn("y", y);
148     T(!BN_is_zero(y));
149
150     /* Generator is not identity element 0 */
151     T(EC_POINT_is_at_infinity(group, generator) == 0);
152
153     /* x and y is in range [1 .. p-1] */
154     T(!BN_is_negative(x));
155     T(!BN_is_negative(y));
156     T(BN_cmp(x, p) < 0);
157     T(BN_cmp(y, p) < 0);
158
159     /* Generator should be on curve */
160     T(EC_POINT_is_on_curve(group, generator, ctx) == 1);
161
162     /* y^2 == (x^3 + ax + b) mod p
163      * Should be same as EC_POINT_is_on_curve(generator),
164      * but, let's calculate it manually. */
165     BIGNUM *yy  = BN_new();
166     BIGNUM *r   = BN_new();
167     BIGNUM *xxx = BN_new();
168     BIGNUM *ax  = BN_new();
169     T(yy && r && xxx && ax);
170     BN_set_word(r, 2);
171     BN_mod_exp(yy, y, r, p, ctx);
172     BN_set_word(r, 3);
173     BN_mod_exp(xxx, x, r, p, ctx);
174     BN_mod_mul(ax, a, x, p, ctx);
175     BN_mod_add(xxx, xxx, ax, p, ctx);
176     BN_mod_add(xxx, xxx, b, p, ctx);
177     T(BN_cmp(yy, xxx) == 0);
178     BN_free(yy);
179     BN_free(r);
180     BN_free(xxx);
181     BN_free(ax);
182     BN_free(p);
183     BN_free(a);
184     BN_free(b);
185     BN_free(x);
186     BN_free(y);
187
188     /* Check order */
189     const BIGNUM *order;
190     T(order = EC_GROUP_get0_order(group));
191     T(!BN_is_zero(order));
192     print_bn("q", order);
193     T(BN_is_odd(order));
194     EC_POINT *point;
195     T((point = EC_POINT_new(group)));
196     T(EC_POINT_mul(group, point, NULL, generator, order, ctx));
197     /* generator * order is the point at infinity? */
198     T(EC_POINT_is_at_infinity(group, point) == 1);
199     EC_POINT_free(point);
200
201     /* Check if order is cyclic */
202     BIGNUM *k1 = BN_new();
203     BIGNUM *k2 = BN_new();
204     EC_POINT *p1 = EC_POINT_new(group);
205     EC_POINT *p2 = EC_POINT_new(group);
206     BN_set_word(k1, 3);
207     BN_set_word(k2, 3);
208     BN_add(k2, k2, order);
209     T(EC_POINT_mul(group, p1, NULL, generator, k1, ctx));
210     T(EC_POINT_mul(group, p2, NULL, generator, k2, ctx));
211     T(EC_POINT_cmp(group, p1, p2, ctx) == 0);
212     BN_free(k1);
213     BN_free(k2);
214     EC_POINT_free(p1);
215     EC_POINT_free(p2);
216
217     /* Cofactor is 1 or 4 */
218     const BIGNUM *c;
219     T(c = EC_GROUP_get0_cofactor(group));
220     T(BN_is_word(c, 1) || BN_is_word(c, 4));
221
222     BN_CTX_free(ctx);
223     EC_KEY_free(ec);
224     TEST_ASSERT(0);
225     return test;
226 }
227
228 int main(int argc, char **argv)
229 {
230     int ret = 0;
231
232     struct test_curve *tc;
233     for (tc = test_curves; tc->nid; tc++) {
234         ret |= parameter_test(tc);
235     }
236
237     if (ret)
238         printf(cDRED "= Some tests FAILED!" cNORM "\n");
239     else
240         printf(cDGREEN "= All tests passed!" cNORM "\n");
241     return ret;
242 }