]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_grasshopper_cipher.c
da67eb4c88eaeaa9d7af47780820fdb690e8b73d
[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 = (gost_grasshopper_cipher_ctx_mgm *)c;
262
263                                         /* 1st bit should be 0*/
264                                         if (iv[0] > 127) {
265                                                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_INIT, GOST_R_INVALID_IV_LENGTH);
266                                                 return 0;
267                                         }
268                                         memcpy(m->mgm_iv, iv, 16);
269                                         *(unsigned char *)(m->mgm_iv) += 128;
270                                 }
271         memcpy((unsigned char *)EVP_CIPHER_CTX_original_iv(ctx), iv,
272                EVP_CIPHER_CTX_iv_length(ctx));
273     }
274
275     memcpy(EVP_CIPHER_CTX_iv_noconst(ctx),
276            EVP_CIPHER_CTX_original_iv(ctx), EVP_CIPHER_CTX_iv_length(ctx));
277
278     grasshopper_zero128(&c->buffer);
279
280     return 1;
281 }
282
283 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ecb(EVP_CIPHER_CTX *ctx, const unsigned char
284                                                         *key, const unsigned char
285                                                         *iv, int enc)
286 {
287     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
288     c->type = GRASSHOPPER_CIPHER_ECB;
289     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
290 }
291
292 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cbc(EVP_CIPHER_CTX *ctx, const unsigned char
293                                                         *key, const unsigned char
294                                                         *iv, int enc)
295 {
296     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
297     c->type = GRASSHOPPER_CIPHER_CBC;
298     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
299 }
300
301 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ofb(EVP_CIPHER_CTX *ctx, const unsigned char
302                                                         *key, const unsigned char
303                                                         *iv, int enc)
304 {
305     gost_grasshopper_cipher_ctx_ofb *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
306
307     c->c.type = GRASSHOPPER_CIPHER_OFB;
308
309     grasshopper_zero128(&c->buffer1);
310
311     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
312 }
313
314 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cfb(EVP_CIPHER_CTX *ctx, const unsigned char
315                                                         *key, const unsigned char
316                                                         *iv, int enc)
317 {
318     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
319     c->type = GRASSHOPPER_CIPHER_CFB;
320     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
321 }
322
323 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctr(EVP_CIPHER_CTX *ctx, const unsigned char
324                                                         *key, const unsigned char
325                                                         *iv, int enc)
326 {
327     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
328
329     c->c.type = GRASSHOPPER_CIPHER_CTR;
330     EVP_CIPHER_CTX_set_num(ctx, 0);
331
332     grasshopper_zero128(&c->partial_buffer);
333
334     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
335 }
336
337 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctracpkm(EVP_CIPHER_CTX
338                                                              *ctx, const unsigned
339                                                              char *key, const unsigned
340                                                              char *iv, int enc)
341 {
342     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
343
344     /* NB: setting type makes EVP do_cipher callback useless */
345     c->c.type = GRASSHOPPER_CIPHER_CTRACPKM;
346     EVP_CIPHER_CTX_set_num(ctx, 0);
347     c->section_size = 4096;
348
349     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
350 }
351
352 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_mgm(EVP_CIPHER_CTX *ctx, const unsigned char
353                                                         *key, const unsigned char
354                                                         *iv, int enc)
355 {
356     gost_grasshopper_cipher_ctx_mgm *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
357
358     c->c.type = GRASSHOPPER_CIPHER_MGM;
359                 c->taglen = 16;
360     EVP_CIPHER_CTX_set_num(ctx, 0);
361
362     grasshopper_zero128(&c->partial_buffer);
363
364     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
365 }
366
367 GRASSHOPPER_INLINE int gost_grasshopper_cipher_do(EVP_CIPHER_CTX *ctx,
368                                                   unsigned char *out,
369                                                   const unsigned char *in,
370                                                   size_t inl)
371 {
372     gost_grasshopper_cipher_ctx *c =
373         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
374     struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
375
376     return params->do_cipher(ctx, out, in, inl);
377 }
378
379 int gost_grasshopper_cipher_do_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
380                                    const unsigned char *in, size_t inl)
381 {
382     gost_grasshopper_cipher_ctx *c =
383         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
384     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
385     const unsigned char *current_in = in;
386     unsigned char *current_out = out;
387     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
388     size_t i;
389
390     for (i = 0; i < blocks;
391          i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
392          GRASSHOPPER_BLOCK_SIZE) {
393         if (encrypting) {
394             grasshopper_encrypt_block(&c->encrypt_round_keys,
395                                       (grasshopper_w128_t *) current_in,
396                                       (grasshopper_w128_t *) current_out,
397                                       &c->buffer);
398         } else {
399             grasshopper_decrypt_block(&c->decrypt_round_keys,
400                                       (grasshopper_w128_t *) current_in,
401                                       (grasshopper_w128_t *) current_out,
402                                       &c->buffer);
403         }
404     }
405
406     return 1;
407 }
408
409 int gost_grasshopper_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
410                                    const unsigned char *in, size_t inl)
411 {
412     gost_grasshopper_cipher_ctx *c =
413         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
414     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
415     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
416     const unsigned char *current_in = in;
417     unsigned char *current_out = out;
418     grasshopper_w128_t *currentInputBlock;
419     grasshopper_w128_t *currentOutputBlock;
420     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
421     size_t i;
422     grasshopper_w128_t *currentBlock;
423
424     currentBlock = (grasshopper_w128_t *) iv;
425
426     for (i = 0; i < blocks;
427          i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
428          GRASSHOPPER_BLOCK_SIZE) {
429         currentInputBlock = (grasshopper_w128_t *) current_in;
430         currentOutputBlock = (grasshopper_w128_t *) current_out;
431         if (encrypting) {
432             grasshopper_append128(currentBlock, currentInputBlock);
433             grasshopper_encrypt_block(&c->encrypt_round_keys, currentBlock,
434                                       currentOutputBlock, &c->buffer);
435             grasshopper_copy128(currentBlock, currentOutputBlock);
436         } else {
437             grasshopper_w128_t tmp;
438
439             grasshopper_copy128(&tmp, currentInputBlock);
440             grasshopper_decrypt_block(&c->decrypt_round_keys,
441                                       currentInputBlock, currentOutputBlock,
442                                       &c->buffer);
443             grasshopper_append128(currentOutputBlock, currentBlock);
444             grasshopper_copy128(currentBlock, &tmp);
445         }
446     }
447
448     return 1;
449 }
450
451 void inc_counter(unsigned char *counter, size_t counter_bytes)
452 {
453     unsigned char c;
454     unsigned int n = counter_bytes;
455
456     do {
457         --n;
458         c = counter[n];
459         ++c;
460         counter[n] = c;
461         if (c)
462             return;
463     } while (n);
464 }
465
466 /* increment counter (128-bit int) by 1 */
467 static void ctr128_inc(unsigned char *counter)
468 {
469     inc_counter(counter, 16);
470 }
471
472 int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *out,
473                                    const unsigned char *in, size_t inl)
474 {
475     gost_grasshopper_cipher_ctx_ctr *c = (gost_grasshopper_cipher_ctx_ctr *)
476         EVP_CIPHER_CTX_get_cipher_data(ctx);
477     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
478     const unsigned char *current_in = in;
479     unsigned char *current_out = out;
480     grasshopper_w128_t *currentInputBlock;
481     grasshopper_w128_t *currentOutputBlock;
482     unsigned int n = EVP_CIPHER_CTX_num(ctx);
483     size_t lasted;
484     size_t i;
485
486     while (n && inl) {
487         *(current_out++) = *(current_in++) ^ c->partial_buffer.b[n];
488         --inl;
489         n = (n + 1) % GRASSHOPPER_BLOCK_SIZE;
490     }
491     EVP_CIPHER_CTX_set_num(ctx, n);
492     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
493
494     grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
495     grasshopper_w128_t tmp;
496
497     // full parts
498     for (i = 0; i < blocks; i++) {
499         currentInputBlock = (grasshopper_w128_t *) current_in;
500         currentOutputBlock = (grasshopper_w128_t *) current_out;
501         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
502                                   &c->partial_buffer, &c->c.buffer);
503         grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
504         grasshopper_copy128(currentOutputBlock, &tmp);
505         ctr128_inc(iv_buffer->b);
506         current_in += GRASSHOPPER_BLOCK_SIZE;
507         current_out += GRASSHOPPER_BLOCK_SIZE;
508     }
509
510     // last part
511     lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
512     if (lasted > 0) {
513         currentInputBlock = (grasshopper_w128_t *) current_in;
514         currentOutputBlock = (grasshopper_w128_t *) current_out;
515         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
516                                   &c->partial_buffer, &c->c.buffer);
517         for (i = 0; i < lasted; i++) {
518             currentOutputBlock->b[i] =
519                 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
520         }
521         EVP_CIPHER_CTX_set_num(ctx, i);
522         ctr128_inc(iv_buffer->b);
523     }
524
525     return 1;
526 }
527
528 #define GRASSHOPPER_BLOCK_MASK (GRASSHOPPER_BLOCK_SIZE - 1)
529 static inline void apply_acpkm_grasshopper(gost_grasshopper_cipher_ctx_ctr *
530                                            ctx, unsigned int *num)
531 {
532     if (!ctx->section_size || (*num < ctx->section_size))
533         return;
534     acpkm_next(&ctx->c);
535     *num &= GRASSHOPPER_BLOCK_MASK;
536 }
537
538 /* If meshing is not configured via ctrl (setting section_size)
539  * this function works exactly like plain ctr */
540 int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx,
541                                         unsigned char *out,
542                                         const unsigned char *in, size_t inl)
543 {
544     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
545     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
546     unsigned int num = EVP_CIPHER_CTX_num(ctx);
547
548     while ((num & GRASSHOPPER_BLOCK_MASK) && inl) {
549         *out++ = *in++ ^ c->partial_buffer.b[num & GRASSHOPPER_BLOCK_MASK];
550         --inl;
551         num++;
552     }
553     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
554     size_t i;
555     grasshopper_w128_t tmp;
556
557     // full parts
558     for (i = 0; i < blocks; i++) {
559         apply_acpkm_grasshopper(c, &num);
560         grasshopper_encrypt_block(&c->c.encrypt_round_keys,
561                                   (grasshopper_w128_t *) iv,
562                                   (grasshopper_w128_t *) & c->partial_buffer,
563                                   &c->c.buffer);
564         grasshopper_plus128(&tmp, &c->partial_buffer,
565                             (grasshopper_w128_t *) in);
566         grasshopper_copy128((grasshopper_w128_t *) out, &tmp);
567         ctr128_inc(iv);
568         in += GRASSHOPPER_BLOCK_SIZE;
569         out += GRASSHOPPER_BLOCK_SIZE;
570         num += GRASSHOPPER_BLOCK_SIZE;
571     }
572
573     // last part
574     size_t lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
575     if (lasted > 0) {
576         apply_acpkm_grasshopper(c, &num);
577         grasshopper_encrypt_block(&c->c.encrypt_round_keys,
578                                   (grasshopper_w128_t *) iv,
579                                   &c->partial_buffer, &c->c.buffer);
580         for (i = 0; i < lasted; i++)
581             out[i] = c->partial_buffer.b[i] ^ in[i];
582         ctr128_inc(iv);
583         num += lasted;
584     }
585     EVP_CIPHER_CTX_set_num(ctx, num);
586
587     return 1;
588 }
589
590 /* ----------------------------------------------------------------------------------------------- */
591 /*! Функция реализует операцию умножения двух элементов конечного поля \f$ \mathbb F_{2^{128}}\f$,
592     порожденного неприводимым многочленом
593     \f$ f(x) = x^{128} + x^7 + x^2 + x + 1 \in \mathbb F_2[x]\f$. Для умножения используется
594     простейшая реализация, основанная на приведении по модулю после каждого шага алгоритма.        */
595 /* ----------------------------------------------------------------------------------------------- */
596 static void gf128_mul_uint64(uint64_t *z, uint64_t *x, uint64_t *y)
597 {
598  int i = 0, n = 0;
599  uint64_t t, s0, s1;
600
601         BUF_reverse((unsigned char *)x, NULL, 16);
602         BUF_reverse((unsigned char *)y, NULL, 16);
603
604 #ifdef L_ENDIAN
605   s0 = x[0];
606         s1 = x[1];
607 #else
608   s0 = bswap_64(x[0]); 
609         s1 = bswap_64(x[1]);
610 #endif
611
612         memset(z, 0, sizeof(uint64_t)*2);
613
614  /* lower half */
615 #ifdef L_ENDIAN
616   t = y[0];
617 #else
618   t = bswap_64(y[0]);
619 #endif
620
621  for( i = 0; i < 64; i++ ) {
622    if( t&0x1 ) { z[0] ^= s0; z[1] ^= s1; }
623    t >>= 1;
624    n = s1 >> 63;
625    s1 <<= 1; s1 ^= ( s0 >> 63 ); s0 <<= 1;
626    if(n) s0 ^= 0x87;
627  }
628
629  /* upper half */
630 #ifdef L_ENDIAN
631   t = y[1];
632 #else
633   t = bswap_64(y[1]);
634 #endif
635
636  for( i = 0; i < 63; i++ ) {
637    if( t&0x1 ) { z[0] ^= s0; z[1] ^= s1; }
638    t >>= 1;
639    n = s1 >> 63;
640    s1 <<= 1; s1 ^= ( s0 >> 63 ); s0 <<= 1;
641    if( n ) s0 ^= 0x87;
642  }
643
644  if( t&0x1 ) {
645    z[0] ^= s0;
646    z[1] ^= s1;
647  }
648 #ifndef L_ENDIAN
649    z[0] = bswap_64(z[0]);
650    z[1] = bswap_64(z[1]);
651 #endif
652         BUF_reverse((unsigned char *)z, NULL, 16);
653 }
654
655 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
656 {
657     int n = 0;
658
659     fprintf(f, "%s", title);
660     for (; n < l; ++n) {
661         if ((n % 16) == 0)
662             fprintf(f, "\n%04x", n);
663         fprintf(f, " %02x", s[n]);
664     }
665     fprintf(f, "\n");
666 }
667
668 int gost_grasshopper_cipher_do_mgm(EVP_CIPHER_CTX *ctx, unsigned char *out,
669                                    const unsigned char *in, size_t inl)
670 {
671     gost_grasshopper_cipher_ctx_mgm *c = (gost_grasshopper_cipher_ctx_mgm *)
672         EVP_CIPHER_CTX_get_cipher_data(ctx);
673     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
674     const unsigned char *current_in = in;
675     unsigned char *current_out = out;
676     grasshopper_w128_t *currentInputBlock;
677     grasshopper_w128_t *currentOutputBlock;
678     unsigned int n = EVP_CIPHER_CTX_num(ctx);
679     size_t lasted;
680     size_t i;
681
682     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
683                 int rest_len = n % GRASSHOPPER_BLOCK_SIZE;
684                 grasshopper_w128_t h;
685
686     grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
687     grasshopper_w128_t tmp;
688
689 /* ======== Here we deal with associated data =========== */
690                 if (out == NULL && c->mgm_state == mgm_associated_data) {
691                         if (n == 0) {
692         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
693                                   &c->partial_buffer, &c->c.buffer);
694                                 memcpy(c->mgm_iv, &c->partial_buffer, GRASSHOPPER_BLOCK_SIZE);
695                                 hexdump(stderr, "Tag", c->tag, 16);
696                         }
697
698                         if (rest_len != 0) {
699                                 /* Finalize partial_data */
700                                 if (inl + rest_len < GRASSHOPPER_BLOCK_SIZE) {
701                                         memcpy(c->mgm_partial_buffer.b+rest_len, current_in, inl);
702                                         n += inl;
703                                         EVP_CIPHER_CTX_set_num(ctx, n);
704                                         return 1;
705                                 } else {
706                                         memcpy(c->mgm_partial_buffer.b+rest_len, current_in, GRASSHOPPER_BLOCK_SIZE - rest_len);
707
708                                         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
709                                                         &h, &c->c.buffer);
710                                         inc_counter(c->mgm_iv->b, 8);
711
712                                 hexdump(stderr, "Hnext", h.b, 16);
713                                 hexdump(stderr, "Adata", c->mgm_partial_buffer.b, 16);
714                                         /* Galois multiply Hi * Ai */
715                                         gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
716
717                                         /* XOR to c->tag */
718                                         grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
719                                         grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
720                                 hexdump(stderr, "Tag", c->tag, 16);
721                                                                                 
722                                         current_in += GRASSHOPPER_BLOCK_SIZE - rest_len;
723                                         inl -= (GRASSHOPPER_BLOCK_SIZE - rest_len);
724                                         n += GRASSHOPPER_BLOCK_SIZE - rest_len;
725                                 }
726                         }
727
728                         while (inl >= GRASSHOPPER_BLOCK_SIZE) {
729         currentInputBlock = (grasshopper_w128_t *) current_in;
730
731         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
732                                   &h, &c->c.buffer);
733                                 inc_counter(c->mgm_iv->b, 8);
734
735                                 hexdump(stderr, "Hnext", h.b, 16);
736                                 hexdump(stderr, "Adata", currentInputBlock->b, 16);
737                                 /* Galois multiply */
738                                 gf128_mul_uint64(tmp.q, h.q, currentInputBlock->q);
739
740                                 /* XOR to c->tag */
741                                 grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
742                                 grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
743                                 hexdump(stderr, "Tag", c->tag, 16);
744
745                                 current_in += GRASSHOPPER_BLOCK_SIZE;
746                                 inl -= GRASSHOPPER_BLOCK_SIZE;
747                                 n += GRASSHOPPER_BLOCK_SIZE;
748                         }
749
750                         if (inl > 0)
751                         {
752                                 memcpy(c->mgm_partial_buffer.b, current_in, inl);
753                                 n += inl;
754                         }
755
756                         EVP_CIPHER_CTX_set_num(ctx, n);
757                         return 1;
758                 }
759
760                 if (out == NULL && in != NULL && inl !=0 && c->mgm_state == mgm_main_data) {
761                         GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_DO_MGM, GOST_R_BAD_ORDER);
762                         return 0;
763                 }
764
765                 if (out != NULL && c->mgm_state == mgm_associated_data) {
766                         memset(c->mgm_partial_buffer.b+rest_len, 0, GRASSHOPPER_BLOCK_SIZE - rest_len);
767
768                         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
769                                         &h, &c->c.buffer);
770                         inc_counter(c->mgm_iv->b, 8);
771
772                         hexdump(stderr, "Hnext", h.b, 16);
773                         hexdump(stderr, "Padded Adata", c->mgm_partial_buffer.b, 16);
774                         /* Galois multiply Hi * Ai */
775                         gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
776
777                         /* XOR to c->tag */
778                         grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
779                         grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
780                                 hexdump(stderr, "Tag", c->tag, 16);
781                                                                                 
782                         /* We finish processing associated data */
783                         /* Pad rest of mgm_partial_buffer */
784                         /* Process last block */
785                         c->ad_length = n;
786                         n = 0;
787                         EVP_CIPHER_CTX_set_num(ctx, 0);
788                         c->mgm_state = mgm_main_data;
789
790                         fprintf(stderr, "============= Deal with main data\n");
791                 }
792
793 /* ======== Here we deal with main data =========== */
794     if (n == 0) {
795                         /* actual IV derived from nonce */
796       grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
797                                   &c->partial_buffer, &c->c.buffer);
798                         memcpy(iv, c->partial_buffer.b, GRASSHOPPER_BLOCK_SIZE);
799                         //hexdump(stderr, "Y1", iv, 16);
800                 }
801
802     while (rest_len && inl) {
803         *(current_out++) = *(current_in++) ^ c->partial_buffer.b[rest_len];
804         --inl;
805         n++;
806                                 rest_len++;
807                                 if (rest_len == GRASSHOPPER_BLOCK_SIZE)
808                                 {
809                                         rest_len = 0;
810                                 }
811     }
812     EVP_CIPHER_CTX_set_num(ctx, n);
813
814     // full parts
815     for (i = 0; i < blocks; i++) {
816         currentInputBlock = (grasshopper_w128_t *) current_in;
817         currentOutputBlock = (grasshopper_w128_t *) current_out;
818         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
819                                   &c->partial_buffer, &c->c.buffer);
820         grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
821         grasshopper_copy128(currentOutputBlock, &tmp);
822                         //hexdump(stderr, "Ciphertext", currentOutputBlock->b, 16);
823
824                                 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
825                                                         &h, &c->c.buffer);
826                                 inc_counter(c->mgm_iv->b, 8);
827                         hexdump(stderr, "Hnext", h.b, 16);
828                         hexdump(stderr, "Ciphertext", currentOutputBlock->b, 16);
829                                 /* Galois multiply Hi * Ai */
830                                 gf128_mul_uint64(tmp.q, h.q, currentOutputBlock->q);
831
832                                 /* XOR to c->tag */
833                                 grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
834                                 grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
835                                 hexdump(stderr, "Tag", c->tag, 16);
836
837         ctr128_inc(iv_buffer->b);
838         current_in += GRASSHOPPER_BLOCK_SIZE;
839         current_out += GRASSHOPPER_BLOCK_SIZE;
840                                 n += GRASSHOPPER_BLOCK_SIZE;
841     }
842
843     // last part
844     lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
845     if (lasted > 0) {
846         currentInputBlock = (grasshopper_w128_t *) current_in;
847         currentOutputBlock = (grasshopper_w128_t *) current_out;
848         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
849                                   &c->partial_buffer, &c->c.buffer);
850         for (i = 0; i < lasted; i++) {
851             currentOutputBlock->b[i] =
852                 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
853         }
854                                 grasshopper_copy128(&c->partial_buffer, currentOutputBlock);
855         EVP_CIPHER_CTX_set_num(ctx, n+i);
856         ctr128_inc(iv_buffer->b);
857     }
858
859                 /* Final step */
860                 if (in == NULL && inl == 0)
861                 {
862                         unsigned char len_buf[16];
863                         uint64_t a_len = 0, p_len = 0;
864
865                         if (rest_len != 0)
866                         {
867                                 memset(c->partial_buffer.b+rest_len, 0, GRASSHOPPER_BLOCK_SIZE - rest_len);
868                                 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
869                                                         &h, &c->c.buffer);
870                                 inc_counter(c->mgm_iv->b, 8);
871                         hexdump(stderr, "Hnext", h.b, 16);
872                         hexdump(stderr, "Padded ciphertext", c->partial_buffer.b, 16);
873                                 /* Galois multiply Hi * Ai */
874                                 gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
875
876                                 /* XOR to c->tag */
877                                 grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
878                                 grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
879                                 hexdump(stderr, "Tag", c->tag, 16);
880                         }
881
882                         a_len = c->ad_length << 3;
883                         p_len = (c->mgm_state == mgm_associated_data) ? 0 : n << 3;
884
885 #ifdef L_ENDIAN
886                         a_len = bswap_64(a_len);
887                         p_len = bswap_64(p_len);
888 #endif
889                         memset(len_buf, 0, 16);
890
891                         memcpy(len_buf, &a_len, sizeof(a_len));
892                         memcpy(len_buf+sizeof(a_len), &p_len, sizeof(p_len));
893                         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
894                                                         &h, &c->c.buffer);
895
896                         hexdump(stderr, "Hlast", h.b, 16);
897                         hexdump(stderr, "Lenbuf", len_buf, 16);
898                         /* Galois multiply Hi * Ai */
899                         gf128_mul_uint64(tmp.q, h.q, (uint64_t *)len_buf);
900
901                         /* XOR to c->tag */
902                         grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
903                         grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
904                                 hexdump(stderr, "Tag", c->tag, 16);
905
906                         /* Final tag calculation */
907       grasshopper_encrypt_block(&c->c.encrypt_round_keys, (grasshopper_w128_t *)c->tag,
908                                   (grasshopper_w128_t *)c->final_tag, &c->c.buffer);
909                 }
910
911     return 1;
912 }
913
914 /*
915  * Fixed 128-bit IV implementation make shift regiser redundant.
916  */
917 static void gost_grasshopper_cnt_next(gost_grasshopper_cipher_ctx_ofb * ctx,
918                                       grasshopper_w128_t * iv,
919                                       grasshopper_w128_t * buf)
920 {
921     memcpy(&ctx->buffer1, iv, 16);
922     grasshopper_encrypt_block(&ctx->c.encrypt_round_keys, &ctx->buffer1,
923                               buf, &ctx->c.buffer);
924     memcpy(iv, buf, 16);
925 }
926
927 int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
928                                    const unsigned char *in, size_t inl)
929 {
930     gost_grasshopper_cipher_ctx_ofb *c = (gost_grasshopper_cipher_ctx_ofb *)
931         EVP_CIPHER_CTX_get_cipher_data(ctx);
932     const unsigned char *in_ptr = in;
933     unsigned char *out_ptr = out;
934     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
935     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
936     int num = EVP_CIPHER_CTX_num(ctx);
937     size_t i = 0;
938     size_t j;
939
940     /* process partial block if any */
941     if (num > 0) {
942         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
943              j++, i++, in_ptr++, out_ptr++) {
944             *out_ptr = buf[j] ^ (*in_ptr);
945         }
946         if (j == GRASSHOPPER_BLOCK_SIZE) {
947             EVP_CIPHER_CTX_set_num(ctx, 0);
948         } else {
949             EVP_CIPHER_CTX_set_num(ctx, (int)j);
950             return 1;
951         }
952     }
953
954     for (; i + GRASSHOPPER_BLOCK_SIZE <
955          inl;
956          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
957          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
958         /*
959          * block cipher current iv
960          */
961         /* Encrypt */
962         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
963                                   (grasshopper_w128_t *) buf);
964
965         /*
966          * xor next block of input text with it and output it
967          */
968         /*
969          * output this block
970          */
971         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
972             out_ptr[j] = buf[j] ^ in_ptr[j];
973         }
974     }
975
976     /* Process rest of buffer */
977     if (i < inl) {
978         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
979                                   (grasshopper_w128_t *) buf);
980         for (j = 0; i < inl; j++, i++) {
981             out_ptr[j] = buf[j] ^ in_ptr[j];
982         }
983         EVP_CIPHER_CTX_set_num(ctx, (int)j);
984     } else {
985         EVP_CIPHER_CTX_set_num(ctx, 0);
986     }
987
988     return 1;
989 }
990
991 int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
992                                    const unsigned char *in, size_t inl)
993 {
994     gost_grasshopper_cipher_ctx *c =
995         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
996     const unsigned char *in_ptr = in;
997     unsigned char *out_ptr = out;
998     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
999     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
1000     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
1001     int num = EVP_CIPHER_CTX_num(ctx);
1002     size_t i = 0;
1003     size_t j = 0;
1004
1005     /* process partial block if any */
1006     if (num > 0) {
1007         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
1008              j++, i++, in_ptr++, out_ptr++) {
1009             if (!encrypting) {
1010                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *in_ptr;
1011             }
1012             *out_ptr = buf[j] ^ (*in_ptr);
1013             if (encrypting) {
1014                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *out_ptr;
1015             }
1016         }
1017         if (j == GRASSHOPPER_BLOCK_SIZE) {
1018             memcpy(iv, buf + GRASSHOPPER_BLOCK_SIZE, GRASSHOPPER_BLOCK_SIZE);
1019             EVP_CIPHER_CTX_set_num(ctx, 0);
1020         } else {
1021             EVP_CIPHER_CTX_set_num(ctx, (int)j);
1022             return 1;
1023         }
1024     }
1025
1026     for (; i + GRASSHOPPER_BLOCK_SIZE <
1027          inl;
1028          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
1029          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
1030         /*
1031          * block cipher current iv
1032          */
1033         grasshopper_encrypt_block(&c->encrypt_round_keys,
1034                                   (grasshopper_w128_t *) iv,
1035                                   (grasshopper_w128_t *) buf, &c->buffer);
1036         /*
1037          * xor next block of input text with it and output it
1038          */
1039         /*
1040          * output this block
1041          */
1042         if (!encrypting) {
1043             memcpy(iv, in_ptr, GRASSHOPPER_BLOCK_SIZE);
1044         }
1045         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1046             out_ptr[j] = buf[j] ^ in_ptr[j];
1047         }
1048         /* Encrypt */
1049         /* Next iv is next block of cipher text */
1050         if (encrypting) {
1051             memcpy(iv, out_ptr, GRASSHOPPER_BLOCK_SIZE);
1052         }
1053     }
1054
1055     /* Process rest of buffer */
1056     if (i < inl) {
1057         grasshopper_encrypt_block(&c->encrypt_round_keys,
1058                                   (grasshopper_w128_t *) iv,
1059                                   (grasshopper_w128_t *) buf, &c->buffer);
1060         if (!encrypting) {
1061             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, in_ptr, inl - i);
1062         }
1063         for (j = 0; i < inl; j++, i++) {
1064             out_ptr[j] = buf[j] ^ in_ptr[j];
1065         }
1066         EVP_CIPHER_CTX_set_num(ctx, (int)j);
1067         if (encrypting) {
1068             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, out_ptr, j);
1069         }
1070     } else {
1071         EVP_CIPHER_CTX_set_num(ctx, 0);
1072     }
1073
1074     return 1;
1075 }
1076
1077 int gost_grasshopper_cipher_cleanup(EVP_CIPHER_CTX *ctx)
1078 {
1079     gost_grasshopper_cipher_ctx *c =
1080         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1081
1082     if (!c)
1083         return 1;
1084
1085     struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
1086
1087     gost_grasshopper_cipher_destroy(c);
1088     if (params->destroy_cipher != NULL) {
1089         params->destroy_cipher(c);
1090     }
1091
1092     EVP_CIPHER_CTX_set_app_data(ctx, NULL);
1093
1094     return 1;
1095 }
1096
1097 int gost_grasshopper_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
1098 {
1099     int len = 0;
1100     unsigned char *buf = NULL;
1101     ASN1_OCTET_STRING *os = NULL;
1102
1103     os = ASN1_OCTET_STRING_new();
1104
1105     if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
1106         OPENSSL_free(buf);
1107         GOSTerr(GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS,
1108                 ERR_R_MALLOC_FAILURE);
1109         return 0;
1110     }
1111     OPENSSL_free(buf);
1112
1113     ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
1114     return 1;
1115 }
1116
1117 GRASSHOPPER_INLINE int gost_grasshopper_get_asn1_parameters(EVP_CIPHER_CTX
1118                                                             *ctx, ASN1_TYPE
1119                                                             *params)
1120 {
1121     int ret = -1;
1122
1123     if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
1124         return ret;
1125     }
1126
1127     return 1;
1128 }
1129
1130 int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
1131                                 void *ptr)
1132 {
1133     switch (type) {
1134     case EVP_CTRL_RAND_KEY:{
1135             if (RAND_bytes
1136                 ((unsigned char *)ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
1137                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_RNG_ERROR);
1138                 return -1;
1139             }
1140             break;
1141         }
1142     case EVP_CTRL_KEY_MESH:{
1143             gost_grasshopper_cipher_ctx_ctr *c =
1144                 EVP_CIPHER_CTX_get_cipher_data(ctx);
1145             if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKM || !arg
1146                 || (arg % GRASSHOPPER_BLOCK_SIZE))
1147                 return -1;
1148             c->section_size = arg;
1149             break;
1150         }
1151 #ifdef EVP_CTRL_TLS1_2_TLSTREE
1152     case EVP_CTRL_TLS1_2_TLSTREE:
1153         {
1154           unsigned char newkey[32];
1155           int mode = EVP_CIPHER_CTX_mode(ctx);
1156           static const unsigned char zeroseq[8];
1157           gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL;
1158           gost_grasshopper_cipher_ctx *c = NULL;
1159
1160           unsigned char adjusted_iv[16];
1161           unsigned char seq[8];
1162           int j, carry;
1163           if (mode != EVP_CIPH_CTR_MODE)
1164             return -1;
1165
1166           ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *)
1167             EVP_CIPHER_CTX_get_cipher_data(ctx);
1168           c = &(ctr_ctx->c);
1169
1170           memcpy(seq, ptr, 8);
1171           if (EVP_CIPHER_CTX_encrypting(ctx)) {
1172             /*
1173              * OpenSSL increments seq after mac calculation.
1174              * As we have Mac-Then-Encrypt, we need decrement it here on encryption
1175              * to derive the key correctly.
1176              * */
1177             if (memcmp(seq, zeroseq, 8) != 0)
1178             {
1179               for(j=7; j>=0; j--)
1180               {
1181                 if (seq[j] != 0) {seq[j]--; break;}
1182                 else seq[j]  = 0xFF;
1183               }
1184             }
1185           }
1186           if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey,
1187                 (const unsigned char *)seq) > 0) {
1188             memset(adjusted_iv, 0, 16);
1189             memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8);
1190             for(j=7,carry=0; j>=0; j--)
1191             {
1192               int adj_byte = adjusted_iv[j]+seq[j]+carry;
1193               carry = (adj_byte > 255) ? 1 : 0;
1194               adjusted_iv[j] = adj_byte & 0xFF;
1195             }
1196             EVP_CIPHER_CTX_set_num(ctx, 0);
1197             memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16);
1198
1199             gost_grasshopper_cipher_key(c, newkey);
1200             return 1;
1201           }
1202         }
1203         return -1;
1204 #endif
1205                 case EVP_CTRL_AEAD_GET_TAG:
1206                 case EVP_CTRL_AEAD_SET_TAG:
1207                 {
1208           gost_grasshopper_cipher_ctx_mgm *mgm_ctx = NULL;
1209           gost_grasshopper_cipher_ctx *c = NULL;
1210                                         int taglen = arg;
1211                                         unsigned char* tag = ptr;
1212                                         
1213           mgm_ctx = (gost_grasshopper_cipher_ctx_mgm *)
1214             EVP_CIPHER_CTX_get_cipher_data(ctx);
1215                                         c = (gost_grasshopper_cipher_ctx *)mgm_ctx;
1216
1217                                         if (c->type != GRASSHOPPER_CIPHER_MGM)
1218                                                 return -1;
1219                                         
1220                                         if (taglen > 16) {
1221                                                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_INVALID_TAG_LENGTH);
1222                                                 return -1;
1223                                         }
1224
1225                                         if (type == EVP_CTRL_AEAD_GET_TAG)
1226                                                 memcpy(tag, mgm_ctx->final_tag, taglen);
1227                                         else
1228                                                 memcpy(mgm_ctx->final_tag, tag, taglen);
1229
1230                                         return 1;
1231                 }
1232     default:
1233         GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1234                 GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
1235         return -1;
1236     }
1237     return 1;
1238 }
1239
1240 GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_create(int
1241                                                               cipher_type, int
1242                                                               block_size)
1243 {
1244     return EVP_CIPHER_meth_new(cipher_type, block_size /* block_size */ ,
1245                                GRASSHOPPER_KEY_SIZE /* key_size */ );
1246 }
1247
1248 const int cipher_gost_grasshopper_setup(EVP_CIPHER *cipher, uint8_t mode,
1249                                         int iv_size, bool padding, int extra_flags)
1250 {
1251     return EVP_CIPHER_meth_set_iv_length(cipher, iv_size)
1252         && EVP_CIPHER_meth_set_flags(cipher,
1253                                      (unsigned long)(mode |
1254                                                      ((!padding) ?
1255                                                       EVP_CIPH_NO_PADDING :
1256                                                       0) | ((iv_size >
1257                                                              0) ?
1258                                                             EVP_CIPH_CUSTOM_IV
1259                                                             : 0) |
1260                                                      EVP_CIPH_RAND_KEY |
1261                                                      EVP_CIPH_ALWAYS_CALL_INIT | extra_flags)
1262         )
1263         && EVP_CIPHER_meth_set_cleanup(cipher, gost_grasshopper_cipher_cleanup)
1264         && EVP_CIPHER_meth_set_set_asn1_params(cipher,
1265                                                gost_grasshopper_set_asn1_parameters)
1266         && EVP_CIPHER_meth_set_get_asn1_params(cipher,
1267                                                gost_grasshopper_get_asn1_parameters)
1268         && EVP_CIPHER_meth_set_ctrl(cipher, gost_grasshopper_cipher_ctl)
1269         && EVP_CIPHER_meth_set_do_cipher(cipher, gost_grasshopper_cipher_do);
1270 }
1271
1272 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper(uint8_t mode,
1273                                                              uint8_t num)
1274 {
1275     EVP_CIPHER **cipher;
1276     struct GRASSHOPPER_CIPHER_PARAMS *params;
1277
1278     cipher = &gost_grasshopper_ciphers[num];
1279
1280     if (*cipher == NULL) {
1281         params = &gost_cipher_params[num];
1282
1283         int nid = params->nid;
1284         grasshopper_init_cipher_func init_cipher = params->init_cipher;
1285         int block_size = params->block_size;
1286         int ctx_size = params->ctx_size;
1287         int iv_size = params->iv_size;
1288         bool padding = params->padding;
1289
1290                                 int extra_flags = (num == GRASSHOPPER_CIPHER_MGM) ? 
1291                                         EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_AEAD_CIPHER : 0;
1292
1293         *cipher = cipher_gost_grasshopper_create(nid, block_size);
1294         if (*cipher == NULL) {
1295             return NULL;
1296         }
1297
1298         if (!cipher_gost_grasshopper_setup(*cipher, mode, iv_size, padding, extra_flags)
1299             || !EVP_CIPHER_meth_set_init(*cipher, init_cipher)
1300             || !EVP_CIPHER_meth_set_impl_ctx_size(*cipher, ctx_size)) {
1301             EVP_CIPHER_meth_free(*cipher);
1302             *cipher = NULL;
1303         }
1304     }
1305
1306     return *cipher;
1307 }
1308
1309 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ecb()
1310 {
1311     return cipher_gost_grasshopper(EVP_CIPH_ECB_MODE, GRASSHOPPER_CIPHER_ECB);
1312 }
1313
1314 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cbc()
1315 {
1316     return cipher_gost_grasshopper(EVP_CIPH_CBC_MODE, GRASSHOPPER_CIPHER_CBC);
1317 }
1318
1319 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ofb()
1320 {
1321     return cipher_gost_grasshopper(EVP_CIPH_OFB_MODE, GRASSHOPPER_CIPHER_OFB);
1322 }
1323
1324 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cfb()
1325 {
1326     return cipher_gost_grasshopper(EVP_CIPH_CFB_MODE, GRASSHOPPER_CIPHER_CFB);
1327 }
1328
1329 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctr()
1330 {
1331     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_CTR);
1332 }
1333
1334 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctracpkm()
1335 {
1336     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE,
1337                                    GRASSHOPPER_CIPHER_CTRACPKM);
1338 }
1339
1340 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_mgm()
1341 {
1342 #ifndef NID_kuznyechik_mgm
1343                 return NULL;
1344 #else
1345     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_MGM);
1346 #endif
1347 }
1348
1349 void cipher_gost_grasshopper_destroy(void)
1350 {
1351     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB]);
1352     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB] = NULL;
1353     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC]);
1354     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC] = NULL;
1355     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB]);
1356     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB] = NULL;
1357     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB]);
1358     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB] = NULL;
1359     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR]);
1360     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR] = NULL;
1361     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM]);
1362     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM] = NULL;
1363     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM]);
1364     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM] = NULL;
1365 }