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 static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
674 fprintf(f, "%s", title);
677 fprintf(f, "\n%04x", n);
678 fprintf(f, " %02x", s[n]);
683 int gost_grasshopper_cipher_do_mgm(EVP_CIPHER_CTX *ctx, unsigned char *out,
684 const unsigned char *in, size_t inl)
686 gost_grasshopper_cipher_ctx_mgm *c = (gost_grasshopper_cipher_ctx_mgm *)
687 EVP_CIPHER_CTX_get_cipher_data(ctx);
688 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
689 const unsigned char *current_in = in;
690 unsigned char *current_out = out;
691 grasshopper_w128_t *currentInputBlock;
692 grasshopper_w128_t *currentOutputBlock;
693 unsigned int n = EVP_CIPHER_CTX_num(ctx);
697 size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE;
698 int rest_len = n % GRASSHOPPER_BLOCK_SIZE;
699 grasshopper_w128_t h;
701 grasshopper_w128_t *iv_buffer = (grasshopper_w128_t *) iv;
702 grasshopper_w128_t tmp;
703 int encrypting = EVP_CIPHER_CTX_encrypting(ctx);
705 /* ======== Here we deal with associated data =========== */
706 if (out == NULL && c->mgm_state == mgm_associated_data) {
708 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
709 &c->partial_buffer, &c->c.buffer);
710 memcpy(c->mgm_iv, &c->partial_buffer, GRASSHOPPER_BLOCK_SIZE);
711 hexdump(stderr, "Tag", c->tag, 16);
715 /* Finalize partial_data */
716 if (inl + rest_len < GRASSHOPPER_BLOCK_SIZE) {
717 memcpy(c->mgm_partial_buffer.b + rest_len, current_in, inl);
719 EVP_CIPHER_CTX_set_num(ctx, n);
722 memcpy(c->mgm_partial_buffer.b + rest_len, current_in,
723 GRASSHOPPER_BLOCK_SIZE - rest_len);
725 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
727 inc_counter(c->mgm_iv->b, 8);
729 hexdump(stderr, "Hnext", h.b, 16);
730 hexdump(stderr, "Adata", c->mgm_partial_buffer.b, 16);
731 /* Galois multiply Hi * Ai */
732 gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
735 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
736 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
737 hexdump(stderr, "Tag", c->tag, 16);
739 current_in += GRASSHOPPER_BLOCK_SIZE - rest_len;
740 inl -= (GRASSHOPPER_BLOCK_SIZE - rest_len);
741 n += GRASSHOPPER_BLOCK_SIZE - rest_len;
745 while (inl >= GRASSHOPPER_BLOCK_SIZE) {
746 currentInputBlock = (grasshopper_w128_t *) current_in;
748 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
750 inc_counter(c->mgm_iv->b, 8);
752 hexdump(stderr, "Hnext", h.b, 16);
753 hexdump(stderr, "Adata", currentInputBlock->b, 16);
754 /* Galois multiply */
755 gf128_mul_uint64(tmp.q, h.q, currentInputBlock->q);
758 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
759 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
760 hexdump(stderr, "Tag", c->tag, 16);
762 current_in += GRASSHOPPER_BLOCK_SIZE;
763 inl -= GRASSHOPPER_BLOCK_SIZE;
764 n += GRASSHOPPER_BLOCK_SIZE;
768 memcpy(c->mgm_partial_buffer.b, current_in, inl);
772 EVP_CIPHER_CTX_set_num(ctx, n);
776 if (out == NULL && in != NULL && inl != 0 && c->mgm_state == mgm_main_data) {
777 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_DO_MGM, GOST_R_BAD_ORDER);
781 if (out != NULL && c->mgm_state == mgm_associated_data) {
782 memset(c->mgm_partial_buffer.b + rest_len, 0,
783 GRASSHOPPER_BLOCK_SIZE - rest_len);
785 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
787 inc_counter(c->mgm_iv->b, 8);
789 hexdump(stderr, "Hnext", h.b, 16);
790 hexdump(stderr, "Padded Adata", c->mgm_partial_buffer.b, 16);
791 /* Galois multiply Hi * Ai */
792 gf128_mul_uint64(tmp.q, h.q, c->mgm_partial_buffer.q);
795 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
796 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
797 hexdump(stderr, "Tag", c->tag, 16);
799 /* We finish processing associated data */
800 /* Pad rest of mgm_partial_buffer */
801 /* Process last block */
805 EVP_CIPHER_CTX_set_num(ctx, 0);
806 c->mgm_state = mgm_main_data;
808 fprintf(stderr, "============= Deal with main data\n");
811 /* ======== Here we deal with main data =========== */
813 /* actual IV derived from nonce */
814 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
815 &c->partial_buffer, &c->c.buffer);
816 memcpy(iv, c->partial_buffer.b, GRASSHOPPER_BLOCK_SIZE);
817 //hexdump(stderr, "Y1", iv, 16);
820 while (rest_len && inl) {
821 *(current_out++) = *(current_in++) ^ c->partial_buffer.b[rest_len];
824 c->partial_buffer.b[rest_len] = *(current_out - 1);
826 c->partial_buffer.b[rest_len] = *(current_in - 1);
831 if (rest_len == GRASSHOPPER_BLOCK_SIZE) {
833 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
835 inc_counter(c->mgm_iv->b, 8);
836 hexdump(stderr, "Hnext", h.b, 16);
837 hexdump(stderr, "Ciphertext", c->partial_buffer.b, 16);
838 /* Galois multiply Hi * Ai */
839 gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
842 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
843 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
844 hexdump(stderr, "Tag", c->tag, 16);
849 for (i = 0; i < blocks; i++) {
850 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
852 inc_counter(c->mgm_iv->b, 8);
854 currentInputBlock = (grasshopper_w128_t *) current_in;
855 currentOutputBlock = (grasshopper_w128_t *) current_out;
856 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
857 &c->partial_buffer, &c->c.buffer);
858 grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock);
861 grasshopper_copy128(currentOutputBlock, &tmp);
863 hexdump(stderr, "Hnext", h.b, 16);
864 hexdump(stderr, "Ciphertext", currentOutputBlock->b, 16);
865 /* Galois multiply Hi * Ai */
866 gf128_mul_uint64(tmp.q, h.q, currentOutputBlock->q);
869 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
870 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
871 hexdump(stderr, "Tag", c->tag, 16);
873 grasshopper_w128_t tmpin;
874 grasshopper_copy128(&tmpin, currentInputBlock);
875 grasshopper_copy128(currentOutputBlock, &tmp);
877 hexdump(stderr, "Hnext", h.b, 16);
878 hexdump(stderr, "Ciphertext", tmpin.b, 16);
879 /* Galois multiply Hi * Ai */
880 gf128_mul_uint64(tmp.q, h.q, tmpin.q);
883 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
884 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
885 hexdump(stderr, "Tag", c->tag, 16);
888 ctr128_inc(iv_buffer->b);
889 current_in += GRASSHOPPER_BLOCK_SIZE;
890 current_out += GRASSHOPPER_BLOCK_SIZE;
891 n += GRASSHOPPER_BLOCK_SIZE;
894 EVP_CIPHER_CTX_set_num(ctx, n);
897 lasted = inl - blocks * GRASSHOPPER_BLOCK_SIZE;
899 currentInputBlock = (grasshopper_w128_t *) current_in;
900 currentOutputBlock = (grasshopper_w128_t *) current_out;
901 grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer,
902 &c->partial_buffer, &c->c.buffer);
903 for (i = 0; i < lasted; i++) {
905 currentOutputBlock->b[i] =
906 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
907 c->partial_buffer.b[i] = currentOutputBlock->b[i];
909 unsigned char in = currentInputBlock->b[i];
910 currentOutputBlock->b[i] =
911 c->partial_buffer.b[i] ^ currentInputBlock->b[i];
912 c->partial_buffer.b[i] = in;
915 EVP_CIPHER_CTX_set_num(ctx, n + i);
916 ctr128_inc(iv_buffer->b);
920 if (in == NULL && inl == 0) {
921 unsigned char len_buf[16];
922 uint64_t a_len = 0, p_len = 0;
925 memset(c->partial_buffer.b + rest_len, 0,
926 GRASSHOPPER_BLOCK_SIZE - rest_len);
927 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv, &h,
929 inc_counter(c->mgm_iv->b, 8);
930 hexdump(stderr, "Hnext", h.b, 16);
931 hexdump(stderr, "Padded ciphertext", c->partial_buffer.b, 16);
932 /* Galois multiply Hi * Ai */
933 gf128_mul_uint64(tmp.q, h.q, c->partial_buffer.q);
936 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
937 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
938 hexdump(stderr, "Tag", c->tag, 16);
941 a_len = c->ad_length << 3;
942 p_len = (c->mgm_state == mgm_associated_data) ? 0 : n << 3;
945 a_len = bswap_64(a_len);
946 p_len = bswap_64(p_len);
948 memset(len_buf, 0, 16);
950 memcpy(len_buf, &a_len, sizeof(a_len));
951 memcpy(len_buf + sizeof(a_len), &p_len, sizeof(p_len));
952 grasshopper_encrypt_block(&c->c.encrypt_round_keys, c->mgm_iv,
955 hexdump(stderr, "Hlast", h.b, 16);
956 hexdump(stderr, "Lenbuf", len_buf, 16);
957 /* Galois multiply Hi * Ai */
958 gf128_mul_uint64(tmp.q, h.q, (uint64_t *)len_buf);
961 grasshopper_plus128(&h, (grasshopper_w128_t *) c->tag, &tmp);
962 grasshopper_copy128((grasshopper_w128_t *) c->tag, &h);
963 hexdump(stderr, "Tag", c->tag, 16);
965 /* Final tag calculation */
967 grasshopper_encrypt_block(&c->c.encrypt_round_keys,
968 (grasshopper_w128_t *) c->tag,
969 (grasshopper_w128_t *) c->final_tag,
973 grasshopper_w128_t decrypt_tag;
974 grasshopper_encrypt_block(&c->c.encrypt_round_keys,
975 (grasshopper_w128_t *) c->tag,
976 &decrypt_tag, &c->c.buffer);
977 if (memcmp(decrypt_tag.b, c->final_tag, 16)) {
978 hexdump(stderr, "Bad final tag", decrypt_tag.b, 16);
989 * Fixed 128-bit IV implementation make shift regiser redundant.
991 static void gost_grasshopper_cnt_next(gost_grasshopper_cipher_ctx_ofb * ctx,
992 grasshopper_w128_t * iv,
993 grasshopper_w128_t * buf)
995 memcpy(&ctx->buffer1, iv, 16);
996 grasshopper_encrypt_block(&ctx->c.encrypt_round_keys, &ctx->buffer1,
997 buf, &ctx->c.buffer);
1001 int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
1002 const unsigned char *in, size_t inl)
1004 gost_grasshopper_cipher_ctx_ofb *c = (gost_grasshopper_cipher_ctx_ofb *)
1005 EVP_CIPHER_CTX_get_cipher_data(ctx);
1006 const unsigned char *in_ptr = in;
1007 unsigned char *out_ptr = out;
1008 unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
1009 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
1010 int num = EVP_CIPHER_CTX_num(ctx);
1014 /* process partial block if any */
1016 for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
1017 j++, i++, in_ptr++, out_ptr++) {
1018 *out_ptr = buf[j] ^ (*in_ptr);
1020 if (j == GRASSHOPPER_BLOCK_SIZE) {
1021 EVP_CIPHER_CTX_set_num(ctx, 0);
1023 EVP_CIPHER_CTX_set_num(ctx, (int)j);
1028 for (; i + GRASSHOPPER_BLOCK_SIZE <
1030 i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
1031 GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
1033 * block cipher current iv
1036 gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
1037 (grasshopper_w128_t *) buf);
1040 * xor next block of input text with it and output it
1045 for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1046 out_ptr[j] = buf[j] ^ in_ptr[j];
1050 /* Process rest of buffer */
1052 gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv,
1053 (grasshopper_w128_t *) buf);
1054 for (j = 0; i < inl; j++, i++) {
1055 out_ptr[j] = buf[j] ^ in_ptr[j];
1057 EVP_CIPHER_CTX_set_num(ctx, (int)j);
1059 EVP_CIPHER_CTX_set_num(ctx, 0);
1065 int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
1066 const unsigned char *in, size_t inl)
1068 gost_grasshopper_cipher_ctx *c =
1069 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1070 const unsigned char *in_ptr = in;
1071 unsigned char *out_ptr = out;
1072 unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
1073 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
1074 bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx);
1075 int num = EVP_CIPHER_CTX_num(ctx);
1079 /* process partial block if any */
1081 for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl;
1082 j++, i++, in_ptr++, out_ptr++) {
1084 buf[j + GRASSHOPPER_BLOCK_SIZE] = *in_ptr;
1086 *out_ptr = buf[j] ^ (*in_ptr);
1088 buf[j + GRASSHOPPER_BLOCK_SIZE] = *out_ptr;
1091 if (j == GRASSHOPPER_BLOCK_SIZE) {
1092 memcpy(iv, buf + GRASSHOPPER_BLOCK_SIZE, GRASSHOPPER_BLOCK_SIZE);
1093 EVP_CIPHER_CTX_set_num(ctx, 0);
1095 EVP_CIPHER_CTX_set_num(ctx, (int)j);
1100 for (; i + GRASSHOPPER_BLOCK_SIZE <
1102 i += GRASSHOPPER_BLOCK_SIZE, in_ptr +=
1103 GRASSHOPPER_BLOCK_SIZE, out_ptr += GRASSHOPPER_BLOCK_SIZE) {
1105 * block cipher current iv
1107 grasshopper_encrypt_block(&c->encrypt_round_keys,
1108 (grasshopper_w128_t *) iv,
1109 (grasshopper_w128_t *) buf, &c->buffer);
1111 * xor next block of input text with it and output it
1117 memcpy(iv, in_ptr, GRASSHOPPER_BLOCK_SIZE);
1119 for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) {
1120 out_ptr[j] = buf[j] ^ in_ptr[j];
1123 /* Next iv is next block of cipher text */
1125 memcpy(iv, out_ptr, GRASSHOPPER_BLOCK_SIZE);
1129 /* Process rest of buffer */
1131 grasshopper_encrypt_block(&c->encrypt_round_keys,
1132 (grasshopper_w128_t *) iv,
1133 (grasshopper_w128_t *) buf, &c->buffer);
1135 memcpy(buf + GRASSHOPPER_BLOCK_SIZE, in_ptr, inl - i);
1137 for (j = 0; i < inl; j++, i++) {
1138 out_ptr[j] = buf[j] ^ in_ptr[j];
1140 EVP_CIPHER_CTX_set_num(ctx, (int)j);
1142 memcpy(buf + GRASSHOPPER_BLOCK_SIZE, out_ptr, j);
1145 EVP_CIPHER_CTX_set_num(ctx, 0);
1151 int gost_grasshopper_cipher_cleanup(EVP_CIPHER_CTX *ctx)
1153 gost_grasshopper_cipher_ctx *c =
1154 (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
1159 struct GRASSHOPPER_CIPHER_PARAMS *params = &gost_cipher_params[c->type];
1161 gost_grasshopper_cipher_destroy(c);
1162 if (params->destroy_cipher != NULL) {
1163 params->destroy_cipher(c);
1166 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
1171 int gost_grasshopper_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
1174 unsigned char *buf = NULL;
1175 ASN1_OCTET_STRING *os = NULL;
1177 os = ASN1_OCTET_STRING_new();
1179 if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
1181 GOSTerr(GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS,
1182 ERR_R_MALLOC_FAILURE);
1187 ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os);
1191 GRASSHOPPER_INLINE int gost_grasshopper_get_asn1_parameters(EVP_CIPHER_CTX
1197 if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
1204 int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
1208 case EVP_CTRL_RAND_KEY:{
1210 ((unsigned char *)ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
1211 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_RNG_ERROR);
1216 case EVP_CTRL_KEY_MESH:{
1217 gost_grasshopper_cipher_ctx_ctr *c =
1218 EVP_CIPHER_CTX_get_cipher_data(ctx);
1219 if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKM || !arg
1220 || (arg % GRASSHOPPER_BLOCK_SIZE))
1222 c->section_size = arg;
1225 #ifdef EVP_CTRL_TLS1_2_TLSTREE
1226 case EVP_CTRL_TLS1_2_TLSTREE:
1228 unsigned char newkey[32];
1229 int mode = EVP_CIPHER_CTX_mode(ctx);
1230 static const unsigned char zeroseq[8];
1231 gost_grasshopper_cipher_ctx_ctr *ctr_ctx = NULL;
1232 gost_grasshopper_cipher_ctx *c = NULL;
1234 unsigned char adjusted_iv[16];
1235 unsigned char seq[8];
1237 if (mode != EVP_CIPH_CTR_MODE)
1240 ctr_ctx = (gost_grasshopper_cipher_ctx_ctr *)
1241 EVP_CIPHER_CTX_get_cipher_data(ctx);
1244 memcpy(seq, ptr, 8);
1245 if (EVP_CIPHER_CTX_encrypting(ctx)) {
1247 * OpenSSL increments seq after mac calculation.
1248 * As we have Mac-Then-Encrypt, we need decrement it here on encryption
1249 * to derive the key correctly.
1251 if (memcmp(seq, zeroseq, 8) != 0) {
1252 for (j = 7; j >= 0; j--) {
1261 if (gost_tlstree(NID_grasshopper_cbc, c->master_key.k.b, newkey,
1262 (const unsigned char *)seq) > 0) {
1263 memset(adjusted_iv, 0, 16);
1264 memcpy(adjusted_iv, EVP_CIPHER_CTX_original_iv(ctx), 8);
1265 for (j = 7; j >= 0; j--) {
1266 int adj_byte, carry = 0;
1267 adj_byte = adjusted_iv[j] + seq[j] + carry;
1268 carry = (adj_byte > 255) ? 1 : 0;
1269 adjusted_iv[j] = adj_byte & 0xFF;
1271 EVP_CIPHER_CTX_set_num(ctx, 0);
1272 memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), adjusted_iv, 16);
1274 gost_grasshopper_cipher_key(c, newkey);
1280 case EVP_CTRL_AEAD_GET_TAG:
1281 case EVP_CTRL_AEAD_SET_TAG:
1283 gost_grasshopper_cipher_ctx_mgm *mgm_ctx = NULL;
1284 gost_grasshopper_cipher_ctx *c = NULL;
1286 unsigned char *tag = ptr;
1288 mgm_ctx = (gost_grasshopper_cipher_ctx_mgm *)
1289 EVP_CIPHER_CTX_get_cipher_data(ctx);
1290 c = (gost_grasshopper_cipher_ctx *) mgm_ctx;
1292 if (c->type != GRASSHOPPER_CIPHER_MGM)
1296 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1297 GOST_R_INVALID_TAG_LENGTH);
1301 if (type == EVP_CTRL_AEAD_GET_TAG)
1302 memcpy(tag, mgm_ctx->final_tag, taglen);
1304 memcpy(mgm_ctx->final_tag, tag, taglen);
1309 GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL,
1310 GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
1316 GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_create(int
1320 return EVP_CIPHER_meth_new(cipher_type, block_size /* block_size */ ,
1321 GRASSHOPPER_KEY_SIZE /* key_size */ );
1324 const int cipher_gost_grasshopper_setup(EVP_CIPHER *cipher, uint8_t mode,
1325 int iv_size, bool padding,
1328 return EVP_CIPHER_meth_set_iv_length(cipher, iv_size)
1329 && EVP_CIPHER_meth_set_flags(cipher,
1330 (unsigned long)(mode |
1332 EVP_CIPH_NO_PADDING :
1338 EVP_CIPH_ALWAYS_CALL_INIT |
1341 && EVP_CIPHER_meth_set_cleanup(cipher, gost_grasshopper_cipher_cleanup)
1342 && EVP_CIPHER_meth_set_set_asn1_params(cipher,
1343 gost_grasshopper_set_asn1_parameters)
1344 && EVP_CIPHER_meth_set_get_asn1_params(cipher,
1345 gost_grasshopper_get_asn1_parameters)
1346 && EVP_CIPHER_meth_set_ctrl(cipher, gost_grasshopper_cipher_ctl)
1347 && EVP_CIPHER_meth_set_do_cipher(cipher, gost_grasshopper_cipher_do);
1350 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper(uint8_t mode,
1353 EVP_CIPHER **cipher;
1354 struct GRASSHOPPER_CIPHER_PARAMS *params;
1356 cipher = &gost_grasshopper_ciphers[num];
1358 if (*cipher == NULL) {
1359 params = &gost_cipher_params[num];
1361 int nid = params->nid;
1362 grasshopper_init_cipher_func init_cipher = params->init_cipher;
1363 int block_size = params->block_size;
1364 int ctx_size = params->ctx_size;
1365 int iv_size = params->iv_size;
1366 bool padding = params->padding;
1368 int extra_flags = (num == GRASSHOPPER_CIPHER_MGM) ?
1369 EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_FLAG_AEAD_CIPHER : 0;
1371 *cipher = cipher_gost_grasshopper_create(nid, block_size);
1372 if (*cipher == NULL) {
1376 if (!cipher_gost_grasshopper_setup
1377 (*cipher, mode, iv_size, padding, extra_flags)
1378 || !EVP_CIPHER_meth_set_init(*cipher, init_cipher)
1379 || !EVP_CIPHER_meth_set_impl_ctx_size(*cipher, ctx_size)) {
1380 EVP_CIPHER_meth_free(*cipher);
1388 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ecb()
1390 return cipher_gost_grasshopper(EVP_CIPH_ECB_MODE, GRASSHOPPER_CIPHER_ECB);
1393 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cbc()
1395 return cipher_gost_grasshopper(EVP_CIPH_CBC_MODE, GRASSHOPPER_CIPHER_CBC);
1398 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ofb()
1400 return cipher_gost_grasshopper(EVP_CIPH_OFB_MODE, GRASSHOPPER_CIPHER_OFB);
1403 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_cfb()
1405 return cipher_gost_grasshopper(EVP_CIPH_CFB_MODE, GRASSHOPPER_CIPHER_CFB);
1408 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctr()
1410 return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_CTR);
1413 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_ctracpkm()
1415 return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE,
1416 GRASSHOPPER_CIPHER_CTRACPKM);
1419 const GRASSHOPPER_INLINE EVP_CIPHER *cipher_gost_grasshopper_mgm()
1421 #ifndef NID_kuznyechik_mgm
1424 return cipher_gost_grasshopper(EVP_CIPH_CTR_MODE, GRASSHOPPER_CIPHER_MGM);
1428 void cipher_gost_grasshopper_destroy(void)
1430 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB]);
1431 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_ECB] = NULL;
1432 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC]);
1433 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CBC] = NULL;
1434 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB]);
1435 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_OFB] = NULL;
1436 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB]);
1437 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CFB] = NULL;
1438 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR]);
1439 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTR] = NULL;
1440 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM]);
1441 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_CTRACPKM] = NULL;
1442 EVP_CIPHER_meth_free(gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM]);
1443 gost_grasshopper_ciphers[GRASSHOPPER_CIPHER_MGM] = NULL;