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