2 * Test GOST 34.11 Digest operation
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>
20 # include <sys/sysmips.h>
23 #define T(e) ({ if (!(e)) { \
24 ERR_print_errors_fp(stderr); \
25 OpenSSLDie(__FILE__, __LINE__, #e); \
28 #define TE(e) ({ if (!(e)) { \
29 ERR_print_errors_fp(stderr); \
30 fprintf(stderr, "Error at %s:%d %s\n", __FILE__, __LINE__, #e); \
35 #define cRED "\033[1;31m"
36 #define cDRED "\033[0;31m"
37 #define cGREEN "\033[1;32m"
38 #define cDGREEN "\033[0;32m"
39 #define cBLUE "\033[1;34m"
40 #define cDBLUE "\033[0;34m"
41 #define cNORM "\033[m"
42 #define TEST_ASSERT(e) {if ((test = (e))) \
43 printf(cRED " Test FAILED\n" cNORM); \
45 printf(cGREEN " Test passed\n" cNORM);}
50 const char *plaintext;
53 unsigned short mdsize;
54 unsigned short block_size;
57 static const struct hash_testvec testvecs[] = {
59 .nid = NID_id_GostR3411_2012_256,
61 .plaintext = "012345678901234567890123456789012345678901234567890123456789012",
64 "\x9d\x15\x1e\xef\xd8\x59\x0b\x89"
65 "\xda\xa6\xba\x6c\xb7\x4a\xf9\x27"
66 "\x5d\xd0\x51\x02\x6b\xb1\x49\xa4"
67 "\x52\xfd\x84\xe5\xe5\x7b\x55\x00",
70 .nid = NID_id_GostR3411_2012_256,
73 "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8"
74 "\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee"
75 "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8"
76 "\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20"
77 "\xf1\x20\xec\xee\xf0\xff\x20\xf1"
78 "\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20"
79 "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0"
80 "\xfb\xff\x20\xef\xeb\xfa\xea\xfb"
81 "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb",
84 "\x9d\xd2\xfe\x4e\x90\x40\x9e\x5d"
85 "\xa8\x7f\x53\x97\x6d\x74\x05\xb0"
86 "\xc0\xca\xc6\x28\xfc\x66\x9a\x74"
87 "\x1d\x50\x06\x3c\x55\x7e\x8f\x50",
90 .nid = NID_id_GostR3411_2012_512,
92 .plaintext = "012345678901234567890123456789012345678901234567890123456789012",
95 "\x1b\x54\xd0\x1a\x4a\xf5\xb9\xd5"
96 "\xcc\x3d\x86\xd6\x8d\x28\x54\x62"
97 "\xb1\x9a\xbc\x24\x75\x22\x2f\x35"
98 "\xc0\x85\x12\x2b\xe4\xba\x1f\xfa"
99 "\x00\xad\x30\xf8\x76\x7b\x3a\x82"
100 "\x38\x4c\x65\x74\xf0\x24\xc3\x11"
101 "\xe2\xa4\x81\x33\x2b\x08\xef\x7f"
102 "\x41\x79\x78\x91\xc1\x64\x6f\x48",
105 .nid = NID_id_GostR3411_2012_512,
108 "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8"
109 "\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee"
110 "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8"
111 "\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20"
112 "\xf1\x20\xec\xee\xf0\xff\x20\xf1"
113 "\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20"
114 "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0"
115 "\xfb\xff\x20\xef\xeb\xfa\xea\xfb"
116 "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb",
119 "\x1e\x88\xe6\x22\x26\xbf\xca\x6f"
120 "\x99\x94\xf1\xf2\xd5\x15\x69\xe0"
121 "\xda\xf8\x47\x5a\x3b\x0f\xe6\x1a"
122 "\x53\x00\xee\xe4\x6d\x96\x13\x76"
123 "\x03\x5f\xe8\x35\x49\xad\xa2\xb8"
124 "\x62\x0f\xcd\x7c\x49\x6c\xe5\xb3"
125 "\x3f\x0c\xb9\xdd\xdc\x2b\x64\x60"
126 "\x14\x3b\x03\xda\xba\xc9\xfb\x28",
132 static const struct hash_testvec stestvecs[] = {
134 .nid = NID_id_GostR3411_2012_256,
135 .name = "streebog256",
139 "\xa2\xf3\x6d\x9c\x42\xa1\x1e\xad\xe3\xc1\xfe\x99\xf9\x99\xc3\x84"
140 "\xe7\x98\xae\x24\x50\x75\x73\xd7\xfc\x99\x81\xa0\x45\x85\x41\xf6"
142 .nid = NID_id_GostR3411_2012_512,
143 .name = "streebog512",
147 "\x1d\x14\x4d\xd8\xb8\x27\xfb\x55\x1a\x5a\x7d\x03\xbb\xdb\xfa\xcb"
148 "\x43\x6b\x5b\xc5\x77\x59\xfd\x5f\xf2\x3b\x8e\xf9\xc4\xdd\x6f\x79"
149 "\x45\xd8\x16\x59\x9e\xaa\xbc\xf2\xb1\x4f\xd0\xe4\xf6\xad\x46\x60"
150 "\x90\x89\xf7\x2f\x93\xd8\x85\x0c\xb0\x43\xff\x5a\xb6\xe3\x69\xbd"
155 static int do_digest(int hash_nid, const char *plaintext, unsigned int psize,
158 unsigned int mdlen = 0;
159 if (hash_nid == NID_id_GostR3411_2012_256)
161 else if (hash_nid == NID_id_GostR3411_2012_512)
163 const EVP_MD *mdtype;
164 T(mdtype = EVP_get_digestbynid(hash_nid));
166 T(ctx = EVP_MD_CTX_new());
167 T(EVP_DigestInit(ctx, mdtype));
168 T(EVP_DigestUpdate(ctx, plaintext, psize));
170 unsigned char md[512 / 8];
171 T(EVP_DigestFinal(ctx, md, &len));
172 EVP_MD_CTX_free(ctx);
174 printf(cRED "digest output len mismatch %u != %u (expected)\n" cNORM,
178 if (memcmp(md, etalon, mdlen) != 0) {
179 printf(cRED "digest mismatch\n" cNORM);
186 static int do_test(const struct hash_testvec *tv)
190 const char *mdname = NULL;
191 if (tv->nid == NID_id_GostR3411_2012_256)
192 mdname = "streebog256";
193 else if (tv->nid == NID_id_GostR3411_2012_512)
194 mdname = "streebog512";
195 printf(cBLUE "Test 1 %s %s: " cNORM, mdname, tv->name);
197 ret |= do_digest(tv->nid, tv->plaintext, tv->psize, tv->digest);
199 /* Text alignment problems. */
203 T(buf = OPENSSL_malloc(tv->psize + shifts));
204 for (i = 0; i < shifts; i++) {
205 memcpy(buf + i, tv->plaintext, tv->psize);
206 ret |= do_digest(tv->nid, buf + i, tv->psize, tv->digest);
211 printf(cGREEN "success\n" cNORM);
213 printf(cRED "fail\n" cNORM);
217 #define SUPER_SIZE 256
219 * For 256-byte buffer filled with 256 bytes from 0 to 255;
220 * Digest them 256 times from the buffer end with lengths from 0 to 256,
221 * and from beginning of the buffer with lengths from 0 to 256;
222 * Each produced digest is digested again into final sum.
224 static int do_stest_once(const struct hash_testvec *tv, unsigned int shifts)
226 unsigned char *ibuf, *md;
227 T(ibuf = OPENSSL_zalloc(SUPER_SIZE + shifts));
229 /* fill with pattern */
231 for (len = 0; len < SUPER_SIZE; len++)
232 ibuf[shifts + len] = len & 0xff;
234 const EVP_MD *mdtype;
235 T(mdtype = EVP_get_digestbynid(tv->nid));
236 OPENSSL_assert(tv->nid == EVP_MD_type(mdtype));
237 EVP_MD_CTX *ctx, *ctx2;
238 T(ctx = EVP_MD_CTX_new());
239 T(ctx2 = EVP_MD_CTX_new());
240 T(EVP_DigestInit(ctx2, mdtype));
241 OPENSSL_assert(tv->nid == EVP_MD_CTX_type(ctx2));
242 OPENSSL_assert(EVP_MD_block_size(mdtype) == tv->block_size);
243 OPENSSL_assert(EVP_MD_CTX_size(ctx2) == tv->mdsize);
244 OPENSSL_assert(EVP_MD_CTX_block_size(ctx2) == tv->block_size);
246 const unsigned int mdlen = EVP_MD_size(mdtype);
247 OPENSSL_assert(mdlen == tv->mdsize);
248 T(md = OPENSSL_zalloc(mdlen + shifts));
249 md += shifts; /* test for output digest alignment problems */
252 for (len = 0; len < SUPER_SIZE; len++) {
253 /* for each len digest len bytes from the end of buf */
254 T(EVP_DigestInit(ctx, mdtype));
255 T(EVP_DigestUpdate(ctx, ibuf + shifts + SUPER_SIZE - len, len));
256 T(EVP_DigestFinal(ctx, md, NULL));
257 T(EVP_DigestUpdate(ctx2, md, mdlen));
260 for (len = 0; len < SUPER_SIZE; len++) {
261 /* for each len digest len bytes from the beginning of buf */
262 T(EVP_DigestInit(ctx, mdtype));
263 T(EVP_DigestUpdate(ctx, ibuf + shifts, len));
264 T(EVP_DigestFinal(ctx, md, NULL));
265 T(EVP_DigestUpdate(ctx2, md, mdlen));
269 EVP_MD_CTX_free(ctx);
271 T(EVP_DigestFinal(ctx2, md, &len));
272 EVP_MD_CTX_free(ctx2);
275 printf(cRED "digest output len mismatch %u != %u (expected)\n" cNORM,
280 if (memcmp(md, tv->digest, mdlen) != 0) {
281 printf(cRED "digest mismatch\n" cNORM);
284 printf(" Expected value is: ");
285 for (i = 0; i < mdlen; i++)
286 printf("\\x%02x", md[i]);
291 OPENSSL_free(md - shifts);
294 OPENSSL_free(md - shifts);
298 /* do different block sizes and different memory offsets */
299 static int do_stest(const struct hash_testvec *tv)
303 printf(cBLUE "Test 2 %s: " cNORM, tv->name);
307 for (shifts = 0; shifts < 16 && !ret; shifts++)
308 ret |= do_stest_once(tv, shifts);
311 printf(cGREEN "success\n" cNORM);
313 printf(cRED "fail\n" cNORM);
317 int main(int argc, char **argv)
322 /* Trigger SIGBUS for unaligned access. */
323 sysmips(MIPS_FIXADE, 0);
325 setenv("OPENSSL_ENGINES", ENGINE_DIR, 0);
326 OPENSSL_add_all_algorithms_conf();
327 ERR_load_crypto_strings();
329 T(eng = ENGINE_by_id("gost"));
331 T(ENGINE_set_default(eng, ENGINE_METHOD_ALL));
333 const struct hash_testvec *tv;
334 for (tv = testvecs; tv->nid; tv++)
336 for (tv = stestvecs; tv->nid; tv++)
343 printf(cDRED "= Some tests FAILED!\n" cNORM);
345 printf(cDGREEN "= All tests passed!\n" cNORM);