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 =
262 (gost_grasshopper_cipher_ctx_mgm *) c;
264 /* 1st bit should be 0 */
266 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_INIT,
267 GOST_R_INVALID_IV_LENGTH);
270 memcpy(m->mgm_iv, iv, 16);
271 *(unsigned char *)(m->mgm_iv) += 128;
273 memcpy((unsigned char *)EVP_CIPHER_CTX_original_iv(ctx), iv,
274 EVP_CIPHER_CTX_iv_length(ctx));
277 memcpy(EVP_CIPHER_CTX_iv_noconst(ctx),
278 EVP_CIPHER_CTX_original_iv(ctx), EVP_CIPHER_CTX_iv_length(ctx));
280 grasshopper_zero128(&c->buffer);
285 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ecb(EVP_CIPHER_CTX *ctx, const unsigned char
286 *key, const unsigned char
289 gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
290 c->type = GRASSHOPPER_CIPHER_ECB;
291 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
294 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cbc(EVP_CIPHER_CTX *ctx, const unsigned char
295 *key, const unsigned char
298 gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
299 c->type = GRASSHOPPER_CIPHER_CBC;
300 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
303 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ofb(EVP_CIPHER_CTX *ctx, const unsigned char
304 *key, const unsigned char
307 gost_grasshopper_cipher_ctx_ofb *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
309 c->c.type = GRASSHOPPER_CIPHER_OFB;
311 grasshopper_zero128(&c->buffer1);
313 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
316 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_cfb(EVP_CIPHER_CTX *ctx, const unsigned char
317 *key, const unsigned char
320 gost_grasshopper_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
321 c->type = GRASSHOPPER_CIPHER_CFB;
322 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
325 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctr(EVP_CIPHER_CTX *ctx, const unsigned char
326 *key, const unsigned char
329 gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
331 c->c.type = GRASSHOPPER_CIPHER_CTR;
332 EVP_CIPHER_CTX_set_num(ctx, 0);
334 grasshopper_zero128(&c->partial_buffer);
336 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
339 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_ctracpkm(EVP_CIPHER_CTX
341 char *key, const unsigned
344 gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
346 /* NB: setting type makes EVP do_cipher callback useless */
347 c->c.type = GRASSHOPPER_CIPHER_CTRACPKM;
348 EVP_CIPHER_CTX_set_num(ctx, 0);
349 c->section_size = 4096;
351 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
354 GRASSHOPPER_INLINE int gost_grasshopper_cipher_init_mgm(EVP_CIPHER_CTX *ctx, const unsigned char
355 *key, const unsigned char
358 gost_grasshopper_cipher_ctx_mgm *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
360 c->c.type = GRASSHOPPER_CIPHER_MGM;
362 EVP_CIPHER_CTX_set_num(ctx, 0);
364 grasshopper_zero128(&c->partial_buffer);
366 return gost_grasshopper_cipher_init(ctx, key, iv, enc);
369 GRASSHOPPER_INLINE int gost_grasshopper_cipher_do(EVP_CIPHER_CTX *ctx,
371 const unsigned char *in,
374 gost_grasshopper_cipher_ctx *c =
375 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
376 struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
378 return params->do_cipher(ctx, out, in, inl);
381 int gost_grasshopper_cipher_do_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
382 const unsigned char *in, size_t inl)
384 gost_grasshopper_cipher_ctx *c =
385 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
386 bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
387 const unsigned char *current_in = in;
388 unsigned char *current_out = out;
389 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
392 for (i = 0; i < blocks;
393 i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
394 GRASSHOPPER_BLOCK_SIZE) {
396 grasshopper_encrypt_block(&c->encrypt_round_keys,
397 (grasshopper_w128_t *) current_in,
398 (grasshopper_w128_t *) current_out,
401 grasshopper_decrypt_block(&c->decrypt_round_keys,
402 (grasshopper_w128_t *) current_in,
403 (grasshopper_w128_t *) current_out,
411 int gost_grasshopper_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
412 const unsigned char *in, size_t inl)
414 gost_grasshopper_cipher_ctx *c =
415 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
416 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
417 bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
418 const unsigned char *current_in = in;
419 unsigned char *current_out = out;
420 grasshopper_w128_t *currentInputBlock;
421 grasshopper_w128_t *currentOutputBlock;
422 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
424 grasshopper_w128_t *currentBlock;
426 currentBlock = (grasshopper_w128_t *) iv;
428 for (i = 0; i < blocks;
429 i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out +=
430 GRASSHOPPER_BLOCK_SIZE) {
431 currentInputBlock = (grasshopper_w128_t *) current_in;
432 currentOutputBlock = (grasshopper_w128_t *) current_out;
434 grasshopper_append128(currentBlock, currentInputBlock);
435 grasshopper_encrypt_block(&c->encrypt_round_keys, currentBlock,
436 currentOutputBlock, &c->buffer);
437 grasshopper_copy128(currentBlock, currentOutputBlock);
439 grasshopper_w128_t tmp;
441 grasshopper_copy128(&tmp, currentInputBlock);
442 grasshopper_decrypt_block(&c->decrypt_round_keys,
443 currentInputBlock, currentOutputBlock,
445 grasshopper_append128(currentOutputBlock, currentBlock);
446 grasshopper_copy128(currentBlock, &tmp);
453 void inc_counter(unsigned char *counter, size_t counter_bytes)
456 unsigned int n = counter_bytes;
468 /* increment counter (128-bit int) by 1 */
469 static void ctr128_inc(unsigned char *counter)
471 inc_counter(counter, 16);
474 int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *out,
475 const unsigned char *in, size_t inl)
477 gost_grasshopper_cipher_ctx_ctr *c = (gost_grasshopper_cipher_ctx_ctr *)
478 EVP_CIPHER_CTX_get_cipher_data(ctx);
479 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
480 const unsigned char *current_in = in;
481 unsigned char *current_out = out;
482 grasshopper_w128_t *currentInputBlock;
483 grasshopper_w128_t *currentOutputBlock;
484 unsigned int n = EVP_CIPHER_CTX_num(ctx);
489 *(current_out++) = *(current_in++) ^ c->partial_buffer.b[n];
491 n = (n + 1) % GRASSHOPPER_BLOCK_SIZE;
493 EVP_CIPHER_CTX_set_num(ctx, n);
494 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
496 grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
497 grasshopper_w128_t tmp;
500 for (i = 0; i < blocks; i++) {
501 currentInputBlock = (grasshopper_w128_t *) current_in;
502 currentOutputBlock = (grasshopper_w128_t *) current_out;
503 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
504 &c->partial_buffer, &c->c.buffer);
505 grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
506 grasshopper_copy128(currentOutputBlock, &tmp);
507 ctr128_inc(iv_buffer->b);
508 current_in += GRASSHOPPER_BLOCK_SIZE;
509 current_out += GRASSHOPPER_BLOCK_SIZE;
513 lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
515 currentInputBlock = (grasshopper_w128_t *) current_in;
516 currentOutputBlock = (grasshopper_w128_t *) current_out;
517 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
518 &c->partial_buffer, &c->c.buffer);
519 for (i = 0; i < lasted; i++) {
520 currentOutputBlock->b[i] =
521 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
523 EVP_CIPHER_CTX_set_num(ctx, i);
524 ctr128_inc(iv_buffer->b);
530 #define GRASSHOPPER_BLOCK_MASK (GRASSHOPPER_BLOCK_SIZE - 1)
531 static inline void apply_acpkm_grasshopper(gost_grasshopper_cipher_ctx_ctr *
532 ctx, unsigned int *num)
534 if (!ctx->section_size || (*num < ctx->section_size))
537 *num &= GRASSHOPPER_BLOCK_MASK;
540 /* If meshing is not configured via ctrl (setting section_size)
541 * this function works exactly like plain ctr */
542 int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx,
544 const unsigned char *in, size_t inl)
546 gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
547 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
548 unsigned int num = EVP_CIPHER_CTX_num(ctx);
550 while ((num & GRASSHOPPER_BLOCK_MASK) && inl) {
551 *out++ = *in++ ^ c->partial_buffer.b[num & GRASSHOPPER_BLOCK_MASK];
555 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
557 grasshopper_w128_t tmp;
560 for (i = 0; i < blocks; i++) {
561 apply_acpkm_grasshopper(c, &num);
562 grasshopper_encrypt_block(&c->c.encrypt_round_keys,
563 (grasshopper_w128_t *) iv,
564 (grasshopper_w128_t *) & c->partial_buffer,
566 grasshopper_plus128(&tmp, &c->partial_buffer,
567 (grasshopper_w128_t *) in);
568 grasshopper_copy128((grasshopper_w128_t *) out, &tmp);
570 in += GRASSHOPPER_BLOCK_SIZE;
571 out += GRASSHOPPER_BLOCK_SIZE;
572 num += GRASSHOPPER_BLOCK_SIZE;
576 size_t lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
578 apply_acpkm_grasshopper(c, &num);
579 grasshopper_encrypt_block(&c->c.encrypt_round_keys,
580 (grasshopper_w128_t *) iv,
581 &c->partial_buffer, &c->c.buffer);
582 for (i = 0; i < lasted; i++)
583 out[i] = c->partial_buffer.b[i] ^ in[i];
587 EVP_CIPHER_CTX_set_num(ctx, num);
592 /* ----------------------------------------------------------------------------------------------- */
593 /*! Функция реализует операцию умножения двух элементов конечного поля \f$ \mathbb F_{2^{128}}\f$,
594 порожденного неприводимым многочленом
595 \f$ f(x) = x^{128} + x^7 + x^2 + x + 1 \in \mathbb F_2[x]\f$. Для умножения используется
596 простейшая реализация, основанная на приведении по модулю после каждого шага алгоритма. */
597 /* ----------------------------------------------------------------------------------------------- */
598 static void gf128_mul_uint64(uint64_t *result, uint64_t *arg1, uint64_t *arg2)
602 uint64_t x[2], y[2], z[2];
604 BUF_reverse((unsigned char *)x, (unsigned char *)arg1, 16);
605 BUF_reverse((unsigned char *)y, (unsigned char *)arg2, 16);
615 memset(z, 0, sizeof(uint64_t) * 2);
624 for (i = 0; i < 64; i++) {
645 for (i = 0; i < 63; i++) {
664 z[0] = bswap_64(z[0]);
665 z[1] = bswap_64(z[1]);
667 BUF_reverse((unsigned char *)result, (unsigned char *)z, 16);
670 int gost_grasshopper_cipher_do_mgm(EVP_CIPHER_CTX *ctx, unsigned char *out,
671 const unsigned char *in, size_t inl)
673 gost_grasshopper_cipher_ctx_mgm *c = (gost_grasshopper_cipher_ctx_mgm *)
674 EVP_CIPHER_CTX_get_cipher_data(ctx);
675 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
676 const unsigned char *current_in = in;
677 unsigned char *current_out = out;
678 grasshopper_w128_t *currentInputBlock;
679 grasshopper_w128_t *currentOutputBlock;
680 unsigned int n = EVP_CIPHER_CTX_num(ctx);
684 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
685 int rest_len = n % GRASSHOPPER_BLOCK_SIZE;
686 grasshopper_w128_t h;
688 grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
689 grasshopper_w128_t tmp;
690 int encrypting = EVP_CIPHER_CTX_encrypting(ctx);
692 /* ======== Here we deal with associated data =========== */
693 if (out == NULL && c->mgm_state == mgm_associated_data) {
695 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
696 &c->partial_buffer, &c->c.buffer);
697 memcpy(c->mgm_iv, &c->partial_buffer, GRASSHOPPER_BLOCK_SIZE);
701 /* Finalize partial_data */
702 if (inl + rest_len < GRASSHOPPER_BLOCK_SIZE) {
703 memcpy(c->mgm_partial_buffer.b + rest_len, current_in, inl);
705 EVP_CIPHER_CTX_set_num(ctx, n);
708 memcpy(c->mgm_partial_buffer.b + rest_len, current_in,
709 GRASSHOPPER_BLOCK_SIZE - rest_len);
711 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
713 inc_counter(c->mgm_iv->b, 8);
715 /* Galois multiply Hi * Ai */
716 gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
719 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
720 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
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 /* Galois multiply */
736 gf128_mul_uint64(tmp.q, h.q, currentInputBlock->q);
739 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
740 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
742 current_in += GRASSHOPPER_BLOCK_SIZE;
743 inl -= GRASSHOPPER_BLOCK_SIZE;
744 n += GRASSHOPPER_BLOCK_SIZE;
748 memcpy(c->mgm_partial_buffer.b, current_in, inl);
752 EVP_CIPHER_CTX_set_num(ctx, n);
756 if (out == NULL && in != NULL && inl != 0 && c->mgm_state == mgm_main_data) {
757 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_DO_MGM, GOST_R_BAD_ORDER);
761 if (out != NULL && c->mgm_state == mgm_associated_data) {
762 memset(c->mgm_partial_buffer.b + rest_len, 0,
763 GRASSHOPPER_BLOCK_SIZE - rest_len);
765 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
767 inc_counter(c->mgm_iv->b, 8);
769 /* Galois multiply Hi * Ai */
770 gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
773 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
774 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
776 /* We finish processing associated data */
777 /* Pad rest of mgm_partial_buffer */
778 /* Process last block */
782 EVP_CIPHER_CTX_set_num(ctx, 0);
783 c->mgm_state = mgm_main_data;
787 /* ======== Here we deal with main data =========== */
789 /* actual IV derived from nonce */
790 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
791 &c->partial_buffer, &c->c.buffer);
792 memcpy(iv, c->partial_buffer.b, GRASSHOPPER_BLOCK_SIZE);
795 while (rest_len && inl) {
796 *(current_out++) = *(current_in++) ^ c->partial_buffer.b[rest_len];
799 c->partial_buffer.b[rest_len] = *(current_out - 1);
801 c->partial_buffer.b[rest_len] = *(current_in - 1);
806 if (rest_len == GRASSHOPPER_BLOCK_SIZE) {
808 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
810 inc_counter(c->mgm_iv->b, 8);
811 /* Galois multiply Hi * Ai */
812 gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
815 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
816 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
821 for (i = 0; i < blocks; i++) {
822 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
824 inc_counter(c->mgm_iv->b, 8);
826 currentInputBlock = (grasshopper_w128_t *) current_in;
827 currentOutputBlock = (grasshopper_w128_t *) current_out;
828 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
829 &c->partial_buffer, &c->c.buffer);
830 grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
833 grasshopper_copy128(currentOutputBlock, &tmp);
835 /* Galois multiply Hi * Ai */
836 gf128_mul_uint64(tmp.q, h.q, currentOutputBlock->q);
839 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
840 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
842 grasshopper_w128_t tmpin;
843 grasshopper_copy128(&tmpin, currentInputBlock);
844 grasshopper_copy128(currentOutputBlock, &tmp);
846 /* Galois multiply Hi * Ai */
847 gf128_mul_uint64(tmp.q, h.q, tmpin.q);
850 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
851 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
854 ctr128_inc(iv_buffer->b);
855 current_in += GRASSHOPPER_BLOCK_SIZE;
856 current_out += GRASSHOPPER_BLOCK_SIZE;
857 n += GRASSHOPPER_BLOCK_SIZE;
860 EVP_CIPHER_CTX_set_num(ctx, n);
863 lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
865 currentInputBlock = (grasshopper_w128_t *) current_in;
866 currentOutputBlock = (grasshopper_w128_t *) current_out;
867 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
868 &c->partial_buffer, &c->c.buffer);
869 for (i = 0; i < lasted; i++) {
871 currentOutputBlock->b[i] =
872 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
873 c->partial_buffer.b[i] = currentOutputBlock->b[i];
875 unsigned char in = currentInputBlock->b[i];
876 currentOutputBlock->b[i] =
877 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
878 c->partial_buffer.b[i] = in;
881 EVP_CIPHER_CTX_set_num(ctx, n + i);
882 ctr128_inc(iv_buffer->b);
886 if (in == NULL && inl == 0) {
887 unsigned char len_buf[16];
888 uint64_t a_len = 0, p_len = 0;
891 memset(c->partial_buffer.b + rest_len, 0,
892 GRASSHOPPER_BLOCK_SIZE - rest_len);
893 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv, &h,
895 inc_counter(c->mgm_iv->b, 8);
896 /* Galois multiply Hi * Ai */
897 gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
900 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
901 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
904 a_len = c->ad_length << 3;
905 p_len = (c->mgm_state == mgm_associated_data) ? 0 : n << 3;
908 a_len = bswap_64(a_len);
909 p_len = bswap_64(p_len);
911 memset(len_buf, 0, 16);
913 memcpy(len_buf, &a_len, sizeof(a_len));
914 memcpy(len_buf + sizeof(a_len), &p_len, sizeof(p_len));
915 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
918 /* Galois multiply Hi * Ai */
919 gf128_mul_uint64(tmp.q, h.q, (uint64_t *)len_buf);
922 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
923 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
925 /* Final tag calculation */
927 grasshopper_encrypt_block(&c->c.encrypt_round_keys,
928 (grasshopper_w128_t *) c->tag,
929 (grasshopper_w128_t *) c->final_tag,
933 grasshopper_w128_t decrypt_tag;
934 grasshopper_encrypt_block(&c->c.encrypt_round_keys,
935 (grasshopper_w128_t *) c->tag,
936 &decrypt_tag, &c->c.buffer);
937 if (memcmp(decrypt_tag.b, c->final_tag, 16)) {
948 * Fixed 128-bit IV implementation make shift regiser redundant.
950 static void gost_grasshopper_cnt_next(gost_grasshopper_cipher_ctx_ofb * ctx,
951 grasshopper_w128_t * iv,
952 grasshopper_w128_t * buf)
954 memcpy(&ctx->buffer1, iv, 16);
955 grasshopper_encrypt_block(&ctx->c.encrypt_round_keys, &ctx->buffer1,
956 buf, &ctx->c.buffer);
960 int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
961 const unsigned char *in, size_t inl)
963 gost_grasshopper_cipher_ctx_ofb *c = (gost_grasshopper_cipher_ctx_ofb *)
964 EVP_CIPHER_CTX_get_cipher_data(ctx);
965 const unsigned char *in_ptr = in;
966 unsigned char *out_ptr = out;
967 unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
968 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
969 int num = EVP_CIPHER_CTX_num(ctx);
973 /* process partial block if any */
975 for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
976 j++, i++, in_ptr++, out_ptr++) {
977 *out_ptr = buf[j] ^ (*in_ptr);
979 if (j == GRASSHOPPER_BLOCK_SIZE) {
980 EVP_CIPHER_CTX_set_num(ctx, 0);
982 EVP_CIPHER_CTX_set_num(ctx, (int)j);
987 for (; i + GRASSHOPPER_BLOCK_SIZE <
989 i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
990 GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
992 * block cipher current iv
995 gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
996 (grasshopper_w128_t *) buf);
999 * xor next block of input text with it and output it
1004 for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1005 out_ptr[j] = buf[j] ^ in_ptr[j];
1009 /* Process rest of buffer */
1011 gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
1012 (grasshopper_w128_t *) buf);
1013 for (j = 0; i < inl; j++, i++) {
1014 out_ptr[j] = buf[j] ^ in_ptr[j];
1016 EVP_CIPHER_CTX_set_num(ctx, (int)j);
1018 EVP_CIPHER_CTX_set_num(ctx, 0);
1024 int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
1025 const unsigned char *in, size_t inl)
1027 gost_grasshopper_cipher_ctx *c =
1028 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1029 const unsigned char *in_ptr = in;
1030 unsigned char *out_ptr = out;
1031 unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
1032 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
1033 bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
1034 int num = EVP_CIPHER_CTX_num(ctx);
1038 /* process partial block if any */
1040 for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
1041 j++, i++, in_ptr++, out_ptr++) {
1043 buf[j + GRASSHOPPER_BLOCK_SIZE] = *in_ptr;
1045 *out_ptr = buf[j] ^ (*in_ptr);
1047 buf[j + GRASSHOPPER_BLOCK_SIZE] = *out_ptr;
1050 if (j == GRASSHOPPER_BLOCK_SIZE) {
1051 memcpy(iv, buf + GRASSHOPPER_BLOCK_SIZE, GRASSHOPPER_BLOCK_SIZE);
1052 EVP_CIPHER_CTX_set_num(ctx, 0);
1054 EVP_CIPHER_CTX_set_num(ctx, (int)j);
1059 for (; i + GRASSHOPPER_BLOCK_SIZE <
1061 i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
1062 GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
1064 * block cipher current iv
1066 grasshopper_encrypt_block(&c->encrypt_round_keys,
1067 (grasshopper_w128_t *) iv,
1068 (grasshopper_w128_t *) buf, &c->buffer);
1070 * xor next block of input text with it and output it
1076 memcpy(iv, in_ptr, GRASSHOPPER_BLOCK_SIZE);
1078 for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1079 out_ptr[j] = buf[j] ^ in_ptr[j];
1082 /* Next iv is next block of cipher text */
1084 memcpy(iv, out_ptr, GRASSHOPPER_BLOCK_SIZE);
1088 /* Process rest of buffer */
1090 grasshopper_encrypt_block(&c->encrypt_round_keys,
1091 (grasshopper_w128_t *) iv,
1092 (grasshopper_w128_t *) buf, &c->buffer);
1094 memcpy(buf + GRASSHOPPER_BLOCK_SIZE, in_ptr, inl - i);
1096 for (j = 0; i < inl; j++, i++) {
1097 out_ptr[j] = buf[j] ^ in_ptr[j];
1099 EVP_CIPHER_CTX_set_num(ctx, (int)j);
1101 memcpy(buf + GRASSHOPPER_BLOCK_SIZE, out_ptr, j);
1104 EVP_CIPHER_CTX_set_num(ctx, 0);
1110 int gost_grasshopper_cipher_cleanup(EVP_CIPHER_CTX *ctx)
1112 gost_grasshopper_cipher_ctx *c =
1113 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1118 struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
1120 gost_grasshopper_cipher_destroy(c);
1121 if (params->destroy_cipher != NULL) {
1122 params->destroy_cipher(c);
1125 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
1130 int gost_grasshopper_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
1133 unsigned char *buf = NULL;
1134 ASN1_OCTET_STRING *os = NULL;
1136 os = ASN1_OCTET_STRING_new();
1138 if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
1140 GOSTerr(GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS,
1141 ERR_R_MALLOC_FAILURE);
1146 ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
1150 GRASSHOPPER_INLINE int gost_grasshopper_get_asn1_parameters(EVP_CIPHER_CTX
1156 if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
1163 int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
1167 case EVP_CTRL_RAND_KEY:{
1169 ((unsigned char *)ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
1170 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_RNG_ERROR);
1175 case EVP_CTRL_KEY_MESH:{
1176 gost_grasshopper_cipher_ctx_ctr *c =
1177 EVP_CIPHER_CTX_get_cipher_data(ctx);
1178 if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKM || !arg
1179 || (arg % GRASSHOPPER_BLOCK_SIZE))
1181 c->section_size = arg;
1184 #ifdef EVP_CTRL_TLS1_2_TLSTREE
1185 case EVP_CTRL_TLS1_2_TLSTREE:
1187 unsigned char newkey[32];
1188 int mode = EVP_CIPHER_CTX_mode(ctx);
1189 static const unsigned char zeroseq[8];
1190 gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL;
1191 gost_grasshopper_cipher_ctx *c = NULL;
1193 unsigned char adjusted_iv[16];
1194 unsigned char seq[8];
1196 if (mode != EVP_CIPH_CTR_MODE)
1199 ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *)
1200 EVP_CIPHER_CTX_get_cipher_data(ctx);
1203 memcpy(seq, ptr, 8);
1204 if (EVP_CIPHER_CTX_encrypting(ctx)) {
1206 * OpenSSL increments seq after mac calculation.
1207 * As we have Mac-Then-Encrypt, we need decrement it here on encryption
1208 * to derive the key correctly.
1210 if (memcmp(seq, zeroseq, 8) != 0) {
1211 for (j = 7; j >= 0; j--) {
1220 if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey,
1221 (const unsigned char *)seq) > 0) {
1222 memset(adjusted_iv, 0, 16);
1223 memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8);
1224 for (j = 7; j >= 0; j--) {
1225 int adj_byte, carry = 0;
1226 adj_byte = adjusted_iv[j] + seq[j] + carry;
1227 carry = (adj_byte > 255) ? 1 : 0;
1228 adjusted_iv[j] = adj_byte & 0xFF;
1230 EVP_CIPHER_CTX_set_num(ctx, 0);
1231 memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16);
1233 gost_grasshopper_cipher_key(c, newkey);
1239 case EVP_CTRL_AEAD_GET_TAG:
1240 case EVP_CTRL_AEAD_SET_TAG:
1242 gost_grasshopper_cipher_ctx_mgm *mgm_ctx = NULL;
1243 gost_grasshopper_cipher_ctx *c = NULL;
1245 unsigned char *tag = ptr;
1247 mgm_ctx = (gost_grasshopper_cipher_ctx_mgm *)
1248 EVP_CIPHER_CTX_get_cipher_data(ctx);
1249 c = (gost_grasshopper_cipher_ctx *) mgm_ctx;
1251 if (c->type != GRASSHOPPER_CIPHER_MGM)
1255 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1256 GOST_R_INVALID_TAG_LENGTH);
1260 if (type == EVP_CTRL_AEAD_GET_TAG)
1261 memcpy(tag, mgm_ctx->final_tag, taglen);
1263 memcpy(mgm_ctx->final_tag, tag, taglen);
1268 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1269 GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
1275 GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_create(int
1279 return EVP_CIPHER_meth_new(cipher_type, block_size /* block_size */ ,
1280 GRASSHOPPER_KEY_SIZE /* key_size */ );
1283 const int cipher_gost_grasshopper_setup(EVP_CIPHER *cipher, uint8_t mode,
1284 int iv_size, bool padding,
1287 return EVP_CIPHER_meth_set_iv_length(cipher, iv_size)
1288 && EVP_CIPHER_meth_set_flags(cipher,
1289 (unsigned long)(mode |
1291 EVP_CIPH_NO_PADDING :
1297 EVP_CIPH_ALWAYS_CALL_INIT |
1300 && EVP_CIPHER_meth_set_cleanup(cipher, gost_grasshopper_cipher_cleanup)
1301 && EVP_CIPHER_meth_set_set_asn1_params(cipher,
1302 gost_grasshopper_set_asn1_parameters)
1303 && EVP_CIPHER_meth_set_get_asn1_params(cipher,
1304 gost_grasshopper_get_asn1_parameters)
1305 && EVP_CIPHER_meth_set_ctrl(cipher, gost_grasshopper_cipher_ctl)
1306 && EVP_CIPHER_meth_set_do_cipher(cipher, gost_grasshopper_cipher_do);
1309 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper(uint8_t mode,
1312 EVP_CIPHER **cipher;
1313 struct GRASSHOPPER_CIPHER_PARAMS *params;
1315 cipher = &gost_grasshopper_ciphers[num];
1317 if (*cipher == NULL) {
1318 params = &gost_cipher_params[num];
1320 int nid = params->nid;
1321 grasshopper_init_cipher_func init_cipher = params->init_cipher;
1322 int block_size = params->block_size;
1323 int ctx_size = params->ctx_size;
1324 int iv_size = params->iv_size;
1325 bool padding = params->padding;
1327 int extra_flags = (num == GRASSHOPPER_CIPHER_MGM) ?
1328 EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_AEAD_CIPHER : 0;
1330 *cipher = cipher_gost_grasshopper_create(nid, block_size);
1331 if (*cipher == NULL) {
1335 if (!cipher_gost_grasshopper_setup
1336 (*cipher, mode, iv_size, padding, extra_flags)
1337 || !EVP_CIPHER_meth_set_init(*cipher, init_cipher)
1338 || !EVP_CIPHER_meth_set_impl_ctx_size(*cipher, ctx_size)) {
1339 EVP_CIPHER_meth_free(*cipher);
1347 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ecb()
1349 return cipher_gost_grasshopper(EVP_CIPH_ECB_MODE, GRASSHOPPER_CIPHER_ECB);
1352 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cbc()
1354 return cipher_gost_grasshopper(EVP_CIPH_CBC_MODE, GRASSHOPPER_CIPHER_CBC);
1357 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ofb()
1359 return cipher_gost_grasshopper(EVP_CIPH_OFB_MODE, GRASSHOPPER_CIPHER_OFB);
1362 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cfb()
1364 return cipher_gost_grasshopper(EVP_CIPH_CFB_MODE, GRASSHOPPER_CIPHER_CFB);
1367 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctr()
1369 return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_CTR);
1372 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctracpkm()
1374 return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE,
1375 GRASSHOPPER_CIPHER_CTRACPKM);
1378 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_mgm()
1380 #ifndef NID_kuznyechik_mgm
1383 return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_MGM);
1387 void cipher_gost_grasshopper_destroy(void)
1389 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB]);
1390 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB] = NULL;
1391 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC]);
1392 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC] = NULL;
1393 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB]);
1394 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB] = NULL;
1395 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB]);
1396 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB] = NULL;
1397 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR]);
1398 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR] = NULL;
1399 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM]);
1400 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM] = NULL;
1401 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM]);
1402 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM] = NULL;