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