]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - gost_grasshopper_cipher.c
No need for special OFB context
[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     grasshopper_w128_t *currentInputBlock;
335     grasshopper_w128_t *currentOutputBlock;
336     size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
337     size_t i;
338     grasshopper_w128_t *currentBlock;
339
340     currentBlock = (grasshopper_w128_t *) iv;
341
342     for (i = 0; i < blocks;
343          i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
344          GRASSHOPPER_BLOCK_SIZE) {
345         currentInputBlock = (grasshopper_w128_t *) current_in;
346         currentOutputBlock = (grasshopper_w128_t *) current_out;
347         if (encrypting) {
348             grasshopper_append128(currentBlock, currentInputBlock);
349             grasshopper_encrypt_block(&c->encrypt_round_keys, currentBlock,
350                                       currentOutputBlock, &c->buffer);
351             grasshopper_copy128(currentBlock, currentOutputBlock);
352         } else {
353             grasshopper_w128_t tmp;
354
355             grasshopper_copy128(&tmp, currentInputBlock);
356             grasshopper_decrypt_block(&c->decrypt_round_keys,
357                                       currentInputBlock, currentOutputBlock,
358                                       &c->buffer);
359             grasshopper_append128(currentOutputBlock, currentBlock);
360             grasshopper_copy128(currentBlock, &tmp);
361         }
362     }
363
364     return 1;
365 }
366
367 void inc_counter(unsigned char *counter, size_t counter_bytes)
368 {
369     unsigned char c;
370     unsigned int n = counter_bytes;
371
372     do {
373         --n;
374         c = counter[n];
375         ++c;
376         counter[n] = c;
377         if (c)
378             return;
379     } while (n);
380 }
381
382 /* increment counter (128-bit int) by 1 */
383 static void ctr128_inc(unsigned char *counter)
384 {
385     inc_counter(counter, 16);
386 }
387
388 int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *out,
389                                    const unsigned char *in, size_t inl)
390 {
391     gost_grasshopper_cipher_ctx_ctr *c = (gost_grasshopper_cipher_ctx_ctr *)
392         EVP_CIPHER_CTX_get_cipher_data(ctx);
393     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
394     const unsigned char *current_in = in;
395     unsigned char *current_out = out;
396     grasshopper_w128_t *currentInputBlock;
397     grasshopper_w128_t *currentOutputBlock;
398     unsigned int n = EVP_CIPHER_CTX_num(ctx);
399     size_t lasted;
400     size_t i;
401     size_t blocks;
402     grasshopper_w128_t *iv_buffer;
403     grasshopper_w128_t tmp;
404
405     while (n && inl) {
406         *(current_out++) = *(current_in++) ^ c->partial_buffer.b[n];
407         --inl;
408         n = (n + 1) % GRASSHOPPER_BLOCK_SIZE;
409     }
410     EVP_CIPHER_CTX_set_num(ctx, n);
411     blocks = inl / GRASSHOPPER_BLOCK_SIZE;
412
413     iv_buffer = (grasshopper_w128_t *) iv;
414
415     // full parts
416     for (i = 0; i < blocks; i++) {
417         currentInputBlock = (grasshopper_w128_t *) current_in;
418         currentOutputBlock = (grasshopper_w128_t *) current_out;
419         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
420                                   &c->partial_buffer, &c->c.buffer);
421         grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
422         grasshopper_copy128(currentOutputBlock, &tmp);
423         ctr128_inc(iv_buffer->b);
424         current_in += GRASSHOPPER_BLOCK_SIZE;
425         current_out += GRASSHOPPER_BLOCK_SIZE;
426     }
427
428     // last part
429     lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
430     if (lasted > 0) {
431         currentInputBlock = (grasshopper_w128_t *) current_in;
432         currentOutputBlock = (grasshopper_w128_t *) current_out;
433         grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
434                                   &c->partial_buffer, &c->c.buffer);
435         for (i = 0; i < lasted; i++) {
436             currentOutputBlock->b[i] =
437                 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
438         }
439         EVP_CIPHER_CTX_set_num(ctx, i);
440         ctr128_inc(iv_buffer->b);
441     }
442
443     return 1;
444 }
445
446 #define GRASSHOPPER_BLOCK_MASK (GRASSHOPPER_BLOCK_SIZE - 1)
447 static inline void apply_acpkm_grasshopper(gost_grasshopper_cipher_ctx_ctr *
448                                            ctx, unsigned int *num)
449 {
450     if (!ctx->section_size || (*num < ctx->section_size))
451         return;
452     acpkm_next(&ctx->c);
453     *num &= GRASSHOPPER_BLOCK_MASK;
454 }
455
456 /* If meshing is not configured via ctrl (setting section_size)
457  * this function works exactly like plain ctr */
458 int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx,
459                                         unsigned char *out,
460                                         const unsigned char *in, size_t inl)
461 {
462     gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
463     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
464     unsigned int num = EVP_CIPHER_CTX_num(ctx);
465     size_t blocks, i, lasted;
466     grasshopper_w128_t tmp;
467
468     while ((num & GRASSHOPPER_BLOCK_MASK) && inl) {
469         *out++ = *in++ ^ c->partial_buffer.b[num & GRASSHOPPER_BLOCK_MASK];
470         --inl;
471         num++;
472     }
473     blocks = inl / GRASSHOPPER_BLOCK_SIZE;
474
475     // full parts
476     for (i = 0; i < blocks; i++) {
477         apply_acpkm_grasshopper(c, &num);
478         grasshopper_encrypt_block(&c->c.encrypt_round_keys,
479                                   (grasshopper_w128_t *) iv,
480                                   (grasshopper_w128_t *) & c->partial_buffer,
481                                   &c->c.buffer);
482         grasshopper_plus128(&tmp, &c->partial_buffer,
483                             (grasshopper_w128_t *) in);
484         grasshopper_copy128((grasshopper_w128_t *) out, &tmp);
485         ctr128_inc(iv);
486         in += GRASSHOPPER_BLOCK_SIZE;
487         out += GRASSHOPPER_BLOCK_SIZE;
488         num += GRASSHOPPER_BLOCK_SIZE;
489     }
490
491     // last part
492     lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
493     if (lasted > 0) {
494         apply_acpkm_grasshopper(c, &num);
495         grasshopper_encrypt_block(&c->c.encrypt_round_keys,
496                                   (grasshopper_w128_t *) iv,
497                                   &c->partial_buffer, &c->c.buffer);
498         for (i = 0; i < lasted; i++)
499             out[i] = c->partial_buffer.b[i] ^ in[i];
500         ctr128_inc(iv);
501         num += lasted;
502     }
503     EVP_CIPHER_CTX_set_num(ctx, num);
504
505     return 1;
506 }
507
508 /*
509  * Fixed 128-bit IV implementation make shift regiser redundant.
510  */
511 static void gost_grasshopper_cnt_next(gost_grasshopper_cipher_ctx * ctx,
512                                       grasshopper_w128_t * iv,
513                                       grasshopper_w128_t * buf)
514 {
515     grasshopper_w128_t tmp;
516     memcpy(&tmp, iv, 16);
517     grasshopper_encrypt_block(&ctx->encrypt_round_keys, &tmp,
518                               buf, &ctx->buffer);
519     memcpy(iv, buf, 16);
520 }
521
522 int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
523                                    const unsigned char *in, size_t inl)
524 {
525     gost_grasshopper_cipher_ctx *c = (gost_grasshopper_cipher_ctx *)
526         EVP_CIPHER_CTX_get_cipher_data(ctx);
527     const unsigned char *in_ptr = in;
528     unsigned char *out_ptr = out;
529     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
530     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
531     int num = EVP_CIPHER_CTX_num(ctx);
532     size_t i = 0;
533     size_t j;
534
535     /* process partial block if any */
536     if (num > 0) {
537         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
538              j++, i++, in_ptr++, out_ptr++) {
539             *out_ptr = buf[j] ^ (*in_ptr);
540         }
541         if (j == GRASSHOPPER_BLOCK_SIZE) {
542             EVP_CIPHER_CTX_set_num(ctx, 0);
543         } else {
544             EVP_CIPHER_CTX_set_num(ctx, (int)j);
545             return 1;
546         }
547     }
548
549     for (; i + GRASSHOPPER_BLOCK_SIZE <
550          inl;
551          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
552          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
553         /*
554          * block cipher current iv
555          */
556         /* Encrypt */
557         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
558                                   (grasshopper_w128_t *) buf);
559
560         /*
561          * xor next block of input text with it and output it
562          */
563         /*
564          * output this block
565          */
566         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
567             out_ptr[j] = buf[j] ^ in_ptr[j];
568         }
569     }
570
571     /* Process rest of buffer */
572     if (i < inl) {
573         gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
574                                   (grasshopper_w128_t *) buf);
575         for (j = 0; i < inl; j++, i++) {
576             out_ptr[j] = buf[j] ^ in_ptr[j];
577         }
578         EVP_CIPHER_CTX_set_num(ctx, (int)j);
579     } else {
580         EVP_CIPHER_CTX_set_num(ctx, 0);
581     }
582
583     return 1;
584 }
585
586 int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
587                                    const unsigned char *in, size_t inl)
588 {
589     gost_grasshopper_cipher_ctx *c =
590         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
591     const unsigned char *in_ptr = in;
592     unsigned char *out_ptr = out;
593     unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
594     unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
595     bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
596     int num = EVP_CIPHER_CTX_num(ctx);
597     size_t i = 0;
598     size_t j = 0;
599
600     /* process partial block if any */
601     if (num > 0) {
602         for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
603              j++, i++, in_ptr++, out_ptr++) {
604             if (!encrypting) {
605                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *in_ptr;
606             }
607             *out_ptr = buf[j] ^ (*in_ptr);
608             if (encrypting) {
609                 buf[j + GRASSHOPPER_BLOCK_SIZE] = *out_ptr;
610             }
611         }
612         if (j == GRASSHOPPER_BLOCK_SIZE) {
613             memcpy(iv, buf + GRASSHOPPER_BLOCK_SIZE, GRASSHOPPER_BLOCK_SIZE);
614             EVP_CIPHER_CTX_set_num(ctx, 0);
615         } else {
616             EVP_CIPHER_CTX_set_num(ctx, (int)j);
617             return 1;
618         }
619     }
620
621     for (; i + GRASSHOPPER_BLOCK_SIZE <
622          inl;
623          i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
624          GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
625         /*
626          * block cipher current iv
627          */
628         grasshopper_encrypt_block(&c->encrypt_round_keys,
629                                   (grasshopper_w128_t *) iv,
630                                   (grasshopper_w128_t *) buf, &c->buffer);
631         /*
632          * xor next block of input text with it and output it
633          */
634         /*
635          * output this block
636          */
637         if (!encrypting) {
638             memcpy(iv, in_ptr, GRASSHOPPER_BLOCK_SIZE);
639         }
640         for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
641             out_ptr[j] = buf[j] ^ in_ptr[j];
642         }
643         /* Encrypt */
644         /* Next iv is next block of cipher text */
645         if (encrypting) {
646             memcpy(iv, out_ptr, GRASSHOPPER_BLOCK_SIZE);
647         }
648     }
649
650     /* Process rest of buffer */
651     if (i < inl) {
652         grasshopper_encrypt_block(&c->encrypt_round_keys,
653                                   (grasshopper_w128_t *) iv,
654                                   (grasshopper_w128_t *) buf, &c->buffer);
655         if (!encrypting) {
656             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, in_ptr, inl - i);
657         }
658         for (j = 0; i < inl; j++, i++) {
659             out_ptr[j] = buf[j] ^ in_ptr[j];
660         }
661         EVP_CIPHER_CTX_set_num(ctx, (int)j);
662         if (encrypting) {
663             memcpy(buf + GRASSHOPPER_BLOCK_SIZE, out_ptr, j);
664         }
665     } else {
666         EVP_CIPHER_CTX_set_num(ctx, 0);
667     }
668
669     return 1;
670 }
671
672 int gost_grasshopper_cipher_cleanup(EVP_CIPHER_CTX *ctx)
673 {
674     struct GRASSHOPPER_CIPHER_PARAMS *params;
675     gost_grasshopper_cipher_ctx *c =
676         (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
677
678     if (!c)
679         return 1;
680
681     params = &gost_cipher_params[c->type];
682
683     gost_grasshopper_cipher_destroy(c);
684     if (params->destroy_cipher != NULL) {
685         params->destroy_cipher(c);
686     }
687
688     EVP_CIPHER_CTX_set_app_data(ctx, NULL);
689
690     return 1;
691 }
692
693 int gost_grasshopper_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
694 {
695     int len = 0;
696     unsigned char *buf = NULL;
697     ASN1_OCTET_STRING *os = NULL;
698
699     os = ASN1_OCTET_STRING_new();
700
701     if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
702         ASN1_OCTET_STRING_free(os);
703         OPENSSL_free(buf);
704         GOSTerr(GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS,
705                 ERR_R_MALLOC_FAILURE);
706         return 0;
707     }
708     OPENSSL_free(buf);
709
710     ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
711     return 1;
712 }
713
714 GRASSHOPPER_INLINE int gost_grasshopper_get_asn1_parameters(EVP_CIPHER_CTX
715                                                             *ctx, ASN1_TYPE
716                                                             *params)
717 {
718     int ret = -1;
719
720     if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
721         return ret;
722     }
723
724     return 1;
725 }
726
727 int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
728                                 void *ptr)
729 {
730     switch (type) {
731     case EVP_CTRL_RAND_KEY:{
732             if (RAND_bytes
733                 ((unsigned char *)ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
734                 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_RNG_ERROR);
735                 return -1;
736             }
737             break;
738         }
739     case EVP_CTRL_KEY_MESH:{
740             gost_grasshopper_cipher_ctx_ctr *c =
741                 EVP_CIPHER_CTX_get_cipher_data(ctx);
742             if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKM || !arg
743                 || (arg % GRASSHOPPER_BLOCK_SIZE))
744                 return -1;
745             c->section_size = arg;
746             break;
747         }
748 #ifdef EVP_CTRL_TLS1_2_TLSTREE
749     case EVP_CTRL_TLS1_2_TLSTREE:
750         {
751           unsigned char newkey[32];
752           int mode = EVP_CIPHER_CTX_mode(ctx);
753           static const unsigned char zeroseq[8];
754           gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL;
755           gost_grasshopper_cipher_ctx *c = NULL;
756
757           unsigned char adjusted_iv[16];
758           unsigned char seq[8];
759           int j, carry;
760           if (mode != EVP_CIPH_CTR_MODE)
761             return -1;
762
763           ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *)
764             EVP_CIPHER_CTX_get_cipher_data(ctx);
765           c = &(ctr_ctx->c);
766
767           memcpy(seq, ptr, 8);
768           if (EVP_CIPHER_CTX_encrypting(ctx)) {
769             /*
770              * OpenSSL increments seq after mac calculation.
771              * As we have Mac-Then-Encrypt, we need decrement it here on encryption
772              * to derive the key correctly.
773              * */
774             if (memcmp(seq, zeroseq, 8) != 0)
775             {
776               for(j=7; j>=0; j--)
777               {
778                 if (seq[j] != 0) {seq[j]--; break;}
779                 else seq[j]  = 0xFF;
780               }
781             }
782           }
783           if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey,
784                 (const unsigned char *)seq) > 0) {
785             memset(adjusted_iv, 0, 16);
786             memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8);
787             for(j=7,carry=0; j>=0; j--)
788             {
789               int adj_byte = adjusted_iv[j]+seq[j]+carry;
790               carry = (adj_byte > 255) ? 1 : 0;
791               adjusted_iv[j] = adj_byte & 0xFF;
792             }
793             EVP_CIPHER_CTX_set_num(ctx, 0);
794             memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16);
795
796             gost_grasshopper_cipher_key(c, newkey);
797             return 1;
798           }
799         }
800         return -1;
801 #endif
802     default:
803         GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
804                 GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
805         return -1;
806     }
807     return 1;
808 }
809
810 GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_create(int
811                                                               cipher_type, int
812                                                               block_size)
813 {
814     return EVP_CIPHER_meth_new(cipher_type, block_size /* block_size */ ,
815                                GRASSHOPPER_KEY_SIZE /* key_size */ );
816 }
817
818 const int cipher_gost_grasshopper_setup(EVP_CIPHER *cipher, uint8_t mode,
819                                         int iv_size, bool padding)
820 {
821     return EVP_CIPHER_meth_set_iv_length(cipher, iv_size)
822         && EVP_CIPHER_meth_set_flags(cipher,
823                                      (unsigned long)(mode |
824                                                      ((!padding) ?
825                                                       EVP_CIPH_NO_PADDING :
826                                                       0) | ((iv_size >
827                                                              0) ?
828                                                             EVP_CIPH_CUSTOM_IV
829                                                             : 0) |
830                                                      EVP_CIPH_RAND_KEY |
831                                                      EVP_CIPH_ALWAYS_CALL_INIT)
832         )
833         && EVP_CIPHER_meth_set_cleanup(cipher, gost_grasshopper_cipher_cleanup)
834         && EVP_CIPHER_meth_set_set_asn1_params(cipher,
835                                                gost_grasshopper_set_asn1_parameters)
836         && EVP_CIPHER_meth_set_get_asn1_params(cipher,
837                                                gost_grasshopper_get_asn1_parameters)
838         && EVP_CIPHER_meth_set_ctrl(cipher, gost_grasshopper_cipher_ctl)
839         && EVP_CIPHER_meth_set_do_cipher(cipher, gost_grasshopper_cipher_do);
840 }
841
842 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper(uint8_t mode,
843                                                              uint8_t num)
844 {
845     EVP_CIPHER **cipher;
846     struct GRASSHOPPER_CIPHER_PARAMS *params;
847
848     cipher = &gost_grasshopper_ciphers[num];
849
850     if (*cipher == NULL) {
851         grasshopper_init_cipher_func init_cipher;
852         int nid, block_size, ctx_size, iv_size;
853         bool padding;
854
855         params = &gost_cipher_params[num];
856
857         nid = params->nid;
858         init_cipher = params->init_cipher;
859         block_size = params->block_size;
860         ctx_size = params->ctx_size;
861         iv_size = params->iv_size;
862         padding = params->padding;
863
864         *cipher = cipher_gost_grasshopper_create(nid, block_size);
865         if (*cipher == NULL) {
866             return NULL;
867         }
868
869         if (!cipher_gost_grasshopper_setup(*cipher, mode, iv_size, padding)
870             || !EVP_CIPHER_meth_set_init(*cipher, init_cipher)
871             || !EVP_CIPHER_meth_set_impl_ctx_size(*cipher, ctx_size)) {
872             EVP_CIPHER_meth_free(*cipher);
873             *cipher = NULL;
874         }
875     }
876
877     return *cipher;
878 }
879
880 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ecb()
881 {
882     return cipher_gost_grasshopper(EVP_CIPH_ECB_MODE, GRASSHOPPER_CIPHER_ECB);
883 }
884
885 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cbc()
886 {
887     return cipher_gost_grasshopper(EVP_CIPH_CBC_MODE, GRASSHOPPER_CIPHER_CBC);
888 }
889
890 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ofb()
891 {
892     return cipher_gost_grasshopper(EVP_CIPH_OFB_MODE, GRASSHOPPER_CIPHER_OFB);
893 }
894
895 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cfb()
896 {
897     return cipher_gost_grasshopper(EVP_CIPH_CFB_MODE, GRASSHOPPER_CIPHER_CFB);
898 }
899
900 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctr()
901 {
902     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_CTR);
903 }
904
905 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctracpkm()
906 {
907     return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE,
908                                    GRASSHOPPER_CIPHER_CTRACPKM);
909 }
910
911 void cipher_gost_grasshopper_destroy(void)
912 {
913     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB]);
914     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB] = NULL;
915     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC]);
916     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC] = NULL;
917     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB]);
918     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB] = NULL;
919     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB]);
920     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB] = NULL;
921     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR]);
922     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR] = NULL;
923     EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM]);
924     gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM] = NULL;
925 }