From da4b36b194bb2856203ce0987a61a0fe201d625f Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 20 Mar 2020 01:11:59 +0300 Subject: [PATCH 40/87] gost: add support for kuznyechik-ctr-acpkm mode Add support for CTR-ACPKM mode for Kuznyechik 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_kuznyechik.c | 60 ++++++++++++++++++++++ src/lib/libcrypto/evp/evp.h | 1 + src/lib/libcrypto/gost/gost.h | 2 + src/lib/libcrypto/gost/kuznyechik.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 142cebf46..c4edd9eb6 100644 --- a/src/lib/libcrypto/Symbols.list +++ b/src/lib/libcrypto/Symbols.list @@ -1728,6 +1728,7 @@ EVP_idea_ofb EVP_kuznyechik_cbc EVP_kuznyechik_cfb64 EVP_kuznyechik_ctr +EVP_kuznyechik_ctr_acpkm EVP_kuznyechik_ecb EVP_kuznyechik_ofb EVP_magma_cbc diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c index 9d66ad40f..c15be0c4f 100644 --- a/src/lib/libcrypto/evp/c_all.c +++ b/src/lib/libcrypto/evp/c_all.c @@ -240,6 +240,7 @@ OpenSSL_add_all_ciphers_internal(void) EVP_add_cipher(EVP_kuznyechik_cfb128()); EVP_add_cipher(EVP_kuznyechik_ofb()); EVP_add_cipher(EVP_kuznyechik_ctr()); + EVP_add_cipher(EVP_kuznyechik_ctr_acpkm()); #endif #ifndef OPENSSL_NO_SM4 diff --git a/src/lib/libcrypto/evp/e_kuznyechik.c b/src/lib/libcrypto/evp/e_kuznyechik.c index ebb857c62..5fd53aff6 100644 --- a/src/lib/libcrypto/evp/e_kuznyechik.c +++ b/src/lib/libcrypto/evp/e_kuznyechik.c @@ -64,6 +64,24 @@ kuznyechik_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) } } +static int +kuznyechik_acpkm_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + EVP_KUZNYECHIK_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_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 = 32; + return 1; + default: + return kuznyechik_ctl(ctx, type, arg, ptr); + } +} + static void Kuznyechik_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, const KUZNYECHIK_KEY *key, unsigned char *ivec, const int enc) @@ -126,6 +144,39 @@ kuznyechik_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned ch return 1; } +static int +kuznyechik_ctr_acpkm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + size_t len) +{ + EVP_KUZNYECHIK_CTX *key = EVP_C_DATA(EVP_KUZNYECHIK_CTX, ctx); + + CRYPTO_ctr128_encrypt(in, out, len, &key->ks, ctx->iv, ctx->buf, + &ctx->num, (block128_f)Kuznyechik_acpkm_encrypt); + return 1; +} + +static int +kuznyechik_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, 256 * 1024, 0); + + return gost3412_ctr_acpkm_set_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx)); +} + +static int +kuznyechik_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, 256 * 1024, 0); + + return gost3412_ctr_acpkm_get_asn1_params(ctx, params, EVP_CIPHER_CTX_iv_length(ctx)); +} + IMPLEMENT_BLOCK_CIPHER(kuznyechik, ks, Kuznyechik, EVP_KUZNYECHIK_CTX, NID_kuznyechik, 16, 32, 16, 128, 0, kuznyechik_init_key, NULL, EVP_CIPHER_set_asn1_iv, @@ -139,4 +190,13 @@ BLOCK_CIPHER_def1(kuznyechik, ctr, ctr, CTR, EVP_KUZNYECHIK_CTX, EVP_CIPHER_get_asn1_iv, kuznyechik_ctl) +#define NID_kuznyechik_ctr_acpkm NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm + +BLOCK_CIPHER_def1(kuznyechik, ctr_acpkm, ctr_acpkm, CTR, EVP_KUZNYECHIK_CTX, + NID_kuznyechik, 1, 32, 8, EVP_CIPH_CTRL_INIT | EVP_CIPH_ALWAYS_CALL_INIT, + kuznyechik_ctr_init_key, NULL, + kuznyechik_ctr_acpkm_set_asn1_params, + kuznyechik_ctr_acpkm_get_asn1_params, + kuznyechik_acpkm_ctl) + #endif diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h index 9e2ed23df..1ef416041 100644 --- a/src/lib/libcrypto/evp/evp.h +++ b/src/lib/libcrypto/evp/evp.h @@ -859,6 +859,7 @@ const EVP_CIPHER *EVP_kuznyechik_cbc(void); const EVP_CIPHER *EVP_kuznyechik_cfb128(void); const EVP_CIPHER *EVP_kuznyechik_ofb(void); const EVP_CIPHER *EVP_kuznyechik_ctr(void); +const EVP_CIPHER *EVP_kuznyechik_ctr_acpkm(void); #endif #ifndef OPENSSL_NO_SM4 diff --git a/src/lib/libcrypto/gost/gost.h b/src/lib/libcrypto/gost/gost.h index 2bddf038e..e84a7625b 100644 --- a/src/lib/libcrypto/gost/gost.h +++ b/src/lib/libcrypto/gost/gost.h @@ -111,6 +111,8 @@ void Kuznyechik_encrypt(const unsigned char *in, unsigned char *out, const KUZNYECHIK_KEY *key); void Kuznyechik_decrypt(const unsigned char *in, unsigned char *out, const KUZNYECHIK_KEY *key); +void Kuznyechik_acpkm_encrypt(const unsigned char *in, unsigned char *out, + KUZNYECHIK_KEY *key); typedef struct { ASN1_OCTET_STRING *iv; diff --git a/src/lib/libcrypto/gost/kuznyechik.c b/src/lib/libcrypto/gost/kuznyechik.c index 862b099fd..e2db0933a 100644 --- a/src/lib/libcrypto/gost/kuznyechik.c +++ b/src/lib/libcrypto/gost/kuznyechik.c @@ -234,4 +234,17 @@ Kuznyechik_decrypt(const unsigned char *src, unsigned char *dst, Sinv(dst, temp); memxor(dst, ctx->key + 16 * 0); } + +void +Kuznyechik_acpkm_encrypt(const unsigned char *in, + unsigned char *out, + KUZNYECHIK_KEY *key) +{ + if (key->key_meshing && key->count == key->key_meshing) { + acpkm_key_mesh(key, (acpkm_block *)Kuznyechik_encrypt, (acpkm_set_key *)Kuznyechik_set_enc_key, 16, 32); + key->count = 0; + } + Kuznyechik_encrypt(in, out, key); + key->count += 16; +} #endif diff --git a/src/regress/lib/libcrypto/evp/evptests.txt b/src/regress/lib/libcrypto/evp/evptests.txt index 69d856826..0c741d5dc 100644 --- a/src/regress/lib/libcrypto/evp/evptests.txt +++ b/src/regress/lib/libcrypto/evp/evptests.txt @@ -422,3 +422,7 @@ kuznyechik-ofb128:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcd kuznyechik-ofb128:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0a1b2c3d4e5f00112:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011:81800a59b1842b24ff1f795e897abd95779146db2d93a94ed93cf68b32397f19e93c9e57441d870545f24036a58ceea3cf3f0061d56423545b960d864cc868da:0 kuznyechik-cfb128:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0a1b2c3d4e5f00112:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011:81800a59b1842b24ff1f795e897abd9568c1b99c4df59cc7951e3739b5b3cdbf073f4dd2d6deb3cfb026545f7af1d8e8e1c852e9a8567162dbb5da7f66dea926:1 kuznyechik-cfb128:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0a1b2c3d4e5f00112:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011:81800a59b1842b24ff1f795e897abd9568c1b99c4df59cc7951e3739b5b3cdbf073f4dd2d6deb3cfb026545f7af1d8e8e1c852e9a8567162dbb5da7f66dea926:0 + +# R 1323565.1.017-2018 +kuznyechik-ctr-acpkm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a001133445566778899aabbcceeff0a001122445566778899aabbcceeff0a001122335566778899aabbcceeff0a0011223344:f195d8bec10ed1dbd57b5fa240bda1b885eee733f6a13e5df33ce4b33c45dee44bceeb8f646f4c55001706275e85e800587c4df568d094393e4834afd0805046cf30f57686aeece11cfc6c316b8a896edffd07ec813636460c4f3b743423163e6409a9c282fac8d469d221e7fbd6de5d:1 +kuznyechik-ctr-acpkm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1234567890abcef0:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a001133445566778899aabbcceeff0a001122445566778899aabbcceeff0a001122335566778899aabbcceeff0a0011223344:f195d8bec10ed1dbd57b5fa240bda1b885eee733f6a13e5df33ce4b33c45dee44bceeb8f646f4c55001706275e85e800587c4df568d094393e4834afd0805046cf30f57686aeece11cfc6c316b8a896edffd07ec813636460c4f3b743423163e6409a9c282fac8d469d221e7fbd6de5d:0 -- 2.17.1