2 * Test GOST 34.10 Sign/Verify operation for every curve parameter
4 * Copyright (C) 2019 vt@altlinux.org. All Rights Reserved.
6 * Contents licensed under the terms of the OpenSSL license
7 * See https://www.openssl.org/source/license.html for details
10 #include "e_gost_err.h"
12 #include <openssl/evp.h>
13 #include <openssl/rand.h>
14 #include <openssl/err.h>
15 #include <openssl/asn1.h>
16 #include <openssl/obj_mac.h>
17 #include <openssl/ec.h>
18 #include <openssl/bn.h>
22 #define T(e) ({ if (!(e)) { \
23 ERR_print_errors_fp(stderr); \
24 OpenSSLDie(__FILE__, __LINE__, #e); \
27 #define TE(e) ({ if (!(e)) { \
28 ERR_print_errors_fp(stderr); \
29 fprintf(stderr, "Error at %s:%d %s\n", __FILE__, __LINE__, #e); \
34 #define cRED "\033[1;31m"
35 #define cDRED "\033[0;31m"
36 #define cGREEN "\033[1;32m"
37 #define cDGREEN "\033[0;32m"
38 #define cBLUE "\033[1;34m"
39 #define cDBLUE "\033[0;34m"
40 #define cNORM "\033[m"
41 #define TEST_ASSERT(e) {if ((test = (e))) \
42 printf(cRED " Test FAILED\n" cNORM); \
44 printf(cGREEN " Test passed\n" cNORM);}
53 #define D(x,y,z) { .name = #x, .nid = x, .bits = y, .paramset = z }
54 static struct test_sign test_signs[] = {
55 D(NID_id_GostR3410_2001_CryptoPro_A_ParamSet, 256, "A"),
56 D(NID_id_GostR3410_2001_CryptoPro_B_ParamSet, 256, "B"),
57 D(NID_id_GostR3410_2001_CryptoPro_C_ParamSet, 256, "C"),
58 D(NID_id_tc26_gost_3410_2012_256_paramSetA, 256, "TCA"),
59 D(NID_id_tc26_gost_3410_2012_256_paramSetB, 256, "TCB"),
60 D(NID_id_tc26_gost_3410_2012_256_paramSetC, 256, "TCC"),
61 D(NID_id_tc26_gost_3410_2012_256_paramSetD, 256, "TCD"),
62 D(NID_id_tc26_gost_3410_2012_512_paramSetA, 512, "A"),
63 D(NID_id_tc26_gost_3410_2012_512_paramSetB, 512, "B"),
64 D(NID_id_tc26_gost_3410_2012_512_paramSetC, 512, "C"),
69 static void hexdump(const void *ptr, size_t len)
71 const unsigned char *p = ptr;
74 for (i = 0; i < len; i += j) {
75 for (j = 0; j < 16 && i + j < len; j++)
76 printf("%s %02x", j? "" : "\n", p[i + j]);
81 static void print_test_tf(int err, int val, const char *t, const char *f)
84 printf(cGREEN "%s\n" cNORM, t);
86 printf(cRED "%s [%d]\n" cNORM, f, val);
89 static void print_test_result(int err)
92 printf(cGREEN "success\n" cNORM);
94 printf(cRED "failure\n" cNORM);
96 ERR_print_errors_fp(stderr);
99 static int test_sign(struct test_sign *t)
102 size_t len = t->bits / 8;
104 printf(cBLUE "Test %s:\n" cNORM, t->name);
106 /* Signature type from size. */
108 const char *algname = NULL;
111 type = NID_id_GostR3410_2012_256;
112 algname = "gost2012_256";
115 type = NID_id_GostR3410_2012_512;
116 algname = "gost2012_512";
121 T(pkey = EVP_PKEY_new());
122 TE(EVP_PKEY_set_type(pkey, type));
124 T(ctx = EVP_PKEY_CTX_new(pkey, NULL));
125 T(EVP_PKEY_keygen_init(ctx));
126 T(EVP_PKEY_CTX_ctrl(ctx, type, -1, EVP_PKEY_CTRL_GOST_PARAMSET, t->nid, NULL));
127 EVP_PKEY *priv_key = NULL;
128 err = EVP_PKEY_keygen(ctx, &priv_key);
129 printf("\tEVP_PKEY_keygen:\t");
130 print_test_result(err);
131 EVP_PKEY_CTX_free(ctx);
136 /* Create another key using string interface. */
138 T(key1 = EVP_PKEY_new());
139 T(EVP_PKEY_set_type_str(key1, algname, strlen(algname)));
141 T(ctx1 = EVP_PKEY_CTX_new(key1, NULL));
142 T(EVP_PKEY_keygen_init(ctx1));
143 T(EVP_PKEY_CTX_ctrl_str(ctx1, "paramset", t->paramset));
144 EVP_PKEY *key2 = NULL;
145 err = EVP_PKEY_keygen(ctx1, &key2);
146 printf("\tEVP_PKEY_*_str:\t\t");
147 print_test_result(err);
149 /* Check if key type and curve_name match expected values. */
150 int id = EVP_PKEY_id(key2);
152 printf("\tEVP_PKEY_id (%d):\t", type);
153 print_test_tf(err, id, "match", "mismatch");
156 const EC_KEY *ec = EVP_PKEY_get0(key2);
157 const EC_GROUP *group = EC_KEY_get0_group(ec);
158 int curve_name = EC_GROUP_get_curve_name(group);
159 err = curve_name == t->nid;
160 printf("\tcurve_name (%d):\t", t->nid);
161 print_test_tf(err, curve_name, "match", "mismatch");
164 /* Compare both keys.
165 * Parameters should match, public keys should mismatch.
167 err = EVP_PKEY_cmp_parameters(priv_key, key2);
168 printf("\tEVP_PKEY_cmp_parameters:");
169 print_test_tf(err, err, "success", "failure");
172 err = EVP_PKEY_cmp(priv_key, key2);
173 err = (err < 0) ? err : !err;
174 printf("\tEVP_PKEY_cmp:\t\t");
175 print_test_tf(err, err, "differ (good)", "equal (error)");
177 EVP_PKEY_CTX_free(ctx1);
181 * Prepare for sign testing.
183 size_t siglen = EVP_PKEY_size(priv_key);
185 T(sig = OPENSSL_malloc(siglen));
187 T(hash = OPENSSL_zalloc(len));
188 T(ctx = EVP_PKEY_CTX_new(priv_key, NULL));
191 T(EVP_PKEY_sign_init(ctx));
192 err = EVP_PKEY_sign(ctx, sig, &siglen, hash, len);
193 printf("\tEVP_PKEY_sign:\t\t");
194 print_test_result(err);
197 /* Non-determinism test.
198 * Check that different signatures for the same data
201 T(sig2 = OPENSSL_malloc(siglen));
202 TE(EVP_PKEY_sign(ctx, sig2, &siglen, hash, len) == 1);
203 printf("\tNon-determinism:\t");
204 err = !!memcmp(sig, sig2, siglen);
205 print_test_result(err);
210 T(EVP_PKEY_verify_init(ctx));
212 err = EVP_PKEY_verify(ctx, sig, siglen, hash, len);
213 printf("\tEVP_PKEY_verify:\t");
214 print_test_result(err);
217 /* False positive Verify. */
218 T(EVP_PKEY_verify_init(ctx));
220 err = EVP_PKEY_verify(ctx, sig, siglen, hash, len);
221 err = (err < 0) ? err : !err;
222 printf("\tFalse positive test:\t");
223 print_test_result(err);
226 EVP_PKEY_CTX_free(ctx);
229 EVP_PKEY_free(priv_key);
235 int main(int argc, char **argv)
239 setenv("OPENSSL_ENGINES", ENGINE_DIR, 0);
240 OPENSSL_add_all_algorithms_conf();
241 ERR_load_crypto_strings();
243 T(eng = ENGINE_by_id("gost"));
245 T(ENGINE_set_default(eng, ENGINE_METHOD_ALL));
247 struct test_sign *sp;
248 for (sp = test_signs; sp->name; sp++)
249 ret |= test_sign(sp);
255 printf(cDRED "= Some tests FAILED!\n" cNORM);
257 printf(cDGREEN "= All tests passed!\n" cNORM);