libressl/0039-gost-add-support-for-magma-ctr-acpkm-mode.patch

194 lines
7.7 KiB
Diff
Raw Permalink Normal View History

From c7aacb08e50b0ca1f9c8f027755eecc57828b8e0 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
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 <dbaryshkov@gmail.com>
---
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