]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_grasshopper_cipher.c
Debug + formatting
[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
704 /* ======== Here we deal with associated data =========== */
705     if (out == NULL && c->mgm_state == mgm_associated_data) {
706         if (n == 0) {
707             grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
708                                       &c->partial_buffer, &c->c.buffer);
709             memcpy(c->mgm_iv, &c->partial_buffer, GRASSHOPPER_BLOCK_SIZE);
710             hexdump(stderr, "Tag", c->tag, 16);
711         }
712
713         if (rest_len != 0) {
714             /* Finalize partial_data */
715             if (inl + rest_len < GRASSHOPPER_BLOCK_SIZE) {
716                 memcpy(c->mgm_partial_buffer.b + rest_len, current_in, inl);
717                 n += inl;
718                 EVP_CIPHER_CTX_set_num(ctx, n);
719                 return 1;
720             } else {
721                 memcpy(c->mgm_partial_buffer.b + rest_len, current_in,
722                        GRASSHOPPER_BLOCK_SIZE - rest_len);
723
724                 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
725                                           &h, &c->c.buffer);
726                 inc_counter(c->mgm_iv->b, 8);
727
728                 hexdump(stderr, "Hnext", h.b, 16);
729                 hexdump(stderr, "Adata", c->mgm_partial_buffer.b, 16);
730                 /* Galois multiply Hi * Ai */
731                 gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
732
733                 /* XOR to c->tag */
734                 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
735                 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
736                 hexdump(stderr, "Tag", c->tag, 16);
737
738                 current_in += GRASSHOPPER_BLOCK_SIZE - rest_len;
739                 inl -= (GRASSHOPPER_BLOCK_SIZE - rest_len);
740                 n += GRASSHOPPER_BLOCK_SIZE - rest_len;
741             }
742         }
743
744         while (inl >= GRASSHOPPER_BLOCK_SIZE) {
745             currentInputBlock = (grasshopper_w128_t *) current_in;
746
747             grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
748                                       &h, &c->c.buffer);
749             inc_counter(c->mgm_iv->b, 8);
750
751             hexdump(stderr, "Hnext", h.b, 16);
752             hexdump(stderr, "Adata", currentInputBlock->b, 16);
753             /* Galois multiply */
754             gf128_mul_uint64(tmp.q, h.q, currentInputBlock->q);
755
756             /* XOR to c->tag */
757             grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
758             grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
759             hexdump(stderr, "Tag", c->tag, 16);
760
761             current_in += GRASSHOPPER_BLOCK_SIZE;
762             inl -= GRASSHOPPER_BLOCK_SIZE;
763             n += GRASSHOPPER_BLOCK_SIZE;
764         }
765
766         if (inl > 0) {
767             memcpy(c->mgm_partial_buffer.b, current_in, inl);
768             n += inl;
769         }
770
771         EVP_CIPHER_CTX_set_num(ctx, n);
772         return 1;
773     }
774
775     if (out == NULL && in != NULL && inl != 0 && c->mgm_state == mgm_main_data) {
776         GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_DO_MGM, GOST_R_BAD_ORDER);
777         return 0;
778     }
779
780     if (out != NULL && c->mgm_state == mgm_associated_data) {
781         memset(c->mgm_partial_buffer.b + rest_len, 0,
782                GRASSHOPPER_BLOCK_SIZE - rest_len);
783
784         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
785                                   &h, &c->c.buffer);
786         inc_counter(c->mgm_iv->b, 8);
787
788         hexdump(stderr, "Hnext", h.b, 16);
789         hexdump(stderr, "Padded Adata", c->mgm_partial_buffer.b, 16);
790         /* Galois multiply Hi * Ai */
791         gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
792
793         /* XOR to c->tag */
794         grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
795         grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
796         hexdump(stderr, "Tag", c->tag, 16);
797
798         /* We finish processing associated data */
799         /* Pad rest of mgm_partial_buffer */
800         /* Process last block */
801         c->ad_length = n;
802         n = 0;
803         rest_len = 0;
804         EVP_CIPHER_CTX_set_num(ctx, 0);
805         c->mgm_state = mgm_main_data;
806
807         fprintf(stderr, "============= Deal with main data\n");
808     }
809
810 /* ======== Here we deal with main data =========== */
811     if (n == 0) {
812         /* actual IV derived from nonce */
813         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
814                                   &c->partial_buffer, &c->c.buffer);
815         memcpy(iv, c->partial_buffer.b, GRASSHOPPER_BLOCK_SIZE);
816         //hexdump(stderr, "Y1", iv, 16);
817     }
818
819     while (rest_len && inl) {
820         *(current_out++) = *(current_in++) ^ c->partial_buffer.b[rest_len];
821         c->partial_buffer.b[rest_len] = *(current_out - 1);
822
823         --inl;
824         n++;
825         rest_len++;
826         if (rest_len == GRASSHOPPER_BLOCK_SIZE) {
827             rest_len = 0;
828             grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
829                                       &h, &c->c.buffer);
830             inc_counter(c->mgm_iv->b, 8);
831             hexdump(stderr, "Hnext", h.b, 16);
832             hexdump(stderr, "Ciphertext", c->partial_buffer.b, 16);
833             /* Galois multiply Hi * Ai */
834             gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
835
836             /* XOR to c->tag */
837             grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
838             grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
839             hexdump(stderr, "Tag", c->tag, 16);
840         }
841     }
842
843     // full parts
844     for (i = 0; i < blocks; i++) {
845         currentInputBlock = (grasshopper_w128_t *) current_in;
846         currentOutputBlock = (grasshopper_w128_t *) current_out;
847         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
848                                   &c->partial_buffer, &c->c.buffer);
849         grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
850         grasshopper_copy128(currentOutputBlock, &tmp);
851         //hexdump(stderr, "Ciphertext", currentOutputBlock->b, 16);
852
853         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
854                                   &h, &c->c.buffer);
855         inc_counter(c->mgm_iv->b, 8);
856         hexdump(stderr, "Hnext", h.b, 16);
857         hexdump(stderr, "Ciphertext", currentOutputBlock->b, 16);
858         /* Galois multiply Hi * Ai */
859         gf128_mul_uint64(tmp.q, h.q, currentOutputBlock->q);
860
861         /* XOR to c->tag */
862         grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
863         grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
864         hexdump(stderr, "Tag", c->tag, 16);
865
866         ctr128_inc(iv_buffer->b);
867         current_in += GRASSHOPPER_BLOCK_SIZE;
868         current_out += GRASSHOPPER_BLOCK_SIZE;
869         n += GRASSHOPPER_BLOCK_SIZE;
870     }
871
872     EVP_CIPHER_CTX_set_num(ctx, n);
873
874     // last part
875     lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
876     if (lasted > 0) {
877         currentInputBlock = (grasshopper_w128_t *) current_in;
878         currentOutputBlock = (grasshopper_w128_t *) current_out;
879         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
880                                   &c->partial_buffer, &c->c.buffer);
881         for (i = 0; i < lasted; i++) {
882             currentOutputBlock->b[i] =
883                 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
884             c->partial_buffer.b[i] = currentOutputBlock->b[i];
885         }
886         EVP_CIPHER_CTX_set_num(ctx, n + i);
887         ctr128_inc(iv_buffer->b);
888     }
889
890     /* Final step */
891     if (in == NULL && inl == 0) {
892         unsigned char len_buf[16];
893         uint64_t a_len = 0, p_len = 0;
894
895         if (rest_len != 0) {
896             memset(c->partial_buffer.b + rest_len, 0,
897                    GRASSHOPPER_BLOCK_SIZE - rest_len);
898             grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv, &h,
899                                       &c->c.buffer);
900             inc_counter(c->mgm_iv->b, 8);
901             hexdump(stderr, "Hnext", h.b, 16);
902             hexdump(stderr, "Padded ciphertext", c->partial_buffer.b, 16);
903             /* Galois multiply Hi * Ai */
904             gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
905
906             /* XOR to c->tag */
907             grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
908             grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
909             hexdump(stderr, "Tag", c->tag, 16);
910         }
911
912         a_len = c->ad_length << 3;
913         p_len = (c->mgm_state == mgm_associated_data) ? 0 : n << 3;
914
915 #ifdef L_ENDIAN
916         a_len = bswap_64(a_len);
917         p_len = bswap_64(p_len);
918 #endif
919         memset(len_buf, 0, 16);
920
921         memcpy(len_buf, &a_len, sizeof(a_len));
922         memcpy(len_buf + sizeof(a_len), &p_len, sizeof(p_len));
923         grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
924                                   &h, &c->c.buffer);
925
926         hexdump(stderr, "Hlast", h.b, 16);
927         hexdump(stderr, "Lenbuf", len_buf, 16);
928         /* Galois multiply Hi * Ai */
929         gf128_mul_uint64(tmp.q, h.q, (uint64_t *)len_buf);
930
931         /* XOR to c->tag */
932         grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
933         grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
934         hexdump(stderr, "Tag", c->tag, 16);
935
936         /* Final tag calculation */
937         grasshopper_encrypt_block(&c->c.encrypt_round_keys,
938                                   (grasshopper_w128_t *) c->tag,
939                                   (grasshopper_w128_t *) c->final_tag,
940                                   &c->c.buffer);
941     }
942
943     return 1;
944 }
945
946 /*
947  * Fixed 128-bit IV implementation make shift regiser redundant.
948  */
949 static void gost_grasshopper_cnt_next(gost_grasshopper_cipher_ctx_ofb * ctx,
950                                       grasshopper_w128_t * iv,
951                                       grasshopper_w128_t * buf)
952 {
953     memcpy(&ctx->buffer1, iv, 16);
954     grasshopper_encrypt_block(&ctx->c.encrypt_round_keys, &ctx->buffer1,
955                               buf, &ctx->c.buffer);
956     memcpy(iv, buf, 16);
957 }
958
959 int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
960                                    const unsigned char *in, size_t inl)
961 {
962     gost_grasshopper_cipher_ctx_ofb *c = (gost_grasshopper_cipher_ctx_ofb *)
963         EVP_CIPHER_CTX_get_cipher_data(ctx);
964     const unsigned char *in_ptr = in;
965     unsigned char *out_ptr = out;
966     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
967     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
968     int num = EVP_CIPHER_CTX_num(ctx);
969     size_t i = 0;
970     size_t j;
971
972     /* process partial block if any */
973     if (num > 0) {
974         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
975              j++, i++, in_ptr++, out_ptr++) {
976             *out_ptr = buf[j] ^ (*in_ptr);
977         }
978         if (j == GRASSHOPPER_BLOCK_SIZE) {
979             EVP_CIPHER_CTX_set_num(ctx, 0);
980         } else {
981             EVP_CIPHER_CTX_set_num(ctx, (int)j);
982             return 1;
983         }
984     }
985
986     for (; i + GRASSHOPPER_BLOCK_SIZE <
987          inl;
988          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
989          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
990         /*
991          * block cipher current iv
992          */
993         /* Encrypt */
994         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
995                                   (grasshopper_w128_t *) buf);
996
997         /*
998          * xor next block of input text with it and output it
999          */
1000         /*
1001          * output this block
1002          */
1003         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1004             out_ptr[j] = buf[j] ^ in_ptr[j];
1005         }
1006     }
1007
1008     /* Process rest of buffer */
1009     if (i < inl) {
1010         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
1011                                   (grasshopper_w128_t *) buf);
1012         for (j = 0; i < inl; j++, i++) {
1013             out_ptr[j] = buf[j] ^ in_ptr[j];
1014         }
1015         EVP_CIPHER_CTX_set_num(ctx, (int)j);
1016     } else {
1017         EVP_CIPHER_CTX_set_num(ctx, 0);
1018     }
1019
1020     return 1;
1021 }
1022
1023 int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
1024                                    const unsigned char *in, size_t inl)
1025 {
1026     gost_grasshopper_cipher_ctx *c =
1027         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1028     const unsigned char *in_ptr = in;
1029     unsigned char *out_ptr = out;
1030     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
1031     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
1032     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
1033     int num = EVP_CIPHER_CTX_num(ctx);
1034     size_t i = 0;
1035     size_t j = 0;
1036
1037     /* process partial block if any */
1038     if (num > 0) {
1039         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
1040              j++, i++, in_ptr++, out_ptr++) {
1041             if (!encrypting) {
1042                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *in_ptr;
1043             }
1044             *out_ptr = buf[j] ^ (*in_ptr);
1045             if (encrypting) {
1046                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *out_ptr;
1047             }
1048         }
1049         if (j == GRASSHOPPER_BLOCK_SIZE) {
1050             memcpy(iv, buf + GRASSHOPPER_BLOCK_SIZE, GRASSHOPPER_BLOCK_SIZE);
1051             EVP_CIPHER_CTX_set_num(ctx, 0);
1052         } else {
1053             EVP_CIPHER_CTX_set_num(ctx, (int)j);
1054             return 1;
1055         }
1056     }
1057
1058     for (; i + GRASSHOPPER_BLOCK_SIZE <
1059          inl;
1060          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
1061          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
1062         /*
1063          * block cipher current iv
1064          */
1065         grasshopper_encrypt_block(&c->encrypt_round_keys,
1066                                   (grasshopper_w128_t *) iv,
1067                                   (grasshopper_w128_t *) buf, &c->buffer);
1068         /*
1069          * xor next block of input text with it and output it
1070          */
1071         /*
1072          * output this block
1073          */
1074         if (!encrypting) {
1075             memcpy(iv, in_ptr, GRASSHOPPER_BLOCK_SIZE);
1076         }
1077         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1078             out_ptr[j] = buf[j] ^ in_ptr[j];
1079         }
1080         /* Encrypt */
1081         /* Next iv is next block of cipher text */
1082         if (encrypting) {
1083             memcpy(iv, out_ptr, GRASSHOPPER_BLOCK_SIZE);
1084         }
1085     }
1086
1087     /* Process rest of buffer */
1088     if (i < inl) {
1089         grasshopper_encrypt_block(&c->encrypt_round_keys,
1090                                   (grasshopper_w128_t *) iv,
1091                                   (grasshopper_w128_t *) buf, &c->buffer);
1092         if (!encrypting) {
1093             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, in_ptr, inl - i);
1094         }
1095         for (j = 0; i < inl; j++, i++) {
1096             out_ptr[j] = buf[j] ^ in_ptr[j];
1097         }
1098         EVP_CIPHER_CTX_set_num(ctx, (int)j);
1099         if (encrypting) {
1100             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, out_ptr, j);
1101         }
1102     } else {
1103         EVP_CIPHER_CTX_set_num(ctx, 0);
1104     }
1105
1106     return 1;
1107 }
1108
1109 int gost_grasshopper_cipher_cleanup(EVP_CIPHER_CTX *ctx)
1110 {
1111     gost_grasshopper_cipher_ctx *c =
1112         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1113
1114     if (!c)
1115         return 1;
1116
1117     struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
1118
1119     gost_grasshopper_cipher_destroy(c);
1120     if (params->destroy_cipher != NULL) {
1121         params->destroy_cipher(c);
1122     }
1123
1124     EVP_CIPHER_CTX_set_app_data(ctx, NULL);
1125
1126     return 1;
1127 }
1128
1129 int gost_grasshopper_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
1130 {
1131     int len = 0;
1132     unsigned char *buf = NULL;
1133     ASN1_OCTET_STRING *os = NULL;
1134
1135     os = ASN1_OCTET_STRING_new();
1136
1137     if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
1138         OPENSSL_free(buf);
1139         GOSTerr(GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS,
1140                 ERR_R_MALLOC_FAILURE);
1141         return 0;
1142     }
1143     OPENSSL_free(buf);
1144
1145     ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
1146     return 1;
1147 }
1148
1149 GRASSHOPPER_INLINE int gost_grasshopper_get_asn1_parameters(EVP_CIPHER_CTX
1150                                                             *ctx, ASN1_TYPE
1151                                                             *params)
1152 {
1153     int ret = -1;
1154
1155     if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
1156         return ret;
1157     }
1158
1159     return 1;
1160 }
1161
1162 int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
1163                                 void *ptr)
1164 {
1165     switch (type) {
1166     case EVP_CTRL_RAND_KEY:{
1167             if (RAND_bytes
1168                 ((unsigned char *)ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
1169                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_RNG_ERROR);
1170                 return -1;
1171             }
1172             break;
1173         }
1174     case EVP_CTRL_KEY_MESH:{
1175             gost_grasshopper_cipher_ctx_ctr *c =
1176                 EVP_CIPHER_CTX_get_cipher_data(ctx);
1177             if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKM || !arg
1178                 || (arg % GRASSHOPPER_BLOCK_SIZE))
1179                 return -1;
1180             c->section_size = arg;
1181             break;
1182         }
1183 #ifdef EVP_CTRL_TLS1_2_TLSTREE
1184     case EVP_CTRL_TLS1_2_TLSTREE:
1185         {
1186             unsigned char newkey[32];
1187             int mode = EVP_CIPHER_CTX_mode(ctx);
1188             static const unsigned char zeroseq[8];
1189             gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL;
1190             gost_grasshopper_cipher_ctx *c = NULL;
1191
1192             unsigned char adjusted_iv[16];
1193             unsigned char seq[8];
1194             int j;
1195             if (mode != EVP_CIPH_CTR_MODE)
1196                 return -1;
1197
1198             ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *)
1199                 EVP_CIPHER_CTX_get_cipher_data(ctx);
1200             c = &(ctr_ctx->c);
1201
1202             memcpy(seq, ptr, 8);
1203             if (EVP_CIPHER_CTX_encrypting(ctx)) {
1204                 /*
1205                  * OpenSSL increments seq after mac calculation.
1206                  * As we have Mac-Then-Encrypt, we need decrement it here on encryption
1207                  * to derive the key correctly.
1208                  * */
1209                 if (memcmp(seq, zeroseq, 8) != 0) {
1210                     for (j = 7; j >= 0; j--) {
1211                         if (seq[j] != 0) {
1212                             seq[j]--;
1213                             break;
1214                         } else
1215                             seq[j] = 0xFF;
1216                     }
1217                 }
1218             }
1219             if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey,
1220                              (const unsigned char *)seq) > 0) {
1221                 memset(adjusted_iv, 0, 16);
1222                 memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8);
1223                 for (j = 7; j >= 0; j--) {
1224                     int adj_byte, carry = 0;
1225                     adj_byte = adjusted_iv[j] + seq[j] + carry;
1226                     carry = (adj_byte > 255) ? 1 : 0;
1227                     adjusted_iv[j] = adj_byte & 0xFF;
1228                 }
1229                 EVP_CIPHER_CTX_set_num(ctx, 0);
1230                 memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16);
1231
1232                 gost_grasshopper_cipher_key(c, newkey);
1233                 return 1;
1234             }
1235         }
1236         return -1;
1237 #endif
1238     case EVP_CTRL_AEAD_GET_TAG:
1239     case EVP_CTRL_AEAD_SET_TAG:
1240         {
1241             gost_grasshopper_cipher_ctx_mgm *mgm_ctx = NULL;
1242             gost_grasshopper_cipher_ctx *c = NULL;
1243             int taglen = arg;
1244             unsigned char *tag = ptr;
1245
1246             mgm_ctx = (gost_grasshopper_cipher_ctx_mgm *)
1247                 EVP_CIPHER_CTX_get_cipher_data(ctx);
1248             c = (gost_grasshopper_cipher_ctx *) mgm_ctx;
1249
1250             if (c->type != GRASSHOPPER_CIPHER_MGM)
1251                 return -1;
1252
1253             if (taglen > 16) {
1254                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1255                         GOST_R_INVALID_TAG_LENGTH);
1256                 return -1;
1257             }
1258
1259             if (type == EVP_CTRL_AEAD_GET_TAG)
1260                 memcpy(tag, mgm_ctx->final_tag, taglen);
1261             else
1262                 memcpy(mgm_ctx->final_tag, tag, taglen);
1263
1264             return 1;
1265         }
1266     default:
1267         GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1268                 GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
1269         return -1;
1270     }
1271     return 1;
1272 }
1273
1274 GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_create(int
1275                                                               cipher_type, int
1276                                                               block_size)
1277 {
1278     return EVP_CIPHER_meth_new(cipher_type, block_size /* block_size */ ,
1279                                GRASSHOPPER_KEY_SIZE /* key_size */ );
1280 }
1281
1282 const int cipher_gost_grasshopper_setup(EVP_CIPHER *cipher, uint8_t mode,
1283                                         int iv_size, bool padding,
1284                                         int extra_flags)
1285 {
1286     return EVP_CIPHER_meth_set_iv_length(cipher, iv_size)
1287         && EVP_CIPHER_meth_set_flags(cipher,
1288                                      (unsigned long)(mode |
1289                                                      ((!padding) ?
1290                                                       EVP_CIPH_NO_PADDING :
1291                                                       0) | ((iv_size >
1292                                                              0) ?
1293                                                             EVP_CIPH_CUSTOM_IV
1294                                                             : 0) |
1295                                                      EVP_CIPH_RAND_KEY |
1296                                                      EVP_CIPH_ALWAYS_CALL_INIT |
1297                                                      extra_flags)
1298         )
1299         && EVP_CIPHER_meth_set_cleanup(cipher, gost_grasshopper_cipher_cleanup)
1300         && EVP_CIPHER_meth_set_set_asn1_params(cipher,
1301                                                gost_grasshopper_set_asn1_parameters)
1302         && EVP_CIPHER_meth_set_get_asn1_params(cipher,
1303                                                gost_grasshopper_get_asn1_parameters)
1304         && EVP_CIPHER_meth_set_ctrl(cipher, gost_grasshopper_cipher_ctl)
1305         && EVP_CIPHER_meth_set_do_cipher(cipher, gost_grasshopper_cipher_do);
1306 }
1307
1308 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper(uint8_t mode,
1309                                                              uint8_t num)
1310 {
1311     EVP_CIPHER **cipher;
1312     struct GRASSHOPPER_CIPHER_PARAMS *params;
1313
1314     cipher = &gost_grasshopper_ciphers[num];
1315
1316     if (*cipher == NULL) {
1317         params = &gost_cipher_params[num];
1318
1319         int nid = params->nid;
1320         grasshopper_init_cipher_func init_cipher = params->init_cipher;
1321         int block_size = params->block_size;
1322         int ctx_size = params->ctx_size;
1323         int iv_size = params->iv_size;
1324         bool padding = params->padding;
1325
1326         int extra_flags = (num == GRASSHOPPER_CIPHER_MGM) ?
1327             EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_AEAD_CIPHER : 0;
1328
1329         *cipher = cipher_gost_grasshopper_create(nid, block_size);
1330         if (*cipher == NULL) {
1331             return NULL;
1332         }
1333
1334         if (!cipher_gost_grasshopper_setup
1335             (*cipher, mode, iv_size, padding, extra_flags)
1336             || !EVP_CIPHER_meth_set_init(*cipher, init_cipher)
1337             || !EVP_CIPHER_meth_set_impl_ctx_size(*cipher, ctx_size)) {
1338             EVP_CIPHER_meth_free(*cipher);
1339             *cipher = NULL;
1340         }
1341     }
1342
1343     return *cipher;
1344 }
1345
1346 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ecb()
1347 {
1348     return cipher_gost_grasshopper(EVP_CIPH_ECB_MODE, GRASSHOPPER_CIPHER_ECB);
1349 }
1350
1351 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cbc()
1352 {
1353     return cipher_gost_grasshopper(EVP_CIPH_CBC_MODE, GRASSHOPPER_CIPHER_CBC);
1354 }
1355
1356 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ofb()
1357 {
1358     return cipher_gost_grasshopper(EVP_CIPH_OFB_MODE, GRASSHOPPER_CIPHER_OFB);
1359 }
1360
1361 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cfb()
1362 {
1363     return cipher_gost_grasshopper(EVP_CIPH_CFB_MODE, GRASSHOPPER_CIPHER_CFB);
1364 }
1365
1366 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctr()
1367 {
1368     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_CTR);
1369 }
1370
1371 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctracpkm()
1372 {
1373     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE,
1374                                    GRASSHOPPER_CIPHER_CTRACPKM);
1375 }
1376
1377 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_mgm()
1378 {
1379 #ifndef NID_kuznyechik_mgm
1380     return NULL;
1381 #else
1382     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_MGM);
1383 #endif
1384 }
1385
1386 void cipher_gost_grasshopper_destroy(void)
1387 {
1388     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB]);
1389     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB] = NULL;
1390     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC]);
1391     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC] = NULL;
1392     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB]);
1393     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB] = NULL;
1394     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB]);
1395     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB] = NULL;
1396     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR]);
1397     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR] = NULL;
1398     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM]);
1399     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM] = NULL;
1400     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM]);
1401     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM] = NULL;
1402 }