]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - test_digest.c
Start converting the engine to provider
[openssl-gost/engine.git] / test_digest.c
1 /*
2  * Test GOST 34.11 Digest operation
3  *
4  * Copyright (C) 2019 vt@altlinux.org. All Rights Reserved.
5  *
6  * Contents licensed under the terms of the OpenSSL license
7  * See https://www.openssl.org/source/license.html for details
8  */
9
10 #include "e_gost_err.h"
11 #include "gost_lcl.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 <string.h>
18 #include <stdlib.h>
19 #if MIPSEL
20 # include <sys/sysmips.h>
21 #endif
22
23 #define T(e) ({ if (!(e)) { \
24                 ERR_print_errors_fp(stderr); \
25                 OpenSSLDie(__FILE__, __LINE__, #e); \
26             } \
27         })
28 #define TE(e) ({ if (!(e)) { \
29                 ERR_print_errors_fp(stderr); \
30                 fprintf(stderr, "Error at %s:%d %s\n", __FILE__, __LINE__, #e); \
31                 return -1; \
32             } \
33         })
34
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); \
44              else \
45                  printf(cGREEN "  Test passed\n" cNORM);}
46
47 struct hash_testvec {
48         int nid;
49         const char *name;
50         const char *plaintext;
51         const char *digest;
52         unsigned short psize;
53 };
54
55 static const struct hash_testvec testvecs[] = {
56         { /* M1 */
57                 .nid = NID_id_GostR3411_2012_256,
58                 .name = "M1",
59                 .plaintext = "012345678901234567890123456789012345678901234567890123456789012",
60                 .psize = 63,
61                 .digest =
62                         "\x9d\x15\x1e\xef\xd8\x59\x0b\x89"
63                         "\xda\xa6\xba\x6c\xb7\x4a\xf9\x27"
64                         "\x5d\xd0\x51\x02\x6b\xb1\x49\xa4"
65                         "\x52\xfd\x84\xe5\xe5\x7b\x55\x00",
66         },
67         { /* M2 */
68                 .nid = NID_id_GostR3411_2012_256,
69                 .name = "M2",
70                 .plaintext =
71                         "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8"
72                         "\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee"
73                         "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8"
74                         "\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20"
75                         "\xf1\x20\xec\xee\xf0\xff\x20\xf1"
76                         "\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20"
77                         "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0"
78                         "\xfb\xff\x20\xef\xeb\xfa\xea\xfb"
79                         "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb",
80                 .psize = 72,
81                 .digest =
82                         "\x9d\xd2\xfe\x4e\x90\x40\x9e\x5d"
83                         "\xa8\x7f\x53\x97\x6d\x74\x05\xb0"
84                         "\xc0\xca\xc6\x28\xfc\x66\x9a\x74"
85                         "\x1d\x50\x06\x3c\x55\x7e\x8f\x50",
86         },
87         { /* M1 */
88                 .nid = NID_id_GostR3411_2012_512,
89                 .name = "M1",
90                 .plaintext = "012345678901234567890123456789012345678901234567890123456789012",
91                 .psize = 63,
92                 .digest =
93                         "\x1b\x54\xd0\x1a\x4a\xf5\xb9\xd5"
94                         "\xcc\x3d\x86\xd6\x8d\x28\x54\x62"
95                         "\xb1\x9a\xbc\x24\x75\x22\x2f\x35"
96                         "\xc0\x85\x12\x2b\xe4\xba\x1f\xfa"
97                         "\x00\xad\x30\xf8\x76\x7b\x3a\x82"
98                         "\x38\x4c\x65\x74\xf0\x24\xc3\x11"
99                         "\xe2\xa4\x81\x33\x2b\x08\xef\x7f"
100                         "\x41\x79\x78\x91\xc1\x64\x6f\x48",
101         },
102         { /* M2 */
103                 .nid = NID_id_GostR3411_2012_512,
104                 .name = "M2",
105                 .plaintext =
106                         "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8"
107                         "\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee"
108                         "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8"
109                         "\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20"
110                         "\xf1\x20\xec\xee\xf0\xff\x20\xf1"
111                         "\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20"
112                         "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0"
113                         "\xfb\xff\x20\xef\xeb\xfa\xea\xfb"
114                         "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb",
115                 .psize = 72,
116                 .digest =
117                         "\x1e\x88\xe6\x22\x26\xbf\xca\x6f"
118                         "\x99\x94\xf1\xf2\xd5\x15\x69\xe0"
119                         "\xda\xf8\x47\x5a\x3b\x0f\xe6\x1a"
120                         "\x53\x00\xee\xe4\x6d\x96\x13\x76"
121                         "\x03\x5f\xe8\x35\x49\xad\xa2\xb8"
122                         "\x62\x0f\xcd\x7c\x49\x6c\xe5\xb3"
123                         "\x3f\x0c\xb9\xdd\xdc\x2b\x64\x60"
124                         "\x14\x3b\x03\xda\xba\xc9\xfb\x28",
125         },
126         { 0 }
127 };
128
129 static int do_digest(int hash_nid, const char *plaintext, unsigned int psize,
130     const char *etalon)
131 {
132         unsigned int mdlen = 0;
133         if (hash_nid == NID_id_GostR3411_2012_256)
134                 mdlen = 256 / 8;
135         else if (hash_nid == NID_id_GostR3411_2012_512)
136                 mdlen = 512 / 8;
137         const EVP_MD *mdtype;
138         T(mdtype = EVP_get_digestbynid(hash_nid));
139         EVP_MD_CTX *ctx;
140         T(ctx = EVP_MD_CTX_new());
141         T(EVP_DigestInit(ctx, mdtype));
142         T(EVP_DigestUpdate(ctx, plaintext, psize));
143         unsigned int len;
144         unsigned char md[512 / 8];
145         T(EVP_DigestFinal(ctx, md, &len));
146         EVP_MD_CTX_free(ctx);
147         if (len != mdlen) {
148                 printf(cRED "digest output len mismatch %u != %u (expected)\n" cNORM,
149                     len, mdlen);
150                 return 1;
151         }
152         if (memcmp(md, etalon, mdlen) != 0) {
153                 printf(cRED "digest mismatch\n" cNORM);
154                 return 1;
155         }
156
157         return 0;
158 }
159
160 static int do_test(const struct hash_testvec *tv)
161 {
162         int ret = 0;
163
164         const char *mdname = NULL;
165         if (tv->nid == NID_id_GostR3411_2012_256)
166                 mdname = "streebog256";
167         else if (tv->nid == NID_id_GostR3411_2012_512)
168                 mdname = "streebog512";
169         printf(cBLUE "Test %s %s: " cNORM, mdname, tv->name);
170         fflush(stdout);
171         ret |= do_digest(tv->nid, tv->plaintext, tv->psize, tv->digest);
172
173         /* Text alignment problems. */
174         int shifts = 32;
175         int i;
176         char *buf;
177         T(buf = OPENSSL_malloc(tv->psize + shifts));
178         for (i = 0; i < shifts; i++) {
179                 memcpy(buf + i, tv->plaintext, tv->psize);
180                 ret |= do_digest(tv->nid, buf + i, tv->psize, tv->digest);
181         }
182         OPENSSL_free(buf);
183
184         if (!ret)
185                 printf(cGREEN "success\n" cNORM);
186         else
187                 printf(cRED "fail\n" cNORM);
188         return ret;
189 }
190
191 int main(int argc, char **argv)
192 {
193     int ret = 0;
194
195 #if MIPSEL
196     /* Trigger SIGBUS for unaligned access. */
197     sysmips(MIPS_FIXADE, 0);
198 #endif
199     setenv("OPENSSL_ENGINES", ENGINE_DIR, 0);
200     OPENSSL_add_all_algorithms_conf();
201     ERR_load_crypto_strings();
202     ENGINE *eng;
203     T(eng = ENGINE_by_id("gost"));
204     T(ENGINE_init(eng));
205     T(ENGINE_set_default(eng, ENGINE_METHOD_ALL));
206
207     const struct hash_testvec *tv;
208     for (tv = testvecs; tv->nid; tv++)
209             ret |= do_test(tv);
210
211     ENGINE_finish(eng);
212     ENGINE_free(eng);
213
214     if (ret)
215         printf(cDRED "= Some tests FAILED!\n" cNORM);
216     else
217         printf(cDGREEN "= All tests passed!\n" cNORM);
218     return ret;
219 }