3 * This file is distributed under the same license as OpenSSL
6 #include "gost_grasshopper_cipher.h"
7 #include "gost_grasshopper_defines.h"
8 #include "gost_grasshopper_math.h"
9 #include "gost_grasshopper_core.h"
11 #include <openssl/evp.h>
12 #include <openssl/rand.h>
13 #include <openssl/err.h>
19 #include "e_gost_err.h"
21 enum GRASSHOPPER_CIPHER_TYPE {
22 GRASSHOPPER_CIPHER_ECB = 0,
23 GRASSHOPPER_CIPHER_CBC,
24 GRASSHOPPER_CIPHER_OFB,
25 GRASSHOPPER_CIPHER_CFB,
26 GRASSHOPPER_CIPHER_CTR,
27 GRASSHOPPER_CIPHER_CTRACPKM,
28 GRASSHOPPER_CIPHER_MGM,
31 static EVP_CIPHER *gost_grasshopper_ciphers[7] = {
32 [GRASSHOPPER_CIPHER_ECB] = NULL,
33 [GRASSHOPPER_CIPHER_CBC] = NULL,
34 [GRASSHOPPER_CIPHER_OFB] = NULL,
35 [GRASSHOPPER_CIPHER_CFB] = NULL,
36 [GRASSHOPPER_CIPHER_CTR] = NULL,
37 [GRASSHOPPER_CIPHER_CTRACPKM] = NULL,
38 [GRASSHOPPER_CIPHER_MGM] = NULL,
41 static GRASSHOPPER_INLINE void
42 gost_grasshopper_cipher_destroy_ofb(gost_grasshopper_cipher_ctx * c);
43 static GRASSHOPPER_INLINE void
44 gost_grasshopper_cipher_destroy_ctr(gost_grasshopper_cipher_ctx * c);
45 static GRASSHOPPER_INLINE void
46 gost_grasshopper_cipher_destroy_mgm(gost_grasshopper_cipher_ctx * c);
48 struct GRASSHOPPER_CIPHER_PARAMS {
50 grasshopper_init_cipher_func init_cipher;
51 grasshopper_do_cipher_func do_cipher;
52 grasshopper_destroy_cipher_func destroy_cipher;
59 static struct GRASSHOPPER_CIPHER_PARAMS gost_cipher_params[7] = {
60 [GRASSHOPPER_CIPHER_ECB] = {
62 gost_grasshopper_cipher_init_ecb,
63 gost_grasshopper_cipher_do_ecb,
66 sizeof(gost_grasshopper_cipher_ctx),
70 [GRASSHOPPER_CIPHER_CBC] = {
72 gost_grasshopper_cipher_init_cbc,
73 gost_grasshopper_cipher_do_cbc,
76 sizeof(gost_grasshopper_cipher_ctx),
80 [GRASSHOPPER_CIPHER_OFB] = {
82 gost_grasshopper_cipher_init_ofb,
83 gost_grasshopper_cipher_do_ofb,
84 gost_grasshopper_cipher_destroy_ofb,
86 sizeof(gost_grasshopper_cipher_ctx_ofb),
90 [GRASSHOPPER_CIPHER_CFB] = {
92 gost_grasshopper_cipher_init_cfb,
93 gost_grasshopper_cipher_do_cfb,
96 sizeof(gost_grasshopper_cipher_ctx),
100 [GRASSHOPPER_CIPHER_CTR] = {
102 gost_grasshopper_cipher_init_ctr,
103 gost_grasshopper_cipher_do_ctr,
104 gost_grasshopper_cipher_destroy_ctr,
106 sizeof(gost_grasshopper_cipher_ctx_ctr),
107 /* IV size is set to match full block, to make it responsibility of
108 * user to assign correct values (IV || 0), and to make naive context
109 * copy possible (for software such as openssh) */
113 [GRASSHOPPER_CIPHER_CTRACPKM] = {
114 NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm,
115 gost_grasshopper_cipher_init_ctracpkm,
116 gost_grasshopper_cipher_do_ctracpkm,
117 gost_grasshopper_cipher_destroy_ctr,
119 sizeof(gost_grasshopper_cipher_ctx_ctr),
123 #ifdef NID_kuznyechik_mgm
124 [GRASSHOPPER_CIPHER_MGM] = {
126 gost_grasshopper_cipher_init_mgm,
127 gost_grasshopper_cipher_do_mgm,
128 gost_grasshopper_cipher_destroy_mgm,
130 sizeof(gost_grasshopper_cipher_ctx_mgm),
135 [GRASSHOPPER_CIPHER_MGM] = {
148 /* first 256 bit of D from draft-irtf-cfrg-re-keying-12 */
149 static const unsigned char ACPKM_D_2018[] = {
150 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 64 bit */
151 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 128 bit */
152 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
153 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 256 bit */
156 static void acpkm_next(gost_grasshopper_cipher_ctx * c)
158 unsigned char newkey[GRASSHOPPER_KEY_SIZE];
159 const int J = GRASSHOPPER_KEY_SIZE / GRASSHOPPER_BLOCK_SIZE;
162 for (n = 0; n < J; n++) {
163 const unsigned char *D_n = &ACPKM_D_2018[n * GRASSHOPPER_BLOCK_SIZE];
165 grasshopper_encrypt_block(&c->encrypt_round_keys,
166 (grasshopper_w128_t *) D_n,
167 (grasshopper_w128_t *) & newkey[n *
168 GRASSHOPPER_BLOCK_SIZE],
171 gost_grasshopper_cipher_key(c, newkey);
174 /* Set 256 bit key into context */
175 GRASSHOPPER_INLINE void
176 gost_grasshopper_cipher_key(gost_grasshopper_cipher_ctx * c, const uint8_t *k)
179 for (i = 0; i < 2; i++) {
180 grasshopper_copy128(&c->key.k.k[i],
181 (const grasshopper_w128_t *)(k + i * 16));
184 grasshopper_set_encrypt_key(&c->encrypt_round_keys, &c->key);
185 grasshopper_set_decrypt_key(&c->decrypt_round_keys, &c->key);
188 /* Set master 256-bit key to be used in TLSTREE calculation into context */
189 GRASSHOPPER_INLINE void
190 gost_grasshopper_master_key(gost_grasshopper_cipher_ctx * c, const uint8_t *k)
193 for (i = 0; i < 2; i++) {
194 grasshopper_copy128(&c->master_key.k.k[i],
195 (const grasshopper_w128_t *)(k + i * 16));
199 /* Cleans up key from context */
200 GRASSHOPPER_INLINE void
201 gost_grasshopper_cipher_destroy(gost_grasshopper_cipher_ctx * c)
204 for (i = 0; i < 2; i++) {
205 grasshopper_zero128(&c->key.k.k[i]);
206 grasshopper_zero128(&c->master_key.k.k[i]);
208 for (i = 0; i < GRASSHOPPER_ROUND_KEYS_COUNT; i++) {
209 grasshopper_zero128(&c->encrypt_round_keys.k[i]);
211 for (i = 0; i < GRASSHOPPER_ROUND_KEYS_COUNT; i++) {
212 grasshopper_zero128(&c->decrypt_round_keys.k[i]);
214 grasshopper_zero128(&c->buffer);
217 static GRASSHOPPER_INLINE void
218 gost_grasshopper_cipher_destroy_ofb(gost_grasshopper_cipher_ctx * c)
220 gost_grasshopper_cipher_ctx_ofb *ctx =
221 (gost_grasshopper_cipher_ctx_ofb *) c;
223 grasshopper_zero128(&ctx->buffer1);
226 static GRASSHOPPER_INLINE void
227 gost_grasshopper_cipher_destroy_ctr(gost_grasshopper_cipher_ctx * c)
229 gost_grasshopper_cipher_ctx_ctr *ctx =
230 (gost_grasshopper_cipher_ctx_ctr *) c;
232 grasshopper_zero128(&ctx->partial_buffer);
235 static GRASSHOPPER_INLINE void
236 gost_grasshopper_cipher_destroy_mgm(gost_grasshopper_cipher_ctx * c)
238 gost_grasshopper_cipher_ctx_mgm *ctx =
239 (gost_grasshopper_cipher_ctx_mgm *) c;
241 grasshopper_zero128(&ctx->partial_buffer);
244 int gost_grasshopper_cipher_init(EVP_CIPHER_CTX *ctx,
245 const unsigned char *key,
246 const unsigned char *iv, int enc)
248 gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
250 if (EVP_CIPHER_CTX_get_app_data(ctx) == NULL) {
251 EVP_CIPHER_CTX_set_app_data(ctx, EVP_CIPHER_CTX_get_cipher_data(ctx));
255 gost_grasshopper_cipher_key(c, key);
256 gost_grasshopper_master_key(c, key);
260 if (c->type == GRASSHOPPER_CIPHER_MGM) {
261 gost_grasshopper_cipher_ctx_mgm *m = (gost_grasshopper_cipher_ctx_mgm *)c;
263 /* 1st bit should be 0*/
265 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_INIT, GOST_R_INVALID_IV_LENGTH);
268 memcpy(m->mgm_iv, iv, 16);
269 *(unsigned char *)(m->mgm_iv) += 128;
271 memcpy((unsigned char *)EVP_CIPHER_CTX_original_iv(ctx), iv,
272 EVP_CIPHER_CTX_iv_length(ctx));
275 memcpy(EVP_CIPHER_CTX_iv_noconst(ctx),
276 EVP_CIPHER_CTX_original_iv(ctx), EVP_CIPHER_CTX_iv_length(ctx));
278 grasshopper_zero128(&c->buffer);
283 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ecb(EVP_CIPHER_CTX *ctx, const unsigned char
284 *key, const unsigned char
287 gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
288 c->type = GRASSHOPPER_CIPHER_ECB;
289 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
292 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cbc(EVP_CIPHER_CTX *ctx, const unsigned char
293 *key, const unsigned char
296 gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
297 c->type = GRASSHOPPER_CIPHER_CBC;
298 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
301 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ofb(EVP_CIPHER_CTX *ctx, const unsigned char
302 *key, const unsigned char
305 gost_grasshopper_cipher_ctx_ofb *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
307 c->c.type = GRASSHOPPER_CIPHER_OFB;
309 grasshopper_zero128(&c->buffer1);
311 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
314 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cfb(EVP_CIPHER_CTX *ctx, const unsigned char
315 *key, const unsigned char
318 gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
319 c->type = GRASSHOPPER_CIPHER_CFB;
320 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
323 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctr(EVP_CIPHER_CTX *ctx, const unsigned char
324 *key, const unsigned char
327 gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
329 c->c.type = GRASSHOPPER_CIPHER_CTR;
330 EVP_CIPHER_CTX_set_num(ctx, 0);
332 grasshopper_zero128(&c->partial_buffer);
334 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
337 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctracpkm(EVP_CIPHER_CTX
339 char *key, const unsigned
342 gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
344 /* NB: setting type makes EVP do_cipher callback useless */
345 c->c.type = GRASSHOPPER_CIPHER_CTRACPKM;
346 EVP_CIPHER_CTX_set_num(ctx, 0);
347 c->section_size = 4096;
349 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
352 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_mgm(EVP_CIPHER_CTX *ctx, const unsigned char
353 *key, const unsigned char
356 gost_grasshopper_cipher_ctx_mgm *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
358 c->c.type = GRASSHOPPER_CIPHER_MGM;
360 EVP_CIPHER_CTX_set_num(ctx, 0);
362 grasshopper_zero128(&c->partial_buffer);
364 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
367 GRASSHOPPER_INLINE int gost_grasshopper_cipher_do(EVP_CIPHER_CTX *ctx,
369 const unsigned char *in,
372 gost_grasshopper_cipher_ctx *c =
373 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
374 struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
376 return params->do_cipher(ctx, out, in, inl);
379 int gost_grasshopper_cipher_do_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
380 const unsigned char *in, size_t inl)
382 gost_grasshopper_cipher_ctx *c =
383 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
384 bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
385 const unsigned char *current_in = in;
386 unsigned char *current_out = out;
387 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
390 for (i = 0; i < blocks;
391 i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
392 GRASSHOPPER_BLOCK_SIZE) {
394 grasshopper_encrypt_block(&c->encrypt_round_keys,
395 (grasshopper_w128_t *) current_in,
396 (grasshopper_w128_t *) current_out,
399 grasshopper_decrypt_block(&c->decrypt_round_keys,
400 (grasshopper_w128_t *) current_in,
401 (grasshopper_w128_t *) current_out,
409 int gost_grasshopper_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
410 const unsigned char *in, size_t inl)
412 gost_grasshopper_cipher_ctx *c =
413 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
414 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
415 bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
416 const unsigned char *current_in = in;
417 unsigned char *current_out = out;
418 grasshopper_w128_t *currentInputBlock;
419 grasshopper_w128_t *currentOutputBlock;
420 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
422 grasshopper_w128_t *currentBlock;
424 currentBlock = (grasshopper_w128_t *) iv;
426 for (i = 0; i < blocks;
427 i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
428 GRASSHOPPER_BLOCK_SIZE) {
429 currentInputBlock = (grasshopper_w128_t *) current_in;
430 currentOutputBlock = (grasshopper_w128_t *) current_out;
432 grasshopper_append128(currentBlock, currentInputBlock);
433 grasshopper_encrypt_block(&c->encrypt_round_keys, currentBlock,
434 currentOutputBlock, &c->buffer);
435 grasshopper_copy128(currentBlock, currentOutputBlock);
437 grasshopper_w128_t tmp;
439 grasshopper_copy128(&tmp, currentInputBlock);
440 grasshopper_decrypt_block(&c->decrypt_round_keys,
441 currentInputBlock, currentOutputBlock,
443 grasshopper_append128(currentOutputBlock, currentBlock);
444 grasshopper_copy128(currentBlock, &tmp);
451 void inc_counter(unsigned char *counter, size_t counter_bytes)
454 unsigned int n = counter_bytes;
466 /* increment counter (128-bit int) by 1 */
467 static void ctr128_inc(unsigned char *counter)
469 inc_counter(counter, 16);
472 int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *out,
473 const unsigned char *in, size_t inl)
475 gost_grasshopper_cipher_ctx_ctr *c = (gost_grasshopper_cipher_ctx_ctr *)
476 EVP_CIPHER_CTX_get_cipher_data(ctx);
477 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
478 const unsigned char *current_in = in;
479 unsigned char *current_out = out;
480 grasshopper_w128_t *currentInputBlock;
481 grasshopper_w128_t *currentOutputBlock;
482 unsigned int n = EVP_CIPHER_CTX_num(ctx);
487 *(current_out++) = *(current_in++) ^ c->partial_buffer.b[n];
489 n = (n + 1) % GRASSHOPPER_BLOCK_SIZE;
491 EVP_CIPHER_CTX_set_num(ctx, n);
492 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
494 grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
495 grasshopper_w128_t tmp;
498 for (i = 0; i < blocks; i++) {
499 currentInputBlock = (grasshopper_w128_t *) current_in;
500 currentOutputBlock = (grasshopper_w128_t *) current_out;
501 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
502 &c->partial_buffer, &c->c.buffer);
503 grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
504 grasshopper_copy128(currentOutputBlock, &tmp);
505 ctr128_inc(iv_buffer->b);
506 current_in += GRASSHOPPER_BLOCK_SIZE;
507 current_out += GRASSHOPPER_BLOCK_SIZE;
511 lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
513 currentInputBlock = (grasshopper_w128_t *) current_in;
514 currentOutputBlock = (grasshopper_w128_t *) current_out;
515 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
516 &c->partial_buffer, &c->c.buffer);
517 for (i = 0; i < lasted; i++) {
518 currentOutputBlock->b[i] =
519 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
521 EVP_CIPHER_CTX_set_num(ctx, i);
522 ctr128_inc(iv_buffer->b);
528 #define GRASSHOPPER_BLOCK_MASK (GRASSHOPPER_BLOCK_SIZE - 1)
529 static inline void apply_acpkm_grasshopper(gost_grasshopper_cipher_ctx_ctr *
530 ctx, unsigned int *num)
532 if (!ctx->section_size || (*num < ctx->section_size))
535 *num &= GRASSHOPPER_BLOCK_MASK;
538 /* If meshing is not configured via ctrl (setting section_size)
539 * this function works exactly like plain ctr */
540 int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx,
542 const unsigned char *in, size_t inl)
544 gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
545 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
546 unsigned int num = EVP_CIPHER_CTX_num(ctx);
548 while ((num & GRASSHOPPER_BLOCK_MASK) && inl) {
549 *out++ = *in++ ^ c->partial_buffer.b[num & GRASSHOPPER_BLOCK_MASK];
553 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
555 grasshopper_w128_t tmp;
558 for (i = 0; i < blocks; i++) {
559 apply_acpkm_grasshopper(c, &num);
560 grasshopper_encrypt_block(&c->c.encrypt_round_keys,
561 (grasshopper_w128_t *) iv,
562 (grasshopper_w128_t *) & c->partial_buffer,
564 grasshopper_plus128(&tmp, &c->partial_buffer,
565 (grasshopper_w128_t *) in);
566 grasshopper_copy128((grasshopper_w128_t *) out, &tmp);
568 in += GRASSHOPPER_BLOCK_SIZE;
569 out += GRASSHOPPER_BLOCK_SIZE;
570 num += GRASSHOPPER_BLOCK_SIZE;
574 size_t lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
576 apply_acpkm_grasshopper(c, &num);
577 grasshopper_encrypt_block(&c->c.encrypt_round_keys,
578 (grasshopper_w128_t *) iv,
579 &c->partial_buffer, &c->c.buffer);
580 for (i = 0; i < lasted; i++)
581 out[i] = c->partial_buffer.b[i] ^ in[i];
585 EVP_CIPHER_CTX_set_num(ctx, num);
590 /* ----------------------------------------------------------------------------------------------- */
591 /*! Функция реализует операцию умножения двух элементов конечного поля \f$ \mathbb F_{2^{128}}\f$,
592 порожденного неприводимым многочленом
593 \f$ f(x) = x^{128} + x^7 + x^2 + x + 1 \in \mathbb F_2[x]\f$. Для умножения используется
594 простейшая реализация, основанная на приведении по модулю после каждого шага алгоритма. */
595 /* ----------------------------------------------------------------------------------------------- */
596 static void gf128_mul_uint64(uint64_t *z, uint64_t *x, uint64_t *y)
601 BUF_reverse((unsigned char *)x, NULL, 16);
602 BUF_reverse((unsigned char *)y, NULL, 16);
612 memset(z, 0, sizeof(uint64_t)*2);
621 for( i = 0; i < 64; i++ ) {
622 if( t&0x1 ) { z[0] ^= s0; z[1] ^= s1; }
625 s1 <<= 1; s1 ^= ( s0 >> 63 ); s0 <<= 1;
636 for( i = 0; i < 63; i++ ) {
637 if( t&0x1 ) { z[0] ^= s0; z[1] ^= s1; }
640 s1 <<= 1; s1 ^= ( s0 >> 63 ); s0 <<= 1;
649 z[0] = bswap_64(z[0]);
650 z[1] = bswap_64(z[1]);
652 BUF_reverse((unsigned char *)z, NULL, 16);
655 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
659 fprintf(f, "%s", title);
662 fprintf(f, "\n%04x", n);
663 fprintf(f, " %02x", s[n]);
668 int gost_grasshopper_cipher_do_mgm(EVP_CIPHER_CTX *ctx, unsigned char *out,
669 const unsigned char *in, size_t inl)
671 gost_grasshopper_cipher_ctx_mgm *c = (gost_grasshopper_cipher_ctx_mgm *)
672 EVP_CIPHER_CTX_get_cipher_data(ctx);
673 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
674 const unsigned char *current_in = in;
675 unsigned char *current_out = out;
676 grasshopper_w128_t *currentInputBlock;
677 grasshopper_w128_t *currentOutputBlock;
678 unsigned int n = EVP_CIPHER_CTX_num(ctx);
682 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
683 int rest_len = n % GRASSHOPPER_BLOCK_SIZE;
684 grasshopper_w128_t h;
686 grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
687 grasshopper_w128_t tmp;
689 /* ======== Here we deal with associated data =========== */
690 if (out == NULL && c->mgm_state == mgm_associated_data) {
692 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
693 &c->partial_buffer, &c->c.buffer);
694 memcpy(c->mgm_iv, &c->partial_buffer, GRASSHOPPER_BLOCK_SIZE);
695 hexdump(stderr, "Tag", c->tag, 16);
699 /* Finalize partial_data */
700 if (inl + rest_len < GRASSHOPPER_BLOCK_SIZE) {
701 memcpy(c->mgm_partial_buffer.b+rest_len, current_in, inl);
703 EVP_CIPHER_CTX_set_num(ctx, n);
706 memcpy(c->mgm_partial_buffer.b+rest_len, current_in, GRASSHOPPER_BLOCK_SIZE - rest_len);
708 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
710 inc_counter(c->mgm_iv->b, 8);
712 hexdump(stderr, "Hnext", h.b, 16);
713 hexdump(stderr, "Adata", c->mgm_partial_buffer.b, 16);
714 /* Galois multiply Hi * Ai */
715 gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
718 grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
719 grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
720 hexdump(stderr, "Tag", c->tag, 16);
722 current_in += GRASSHOPPER_BLOCK_SIZE - rest_len;
723 inl -= (GRASSHOPPER_BLOCK_SIZE - rest_len);
724 n += GRASSHOPPER_BLOCK_SIZE - rest_len;
728 while (inl >= GRASSHOPPER_BLOCK_SIZE) {
729 currentInputBlock = (grasshopper_w128_t *) current_in;
731 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
733 inc_counter(c->mgm_iv->b, 8);
735 hexdump(stderr, "Hnext", h.b, 16);
736 hexdump(stderr, "Adata", currentInputBlock->b, 16);
737 /* Galois multiply */
738 gf128_mul_uint64(tmp.q, h.q, currentInputBlock->q);
741 grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
742 grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
743 hexdump(stderr, "Tag", c->tag, 16);
745 current_in += GRASSHOPPER_BLOCK_SIZE;
746 inl -= GRASSHOPPER_BLOCK_SIZE;
747 n += GRASSHOPPER_BLOCK_SIZE;
752 memcpy(c->mgm_partial_buffer.b, current_in, inl);
756 EVP_CIPHER_CTX_set_num(ctx, n);
760 if (out == NULL && in != NULL && inl !=0 && c->mgm_state == mgm_main_data) {
761 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_DO_MGM, GOST_R_BAD_ORDER);
765 if (out != NULL && c->mgm_state == mgm_associated_data) {
766 memset(c->mgm_partial_buffer.b+rest_len, 0, GRASSHOPPER_BLOCK_SIZE - rest_len);
768 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
770 inc_counter(c->mgm_iv->b, 8);
772 hexdump(stderr, "Hnext", h.b, 16);
773 hexdump(stderr, "Padded Adata", c->mgm_partial_buffer.b, 16);
774 /* Galois multiply Hi * Ai */
775 gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
778 grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
779 grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
780 hexdump(stderr, "Tag", c->tag, 16);
782 /* We finish processing associated data */
783 /* Pad rest of mgm_partial_buffer */
784 /* Process last block */
788 EVP_CIPHER_CTX_set_num(ctx, 0);
789 c->mgm_state = mgm_main_data;
791 fprintf(stderr, "============= Deal with main data\n");
794 /* ======== Here we deal with main data =========== */
796 /* actual IV derived from nonce */
797 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
798 &c->partial_buffer, &c->c.buffer);
799 memcpy(iv, c->partial_buffer.b, GRASSHOPPER_BLOCK_SIZE);
800 //hexdump(stderr, "Y1", iv, 16);
803 while (rest_len && inl) {
804 *(current_out++) = *(current_in++) ^ c->partial_buffer.b[rest_len];
808 if (rest_len == GRASSHOPPER_BLOCK_SIZE)
813 EVP_CIPHER_CTX_set_num(ctx, n);
816 for (i = 0; i < blocks; i++) {
817 currentInputBlock = (grasshopper_w128_t *) current_in;
818 currentOutputBlock = (grasshopper_w128_t *) current_out;
819 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
820 &c->partial_buffer, &c->c.buffer);
821 grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
822 grasshopper_copy128(currentOutputBlock, &tmp);
823 //hexdump(stderr, "Ciphertext", currentOutputBlock->b, 16);
825 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
827 inc_counter(c->mgm_iv->b, 8);
828 hexdump(stderr, "Hnext", h.b, 16);
829 hexdump(stderr, "Ciphertext", currentOutputBlock->b, 16);
830 /* Galois multiply Hi * Ai */
831 gf128_mul_uint64(tmp.q, h.q, currentOutputBlock->q);
834 grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
835 grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
836 hexdump(stderr, "Tag", c->tag, 16);
838 ctr128_inc(iv_buffer->b);
839 current_in += GRASSHOPPER_BLOCK_SIZE;
840 current_out += GRASSHOPPER_BLOCK_SIZE;
841 n += GRASSHOPPER_BLOCK_SIZE;
845 lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
847 currentInputBlock = (grasshopper_w128_t *) current_in;
848 currentOutputBlock = (grasshopper_w128_t *) current_out;
849 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
850 &c->partial_buffer, &c->c.buffer);
851 for (i = 0; i < lasted; i++) {
852 currentOutputBlock->b[i] =
853 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
855 grasshopper_copy128(&c->partial_buffer, currentOutputBlock);
856 EVP_CIPHER_CTX_set_num(ctx, n+i);
857 ctr128_inc(iv_buffer->b);
861 if (in == NULL && inl == 0)
863 unsigned char len_buf[16];
864 uint64_t a_len = 0, p_len = 0;
868 memset(c->partial_buffer.b+rest_len, 0, GRASSHOPPER_BLOCK_SIZE - rest_len);
869 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
871 inc_counter(c->mgm_iv->b, 8);
872 hexdump(stderr, "Hnext", h.b, 16);
873 hexdump(stderr, "Padded ciphertext", c->partial_buffer.b, 16);
874 /* Galois multiply Hi * Ai */
875 gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
878 grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
879 grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
880 hexdump(stderr, "Tag", c->tag, 16);
883 a_len = c->ad_length << 3;
884 p_len = (c->mgm_state == mgm_associated_data) ? 0 : n << 3;
887 a_len = bswap_64(a_len);
888 p_len = bswap_64(p_len);
890 memset(len_buf, 0, 16);
892 memcpy(len_buf, &a_len, sizeof(a_len));
893 memcpy(len_buf+sizeof(a_len), &p_len, sizeof(p_len));
894 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
897 hexdump(stderr, "Hlast", h.b, 16);
898 hexdump(stderr, "Lenbuf", len_buf, 16);
899 /* Galois multiply Hi * Ai */
900 gf128_mul_uint64(tmp.q, h.q, (uint64_t *)len_buf);
903 grasshopper_plus128(&h, (grasshopper_w128_t *)c->tag, &tmp);
904 grasshopper_copy128((grasshopper_w128_t *)c->tag, &h);
905 hexdump(stderr, "Tag", c->tag, 16);
907 /* Final tag calculation */
908 grasshopper_encrypt_block(&c->c.encrypt_round_keys, (grasshopper_w128_t *)c->tag,
909 (grasshopper_w128_t *)c->final_tag, &c->c.buffer);
916 * Fixed 128-bit IV implementation make shift regiser redundant.
918 static void gost_grasshopper_cnt_next(gost_grasshopper_cipher_ctx_ofb * ctx,
919 grasshopper_w128_t * iv,
920 grasshopper_w128_t * buf)
922 memcpy(&ctx->buffer1, iv, 16);
923 grasshopper_encrypt_block(&ctx->c.encrypt_round_keys, &ctx->buffer1,
924 buf, &ctx->c.buffer);
928 int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
929 const unsigned char *in, size_t inl)
931 gost_grasshopper_cipher_ctx_ofb *c = (gost_grasshopper_cipher_ctx_ofb *)
932 EVP_CIPHER_CTX_get_cipher_data(ctx);
933 const unsigned char *in_ptr = in;
934 unsigned char *out_ptr = out;
935 unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
936 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
937 int num = EVP_CIPHER_CTX_num(ctx);
941 /* process partial block if any */
943 for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
944 j++, i++, in_ptr++, out_ptr++) {
945 *out_ptr = buf[j] ^ (*in_ptr);
947 if (j == GRASSHOPPER_BLOCK_SIZE) {
948 EVP_CIPHER_CTX_set_num(ctx, 0);
950 EVP_CIPHER_CTX_set_num(ctx, (int)j);
955 for (; i + GRASSHOPPER_BLOCK_SIZE <
957 i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
958 GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
960 * block cipher current iv
963 gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
964 (grasshopper_w128_t *) buf);
967 * xor next block of input text with it and output it
972 for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
973 out_ptr[j] = buf[j] ^ in_ptr[j];
977 /* Process rest of buffer */
979 gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
980 (grasshopper_w128_t *) buf);
981 for (j = 0; i < inl; j++, i++) {
982 out_ptr[j] = buf[j] ^ in_ptr[j];
984 EVP_CIPHER_CTX_set_num(ctx, (int)j);
986 EVP_CIPHER_CTX_set_num(ctx, 0);
992 int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
993 const unsigned char *in, size_t inl)
995 gost_grasshopper_cipher_ctx *c =
996 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
997 const unsigned char *in_ptr = in;
998 unsigned char *out_ptr = out;
999 unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
1000 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
1001 bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
1002 int num = EVP_CIPHER_CTX_num(ctx);
1006 /* process partial block if any */
1008 for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
1009 j++, i++, in_ptr++, out_ptr++) {
1011 buf[j + GRASSHOPPER_BLOCK_SIZE] = *in_ptr;
1013 *out_ptr = buf[j] ^ (*in_ptr);
1015 buf[j + GRASSHOPPER_BLOCK_SIZE] = *out_ptr;
1018 if (j == GRASSHOPPER_BLOCK_SIZE) {
1019 memcpy(iv, buf + GRASSHOPPER_BLOCK_SIZE, GRASSHOPPER_BLOCK_SIZE);
1020 EVP_CIPHER_CTX_set_num(ctx, 0);
1022 EVP_CIPHER_CTX_set_num(ctx, (int)j);
1027 for (; i + GRASSHOPPER_BLOCK_SIZE <
1029 i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
1030 GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
1032 * block cipher current iv
1034 grasshopper_encrypt_block(&c->encrypt_round_keys,
1035 (grasshopper_w128_t *) iv,
1036 (grasshopper_w128_t *) buf, &c->buffer);
1038 * xor next block of input text with it and output it
1044 memcpy(iv, in_ptr, GRASSHOPPER_BLOCK_SIZE);
1046 for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1047 out_ptr[j] = buf[j] ^ in_ptr[j];
1050 /* Next iv is next block of cipher text */
1052 memcpy(iv, out_ptr, GRASSHOPPER_BLOCK_SIZE);
1056 /* Process rest of buffer */
1058 grasshopper_encrypt_block(&c->encrypt_round_keys,
1059 (grasshopper_w128_t *) iv,
1060 (grasshopper_w128_t *) buf, &c->buffer);
1062 memcpy(buf + GRASSHOPPER_BLOCK_SIZE, in_ptr, inl - i);
1064 for (j = 0; i < inl; j++, i++) {
1065 out_ptr[j] = buf[j] ^ in_ptr[j];
1067 EVP_CIPHER_CTX_set_num(ctx, (int)j);
1069 memcpy(buf + GRASSHOPPER_BLOCK_SIZE, out_ptr, j);
1072 EVP_CIPHER_CTX_set_num(ctx, 0);
1078 int gost_grasshopper_cipher_cleanup(EVP_CIPHER_CTX *ctx)
1080 gost_grasshopper_cipher_ctx *c =
1081 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1086 struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
1088 gost_grasshopper_cipher_destroy(c);
1089 if (params->destroy_cipher != NULL) {
1090 params->destroy_cipher(c);
1093 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
1098 int gost_grasshopper_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
1101 unsigned char *buf = NULL;
1102 ASN1_OCTET_STRING *os = NULL;
1104 os = ASN1_OCTET_STRING_new();
1106 if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
1108 GOSTerr(GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS,
1109 ERR_R_MALLOC_FAILURE);
1114 ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
1118 GRASSHOPPER_INLINE int gost_grasshopper_get_asn1_parameters(EVP_CIPHER_CTX
1124 if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
1131 int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
1135 case EVP_CTRL_RAND_KEY:{
1137 ((unsigned char *)ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
1138 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_RNG_ERROR);
1143 case EVP_CTRL_KEY_MESH:{
1144 gost_grasshopper_cipher_ctx_ctr *c =
1145 EVP_CIPHER_CTX_get_cipher_data(ctx);
1146 if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKM || !arg
1147 || (arg % GRASSHOPPER_BLOCK_SIZE))
1149 c->section_size = arg;
1152 #ifdef EVP_CTRL_TLS1_2_TLSTREE
1153 case EVP_CTRL_TLS1_2_TLSTREE:
1155 unsigned char newkey[32];
1156 int mode = EVP_CIPHER_CTX_mode(ctx);
1157 static const unsigned char zeroseq[8];
1158 gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL;
1159 gost_grasshopper_cipher_ctx *c = NULL;
1161 unsigned char adjusted_iv[16];
1162 unsigned char seq[8];
1164 if (mode != EVP_CIPH_CTR_MODE)
1167 ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *)
1168 EVP_CIPHER_CTX_get_cipher_data(ctx);
1171 memcpy(seq, ptr, 8);
1172 if (EVP_CIPHER_CTX_encrypting(ctx)) {
1174 * OpenSSL increments seq after mac calculation.
1175 * As we have Mac-Then-Encrypt, we need decrement it here on encryption
1176 * to derive the key correctly.
1178 if (memcmp(seq, zeroseq, 8) != 0)
1182 if (seq[j] != 0) {seq[j]--; break;}
1187 if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey,
1188 (const unsigned char *)seq) > 0) {
1189 memset(adjusted_iv, 0, 16);
1190 memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8);
1191 for(j=7,carry=0; j>=0; j--)
1193 int adj_byte = adjusted_iv[j]+seq[j]+carry;
1194 carry = (adj_byte > 255) ? 1 : 0;
1195 adjusted_iv[j] = adj_byte & 0xFF;
1197 EVP_CIPHER_CTX_set_num(ctx, 0);
1198 memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16);
1200 gost_grasshopper_cipher_key(c, newkey);
1206 case EVP_CTRL_AEAD_GET_TAG:
1207 case EVP_CTRL_AEAD_SET_TAG:
1209 gost_grasshopper_cipher_ctx_mgm *mgm_ctx = NULL;
1210 gost_grasshopper_cipher_ctx *c = NULL;
1212 unsigned char* tag = ptr;
1214 mgm_ctx = (gost_grasshopper_cipher_ctx_mgm *)
1215 EVP_CIPHER_CTX_get_cipher_data(ctx);
1216 c = (gost_grasshopper_cipher_ctx *)mgm_ctx;
1218 if (c->type != GRASSHOPPER_CIPHER_MGM)
1222 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_INVALID_TAG_LENGTH);
1226 if (type == EVP_CTRL_AEAD_GET_TAG)
1227 memcpy(tag, mgm_ctx->final_tag, taglen);
1229 memcpy(mgm_ctx->final_tag, tag, taglen);
1234 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1235 GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
1241 GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_create(int
1245 return EVP_CIPHER_meth_new(cipher_type, block_size /* block_size */ ,
1246 GRASSHOPPER_KEY_SIZE /* key_size */ );
1249 const int cipher_gost_grasshopper_setup(EVP_CIPHER *cipher, uint8_t mode,
1250 int iv_size, bool padding, int extra_flags)
1252 return EVP_CIPHER_meth_set_iv_length(cipher, iv_size)
1253 && EVP_CIPHER_meth_set_flags(cipher,
1254 (unsigned long)(mode |
1256 EVP_CIPH_NO_PADDING :
1262 EVP_CIPH_ALWAYS_CALL_INIT | extra_flags)
1264 && EVP_CIPHER_meth_set_cleanup(cipher, gost_grasshopper_cipher_cleanup)
1265 && EVP_CIPHER_meth_set_set_asn1_params(cipher,
1266 gost_grasshopper_set_asn1_parameters)
1267 && EVP_CIPHER_meth_set_get_asn1_params(cipher,
1268 gost_grasshopper_get_asn1_parameters)
1269 && EVP_CIPHER_meth_set_ctrl(cipher, gost_grasshopper_cipher_ctl)
1270 && EVP_CIPHER_meth_set_do_cipher(cipher, gost_grasshopper_cipher_do);
1273 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper(uint8_t mode,
1276 EVP_CIPHER **cipher;
1277 struct GRASSHOPPER_CIPHER_PARAMS *params;
1279 cipher = &gost_grasshopper_ciphers[num];
1281 if (*cipher == NULL) {
1282 params = &gost_cipher_params[num];
1284 int nid = params->nid;
1285 grasshopper_init_cipher_func init_cipher = params->init_cipher;
1286 int block_size = params->block_size;
1287 int ctx_size = params->ctx_size;
1288 int iv_size = params->iv_size;
1289 bool padding = params->padding;
1291 int extra_flags = (num == GRASSHOPPER_CIPHER_MGM) ?
1292 EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_AEAD_CIPHER : 0;
1294 *cipher = cipher_gost_grasshopper_create(nid, block_size);
1295 if (*cipher == NULL) {
1299 if (!cipher_gost_grasshopper_setup(*cipher, mode, iv_size, padding, extra_flags)
1300 || !EVP_CIPHER_meth_set_init(*cipher, init_cipher)
1301 || !EVP_CIPHER_meth_set_impl_ctx_size(*cipher, ctx_size)) {
1302 EVP_CIPHER_meth_free(*cipher);
1310 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ecb()
1312 return cipher_gost_grasshopper(EVP_CIPH_ECB_MODE, GRASSHOPPER_CIPHER_ECB);
1315 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cbc()
1317 return cipher_gost_grasshopper(EVP_CIPH_CBC_MODE, GRASSHOPPER_CIPHER_CBC);
1320 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ofb()
1322 return cipher_gost_grasshopper(EVP_CIPH_OFB_MODE, GRASSHOPPER_CIPHER_OFB);
1325 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cfb()
1327 return cipher_gost_grasshopper(EVP_CIPH_CFB_MODE, GRASSHOPPER_CIPHER_CFB);
1330 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctr()
1332 return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_CTR);
1335 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctracpkm()
1337 return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE,
1338 GRASSHOPPER_CIPHER_CTRACPKM);
1341 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_mgm()
1343 #ifndef NID_kuznyechik_mgm
1346 return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_MGM);
1350 void cipher_gost_grasshopper_destroy(void)
1352 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB]);
1353 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB] = NULL;
1354 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC]);
1355 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC] = NULL;
1356 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB]);
1357 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB] = NULL;
1358 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB]);
1359 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB] = NULL;
1360 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR]);
1361 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR] = NULL;
1362 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM]);
1363 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM] = NULL;
1364 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM]);
1365 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM] = NULL;