]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_grasshopper_cipher.c
Merge branch 'master' of https://github.com/gost-engine/engine
[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 #include <string.h>
15
16 #include "gost_lcl.h"
17 #include "e_gost_err.h"
18
19 enum GRASSHOPPER_CIPHER_TYPE {
20     GRASSHOPPER_CIPHER_ECB = 0,
21     GRASSHOPPER_CIPHER_CBC,
22     GRASSHOPPER_CIPHER_OFB,
23     GRASSHOPPER_CIPHER_CFB,
24     GRASSHOPPER_CIPHER_CTR,
25     GRASSHOPPER_CIPHER_CTRACPKM,
26 };
27
28 static EVP_CIPHER *gost_grasshopper_ciphers[6] = {
29     [GRASSHOPPER_CIPHER_ECB] = NULL,
30     [GRASSHOPPER_CIPHER_CBC] = NULL,
31     [GRASSHOPPER_CIPHER_OFB] = NULL,
32     [GRASSHOPPER_CIPHER_CFB] = NULL,
33     [GRASSHOPPER_CIPHER_CTR] = NULL,
34     [GRASSHOPPER_CIPHER_CTRACPKM] = NULL,
35 };
36
37 static GRASSHOPPER_INLINE void
38 gost_grasshopper_cipher_destroy_ofb(gost_grasshopper_cipher_ctx * c);
39 static GRASSHOPPER_INLINE void
40 gost_grasshopper_cipher_destroy_ctr(gost_grasshopper_cipher_ctx * c);
41
42 struct GRASSHOPPER_CIPHER_PARAMS {
43     int nid;
44     grasshopper_init_cipher_func init_cipher;
45     grasshopper_do_cipher_func do_cipher;
46     grasshopper_destroy_cipher_func destroy_cipher;
47     int block_size;
48     int ctx_size;
49     int iv_size;
50     bool padding;
51 };
52
53 static struct GRASSHOPPER_CIPHER_PARAMS gost_cipher_params[6] = {
54     [GRASSHOPPER_CIPHER_ECB] = {
55                                 NID_grasshopper_ecb,
56                                 gost_grasshopper_cipher_init_ecb,
57                                 gost_grasshopper_cipher_do_ecb,
58                                 NULL,
59                                 16,
60                                 sizeof(gost_grasshopper_cipher_ctx),
61                                 0,
62                                 true}
63     ,
64     [GRASSHOPPER_CIPHER_CBC] = {
65                                 NID_grasshopper_cbc,
66                                 gost_grasshopper_cipher_init_cbc,
67                                 gost_grasshopper_cipher_do_cbc,
68                                 NULL,
69                                 16,
70                                 sizeof(gost_grasshopper_cipher_ctx),
71                                 16,
72                                 true}
73     ,
74     [GRASSHOPPER_CIPHER_OFB] = {
75                                 NID_grasshopper_ofb,
76                                 gost_grasshopper_cipher_init_ofb,
77                                 gost_grasshopper_cipher_do_ofb,
78                                 gost_grasshopper_cipher_destroy_ofb,
79                                 1,
80                                 sizeof(gost_grasshopper_cipher_ctx_ofb),
81                                 16,
82                                 false}
83     ,
84     [GRASSHOPPER_CIPHER_CFB] = {
85                                 NID_grasshopper_cfb,
86                                 gost_grasshopper_cipher_init_cfb,
87                                 gost_grasshopper_cipher_do_cfb,
88                                 NULL,
89                                 1,
90                                 sizeof(gost_grasshopper_cipher_ctx),
91                                 16,
92                                 false}
93     ,
94     [GRASSHOPPER_CIPHER_CTR] = {
95                                 NID_grasshopper_ctr,
96                                 gost_grasshopper_cipher_init_ctr,
97                                 gost_grasshopper_cipher_do_ctr,
98                                 gost_grasshopper_cipher_destroy_ctr,
99                                 1,
100                                 sizeof(gost_grasshopper_cipher_ctx_ctr),
101                                 /* IV size is set to match full block, to make it responsibility of
102                                  * user to assign correct values (IV || 0), and to make naive context
103                                  * copy possible (for software such as openssh) */
104                                 16,
105                                 false}
106     ,
107     [GRASSHOPPER_CIPHER_CTRACPKM] = {
108                                      NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm,
109                                      gost_grasshopper_cipher_init_ctracpkm,
110                                      gost_grasshopper_cipher_do_ctracpkm,
111                                      gost_grasshopper_cipher_destroy_ctr,
112                                      1,
113                                      sizeof(gost_grasshopper_cipher_ctx_ctr),
114                                      16,
115                                      false}
116     ,
117 };
118
119 /* first 256 bit of D from draft-irtf-cfrg-re-keying-12 */
120 static const unsigned char ACPKM_D_2018[] = {
121     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /*  64 bit */
122     0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 128 bit */
123     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
124     0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 256 bit */
125 };
126
127 static void acpkm_next(gost_grasshopper_cipher_ctx * c)
128 {
129     unsigned char newkey[GRASSHOPPER_KEY_SIZE];
130     const int J = GRASSHOPPER_KEY_SIZE / GRASSHOPPER_BLOCK_SIZE;
131     int n;
132
133     for (n = 0; n < J; n++) {
134         const unsigned char *D_n = &ACPKM_D_2018[n * GRASSHOPPER_BLOCK_SIZE];
135
136         grasshopper_encrypt_block(&c->encrypt_round_keys,
137                                   (grasshopper_w128_t *) D_n,
138                                   (grasshopper_w128_t *) & newkey[n *
139                                                                   GRASSHOPPER_BLOCK_SIZE],
140                                   &c->buffer);
141     }
142     gost_grasshopper_cipher_key(c, newkey);
143 }
144
145 /* Set 256 bit  key into context */
146 GRASSHOPPER_INLINE void
147 gost_grasshopper_cipher_key(gost_grasshopper_cipher_ctx * c, const uint8_t *k)
148 {
149     int i;
150     for (i = 0; i < 2; i++) {
151         grasshopper_copy128(&c->key.k.k[i],
152                             (const grasshopper_w128_t *)(k + i * 16));
153     }
154
155     grasshopper_set_encrypt_key(&c->encrypt_round_keys, &c->key);
156     grasshopper_set_decrypt_key(&c->decrypt_round_keys, &c->key);
157 }
158
159 /* Set master 256-bit key to be used in TLSTREE calculation into context */
160 GRASSHOPPER_INLINE void
161 gost_grasshopper_master_key(gost_grasshopper_cipher_ctx * c, const uint8_t *k)
162 {
163     int i;
164     for (i = 0; i < 2; i++) {
165         grasshopper_copy128(&c->master_key.k.k[i],
166                             (const grasshopper_w128_t *)(k + i * 16));
167     }
168 }
169
170 /* Cleans up key from context */
171 GRASSHOPPER_INLINE void
172 gost_grasshopper_cipher_destroy(gost_grasshopper_cipher_ctx * c)
173 {
174     int i;
175     for (i = 0; i < 2; i++) {
176         grasshopper_zero128(&c->key.k.k[i]);
177         grasshopper_zero128(&c->master_key.k.k[i]);
178     }
179     for (i = 0; i < GRASSHOPPER_ROUND_KEYS_COUNT; i++) {
180         grasshopper_zero128(&c->encrypt_round_keys.k[i]);
181     }
182     for (i = 0; i < GRASSHOPPER_ROUND_KEYS_COUNT; i++) {
183         grasshopper_zero128(&c->decrypt_round_keys.k[i]);
184     }
185     grasshopper_zero128(&c->buffer);
186 }
187
188 static GRASSHOPPER_INLINE void
189 gost_grasshopper_cipher_destroy_ofb(gost_grasshopper_cipher_ctx * c)
190 {
191     gost_grasshopper_cipher_ctx_ofb *ctx =
192         (gost_grasshopper_cipher_ctx_ofb *) c;
193
194     grasshopper_zero128(&ctx->buffer1);
195 }
196
197 static GRASSHOPPER_INLINE void
198 gost_grasshopper_cipher_destroy_ctr(gost_grasshopper_cipher_ctx * c)
199 {
200     gost_grasshopper_cipher_ctx_ctr *ctx =
201         (gost_grasshopper_cipher_ctx_ctr *) c;
202
203     grasshopper_zero128(&ctx->partial_buffer);
204 }
205
206 int gost_grasshopper_cipher_init(EVP_CIPHER_CTX *ctx,
207                                  const unsigned char *key,
208                                  const unsigned char *iv, int enc)
209 {
210     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
211
212     if (EVP_CIPHER_CTX_get_app_data(ctx) == NULL) {
213         EVP_CIPHER_CTX_set_app_data(ctx, EVP_CIPHER_CTX_get_cipher_data(ctx));
214     }
215
216     if (key != NULL) {
217         gost_grasshopper_cipher_key(c, key);
218         gost_grasshopper_master_key(c, key);
219     }
220
221     if (iv != NULL) {
222         memcpy((unsigned char *)EVP_CIPHER_CTX_original_iv(ctx), iv,
223                EVP_CIPHER_CTX_iv_length(ctx));
224     }
225
226     memcpy(EVP_CIPHER_CTX_iv_noconst(ctx),
227            EVP_CIPHER_CTX_original_iv(ctx), EVP_CIPHER_CTX_iv_length(ctx));
228
229     grasshopper_zero128(&c->buffer);
230
231     return 1;
232 }
233
234 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ecb(EVP_CIPHER_CTX *ctx, const unsigned char
235                                                         *key, const unsigned char
236                                                         *iv, int enc)
237 {
238     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
239     c->type = GRASSHOPPER_CIPHER_ECB;
240     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
241 }
242
243 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cbc(EVP_CIPHER_CTX *ctx, const unsigned char
244                                                         *key, const unsigned char
245                                                         *iv, int enc)
246 {
247     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
248     c->type = GRASSHOPPER_CIPHER_CBC;
249     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
250 }
251
252 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ofb(EVP_CIPHER_CTX *ctx, const unsigned char
253                                                         *key, const unsigned char
254                                                         *iv, int enc)
255 {
256     gost_grasshopper_cipher_ctx_ofb *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
257
258     c->c.type = GRASSHOPPER_CIPHER_OFB;
259
260     grasshopper_zero128(&c->buffer1);
261
262     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
263 }
264
265 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cfb(EVP_CIPHER_CTX *ctx, const unsigned char
266                                                         *key, const unsigned char
267                                                         *iv, int enc)
268 {
269     gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
270     c->type = GRASSHOPPER_CIPHER_CFB;
271     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
272 }
273
274 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctr(EVP_CIPHER_CTX *ctx, const unsigned char
275                                                         *key, const unsigned char
276                                                         *iv, int enc)
277 {
278     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
279
280     c->c.type = GRASSHOPPER_CIPHER_CTR;
281     EVP_CIPHER_CTX_set_num(ctx, 0);
282
283     grasshopper_zero128(&c->partial_buffer);
284
285     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
286 }
287
288 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctracpkm(EVP_CIPHER_CTX
289                                                              *ctx, const unsigned
290                                                              char *key, const unsigned
291                                                              char *iv, int enc)
292 {
293     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
294
295     /* NB: setting type makes EVP do_cipher callback useless */
296     c->c.type = GRASSHOPPER_CIPHER_CTRACPKM;
297     EVP_CIPHER_CTX_set_num(ctx, 0);
298     c->section_size = 4096;
299
300     return gost_grasshopper_cipher_init(ctx, key, iv, enc);
301 }
302
303 GRASSHOPPER_INLINE int gost_grasshopper_cipher_do(EVP_CIPHER_CTX *ctx,
304                                                   unsigned char *out,
305                                                   const unsigned char *in,
306                                                   size_t inl)
307 {
308     gost_grasshopper_cipher_ctx *c =
309         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
310     struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
311
312     return params->do_cipher(ctx, out, in, inl);
313 }
314
315 int gost_grasshopper_cipher_do_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
316                                    const unsigned char *in, size_t inl)
317 {
318     gost_grasshopper_cipher_ctx *c =
319         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
320     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
321     const unsigned char *current_in = in;
322     unsigned char *current_out = out;
323     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
324     size_t i;
325
326     for (i = 0; i < blocks;
327          i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
328          GRASSHOPPER_BLOCK_SIZE) {
329         if (encrypting) {
330             grasshopper_encrypt_block(&c->encrypt_round_keys,
331                                       (grasshopper_w128_t *) current_in,
332                                       (grasshopper_w128_t *) current_out,
333                                       &c->buffer);
334         } else {
335             grasshopper_decrypt_block(&c->decrypt_round_keys,
336                                       (grasshopper_w128_t *) current_in,
337                                       (grasshopper_w128_t *) current_out,
338                                       &c->buffer);
339         }
340     }
341
342     return 1;
343 }
344
345 int gost_grasshopper_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
346                                    const unsigned char *in, size_t inl)
347 {
348     gost_grasshopper_cipher_ctx *c =
349         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
350     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
351     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
352     const unsigned char *current_in = in;
353     unsigned char *current_out = out;
354     grasshopper_w128_t *currentInputBlock;
355     grasshopper_w128_t *currentOutputBlock;
356     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
357     size_t i;
358     grasshopper_w128_t *currentBlock;
359
360     currentBlock = (grasshopper_w128_t *) iv;
361
362     for (i = 0; i < blocks;
363          i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
364          GRASSHOPPER_BLOCK_SIZE) {
365         currentInputBlock = (grasshopper_w128_t *) current_in;
366         currentOutputBlock = (grasshopper_w128_t *) current_out;
367         if (encrypting) {
368             grasshopper_append128(currentBlock, currentInputBlock);
369             grasshopper_encrypt_block(&c->encrypt_round_keys, currentBlock,
370                                       currentOutputBlock, &c->buffer);
371             grasshopper_copy128(currentBlock, currentOutputBlock);
372         } else {
373             grasshopper_w128_t tmp;
374
375             grasshopper_copy128(&tmp, currentInputBlock);
376             grasshopper_decrypt_block(&c->decrypt_round_keys,
377                                       currentInputBlock, currentOutputBlock,
378                                       &c->buffer);
379             grasshopper_append128(currentOutputBlock, currentBlock);
380             grasshopper_copy128(currentBlock, &tmp);
381         }
382     }
383
384     return 1;
385 }
386
387 void inc_counter(unsigned char *counter, size_t counter_bytes)
388 {
389     unsigned char c;
390     unsigned int n = counter_bytes;
391
392     do {
393         --n;
394         c = counter[n];
395         ++c;
396         counter[n] = c;
397         if (c)
398             return;
399     } while (n);
400 }
401
402 /* increment counter (128-bit int) by 1 */
403 static void ctr128_inc(unsigned char *counter)
404 {
405     inc_counter(counter, 16);
406 }
407
408 int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *out,
409                                    const unsigned char *in, size_t inl)
410 {
411     gost_grasshopper_cipher_ctx_ctr *c = (gost_grasshopper_cipher_ctx_ctr *)
412         EVP_CIPHER_CTX_get_cipher_data(ctx);
413     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
414     const unsigned char *current_in = in;
415     unsigned char *current_out = out;
416     grasshopper_w128_t *currentInputBlock;
417     grasshopper_w128_t *currentOutputBlock;
418     unsigned int n = EVP_CIPHER_CTX_num(ctx);
419     size_t lasted;
420     size_t i;
421
422     while (n && inl) {
423         *(current_out++) = *(current_in++) ^ c->partial_buffer.b[n];
424         --inl;
425         n = (n + 1) % GRASSHOPPER_BLOCK_SIZE;
426     }
427     EVP_CIPHER_CTX_set_num(ctx, n);
428     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
429
430     grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
431     grasshopper_w128_t tmp;
432
433     // full parts
434     for (i = 0; i < blocks; i++) {
435         currentInputBlock = (grasshopper_w128_t *) current_in;
436         currentOutputBlock = (grasshopper_w128_t *) current_out;
437         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
438                                   &c->partial_buffer, &c->c.buffer);
439         grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
440         grasshopper_copy128(currentOutputBlock, &tmp);
441         ctr128_inc(iv_buffer->b);
442         current_in += GRASSHOPPER_BLOCK_SIZE;
443         current_out += GRASSHOPPER_BLOCK_SIZE;
444     }
445
446     // last part
447     lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
448     if (lasted > 0) {
449         currentInputBlock = (grasshopper_w128_t *) current_in;
450         currentOutputBlock = (grasshopper_w128_t *) current_out;
451         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
452                                   &c->partial_buffer, &c->c.buffer);
453         for (i = 0; i < lasted; i++) {
454             currentOutputBlock->b[i] =
455                 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
456         }
457         EVP_CIPHER_CTX_set_num(ctx, i);
458         ctr128_inc(iv_buffer->b);
459     }
460
461     return 1;
462 }
463
464 #define GRASSHOPPER_BLOCK_MASK (GRASSHOPPER_BLOCK_SIZE - 1)
465 static inline void apply_acpkm_grasshopper(gost_grasshopper_cipher_ctx_ctr *
466                                            ctx, unsigned int *num)
467 {
468     if (!ctx->section_size || (*num < ctx->section_size))
469         return;
470     acpkm_next(&ctx->c);
471     *num &= GRASSHOPPER_BLOCK_MASK;
472 }
473
474 /* If meshing is not configured via ctrl (setting section_size)
475  * this function works exactly like plain ctr */
476 int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx,
477                                         unsigned char *out,
478                                         const unsigned char *in, size_t inl)
479 {
480     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
481     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
482     unsigned int num = EVP_CIPHER_CTX_num(ctx);
483
484     while ((num & GRASSHOPPER_BLOCK_MASK) && inl) {
485         *out++ = *in++ ^ c->partial_buffer.b[num & GRASSHOPPER_BLOCK_MASK];
486         --inl;
487         num++;
488     }
489     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
490     size_t i;
491     grasshopper_w128_t tmp;
492
493     // full parts
494     for (i = 0; i < blocks; i++) {
495         apply_acpkm_grasshopper(c, &num);
496         grasshopper_encrypt_block(&c->c.encrypt_round_keys,
497                                   (grasshopper_w128_t *) iv,
498                                   (grasshopper_w128_t *) & c->partial_buffer,
499                                   &c->c.buffer);
500         grasshopper_plus128(&tmp, &c->partial_buffer,
501                             (grasshopper_w128_t *) in);
502         grasshopper_copy128((grasshopper_w128_t *) out, &tmp);
503         ctr128_inc(iv);
504         in += GRASSHOPPER_BLOCK_SIZE;
505         out += GRASSHOPPER_BLOCK_SIZE;
506         num += GRASSHOPPER_BLOCK_SIZE;
507     }
508
509     // last part
510     size_t lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
511     if (lasted > 0) {
512         apply_acpkm_grasshopper(c, &num);
513         grasshopper_encrypt_block(&c->c.encrypt_round_keys,
514                                   (grasshopper_w128_t *) iv,
515                                   &c->partial_buffer, &c->c.buffer);
516         for (i = 0; i < lasted; i++)
517             out[i] = c->partial_buffer.b[i] ^ in[i];
518         ctr128_inc(iv);
519         num += lasted;
520     }
521     EVP_CIPHER_CTX_set_num(ctx, num);
522
523     return 1;
524 }
525
526 /*
527  * Fixed 128-bit IV implementation make shift regiser redundant.
528  */
529 static void gost_grasshopper_cnt_next(gost_grasshopper_cipher_ctx_ofb * ctx,
530                                       grasshopper_w128_t * iv,
531                                       grasshopper_w128_t * buf)
532 {
533     memcpy(&ctx->buffer1, iv, 16);
534     grasshopper_encrypt_block(&ctx->c.encrypt_round_keys, &ctx->buffer1,
535                               buf, &ctx->c.buffer);
536     memcpy(iv, buf, 16);
537 }
538
539 int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
540                                    const unsigned char *in, size_t inl)
541 {
542     gost_grasshopper_cipher_ctx_ofb *c = (gost_grasshopper_cipher_ctx_ofb *)
543         EVP_CIPHER_CTX_get_cipher_data(ctx);
544     const unsigned char *in_ptr = in;
545     unsigned char *out_ptr = out;
546     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
547     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
548     int num = EVP_CIPHER_CTX_num(ctx);
549     size_t i = 0;
550     size_t j;
551
552     /* process partial block if any */
553     if (num > 0) {
554         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
555              j++, i++, in_ptr++, out_ptr++) {
556             *out_ptr = buf[j] ^ (*in_ptr);
557         }
558         if (j == GRASSHOPPER_BLOCK_SIZE) {
559             EVP_CIPHER_CTX_set_num(ctx, 0);
560         } else {
561             EVP_CIPHER_CTX_set_num(ctx, (int)j);
562             return 1;
563         }
564     }
565
566     for (; i + GRASSHOPPER_BLOCK_SIZE <
567          inl;
568          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
569          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
570         /*
571          * block cipher current iv
572          */
573         /* Encrypt */
574         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
575                                   (grasshopper_w128_t *) buf);
576
577         /*
578          * xor next block of input text with it and output it
579          */
580         /*
581          * output this block
582          */
583         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
584             out_ptr[j] = buf[j] ^ in_ptr[j];
585         }
586     }
587
588     /* Process rest of buffer */
589     if (i < inl) {
590         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
591                                   (grasshopper_w128_t *) buf);
592         for (j = 0; i < inl; j++, i++) {
593             out_ptr[j] = buf[j] ^ in_ptr[j];
594         }
595         EVP_CIPHER_CTX_set_num(ctx, (int)j);
596     } else {
597         EVP_CIPHER_CTX_set_num(ctx, 0);
598     }
599
600     return 1;
601 }
602
603 int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
604                                    const unsigned char *in, size_t inl)
605 {
606     gost_grasshopper_cipher_ctx *c =
607         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
608     const unsigned char *in_ptr = in;
609     unsigned char *out_ptr = out;
610     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
611     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
612     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
613     int num = EVP_CIPHER_CTX_num(ctx);
614     size_t i = 0;
615     size_t j = 0;
616
617     /* process partial block if any */
618     if (num > 0) {
619         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
620              j++, i++, in_ptr++, out_ptr++) {
621             if (!encrypting) {
622                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *in_ptr;
623             }
624             *out_ptr = buf[j] ^ (*in_ptr);
625             if (encrypting) {
626                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *out_ptr;
627             }
628         }
629         if (j == GRASSHOPPER_BLOCK_SIZE) {
630             memcpy(iv, buf + GRASSHOPPER_BLOCK_SIZE, GRASSHOPPER_BLOCK_SIZE);
631             EVP_CIPHER_CTX_set_num(ctx, 0);
632         } else {
633             EVP_CIPHER_CTX_set_num(ctx, (int)j);
634             return 1;
635         }
636     }
637
638     for (; i + GRASSHOPPER_BLOCK_SIZE <
639          inl;
640          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
641          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
642         /*
643          * block cipher current iv
644          */
645         grasshopper_encrypt_block(&c->encrypt_round_keys,
646                                   (grasshopper_w128_t *) iv,
647                                   (grasshopper_w128_t *) buf, &c->buffer);
648         /*
649          * xor next block of input text with it and output it
650          */
651         /*
652          * output this block
653          */
654         if (!encrypting) {
655             memcpy(iv, in_ptr, GRASSHOPPER_BLOCK_SIZE);
656         }
657         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
658             out_ptr[j] = buf[j] ^ in_ptr[j];
659         }
660         /* Encrypt */
661         /* Next iv is next block of cipher text */
662         if (encrypting) {
663             memcpy(iv, out_ptr, GRASSHOPPER_BLOCK_SIZE);
664         }
665     }
666
667     /* Process rest of buffer */
668     if (i < inl) {
669         grasshopper_encrypt_block(&c->encrypt_round_keys,
670                                   (grasshopper_w128_t *) iv,
671                                   (grasshopper_w128_t *) buf, &c->buffer);
672         if (!encrypting) {
673             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, in_ptr, inl - i);
674         }
675         for (j = 0; i < inl; j++, i++) {
676             out_ptr[j] = buf[j] ^ in_ptr[j];
677         }
678         EVP_CIPHER_CTX_set_num(ctx, (int)j);
679         if (encrypting) {
680             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, out_ptr, j);
681         }
682     } else {
683         EVP_CIPHER_CTX_set_num(ctx, 0);
684     }
685
686     return 1;
687 }
688
689 int gost_grasshopper_cipher_cleanup(EVP_CIPHER_CTX *ctx)
690 {
691     gost_grasshopper_cipher_ctx *c =
692         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
693
694     if (!c)
695         return 1;
696
697     struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
698
699     gost_grasshopper_cipher_destroy(c);
700     if (params->destroy_cipher != NULL) {
701         params->destroy_cipher(c);
702     }
703
704     EVP_CIPHER_CTX_set_app_data(ctx, NULL);
705
706     return 1;
707 }
708
709 int gost_grasshopper_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
710 {
711     int len = 0;
712     unsigned char *buf = NULL;
713     ASN1_OCTET_STRING *os = NULL;
714
715     os = ASN1_OCTET_STRING_new();
716
717     if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
718         OPENSSL_free(buf);
719         GOSTerr(GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS,
720                 ERR_R_MALLOC_FAILURE);
721         return 0;
722     }
723     OPENSSL_free(buf);
724
725     ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
726     return 1;
727 }
728
729 GRASSHOPPER_INLINE int gost_grasshopper_get_asn1_parameters(EVP_CIPHER_CTX
730                                                             *ctx, ASN1_TYPE
731                                                             *params)
732 {
733     int ret = -1;
734
735     if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
736         return ret;
737     }
738
739     return 1;
740 }
741
742 int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
743                                 void *ptr)
744 {
745     switch (type) {
746     case EVP_CTRL_RAND_KEY:{
747             if (RAND_bytes
748                 ((unsigned char *)ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
749                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_RNG_ERROR);
750                 return -1;
751             }
752             break;
753         }
754     case EVP_CTRL_KEY_MESH:{
755             gost_grasshopper_cipher_ctx_ctr *c =
756                 EVP_CIPHER_CTX_get_cipher_data(ctx);
757             if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKM || !arg
758                 || (arg % GRASSHOPPER_BLOCK_SIZE))
759                 return -1;
760             c->section_size = arg;
761             break;
762         }
763 #ifdef EVP_CTRL_TLS1_2_TLSTREE
764     case EVP_CTRL_TLS1_2_TLSTREE:
765         {
766           unsigned char newkey[32];
767           int mode = EVP_CIPHER_CTX_mode(ctx);
768           static const unsigned char zeroseq[8];
769           gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL;
770           gost_grasshopper_cipher_ctx *c = NULL;
771
772           unsigned char adjusted_iv[16];
773           unsigned char seq[8];
774           int j;
775           if (mode != EVP_CIPH_CTR_MODE)
776             return -1;
777
778           ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *)
779             EVP_CIPHER_CTX_get_cipher_data(ctx);
780           c = &(ctr_ctx->c);
781
782           memcpy(seq, ptr, 8);
783           if (EVP_CIPHER_CTX_encrypting(ctx)) {
784             /*
785              * OpenSSL increments seq after mac calculation.
786              * As we have Mac-Then-Encrypt, we need decrement it here on encryption
787              * to derive the key correctly.
788              * */
789             if (memcmp(seq, zeroseq, 8) != 0)
790             {
791               for(j=7; j>=0; j--)
792               {
793                 if (seq[j] != 0) {seq[j]--; break;}
794                 else seq[j]  = 0xFF;
795               }
796             }
797           }
798           if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey,
799                 (const unsigned char *)seq) > 0) {
800             memset(adjusted_iv, 0, 16);
801             memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8);
802             for(j=7; j>=0; j--)
803             {
804               int adj_byte, carry = 0;
805               adj_byte = adjusted_iv[j]+seq[j]+carry;
806               carry = (adj_byte > 255) ? 1 : 0;
807               adjusted_iv[j] = adj_byte & 0xFF;
808             }
809             EVP_CIPHER_CTX_set_num(ctx, 0);
810             memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16);
811
812             gost_grasshopper_cipher_key(c, newkey);
813             return 1;
814           }
815         }
816         return -1;
817 #endif
818     default:
819         GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
820                 GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
821         return -1;
822     }
823     return 1;
824 }
825
826 GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_create(int
827                                                               cipher_type, int
828                                                               block_size)
829 {
830     return EVP_CIPHER_meth_new(cipher_type, block_size /* block_size */ ,
831                                GRASSHOPPER_KEY_SIZE /* key_size */ );
832 }
833
834 const int cipher_gost_grasshopper_setup(EVP_CIPHER *cipher, uint8_t mode,
835                                         int iv_size, bool padding)
836 {
837     return EVP_CIPHER_meth_set_iv_length(cipher, iv_size)
838         && EVP_CIPHER_meth_set_flags(cipher,
839                                      (unsigned long)(mode |
840                                                      ((!padding) ?
841                                                       EVP_CIPH_NO_PADDING :
842                                                       0) | ((iv_size >
843                                                              0) ?
844                                                             EVP_CIPH_CUSTOM_IV
845                                                             : 0) |
846                                                      EVP_CIPH_RAND_KEY |
847                                                      EVP_CIPH_ALWAYS_CALL_INIT)
848         )
849         && EVP_CIPHER_meth_set_cleanup(cipher, gost_grasshopper_cipher_cleanup)
850         && EVP_CIPHER_meth_set_set_asn1_params(cipher,
851                                                gost_grasshopper_set_asn1_parameters)
852         && EVP_CIPHER_meth_set_get_asn1_params(cipher,
853                                                gost_grasshopper_get_asn1_parameters)
854         && EVP_CIPHER_meth_set_ctrl(cipher, gost_grasshopper_cipher_ctl)
855         && EVP_CIPHER_meth_set_do_cipher(cipher, gost_grasshopper_cipher_do);
856 }
857
858 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper(uint8_t mode,
859                                                              uint8_t num)
860 {
861     EVP_CIPHER **cipher;
862     struct GRASSHOPPER_CIPHER_PARAMS *params;
863
864     cipher = &gost_grasshopper_ciphers[num];
865
866     if (*cipher == NULL) {
867         params = &gost_cipher_params[num];
868
869         int nid = params->nid;
870         grasshopper_init_cipher_func init_cipher = params->init_cipher;
871         int block_size = params->block_size;
872         int ctx_size = params->ctx_size;
873         int iv_size = params->iv_size;
874         bool padding = params->padding;
875
876         *cipher = cipher_gost_grasshopper_create(nid, block_size);
877         if (*cipher == NULL) {
878             return NULL;
879         }
880
881         if (!cipher_gost_grasshopper_setup(*cipher, mode, iv_size, padding)
882             || !EVP_CIPHER_meth_set_init(*cipher, init_cipher)
883             || !EVP_CIPHER_meth_set_impl_ctx_size(*cipher, ctx_size)) {
884             EVP_CIPHER_meth_free(*cipher);
885             *cipher = NULL;
886         }
887     }
888
889     return *cipher;
890 }
891
892 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ecb()
893 {
894     return cipher_gost_grasshopper(EVP_CIPH_ECB_MODE, GRASSHOPPER_CIPHER_ECB);
895 }
896
897 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cbc()
898 {
899     return cipher_gost_grasshopper(EVP_CIPH_CBC_MODE, GRASSHOPPER_CIPHER_CBC);
900 }
901
902 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ofb()
903 {
904     return cipher_gost_grasshopper(EVP_CIPH_OFB_MODE, GRASSHOPPER_CIPHER_OFB);
905 }
906
907 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cfb()
908 {
909     return cipher_gost_grasshopper(EVP_CIPH_CFB_MODE, GRASSHOPPER_CIPHER_CFB);
910 }
911
912 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctr()
913 {
914     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_CTR);
915 }
916
917 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctracpkm()
918 {
919     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE,
920                                    GRASSHOPPER_CIPHER_CTRACPKM);
921 }
922
923 void cipher_gost_grasshopper_destroy(void)
924 {
925     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB]);
926     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB] = NULL;
927     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC]);
928     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC] = NULL;
929     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB]);
930     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB] = NULL;
931     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB]);
932     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB] = NULL;
933     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR]);
934     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR] = NULL;
935     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM]);
936     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM] = NULL;
937 }