]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - test_mgm.c
Travis workaround 3
[openssl-gost/engine.git] / test_mgm.c
1 # include <stdio.h>
2 # include <string.h>
3 # include <openssl/err.h>
4 # include <openssl/evp.h>
5 #include <openssl/buffer.h>
6 #include <byteswap.h>
7
8 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
9 {
10     int n = 0;
11
12     fprintf(f, "%s", title);
13     for (; n < l; ++n) {
14         if ((n % 16) == 0)
15             fprintf(f, "\n%04x", n);
16         fprintf(f, " %02x", s[n]);
17     }
18     fprintf(f, "\n");
19 }
20
21 void grasshopper_mgm_big()
22 {
23         const unsigned char gh_key[] = { 
24 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
25 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
26         };
27
28         const unsigned char gh_nonce[] = {
29         0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88
30         };
31
32         const unsigned char gh_adata[] = {
33         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
34         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
35         0xEA, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05
36         };
37
38         const unsigned char gh_pdata[] = {
39         0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88,
40         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xEE, 0xFF, 0x0A,
41         0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xEE, 0xFF, 0x0A, 0x00,
42         0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xEE, 0xFF, 0x0A, 0x00, 0x11,
43         0xAA, 0xBB, 0xCC
44         };
45
46         const unsigned char etalon_tag[] = {
47                 0xCF, 0x5D, 0x65, 0x6F, 0x40, 0xC3, 0x4F, 0x5C, 0x46, 0xE8, 0xBB, 0x0E, 0x29, 0xFC, 0xDB, 0x4C
48         };
49
50         unsigned char tag[16];
51         unsigned char gh_cdata[sizeof(gh_pdata)];
52         unsigned char *pcdata = gh_cdata;
53
54         int asize = sizeof(gh_adata);
55         int psize = sizeof(gh_pdata);
56         int fsize = 0;
57
58         const EVP_CIPHER *ciph;
59         EVP_CIPHER_CTX *enc = NULL;
60
61         int i;
62
63         ciph = EVP_get_cipherbynid(NID_kuznyechik_mgm);
64         if (ciph == NULL) {
65                 fprintf(stderr, "Could not obtain cipher");
66                 return;
67         }
68                 
69         enc = EVP_CIPHER_CTX_new();
70         EVP_EncryptInit_ex(enc, ciph, NULL, gh_key, gh_nonce);
71
72         EVP_EncryptUpdate(enc, NULL, &asize, gh_adata, sizeof(gh_adata));
73         EVP_EncryptUpdate(enc, gh_cdata, &psize, gh_pdata, sizeof(gh_pdata));
74         EVP_EncryptFinal_ex(enc, NULL, &fsize);
75
76         EVP_CIPHER_CTX_ctrl(enc, EVP_CTRL_AEAD_GET_TAG, 16, tag);
77
78         if (memcmp (tag, etalon_tag, 16)) {
79                 fprintf(stderr, "Shit happens!\n");
80                 hexdump(stderr, "Etalon tag", etalon_tag, 16);
81                 hexdump(stderr, "Got tag", tag, 16);
82                 return;
83         }
84         fprintf(stderr, "OK - big chunks!\n");
85         EVP_CIPHER_CTX_free(enc);
86
87         fprintf(stderr, "================ \n");
88 }
89
90 void grasshopper_mgm_small()
91 {
92         const unsigned char gh_key[] = { 
93 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
94 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
95         };
96
97         const unsigned char gh_nonce[] = {
98         0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88
99         };
100
101         const unsigned char gh_adata[] = {
102         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
103         0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
104         0xEA, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05
105         };
106
107         const unsigned char gh_pdata[] = {
108         0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88,
109         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xEE, 0xFF, 0x0A,
110         0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xEE, 0xFF, 0x0A, 0x00,
111         0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xEE, 0xFF, 0x0A, 0x00, 0x11,
112         0xAA, 0xBB, 0xCC
113         };
114
115         const unsigned char etalon_tag[] = {
116                 0xCF, 0x5D, 0x65, 0x6F, 0x40, 0xC3, 0x4F, 0x5C, 0x46, 0xE8, 0xBB, 0x0E, 0x29, 0xFC, 0xDB, 0x4C
117         };
118
119         unsigned char tag[16];
120         unsigned char gh_cdata[sizeof(gh_pdata)];
121         unsigned char *pcdata = gh_cdata;
122
123         int asize = sizeof(gh_adata);
124         int psize = sizeof(gh_pdata);
125         int fsize = 0;
126
127         const EVP_CIPHER *ciph;
128         EVP_CIPHER_CTX *enc = NULL;
129
130         int i;
131
132         ciph = EVP_get_cipherbynid(NID_kuznyechik_mgm);
133         if (ciph == NULL) {
134                 fprintf(stderr, "Could not obtain cipher");
135                 return;
136         }
137                 
138         enc = EVP_CIPHER_CTX_new();
139         EVP_EncryptInit_ex(enc, ciph, NULL, gh_key, gh_nonce);
140
141         for (i = 0; i < sizeof(gh_adata); i++)
142         {
143                 asize = 1;
144                 EVP_EncryptUpdate(enc, NULL, &asize, gh_adata+i, 1);
145         }
146
147         for (i = 0; i < sizeof(gh_pdata); i++)
148         {
149                 psize = 1;
150                 EVP_EncryptUpdate(enc, pcdata, &psize, gh_pdata+i, 1);
151                 pcdata += psize;
152         }
153
154         EVP_EncryptFinal_ex(enc, NULL, &fsize);
155
156         EVP_CIPHER_CTX_ctrl(enc, EVP_CTRL_AEAD_GET_TAG, 16, tag);
157
158         if (memcmp (tag, etalon_tag, 16)) {
159                 fprintf(stderr, "Shit happens!\n");
160                 hexdump(stderr, "Etalon tag", etalon_tag, 16);
161                 hexdump(stderr, "Got tag", tag, 16);
162                 return;
163         }
164         fprintf(stderr, "OK - small chunks!\n");
165         EVP_CIPHER_CTX_free(enc);
166
167 }
168
169 #define L_ENDIAN 1
170 static void gf128_mul_uint64(uint64_t *z, uint64_t *x, uint64_t *y)
171 {
172  int i = 0, n = 0;
173  uint64_t t, s0, s1;
174
175         BUF_reverse((unsigned char *)x, NULL, 16);
176         BUF_reverse((unsigned char *)y, NULL, 16);
177
178 #ifdef L_ENDIAN
179   s0 = x[0];
180         s1 = x[1];
181 #else
182   s0 = bswap_64(x[0]); 
183         s1 = bswap_64(x[1]);
184 #endif
185
186         memset(z, 0, sizeof(uint64_t)*2);
187
188  /* lower half */
189 #ifdef L_ENDIAN
190   t = y[0];
191 #else
192   t = bswap_64(y[0]);
193 #endif
194
195  for( i = 0; i < 64; i++ ) {
196    if( t&0x1 ) { z[0] ^= s0; z[1] ^= s1; }
197    t >>= 1;
198    n = s1 >> 63;
199    s1 <<= 1; s1 ^= ( s0 >> 63 ); s0 <<= 1;
200    if(n) s0 ^= 0x87;
201  }
202
203  /* upper half */
204 #ifdef L_ENDIAN
205   t = y[1];
206 #else
207   t = bswap_64(y[1]);
208 #endif
209
210  for( i = 0; i < 63; i++ ) {
211    if( t&0x1 ) { z[0] ^= s0; z[1] ^= s1; }
212    t >>= 1;
213    n = s1 >> 63;
214    s1 <<= 1; s1 ^= ( s0 >> 63 ); s0 <<= 1;
215    if( n ) s0 ^= 0x87;
216  }
217
218  if( t&0x1 ) {
219    z[0] ^= s0;
220    z[1] ^= s1;
221  }
222 #ifndef L_ENDIAN
223    z[0] = bswap_64(z[0]);
224    z[1] = bswap_64(z[1]);
225 #endif
226         BUF_reverse((unsigned char *)z, NULL, 16);
227 }
228
229 void gf_mul(void)
230 {
231         unsigned char H[16] = {
232                 0x8D, 0xB1, 0x87, 0xD6, 0x53, 0x83, 0x0E, 0xA4, 0xBC, 0x44, 0x64, 0x76, 0x95, 0x2C, 0x30, 0x0B
233         };
234
235         unsigned char A[16] = {
236         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
237         };
238
239         unsigned char etalon[16] = {
240         0x4C, 0xF4, 0x27, 0xF4, 0xAD, 0xB7, 0x5C, 0xF4, 0xC0, 0xDA, 0x39, 0xD5, 0xAB, 0x48, 0xCF, 0x38
241         };
242
243         unsigned char result_bd[16];
244         gf128_mul_uint64((uint64_t *)result_bd, (uint64_t *)H, (uint64_t *)A);
245
246
247         hexdump(stderr, "Etalon", etalon, 16);
248
249         if (memcmp (etalon, result_bd, 16)) {
250                 fprintf(stderr, "Shit happens - BD!\n");
251                 hexdump(stderr, "Result - BD", result_bd, 16);
252         } else
253                 fprintf(stderr, "OK - BD!\n");
254
255         return;
256 }
257
258 int main(void)
259 {
260         OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
261
262         gf_mul();
263         grasshopper_mgm_big();
264         grasshopper_mgm_small();
265         ERR_print_errors_fp(stderr);
266
267         return 0;
268 }