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