From c7aacb08e50b0ca1f9c8f027755eecc57828b8e0 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 20 Mar 2020 01:11:59 +0300 Subject: [PATCH 39/87] gost: add support for magma-ctr-acpkm mode Add support for CTR-ACPKM mode for Magma cipher (see RFC 8645, Section 6.2.2). Signed-off-by: Dmitry Baryshkov --- src/lib/libcrypto/Symbols.list | 1 + src/lib/libcrypto/evp/c_all.c | 1 + src/lib/libcrypto/evp/e_magma.c | 60 ++++++++++++++++++++++ src/lib/libcrypto/evp/evp.h | 1 + src/lib/libcrypto/gost/gost.h | 2 + src/lib/libcrypto/gost/gost2814789.c | 13 +++++ src/regress/lib/libcrypto/evp/evptests.txt | 4 ++ 7 files changed, 82 insertions(+) diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list index d1d317fbd..142cebf46 100644 --- a/src/lib/libcrypto/Symbols.list +++ b/src/lib/libcrypto/Symbols.list @@ -1733,6 +1733,7 @@ EVP_kuznyechik_ofb EVP_magma_cbc EVP_magma_cfb64 EVP_magma_ctr +EVP_magma_ctr_acpkm EVP_magma_ecb EVP_magma_ofb EVP_md4 diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c index 2bb9a9a24..9d66ad40f 100644 --- a/src/lib/libcrypto/evp/c_all.c +++ b/src/lib/libcrypto/evp/c_all.c @@ -234,6 +234,7 @@ OpenSSL_add_all_ciphers_internal(void) EVP_add_cipher(EVP_magma_cfb64()); EVP_add_cipher(EVP_magma_ofb()); EVP_add_cipher(EVP_magma_ctr()); + EVP_add_cipher(EVP_magma_ctr_acpkm()); EVP_add_cipher(EVP_kuznyechik_ecb()); EVP_add_cipher(EVP_kuznyechik_cbc()); EVP_add_cipher(EVP_kuznyechik_cfb128()); diff --git a/src/lib/libcrypto/evp/e_magma.c b/src/lib/libcrypto/evp/e_magma.c index c88b25827..0311e04b1 100644 --- a/src/lib/libcrypto/evp/e_magma.c +++ b/src/lib/libcrypto/evp/e_magma.c @@ -58,6 +58,24 @@ magma_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) } } +static int +magma_acpkm_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + EVP_MAGMA_CTX *key = EVP_C_DATA(EVP_MAGMA_CTX, ctx); + + switch (type) { + case EVP_CTRL_GOST_SET_MESHING: + key->ks.key_meshing = arg; + return 1; + case EVP_CTRL_INIT: + /* deafult for tests */ + key->ks.key_meshing = 16; + return 1; + default: + return magma_ctl(ctx, type, arg, ptr); + } +} + static void Magma_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, const MAGMA_KEY *key, unsigned char *ivec, const int enc) @@ -120,6 +138,39 @@ magma_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *i return 1; } +static int +magma_ctr_acpkm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + size_t len) +{ + EVP_MAGMA_CTX *key = EVP_C_DATA(EVP_MAGMA_CTX, ctx); + + CRYPTO_ctr64_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf, + &ctx->num, (block64_f)Magma_acpkm_encrypt); + return 1; +} + +static int +magma_ctr_acpkm_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) +{ + /* Also set meshing section size here. + * There is no other good place to enable meshing for CMS + */ + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 8 * 1024, 0); + + return gost3412_ctr_acpkm_set_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx)); +} + +static int +magma_ctr_acpkm_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) +{ + /* Also set meshing section size here. + * There is no other good place to enable meshing for CMS + */ + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GOST_SET_MESHING, 8 * 1024, 0); + + return gost3412_ctr_acpkm_get_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx)); +} + IMPLEMENT_BLOCK_CIPHER(magma, ks, Magma, EVP_MAGMA_CTX, NID_magma, 8, 32, 8, 64, 0, magma_init_key, NULL, EVP_CIPHER_set_asn1_iv, @@ -133,4 +184,13 @@ BLOCK_CIPHER_def1(magma, ctr, ctr, CTR, EVP_MAGMA_CTX, EVP_CIPHER_get_asn1_iv, magma_ctl) +#define NID_magma_ctr_acpkm NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm + +BLOCK_CIPHER_def1(magma, ctr_acpkm, ctr_acpkm, CTR, EVP_MAGMA_CTX, + NID_magma, 1, 32, 4, EVP_CIPH_CTRL_INIT | EVP_CIPH_ALWAYS_CALL_INIT, + magma_ctr_init_key, NULL, + magma_ctr_acpkm_set_asn1_params, + magma_ctr_acpkm_get_asn1_params, + magma_acpkm_ctl) + #endif diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h index 77b3a4f8e..9e2ed23df 100644 --- a/src/lib/libcrypto/evp/evp.h +++ b/src/lib/libcrypto/evp/evp.h @@ -853,6 +853,7 @@ const EVP_CIPHER *EVP_magma_cbc(void); const EVP_CIPHER *EVP_magma_cfb64(void); const EVP_CIPHER *EVP_magma_ofb(void); const EVP_CIPHER *EVP_magma_ctr(void); +const EVP_CIPHER *EVP_magma_ctr_acpkm(void); const EVP_CIPHER *EVP_kuznyechik_ecb(void); const EVP_CIPHER *EVP_kuznyechik_cbc(void); const EVP_CIPHER *EVP_kuznyechik_cfb128(void); diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h index 421ca29f3..2bddf038e 100644 --- a/src/lib/libcrypto/gost/gost.h +++ b/src/lib/libcrypto/gost/gost.h @@ -91,6 +91,8 @@ void Magma_encrypt(const unsigned char *in, unsigned char *out, const MAGMA_KEY *key); void Magma_decrypt(const unsigned char *in, unsigned char *out, const MAGMA_KEY *key); +void Magma_acpkm_encrypt(const unsigned char *in, unsigned char *out, + MAGMA_KEY *key); #define KUZNYECHIK_KEY_SIZE 32 #define KUZNYECHIK_SUBKEYS_SIZE (16 * 10) diff --git a/src/lib/libcrypto/gost/gost2814789.c b/src/lib/libcrypto/gost/gost2814789.c index c9deee695..15449c6b4 100644 --- a/src/lib/libcrypto/gost/gost2814789.c +++ b/src/lib/libcrypto/gost/gost2814789.c @@ -205,6 +205,19 @@ Magma_decrypt(const unsigned char *in, unsigned char *out, be_l2c(n2, out); } +void +Magma_acpkm_encrypt(const unsigned char *in, + unsigned char *out, + MAGMA_KEY *key) +{ + if (key->key_meshing && key->count == key->key_meshing) { + acpkm_key_mesh(key, (acpkm_block *)Magma_encrypt, (acpkm_set_key *)Magma_set_key_int, 8, 32); + key->count = 0; + } + Magma_encrypt(in, out, key); + key->count += 8; +} + static void Gost2814789_mac(const unsigned char *in, unsigned char *mac, GOST2814789_KEY *key) diff --git a/src/regress/lib/libcrypto/evp/evptests.txt b/src/regress/lib/libcrypto/evp/evptests.txt index 064da8a12..69d856826 100644 --- a/src/regress/lib/libcrypto/evp/evptests.txt +++ b/src/regress/lib/libcrypto/evp/evptests.txt @@ -401,6 +401,10 @@ magma-ofb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:123 magma-cfb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:db37e0e266903c83b571ee29cca54ce791fabcb3abbe2fe3ff5d972d770f6ae9:1 magma-cfb64:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1234567890abcdef234567890abcdef1:92def06b3c130a59db54c704f8189d204a98fb2e67a8024c8912409b17b57e41:db37e0e266903c83b571ee29cca54ce791fabcb3abbe2fe3ff5d972d770f6ae9:0 +# R 1323565.1.017-2018 +magma-ctr-acpkm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:12345678:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899:2ab81deeeb1e4cab68e104c4bd6b94eac72c67af6c2e5b6b0eafb61770f1b32ea1ae71149eed1382abd467180672ec6f84a2f15b3fca72c1:1 +magma-ctr-acpkm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:12345678:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899:2ab81deeeb1e4cab68e104c4bd6b94eac72c67af6c2e5b6b0eafb61770f1b32ea1ae71149eed1382abd467180672ec6f84a2f15b3fca72c1:0 + # GOST R 34.12-2015 kuznyechik-ecb:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef::1122334455667700ffeeddccbbaa9988:7f679d90bebc24305a468d42b9d4edcd:1 kuznyechik-ecb:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef::1122334455667700ffeeddccbbaa9988:7f679d90bebc24305a468d42b9d4edcd:0 -- 2.17.1