]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_grasshopper_cipher.c
Decrypt
[openssl-gost/engine.git] / gost_grasshopper_cipher.c
1 /*
2  * Maxim Tishkov 2016
3  * This file is distributed under the same license as OpenSSL
4  */
5
6 #include "gost_grasshopper_cipher.h"
7 #include "gost_grasshopper_defines.h"
8 #include "gost_grasshopper_math.h"
9 #include "gost_grasshopper_core.h"
10
11 #include <openssl/evp.h>
12 #include <openssl/rand.h>
13 #include <openssl/err.h>
14
15 #include <string.h>
16 #include <byteswap.h>
17
18 #include "gost_lcl.h"
19 #include "e_gost_err.h"
20
21 enum GRASSHOPPER_CIPHER_TYPE {
22     GRASSHOPPER_CIPHER_ECB = 0,
23     GRASSHOPPER_CIPHER_CBC,
24     GRASSHOPPER_CIPHER_OFB,
25     GRASSHOPPER_CIPHER_CFB,
26     GRASSHOPPER_CIPHER_CTR,
27     GRASSHOPPER_CIPHER_CTRACPKM,
28     GRASSHOPPER_CIPHER_MGM,
29 };
30
31 static EVP_CIPHER *gost_grasshopper_ciphers[7] = {
32     [GRASSHOPPER_CIPHER_ECB] = NULL,
33     [GRASSHOPPER_CIPHER_CBC] = NULL,
34     [GRASSHOPPER_CIPHER_OFB] = NULL,
35     [GRASSHOPPER_CIPHER_CFB] = NULL,
36     [GRASSHOPPER_CIPHER_CTR] = NULL,
37     [GRASSHOPPER_CIPHER_CTRACPKM] = NULL,
38     [GRASSHOPPER_CIPHER_MGM] = NULL,
39 };
40
41 static GRASSHOPPER_INLINE void
42 gost_grasshopper_cipher_destroy_ofb(gost_grasshopper_cipher_ctx * c);
43 static GRASSHOPPER_INLINE void
44 gost_grasshopper_cipher_destroy_ctr(gost_grasshopper_cipher_ctx * c);
45 static GRASSHOPPER_INLINE void
46 gost_grasshopper_cipher_destroy_mgm(gost_grasshopper_cipher_ctx * c);
47
48 struct GRASSHOPPER_CIPHER_PARAMS {
49     int nid;
50     grasshopper_init_cipher_func init_cipher;
51     grasshopper_do_cipher_func do_cipher;
52     grasshopper_destroy_cipher_func destroy_cipher;
53     int block_size;
54     int ctx_size;
55     int iv_size;
56     bool padding;
57 };
58
59 static struct GRASSHOPPER_CIPHER_PARAMS gost_cipher_params[7] = {
60     [GRASSHOPPER_CIPHER_ECB] = {
61                                 NID_grasshopper_ecb,
62                                 gost_grasshopper_cipher_init_ecb,
63                                 gost_grasshopper_cipher_do_ecb,
64                                 NULL,
65                                 16,
66                                 sizeof(gost_grasshopper_cipher_ctx),
67                                 0,
68                                 true}
69     ,
70     [GRASSHOPPER_CIPHER_CBC] = {
71                                 NID_grasshopper_cbc,
72                                 gost_grasshopper_cipher_init_cbc,
73                                 gost_grasshopper_cipher_do_cbc,
74                                 NULL,
75                                 16,
76                                 sizeof(gost_grasshopper_cipher_ctx),
77                                 16,
78                                 true}
79     ,
80     [GRASSHOPPER_CIPHER_OFB] = {
81                                 NID_grasshopper_ofb,
82                                 gost_grasshopper_cipher_init_ofb,
83                                 gost_grasshopper_cipher_do_ofb,
84                                 gost_grasshopper_cipher_destroy_ofb,
85                                 1,
86                                 sizeof(gost_grasshopper_cipher_ctx_ofb),
87                                 16,
88                                 false}
89     ,
90     [GRASSHOPPER_CIPHER_CFB] = {
91                                 NID_grasshopper_cfb,
92                                 gost_grasshopper_cipher_init_cfb,
93                                 gost_grasshopper_cipher_do_cfb,
94                                 NULL,
95                                 1,
96                                 sizeof(gost_grasshopper_cipher_ctx),
97                                 16,
98                                 false}
99     ,
100     [GRASSHOPPER_CIPHER_CTR] = {
101                                 NID_grasshopper_ctr,
102                                 gost_grasshopper_cipher_init_ctr,
103                                 gost_grasshopper_cipher_do_ctr,
104                                 gost_grasshopper_cipher_destroy_ctr,
105                                 1,
106                                 sizeof(gost_grasshopper_cipher_ctx_ctr),
107                                 /* IV size is set to match full block, to make it responsibility of
108                                  * user to assign correct values (IV || 0), and to make naive context
109                                  * copy possible (for software such as openssh) */
110                                 16,
111                                 false}
112     ,
113     [GRASSHOPPER_CIPHER_CTRACPKM] = {
114                                      NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm,
115                                      gost_grasshopper_cipher_init_ctracpkm,
116                                      gost_grasshopper_cipher_do_ctracpkm,
117                                      gost_grasshopper_cipher_destroy_ctr,
118                                      1,
119                                      sizeof(gost_grasshopper_cipher_ctx_ctr),
120                                      16,
121                                      false}
122     ,
123 #ifdef NID_kuznyechik_mgm
124     [GRASSHOPPER_CIPHER_MGM] = {
125                                 NID_kuznyechik_mgm,
126                                 gost_grasshopper_cipher_init_mgm,
127                                 gost_grasshopper_cipher_do_mgm,
128                                 gost_grasshopper_cipher_destroy_mgm,
129                                 1,
130                                 sizeof(gost_grasshopper_cipher_ctx_mgm),
131                                 16,
132                                 false}
133     ,
134 #else
135     [GRASSHOPPER_CIPHER_MGM] = {
136                                 NID_undef,
137                                 NULL,
138                                 NULL,
139                                 NULL,
140                                 0,
141                                 0,
142                                 0,
143                                 false}
144     ,
145 #endif
146 };
147
148 /* first 256 bit of D from draft-irtf-cfrg-re-keying-12 */
149 static const unsigned char ACPKM_D_2018[] = {
150     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /*  64 bit */
151     0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 128 bit */
152     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
153     0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 256 bit */
154 };
155
156 static void acpkm_next(gost_grasshopper_cipher_ctx * c)
157 {
158     unsigned char newkey[GRASSHOPPER_KEY_SIZE];
159     const int J = GRASSHOPPER_KEY_SIZE / GRASSHOPPER_BLOCK_SIZE;
160     int n;
161
162     for (n = 0; n < J; n++) {
163         const unsigned char *D_n = &ACPKM_D_2018[n * GRASSHOPPER_BLOCK_SIZE];
164
165         grasshopper_encrypt_block(&c->encrypt_round_keys,
166                                   (grasshopper_w128_t *) D_n,
167                                   (grasshopper_w128_t *) & newkey[n *
168                                                                   GRASSHOPPER_BLOCK_SIZE],
169                                   &c->buffer);
170     }
171     gost_grasshopper_cipher_key(c, newkey);
172 }
173
174 /* Set 256 bit  key into context */
175 GRASSHOPPER_INLINE void
176 gost_grasshopper_cipher_key(gost_grasshopper_cipher_ctx * c, const uint8_t *k)
177 {
178     int i;
179     for (i = 0; i < 2; i++) {
180         grasshopper_copy128(&c->key.k.k[i],
181                             (const grasshopper_w128_t *)(k + i * 16));
182     }
183
184     grasshopper_set_encrypt_key(&c->encrypt_round_keys, &c->key);
185     grasshopper_set_decrypt_key(&c->decrypt_round_keys, &c->key);
186 }
187
188 /* Set master 256-bit key to be used in TLSTREE calculation into context */
189 GRASSHOPPER_INLINE void
190 gost_grasshopper_master_key(gost_grasshopper_cipher_ctx * c, const uint8_t *k)
191 {
192     int i;
193     for (i = 0; i < 2; i++) {
194         grasshopper_copy128(&c->master_key.k.k[i],
195                             (const grasshopper_w128_t *)(k + i * 16));
196     }
197 }
198
199 /* Cleans up key from context */
200 GRASSHOPPER_INLINE void
201 gost_grasshopper_cipher_destroy(gost_grasshopper_cipher_ctx * c)
202 {
203     int i;
204     for (i = 0; i < 2; i++) {
205         grasshopper_zero128(&c->key.k.k[i]);
206         grasshopper_zero128(&c->master_key.k.k[i]);
207     }
208     for (i = 0; i < GRASSHOPPER_ROUND_KEYS_COUNT; i++) {
209         grasshopper_zero128(&c->encrypt_round_keys.k[i]);
210     }
211     for (i = 0; i < GRASSHOPPER_ROUND_KEYS_COUNT; i++) {
212         grasshopper_zero128(&c->decrypt_round_keys.k[i]);
213     }
214     grasshopper_zero128(&c->buffer);
215 }
216
217 static GRASSHOPPER_INLINE void
218 gost_grasshopper_cipher_destroy_ofb(gost_grasshopper_cipher_ctx * c)
219 {
220     gost_grasshopper_cipher_ctx_ofb *ctx =
221         (gost_grasshopper_cipher_ctx_ofb *) c;
222
223     grasshopper_zero128(&ctx->buffer1);
224 }
225
226 static GRASSHOPPER_INLINE void
227 gost_grasshopper_cipher_destroy_ctr(gost_grasshopper_cipher_ctx * c)
228 {
229     gost_grasshopper_cipher_ctx_ctr *ctx =
230         (gost_grasshopper_cipher_ctx_ctr *) c;
231
232     grasshopper_zero128(&ctx->partial_buffer);
233 }
234
235 static GRASSHOPPER_INLINE void
236 gost_grasshopper_cipher_destroy_mgm(gost_grasshopper_cipher_ctx * c)
237 {
238     gost_grasshopper_cipher_ctx_mgm *ctx =
239         (gost_grasshopper_cipher_ctx_mgm *) c;
240
241     grasshopper_zero128(&ctx->partial_buffer);
242 }
243
244 int gost_grasshopper_cipher_init(EVP_CIPHER_CTX *ctx,
245                                  const unsigned char *key,
246                                  const unsigned char *iv, int enc)
247 {
248     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
249
250     if (EVP_CIPHER_CTX_get_app_data(ctx) == NULL) {
251         EVP_CIPHER_CTX_set_app_data(ctx, EVP_CIPHER_CTX_get_cipher_data(ctx));
252     }
253
254     if (key != NULL) {
255         gost_grasshopper_cipher_key(c, key);
256         gost_grasshopper_master_key(c, key);
257     }
258
259     if (iv != NULL) {
260         if (c->type == GRASSHOPPER_CIPHER_MGM) {
261             gost_grasshopper_cipher_ctx_mgm *m =
262                 (gost_grasshopper_cipher_ctx_mgm *) c;
263
264             /* 1st bit should be 0 */
265             if (iv[0] > 127) {
266                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_INIT,
267                         GOST_R_INVALID_IV_LENGTH);
268                 return 0;
269             }
270             memcpy(m->mgm_iv, iv, 16);
271             *(unsigned char *)(m->mgm_iv) += 128;
272         }
273         memcpy((unsigned char *)EVP_CIPHER_CTX_original_iv(ctx), iv,
274                EVP_CIPHER_CTX_iv_length(ctx));
275     }
276
277     memcpy(EVP_CIPHER_CTX_iv_noconst(ctx),
278            EVP_CIPHER_CTX_original_iv(ctx), EVP_CIPHER_CTX_iv_length(ctx));
279
280     grasshopper_zero128(&c->buffer);
281
282     return 1;
283 }
284
285 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ecb(EVP_CIPHER_CTX *ctx, const unsigned char
286                                                         *key, const unsigned char
287                                                         *iv, int enc)
288 {
289     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
290     c->type = GRASSHOPPER_CIPHER_ECB;
291     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
292 }
293
294 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cbc(EVP_CIPHER_CTX *ctx, const unsigned char
295                                                         *key, const unsigned char
296                                                         *iv, int enc)
297 {
298     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
299     c->type = GRASSHOPPER_CIPHER_CBC;
300     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
301 }
302
303 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ofb(EVP_CIPHER_CTX *ctx, const unsigned char
304                                                         *key, const unsigned char
305                                                         *iv, int enc)
306 {
307     gost_grasshopper_cipher_ctx_ofb *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
308
309     c->c.type = GRASSHOPPER_CIPHER_OFB;
310
311     grasshopper_zero128(&c->buffer1);
312
313     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
314 }
315
316 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cfb(EVP_CIPHER_CTX *ctx, const unsigned char
317                                                         *key, const unsigned char
318                                                         *iv, int enc)
319 {
320     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
321     c->type = GRASSHOPPER_CIPHER_CFB;
322     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
323 }
324
325 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctr(EVP_CIPHER_CTX *ctx, const unsigned char
326                                                         *key, const unsigned char
327                                                         *iv, int enc)
328 {
329     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
330
331     c->c.type = GRASSHOPPER_CIPHER_CTR;
332     EVP_CIPHER_CTX_set_num(ctx, 0);
333
334     grasshopper_zero128(&c->partial_buffer);
335
336     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
337 }
338
339 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctracpkm(EVP_CIPHER_CTX
340                                                              *ctx, const unsigned
341                                                              char *key, const unsigned
342                                                              char *iv, int enc)
343 {
344     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
345
346     /* NB: setting type makes EVP do_cipher callback useless */
347     c->c.type = GRASSHOPPER_CIPHER_CTRACPKM;
348     EVP_CIPHER_CTX_set_num(ctx, 0);
349     c->section_size = 4096;
350
351     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
352 }
353
354 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_mgm(EVP_CIPHER_CTX *ctx, const unsigned char
355                                                         *key, const unsigned char
356                                                         *iv, int enc)
357 {
358     gost_grasshopper_cipher_ctx_mgm *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
359
360     c->c.type = GRASSHOPPER_CIPHER_MGM;
361     c->taglen = 16;
362     EVP_CIPHER_CTX_set_num(ctx, 0);
363
364     grasshopper_zero128(&c->partial_buffer);
365
366     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
367 }
368
369 GRASSHOPPER_INLINE int gost_grasshopper_cipher_do(EVP_CIPHER_CTX *ctx,
370                                                   unsigned char *out,
371                                                   const unsigned char *in,
372                                                   size_t inl)
373 {
374     gost_grasshopper_cipher_ctx *c =
375         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
376     struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
377
378     return params->do_cipher(ctx, out, in, inl);
379 }
380
381 int gost_grasshopper_cipher_do_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
382                                    const unsigned char *in, size_t inl)
383 {
384     gost_grasshopper_cipher_ctx *c =
385         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
386     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
387     const unsigned char *current_in = in;
388     unsigned char *current_out = out;
389     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
390     size_t i;
391
392     for (i = 0; i < blocks;
393          i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
394          GRASSHOPPER_BLOCK_SIZE) {
395         if (encrypting) {
396             grasshopper_encrypt_block(&c->encrypt_round_keys,
397                                       (grasshopper_w128_t *) current_in,
398                                       (grasshopper_w128_t *) current_out,
399                                       &c->buffer);
400         } else {
401             grasshopper_decrypt_block(&c->decrypt_round_keys,
402                                       (grasshopper_w128_t *) current_in,
403                                       (grasshopper_w128_t *) current_out,
404                                       &c->buffer);
405         }
406     }
407
408     return 1;
409 }
410
411 int gost_grasshopper_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
412                                    const unsigned char *in, size_t inl)
413 {
414     gost_grasshopper_cipher_ctx *c =
415         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
416     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
417     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
418     const unsigned char *current_in = in;
419     unsigned char *current_out = out;
420     grasshopper_w128_t *currentInputBlock;
421     grasshopper_w128_t *currentOutputBlock;
422     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
423     size_t i;
424     grasshopper_w128_t *currentBlock;
425
426     currentBlock = (grasshopper_w128_t *) iv;
427
428     for (i = 0; i < blocks;
429          i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
430          GRASSHOPPER_BLOCK_SIZE) {
431         currentInputBlock = (grasshopper_w128_t *) current_in;
432         currentOutputBlock = (grasshopper_w128_t *) current_out;
433         if (encrypting) {
434             grasshopper_append128(currentBlock, currentInputBlock);
435             grasshopper_encrypt_block(&c->encrypt_round_keys, currentBlock,
436                                       currentOutputBlock, &c->buffer);
437             grasshopper_copy128(currentBlock, currentOutputBlock);
438         } else {
439             grasshopper_w128_t tmp;
440
441             grasshopper_copy128(&tmp, currentInputBlock);
442             grasshopper_decrypt_block(&c->decrypt_round_keys,
443                                       currentInputBlock, currentOutputBlock,
444                                       &c->buffer);
445             grasshopper_append128(currentOutputBlock, currentBlock);
446             grasshopper_copy128(currentBlock, &tmp);
447         }
448     }
449
450     return 1;
451 }
452
453 void inc_counter(unsigned char *counter, size_t counter_bytes)
454 {
455     unsigned char c;
456     unsigned int n = counter_bytes;
457
458     do {
459         --n;
460         c = counter[n];
461         ++c;
462         counter[n] = c;
463         if (c)
464             return;
465     } while (n);
466 }
467
468 /* increment counter (128-bit int) by 1 */
469 static void ctr128_inc(unsigned char *counter)
470 {
471     inc_counter(counter, 16);
472 }
473
474 int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *out,
475                                    const unsigned char *in, size_t inl)
476 {
477     gost_grasshopper_cipher_ctx_ctr *c = (gost_grasshopper_cipher_ctx_ctr *)
478         EVP_CIPHER_CTX_get_cipher_data(ctx);
479     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
480     const unsigned char *current_in = in;
481     unsigned char *current_out = out;
482     grasshopper_w128_t *currentInputBlock;
483     grasshopper_w128_t *currentOutputBlock;
484     unsigned int n = EVP_CIPHER_CTX_num(ctx);
485     size_t lasted;
486     size_t i;
487
488     while (n && inl) {
489         *(current_out++) = *(current_in++) ^ c->partial_buffer.b[n];
490         --inl;
491         n = (n + 1) % GRASSHOPPER_BLOCK_SIZE;
492     }
493     EVP_CIPHER_CTX_set_num(ctx, n);
494     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
495
496     grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
497     grasshopper_w128_t tmp;
498
499     // full parts
500     for (i = 0; i < blocks; i++) {
501         currentInputBlock = (grasshopper_w128_t *) current_in;
502         currentOutputBlock = (grasshopper_w128_t *) current_out;
503         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
504                                   &c->partial_buffer, &c->c.buffer);
505         grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
506         grasshopper_copy128(currentOutputBlock, &tmp);
507         ctr128_inc(iv_buffer->b);
508         current_in += GRASSHOPPER_BLOCK_SIZE;
509         current_out += GRASSHOPPER_BLOCK_SIZE;
510     }
511
512     // last part
513     lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
514     if (lasted > 0) {
515         currentInputBlock = (grasshopper_w128_t *) current_in;
516         currentOutputBlock = (grasshopper_w128_t *) current_out;
517         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
518                                   &c->partial_buffer, &c->c.buffer);
519         for (i = 0; i < lasted; i++) {
520             currentOutputBlock->b[i] =
521                 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
522         }
523         EVP_CIPHER_CTX_set_num(ctx, i);
524         ctr128_inc(iv_buffer->b);
525     }
526
527     return 1;
528 }
529
530 #define GRASSHOPPER_BLOCK_MASK (GRASSHOPPER_BLOCK_SIZE - 1)
531 static inline void apply_acpkm_grasshopper(gost_grasshopper_cipher_ctx_ctr *
532                                            ctx, unsigned int *num)
533 {
534     if (!ctx->section_size || (*num < ctx->section_size))
535         return;
536     acpkm_next(&ctx->c);
537     *num &= GRASSHOPPER_BLOCK_MASK;
538 }
539
540 /* If meshing is not configured via ctrl (setting section_size)
541  * this function works exactly like plain ctr */
542 int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx,
543                                         unsigned char *out,
544                                         const unsigned char *in, size_t inl)
545 {
546     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
547     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
548     unsigned int num = EVP_CIPHER_CTX_num(ctx);
549
550     while ((num & GRASSHOPPER_BLOCK_MASK) && inl) {
551         *out++ = *in++ ^ c->partial_buffer.b[num & GRASSHOPPER_BLOCK_MASK];
552         --inl;
553         num++;
554     }
555     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
556     size_t i;
557     grasshopper_w128_t tmp;
558
559     // full parts
560     for (i = 0; i < blocks; i++) {
561         apply_acpkm_grasshopper(c, &num);
562         grasshopper_encrypt_block(&c->c.encrypt_round_keys,
563                                   (grasshopper_w128_t *) iv,
564                                   (grasshopper_w128_t *) & c->partial_buffer,
565                                   &c->c.buffer);
566         grasshopper_plus128(&tmp, &c->partial_buffer,
567                             (grasshopper_w128_t *) in);
568         grasshopper_copy128((grasshopper_w128_t *) out, &tmp);
569         ctr128_inc(iv);
570         in += GRASSHOPPER_BLOCK_SIZE;
571         out += GRASSHOPPER_BLOCK_SIZE;
572         num += GRASSHOPPER_BLOCK_SIZE;
573     }
574
575     // last part
576     size_t lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
577     if (lasted > 0) {
578         apply_acpkm_grasshopper(c, &num);
579         grasshopper_encrypt_block(&c->c.encrypt_round_keys,
580                                   (grasshopper_w128_t *) iv,
581                                   &c->partial_buffer, &c->c.buffer);
582         for (i = 0; i < lasted; i++)
583             out[i] = c->partial_buffer.b[i] ^ in[i];
584         ctr128_inc(iv);
585         num += lasted;
586     }
587     EVP_CIPHER_CTX_set_num(ctx, num);
588
589     return 1;
590 }
591
592 /* ----------------------------------------------------------------------------------------------- */
593 /*! Функция реализует операцию умножения двух элементов конечного поля \f$ \mathbb F_{2^{128}}\f$,
594     порожденного неприводимым многочленом
595     \f$ f(x) = x^{128} + x^7 + x^2 + x + 1 \in \mathbb F_2[x]\f$. Для умножения используется
596     простейшая реализация, основанная на приведении по модулю после каждого шага алгоритма.        */
597 /* ----------------------------------------------------------------------------------------------- */
598 static void gf128_mul_uint64(uint64_t *result, uint64_t *arg1, uint64_t *arg2)
599 {
600     int i = 0, n = 0;
601     uint64_t t, s0, s1;
602     uint64_t x[2], y[2], z[2];
603
604     BUF_reverse((unsigned char *)x, (unsigned char *)arg1, 16);
605     BUF_reverse((unsigned char *)y, (unsigned char *)arg2, 16);
606
607 #ifdef L_ENDIAN
608     s0 = x[0];
609     s1 = x[1];
610 #else
611     s0 = bswap_64(x[0]);
612     s1 = bswap_64(x[1]);
613 #endif
614
615     memset(z, 0, sizeof(uint64_t) * 2);
616
617     /* lower half */
618 #ifdef L_ENDIAN
619     t = y[0];
620 #else
621     t = bswap_64(y[0]);
622 #endif
623
624     for (i = 0; i < 64; i++) {
625         if (t & 0x1) {
626             z[0] ^= s0;
627             z[1] ^= s1;
628         }
629         t >>= 1;
630         n = s1 >> 63;
631         s1 <<= 1;
632         s1 ^= (s0 >> 63);
633         s0 <<= 1;
634         if (n)
635             s0 ^= 0x87;
636     }
637
638     /* upper half */
639 #ifdef L_ENDIAN
640     t = y[1];
641 #else
642     t = bswap_64(y[1]);
643 #endif
644
645     for (i = 0; i < 63; i++) {
646         if (t & 0x1) {
647             z[0] ^= s0;
648             z[1] ^= s1;
649         }
650         t >>= 1;
651         n = s1 >> 63;
652         s1 <<= 1;
653         s1 ^= (s0 >> 63);
654         s0 <<= 1;
655         if (n)
656             s0 ^= 0x87;
657     }
658
659     if (t & 0x1) {
660         z[0] ^= s0;
661         z[1] ^= s1;
662     }
663 #ifndef L_ENDIAN
664     z[0] = bswap_64(z[0]);
665     z[1] = bswap_64(z[1]);
666 #endif
667     BUF_reverse((unsigned char *)result, (unsigned char *)z, 16);
668 }
669
670 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
671 {
672     int n = 0;
673
674     fprintf(f, "%s", title);
675     for (; n < l; ++n) {
676         if ((n % 16) == 0)
677             fprintf(f, "\n%04x", n);
678         fprintf(f, " %02x", s[n]);
679     }
680     fprintf(f, "\n");
681 }
682
683 int gost_grasshopper_cipher_do_mgm(EVP_CIPHER_CTX *ctx, unsigned char *out,
684                                    const unsigned char *in, size_t inl)
685 {
686     gost_grasshopper_cipher_ctx_mgm *c = (gost_grasshopper_cipher_ctx_mgm *)
687         EVP_CIPHER_CTX_get_cipher_data(ctx);
688     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
689     const unsigned char *current_in = in;
690     unsigned char *current_out = out;
691     grasshopper_w128_t *currentInputBlock;
692     grasshopper_w128_t *currentOutputBlock;
693     unsigned int n = EVP_CIPHER_CTX_num(ctx);
694     size_t lasted;
695     size_t i;
696
697     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
698     int rest_len = n % GRASSHOPPER_BLOCK_SIZE;
699     grasshopper_w128_t h;
700
701     grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
702     grasshopper_w128_t tmp;
703     int encrypting = EVP_CIPHER_CTX_encrypting(ctx);
704
705 /* ======== Here we deal with associated data =========== */
706     if (out == NULL && c->mgm_state == mgm_associated_data) {
707         if (n == 0) {
708             grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
709                                       &c->partial_buffer, &c->c.buffer);
710             memcpy(c->mgm_iv, &c->partial_buffer, GRASSHOPPER_BLOCK_SIZE);
711             hexdump(stderr, "Tag", c->tag, 16);
712         }
713
714         if (rest_len != 0) {
715             /* Finalize partial_data */
716             if (inl + rest_len < GRASSHOPPER_BLOCK_SIZE) {
717                 memcpy(c->mgm_partial_buffer.b + rest_len, current_in, inl);
718                 n += inl;
719                 EVP_CIPHER_CTX_set_num(ctx, n);
720                 return 1;
721             } else {
722                 memcpy(c->mgm_partial_buffer.b + rest_len, current_in,
723                        GRASSHOPPER_BLOCK_SIZE - rest_len);
724
725                 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
726                                           &h, &c->c.buffer);
727                 inc_counter(c->mgm_iv->b, 8);
728
729                 hexdump(stderr, "Hnext", h.b, 16);
730                 hexdump(stderr, "Adata", c->mgm_partial_buffer.b, 16);
731                 /* Galois multiply Hi * Ai */
732                 gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
733
734                 /* XOR to c->tag */
735                 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
736                 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
737                 hexdump(stderr, "Tag", c->tag, 16);
738
739                 current_in += GRASSHOPPER_BLOCK_SIZE - rest_len;
740                 inl -= (GRASSHOPPER_BLOCK_SIZE - rest_len);
741                 n += GRASSHOPPER_BLOCK_SIZE - rest_len;
742             }
743         }
744
745         while (inl >= GRASSHOPPER_BLOCK_SIZE) {
746             currentInputBlock = (grasshopper_w128_t *) current_in;
747
748             grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
749                                       &h, &c->c.buffer);
750             inc_counter(c->mgm_iv->b, 8);
751
752             hexdump(stderr, "Hnext", h.b, 16);
753             hexdump(stderr, "Adata", currentInputBlock->b, 16);
754             /* Galois multiply */
755             gf128_mul_uint64(tmp.q, h.q, currentInputBlock->q);
756
757             /* XOR to c->tag */
758             grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
759             grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
760             hexdump(stderr, "Tag", c->tag, 16);
761
762             current_in += GRASSHOPPER_BLOCK_SIZE;
763             inl -= GRASSHOPPER_BLOCK_SIZE;
764             n += GRASSHOPPER_BLOCK_SIZE;
765         }
766
767         if (inl > 0) {
768             memcpy(c->mgm_partial_buffer.b, current_in, inl);
769             n += inl;
770         }
771
772         EVP_CIPHER_CTX_set_num(ctx, n);
773         return 1;
774     }
775
776     if (out == NULL && in != NULL && inl != 0 && c->mgm_state == mgm_main_data) {
777         GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_DO_MGM, GOST_R_BAD_ORDER);
778         return 0;
779     }
780
781     if (out != NULL && c->mgm_state == mgm_associated_data) {
782         memset(c->mgm_partial_buffer.b + rest_len, 0,
783                GRASSHOPPER_BLOCK_SIZE - rest_len);
784
785         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
786                                   &h, &c->c.buffer);
787         inc_counter(c->mgm_iv->b, 8);
788
789         hexdump(stderr, "Hnext", h.b, 16);
790         hexdump(stderr, "Padded Adata", c->mgm_partial_buffer.b, 16);
791         /* Galois multiply Hi * Ai */
792         gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
793
794         /* XOR to c->tag */
795         grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
796         grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
797         hexdump(stderr, "Tag", c->tag, 16);
798
799         /* We finish processing associated data */
800         /* Pad rest of mgm_partial_buffer */
801         /* Process last block */
802         c->ad_length = n;
803         n = 0;
804         rest_len = 0;
805         EVP_CIPHER_CTX_set_num(ctx, 0);
806         c->mgm_state = mgm_main_data;
807
808         fprintf(stderr, "============= Deal with main data\n");
809     }
810
811 /* ======== Here we deal with main data =========== */
812     if (n == 0) {
813         /* actual IV derived from nonce */
814         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
815                                   &c->partial_buffer, &c->c.buffer);
816         memcpy(iv, c->partial_buffer.b, GRASSHOPPER_BLOCK_SIZE);
817         //hexdump(stderr, "Y1", iv, 16);
818     }
819
820     while (rest_len && inl) {
821         *(current_out++) = *(current_in++) ^ c->partial_buffer.b[rest_len];
822
823         if (encrypting)
824             c->partial_buffer.b[rest_len] = *(current_out - 1);
825         else
826             c->partial_buffer.b[rest_len] = *(current_in - 1);
827
828         --inl;
829         n++;
830         rest_len++;
831         if (rest_len == GRASSHOPPER_BLOCK_SIZE) {
832             rest_len = 0;
833             grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
834                                       &h, &c->c.buffer);
835             inc_counter(c->mgm_iv->b, 8);
836             hexdump(stderr, "Hnext", h.b, 16);
837             hexdump(stderr, "Ciphertext", c->partial_buffer.b, 16);
838             /* Galois multiply Hi * Ai */
839             gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
840
841             /* XOR to c->tag */
842             grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
843             grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
844             hexdump(stderr, "Tag", c->tag, 16);
845         }
846     }
847
848     // full parts
849     for (i = 0; i < blocks; i++) {
850         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
851                                   &h, &c->c.buffer);
852         inc_counter(c->mgm_iv->b, 8);
853
854         currentInputBlock = (grasshopper_w128_t *) current_in;
855         currentOutputBlock = (grasshopper_w128_t *) current_out;
856         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
857                                   &c->partial_buffer, &c->c.buffer);
858         grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
859
860         if (encrypting) {
861             grasshopper_copy128(currentOutputBlock, &tmp);
862
863             hexdump(stderr, "Hnext", h.b, 16);
864             hexdump(stderr, "Ciphertext", currentOutputBlock->b, 16);
865             /* Galois multiply Hi * Ai */
866             gf128_mul_uint64(tmp.q, h.q, currentOutputBlock->q);
867
868             /* XOR to c->tag */
869             grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
870             grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
871             hexdump(stderr, "Tag", c->tag, 16);
872         } else {
873             grasshopper_w128_t tmpin;
874             grasshopper_copy128(&tmpin, currentInputBlock);
875             grasshopper_copy128(currentOutputBlock, &tmp);
876
877             hexdump(stderr, "Hnext", h.b, 16);
878             hexdump(stderr, "Ciphertext", tmpin.b, 16);
879             /* Galois multiply Hi * Ai */
880             gf128_mul_uint64(tmp.q, h.q, tmpin.q);
881
882             /* XOR to c->tag */
883             grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
884             grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
885             hexdump(stderr, "Tag", c->tag, 16);
886         }
887
888         ctr128_inc(iv_buffer->b);
889         current_in += GRASSHOPPER_BLOCK_SIZE;
890         current_out += GRASSHOPPER_BLOCK_SIZE;
891         n += GRASSHOPPER_BLOCK_SIZE;
892     }
893
894     EVP_CIPHER_CTX_set_num(ctx, n);
895
896     // last part
897     lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
898     if (lasted > 0) {
899         currentInputBlock = (grasshopper_w128_t *) current_in;
900         currentOutputBlock = (grasshopper_w128_t *) current_out;
901         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
902                                   &c->partial_buffer, &c->c.buffer);
903         for (i = 0; i < lasted; i++) {
904             if (encrypting) {
905                 currentOutputBlock->b[i] =
906                     c->partial_buffer.b[i] ^ currentInputBlock->b[i];
907                 c->partial_buffer.b[i] = currentOutputBlock->b[i];
908             } else {
909                 unsigned char in = currentInputBlock->b[i];
910                 currentOutputBlock->b[i] =
911                     c->partial_buffer.b[i] ^ currentInputBlock->b[i];
912                 c->partial_buffer.b[i] = in;
913             }
914         }
915         EVP_CIPHER_CTX_set_num(ctx, n + i);
916         ctr128_inc(iv_buffer->b);
917     }
918
919     /* Final step */
920     if (in == NULL && inl == 0) {
921         unsigned char len_buf[16];
922         uint64_t a_len = 0, p_len = 0;
923
924         if (rest_len != 0) {
925             memset(c->partial_buffer.b + rest_len, 0,
926                    GRASSHOPPER_BLOCK_SIZE - rest_len);
927             grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv, &h,
928                                       &c->c.buffer);
929             inc_counter(c->mgm_iv->b, 8);
930             hexdump(stderr, "Hnext", h.b, 16);
931             hexdump(stderr, "Padded ciphertext", c->partial_buffer.b, 16);
932             /* Galois multiply Hi * Ai */
933             gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
934
935             /* XOR to c->tag */
936             grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
937             grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
938             hexdump(stderr, "Tag", c->tag, 16);
939         }
940
941         a_len = c->ad_length << 3;
942         p_len = (c->mgm_state == mgm_associated_data) ? 0 : n << 3;
943
944 #ifdef L_ENDIAN
945         a_len = bswap_64(a_len);
946         p_len = bswap_64(p_len);
947 #endif
948         memset(len_buf, 0, 16);
949
950         memcpy(len_buf, &a_len, sizeof(a_len));
951         memcpy(len_buf + sizeof(a_len), &p_len, sizeof(p_len));
952         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
953                                   &h, &c->c.buffer);
954
955         hexdump(stderr, "Hlast", h.b, 16);
956         hexdump(stderr, "Lenbuf", len_buf, 16);
957         /* Galois multiply Hi * Ai */
958         gf128_mul_uint64(tmp.q, h.q, (uint64_t *)len_buf);
959
960         /* XOR to c->tag */
961         grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
962         grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
963         hexdump(stderr, "Tag", c->tag, 16);
964
965         /* Final tag calculation */
966         if (encrypting) {
967             grasshopper_encrypt_block(&c->c.encrypt_round_keys,
968                                       (grasshopper_w128_t *) c->tag,
969                                       (grasshopper_w128_t *) c->final_tag,
970                                       &c->c.buffer);
971             return 1;
972         } else {
973             grasshopper_w128_t decrypt_tag;
974             grasshopper_encrypt_block(&c->c.encrypt_round_keys,
975                                       (grasshopper_w128_t *) c->tag,
976                                       &decrypt_tag, &c->c.buffer);
977             if (memcmp(decrypt_tag.b, c->final_tag, 16)) {
978                 hexdump(stderr, "Bad final tag", decrypt_tag.b, 16);
979                 return 0;
980             } else
981                 return 1;
982         }
983     }
984
985     return 1;
986 }
987
988 /*
989  * Fixed 128-bit IV implementation make shift regiser redundant.
990  */
991 static void gost_grasshopper_cnt_next(gost_grasshopper_cipher_ctx_ofb * ctx,
992                                       grasshopper_w128_t * iv,
993                                       grasshopper_w128_t * buf)
994 {
995     memcpy(&ctx->buffer1, iv, 16);
996     grasshopper_encrypt_block(&ctx->c.encrypt_round_keys, &ctx->buffer1,
997                               buf, &ctx->c.buffer);
998     memcpy(iv, buf, 16);
999 }
1000
1001 int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
1002                                    const unsigned char *in, size_t inl)
1003 {
1004     gost_grasshopper_cipher_ctx_ofb *c = (gost_grasshopper_cipher_ctx_ofb *)
1005         EVP_CIPHER_CTX_get_cipher_data(ctx);
1006     const unsigned char *in_ptr = in;
1007     unsigned char *out_ptr = out;
1008     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
1009     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
1010     int num = EVP_CIPHER_CTX_num(ctx);
1011     size_t i = 0;
1012     size_t j;
1013
1014     /* process partial block if any */
1015     if (num > 0) {
1016         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
1017              j++, i++, in_ptr++, out_ptr++) {
1018             *out_ptr = buf[j] ^ (*in_ptr);
1019         }
1020         if (j == GRASSHOPPER_BLOCK_SIZE) {
1021             EVP_CIPHER_CTX_set_num(ctx, 0);
1022         } else {
1023             EVP_CIPHER_CTX_set_num(ctx, (int)j);
1024             return 1;
1025         }
1026     }
1027
1028     for (; i + GRASSHOPPER_BLOCK_SIZE <
1029          inl;
1030          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
1031          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
1032         /*
1033          * block cipher current iv
1034          */
1035         /* Encrypt */
1036         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
1037                                   (grasshopper_w128_t *) buf);
1038
1039         /*
1040          * xor next block of input text with it and output it
1041          */
1042         /*
1043          * output this block
1044          */
1045         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1046             out_ptr[j] = buf[j] ^ in_ptr[j];
1047         }
1048     }
1049
1050     /* Process rest of buffer */
1051     if (i < inl) {
1052         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
1053                                   (grasshopper_w128_t *) buf);
1054         for (j = 0; i < inl; j++, i++) {
1055             out_ptr[j] = buf[j] ^ in_ptr[j];
1056         }
1057         EVP_CIPHER_CTX_set_num(ctx, (int)j);
1058     } else {
1059         EVP_CIPHER_CTX_set_num(ctx, 0);
1060     }
1061
1062     return 1;
1063 }
1064
1065 int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
1066                                    const unsigned char *in, size_t inl)
1067 {
1068     gost_grasshopper_cipher_ctx *c =
1069         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1070     const unsigned char *in_ptr = in;
1071     unsigned char *out_ptr = out;
1072     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
1073     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
1074     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
1075     int num = EVP_CIPHER_CTX_num(ctx);
1076     size_t i = 0;
1077     size_t j = 0;
1078
1079     /* process partial block if any */
1080     if (num > 0) {
1081         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
1082              j++, i++, in_ptr++, out_ptr++) {
1083             if (!encrypting) {
1084                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *in_ptr;
1085             }
1086             *out_ptr = buf[j] ^ (*in_ptr);
1087             if (encrypting) {
1088                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *out_ptr;
1089             }
1090         }
1091         if (j == GRASSHOPPER_BLOCK_SIZE) {
1092             memcpy(iv, buf + GRASSHOPPER_BLOCK_SIZE, GRASSHOPPER_BLOCK_SIZE);
1093             EVP_CIPHER_CTX_set_num(ctx, 0);
1094         } else {
1095             EVP_CIPHER_CTX_set_num(ctx, (int)j);
1096             return 1;
1097         }
1098     }
1099
1100     for (; i + GRASSHOPPER_BLOCK_SIZE <
1101          inl;
1102          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
1103          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
1104         /*
1105          * block cipher current iv
1106          */
1107         grasshopper_encrypt_block(&c->encrypt_round_keys,
1108                                   (grasshopper_w128_t *) iv,
1109                                   (grasshopper_w128_t *) buf, &c->buffer);
1110         /*
1111          * xor next block of input text with it and output it
1112          */
1113         /*
1114          * output this block
1115          */
1116         if (!encrypting) {
1117             memcpy(iv, in_ptr, GRASSHOPPER_BLOCK_SIZE);
1118         }
1119         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1120             out_ptr[j] = buf[j] ^ in_ptr[j];
1121         }
1122         /* Encrypt */
1123         /* Next iv is next block of cipher text */
1124         if (encrypting) {
1125             memcpy(iv, out_ptr, GRASSHOPPER_BLOCK_SIZE);
1126         }
1127     }
1128
1129     /* Process rest of buffer */
1130     if (i < inl) {
1131         grasshopper_encrypt_block(&c->encrypt_round_keys,
1132                                   (grasshopper_w128_t *) iv,
1133                                   (grasshopper_w128_t *) buf, &c->buffer);
1134         if (!encrypting) {
1135             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, in_ptr, inl - i);
1136         }
1137         for (j = 0; i < inl; j++, i++) {
1138             out_ptr[j] = buf[j] ^ in_ptr[j];
1139         }
1140         EVP_CIPHER_CTX_set_num(ctx, (int)j);
1141         if (encrypting) {
1142             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, out_ptr, j);
1143         }
1144     } else {
1145         EVP_CIPHER_CTX_set_num(ctx, 0);
1146     }
1147
1148     return 1;
1149 }
1150
1151 int gost_grasshopper_cipher_cleanup(EVP_CIPHER_CTX *ctx)
1152 {
1153     gost_grasshopper_cipher_ctx *c =
1154         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1155
1156     if (!c)
1157         return 1;
1158
1159     struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
1160
1161     gost_grasshopper_cipher_destroy(c);
1162     if (params->destroy_cipher != NULL) {
1163         params->destroy_cipher(c);
1164     }
1165
1166     EVP_CIPHER_CTX_set_app_data(ctx, NULL);
1167
1168     return 1;
1169 }
1170
1171 int gost_grasshopper_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
1172 {
1173     int len = 0;
1174     unsigned char *buf = NULL;
1175     ASN1_OCTET_STRING *os = NULL;
1176
1177     os = ASN1_OCTET_STRING_new();
1178
1179     if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
1180         OPENSSL_free(buf);
1181         GOSTerr(GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS,
1182                 ERR_R_MALLOC_FAILURE);
1183         return 0;
1184     }
1185     OPENSSL_free(buf);
1186
1187     ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
1188     return 1;
1189 }
1190
1191 GRASSHOPPER_INLINE int gost_grasshopper_get_asn1_parameters(EVP_CIPHER_CTX
1192                                                             *ctx, ASN1_TYPE
1193                                                             *params)
1194 {
1195     int ret = -1;
1196
1197     if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
1198         return ret;
1199     }
1200
1201     return 1;
1202 }
1203
1204 int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
1205                                 void *ptr)
1206 {
1207     switch (type) {
1208     case EVP_CTRL_RAND_KEY:{
1209             if (RAND_bytes
1210                 ((unsigned char *)ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
1211                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_RNG_ERROR);
1212                 return -1;
1213             }
1214             break;
1215         }
1216     case EVP_CTRL_KEY_MESH:{
1217             gost_grasshopper_cipher_ctx_ctr *c =
1218                 EVP_CIPHER_CTX_get_cipher_data(ctx);
1219             if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKM || !arg
1220                 || (arg % GRASSHOPPER_BLOCK_SIZE))
1221                 return -1;
1222             c->section_size = arg;
1223             break;
1224         }
1225 #ifdef EVP_CTRL_TLS1_2_TLSTREE
1226     case EVP_CTRL_TLS1_2_TLSTREE:
1227         {
1228           unsigned char newkey[32];
1229           int mode = EVP_CIPHER_CTX_mode(ctx);
1230           static const unsigned char zeroseq[8];
1231           gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL;
1232           gost_grasshopper_cipher_ctx *c = NULL;
1233
1234           unsigned char adjusted_iv[16];
1235           unsigned char seq[8];
1236           int j, carry;
1237           if (mode != EVP_CIPH_CTR_MODE)
1238             return -1;
1239
1240           ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *)
1241             EVP_CIPHER_CTX_get_cipher_data(ctx);
1242           c = &(ctr_ctx->c);
1243
1244           memcpy(seq, ptr, 8);
1245           if (EVP_CIPHER_CTX_encrypting(ctx)) {
1246             /*
1247              * OpenSSL increments seq after mac calculation.
1248              * As we have Mac-Then-Encrypt, we need decrement it here on encryption
1249              * to derive the key correctly.
1250              * */
1251             if (memcmp(seq, zeroseq, 8) != 0)
1252             {
1253               for(j=7; j>=0; j--)
1254               {
1255                 if (seq[j] != 0) {seq[j]--; break;}
1256                 else seq[j]  = 0xFF;
1257               }
1258             }
1259           }
1260           if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey,
1261                 (const unsigned char *)seq) > 0) {
1262             memset(adjusted_iv, 0, 16);
1263             memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8);
1264             for(j=7,carry=0; j>=0; j--)
1265             {
1266               int adj_byte = adjusted_iv[j]+seq[j]+carry;
1267               carry = (adj_byte > 255) ? 1 : 0;
1268               adjusted_iv[j] = adj_byte & 0xFF;
1269             }
1270         }
1271         return -1;
1272 #endif
1273     case EVP_CTRL_AEAD_GET_TAG:
1274     case EVP_CTRL_AEAD_SET_TAG:
1275         {
1276             gost_grasshopper_cipher_ctx_mgm *mgm_ctx = NULL;
1277             gost_grasshopper_cipher_ctx *c = NULL;
1278             int taglen = arg;
1279             unsigned char *tag = ptr;
1280
1281             mgm_ctx = (gost_grasshopper_cipher_ctx_mgm *)
1282                 EVP_CIPHER_CTX_get_cipher_data(ctx);
1283             c = (gost_grasshopper_cipher_ctx *) mgm_ctx;
1284
1285             if (c->type != GRASSHOPPER_CIPHER_MGM)
1286                 return -1;
1287
1288             if (taglen > 16) {
1289                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1290                         GOST_R_INVALID_TAG_LENGTH);
1291                 return -1;
1292             }
1293
1294             if (type == EVP_CTRL_AEAD_GET_TAG)
1295                 memcpy(tag, mgm_ctx->final_tag, taglen);
1296             else
1297                 memcpy(mgm_ctx->final_tag, tag, taglen);
1298
1299             return 1;
1300         }
1301     default:
1302         GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1303                 GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
1304         return -1;
1305     }
1306     return 1;
1307 }
1308
1309 GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_create(int
1310                                                               cipher_type, int
1311                                                               block_size)
1312 {
1313     return EVP_CIPHER_meth_new(cipher_type, block_size /* block_size */ ,
1314                                GRASSHOPPER_KEY_SIZE /* key_size */ );
1315 }
1316
1317 const int cipher_gost_grasshopper_setup(EVP_CIPHER *cipher, uint8_t mode,
1318                                         int iv_size, bool padding,
1319                                         int extra_flags)
1320 {
1321     return EVP_CIPHER_meth_set_iv_length(cipher, iv_size)
1322         && EVP_CIPHER_meth_set_flags(cipher,
1323                                      (unsigned long)(mode |
1324                                                      ((!padding) ?
1325                                                       EVP_CIPH_NO_PADDING :
1326                                                       0) | ((iv_size >
1327                                                              0) ?
1328                                                             EVP_CIPH_CUSTOM_IV
1329                                                             : 0) |
1330                                                      EVP_CIPH_RAND_KEY |
1331                                                      EVP_CIPH_ALWAYS_CALL_INIT |
1332                                                      extra_flags)
1333         )
1334         && EVP_CIPHER_meth_set_cleanup(cipher, gost_grasshopper_cipher_cleanup)
1335         && EVP_CIPHER_meth_set_set_asn1_params(cipher,
1336                                                gost_grasshopper_set_asn1_parameters)
1337         && EVP_CIPHER_meth_set_get_asn1_params(cipher,
1338                                                gost_grasshopper_get_asn1_parameters)
1339         && EVP_CIPHER_meth_set_ctrl(cipher, gost_grasshopper_cipher_ctl)
1340         && EVP_CIPHER_meth_set_do_cipher(cipher, gost_grasshopper_cipher_do);
1341 }
1342
1343 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper(uint8_t mode,
1344                                                              uint8_t num)
1345 {
1346     EVP_CIPHER **cipher;
1347     struct GRASSHOPPER_CIPHER_PARAMS *params;
1348
1349     cipher = &gost_grasshopper_ciphers[num];
1350
1351     if (*cipher == NULL) {
1352         params = &gost_cipher_params[num];
1353
1354         int nid = params->nid;
1355         grasshopper_init_cipher_func init_cipher = params->init_cipher;
1356         int block_size = params->block_size;
1357         int ctx_size = params->ctx_size;
1358         int iv_size = params->iv_size;
1359         bool padding = params->padding;
1360
1361         int extra_flags = (num == GRASSHOPPER_CIPHER_MGM) ?
1362             EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_AEAD_CIPHER : 0;
1363
1364         *cipher = cipher_gost_grasshopper_create(nid, block_size);
1365         if (*cipher == NULL) {
1366             return NULL;
1367         }
1368
1369         if (!cipher_gost_grasshopper_setup
1370             (*cipher, mode, iv_size, padding, extra_flags)
1371             || !EVP_CIPHER_meth_set_init(*cipher, init_cipher)
1372             || !EVP_CIPHER_meth_set_impl_ctx_size(*cipher, ctx_size)) {
1373             EVP_CIPHER_meth_free(*cipher);
1374             *cipher = NULL;
1375         }
1376     }
1377
1378     return *cipher;
1379 }
1380
1381 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ecb()
1382 {
1383     return cipher_gost_grasshopper(EVP_CIPH_ECB_MODE, GRASSHOPPER_CIPHER_ECB);
1384 }
1385
1386 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cbc()
1387 {
1388     return cipher_gost_grasshopper(EVP_CIPH_CBC_MODE, GRASSHOPPER_CIPHER_CBC);
1389 }
1390
1391 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ofb()
1392 {
1393     return cipher_gost_grasshopper(EVP_CIPH_OFB_MODE, GRASSHOPPER_CIPHER_OFB);
1394 }
1395
1396 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cfb()
1397 {
1398     return cipher_gost_grasshopper(EVP_CIPH_CFB_MODE, GRASSHOPPER_CIPHER_CFB);
1399 }
1400
1401 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctr()
1402 {
1403     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_CTR);
1404 }
1405
1406 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctracpkm()
1407 {
1408     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE,
1409                                    GRASSHOPPER_CIPHER_CTRACPKM);
1410 }
1411
1412 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_mgm()
1413 {
1414 #ifndef NID_kuznyechik_mgm
1415     return NULL;
1416 #else
1417     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_MGM);
1418 #endif
1419 }
1420
1421 void cipher_gost_grasshopper_destroy(void)
1422 {
1423     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB]);
1424     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB] = NULL;
1425     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC]);
1426     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC] = NULL;
1427     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB]);
1428     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB] = NULL;
1429     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB]);
1430     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB] = NULL;
1431     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR]);
1432     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR] = NULL;
1433     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM]);
1434     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM] = NULL;
1435     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM]);
1436     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM] = NULL;
1437 }