libressl/0048-evp-add-EVP_CIPHER-interface-for-kuznyechik-mgm.patch

245 lines
8.6 KiB
Diff
Raw Permalink Normal View History

From c9c7e6ed9d8c2deffdfe30c977ca91d2297177a9 Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
Date: Wed, 25 Mar 2020 23:44:15 +0300
Subject: [PATCH 48/87] evp: add EVP_CIPHER interface for kuznyechik-mgm
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_kuznyechik.c | 153 ++++++++++++++++++
src/lib/libcrypto/evp/evp.h | 3 +
.../lib/libcrypto/evp/evpaeadtests.txt | 3 +
5 files changed, 161 insertions(+)
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index 56169f990..d19720109 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1732,6 +1732,7 @@ EVP_kuznyechik_cfb64
EVP_kuznyechik_ctr
EVP_kuznyechik_ctr_acpkm
EVP_kuznyechik_ecb
+EVP_kuznyechik_mgm
EVP_kuznyechik_ofb
EVP_magma_cbc
EVP_magma_cfb64
diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c
index c15be0c4f..586466eb6 100644
--- a/src/lib/libcrypto/evp/c_all.c
+++ b/src/lib/libcrypto/evp/c_all.c
@@ -241,6 +241,7 @@ OpenSSL_add_all_ciphers_internal(void)
EVP_add_cipher(EVP_kuznyechik_ofb());
EVP_add_cipher(EVP_kuznyechik_ctr());
EVP_add_cipher(EVP_kuznyechik_ctr_acpkm());
+ EVP_add_cipher(EVP_kuznyechik_mgm());
#endif
#ifndef OPENSSL_NO_SM4
diff --git a/src/lib/libcrypto/evp/e_kuznyechik.c b/src/lib/libcrypto/evp/e_kuznyechik.c
index 88ecef8e5..d022db39c 100644
--- a/src/lib/libcrypto/evp/e_kuznyechik.c
+++ b/src/lib/libcrypto/evp/e_kuznyechik.c
@@ -202,6 +202,14 @@ BLOCK_CIPHER_def1(kuznyechik, ctr_acpkm, ctr_acpkm, CTR, EVP_KUZNYECHIK_CTX,
#define EVP_AEAD_KUZNYECHIK_MGM_TAG_LEN 16
+typedef struct {
+ KUZNYECHIK_KEY ks; /* KUZNYECHIK key schedule to use */
+ MGM128_CONTEXT mgm;
+ int key_set; /* Set if key initialised */
+ int iv_set; /* Set if an iv is set */
+ int tag_len;
+} EVP_KUZNYECHIK_MGM_CTX;
+
struct aead_kuznyechik_mgm_ctx {
KUZNYECHIK_KEY ks;
MGM128_CONTEXT mgm;
@@ -216,6 +224,151 @@ kuznyechik_mgm_set_key(KUZNYECHIK_KEY *kuznyechik_key, MGM128_CONTEXT *mgm_ctx,
CRYPTO_mgm128_init(mgm_ctx, kuznyechik_key, (block128_f)Kuznyechik_encrypt);
}
+static int
+kuznyechik_mgm_cleanup(EVP_CIPHER_CTX *c)
+{
+ EVP_KUZNYECHIK_MGM_CTX *gctx = c->cipher_data;
+
+ explicit_bzero(gctx, sizeof(*gctx));
+ return 1;
+}
+
+static int
+kuznyechik_mgm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+ EVP_KUZNYECHIK_MGM_CTX *gctx = c->cipher_data;
+
+ switch (type) {
+ case EVP_CTRL_INIT:
+ gctx->key_set = 0;
+ gctx->iv_set = 0;
+ gctx->tag_len = -1;
+ return 1;
+
+ case EVP_CTRL_MGM_SET_TAG:
+ if (arg <= 0 || arg > 16 || c->encrypt)
+ return 0;
+ memcpy(c->buf, ptr, arg);
+ gctx->tag_len = arg;
+ return 1;
+
+ case EVP_CTRL_MGM_GET_TAG:
+ if (arg <= 0 || arg > 16 || !c->encrypt || gctx->tag_len < 0)
+ return 0;
+ memcpy(ptr, c->buf, arg);
+ return 1;
+
+ case EVP_CTRL_COPY:
+ {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_KUZNYECHIK_MGM_CTX *gctx_out = out->cipher_data;
+
+ if (gctx->mgm.key) {
+ if (gctx->mgm.key != &gctx->ks)
+ return 0;
+ gctx_out->mgm.key = &gctx_out->ks;
+ }
+
+ return 1;
+ }
+
+ default:
+ return -1;
+
+ }
+}
+
+static int
+kuznyechik_mgm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc)
+{
+ EVP_KUZNYECHIK_MGM_CTX *gctx = ctx->cipher_data;
+
+ if (!iv && !key)
+ return 1;
+ if (key) {
+ kuznyechik_mgm_set_key(&gctx->ks, &gctx->mgm, key, ctx->key_len);
+
+ /* If we have an iv can set it directly, otherwise use
+ * saved IV.
+ */
+ if (gctx->iv_set)
+ iv = ctx->iv;
+ if (iv) {
+ CRYPTO_mgm128_setiv(&gctx->mgm, iv);
+ gctx->iv_set = 1;
+ }
+ gctx->key_set = 1;
+ } else {
+ /* If key set use IV, otherwise copy */
+ if (gctx->key_set)
+ CRYPTO_mgm128_setiv(&gctx->mgm, iv);
+ else
+ memcpy(ctx->iv, iv, ctx->cipher->iv_len);
+ gctx->iv_set = 1;
+ }
+ return 1;
+}
+
+static int
+kuznyechik_mgm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t len)
+{
+ EVP_KUZNYECHIK_MGM_CTX *gctx = ctx->cipher_data;
+
+ /* If not set up, return error */
+ if (!gctx->key_set)
+ return -1;
+
+ if (!gctx->iv_set)
+ return -1;
+
+ if (in) {
+ if (out == NULL) {
+ if (CRYPTO_mgm128_aad(&gctx->mgm, in, len))
+ return -1;
+ } else if (ctx->encrypt) {
+ if (CRYPTO_mgm128_encrypt(&gctx->mgm, in, out, len))
+ return -1;
+ } else {
+ if (CRYPTO_mgm128_decrypt(&gctx->mgm, in, out, len))
+ return -1;
+ }
+ return len;
+ } else {
+ if (!ctx->encrypt) {
+ if (gctx->tag_len < 0)
+ return -1;
+ if (CRYPTO_mgm128_finish(&gctx->mgm, ctx->buf, gctx->tag_len) != 0)
+ return -1;
+ gctx->iv_set = 0;
+ return 0;
+ }
+ CRYPTO_mgm128_tag(&gctx->mgm, ctx->buf, 16);
+ gctx->tag_len = 16;
+
+ /* Don't reuse the IV */
+ gctx->iv_set = 0;
+ return 0;
+ }
+
+}
+
+#define CUSTOM_FLAGS \
+ ( EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV | \
+ EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | \
+ EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY )
+
+#define NID_kuznyechik_mgm NID_id_tc26_cipher_gostr3412_2015_kuznyechik_mgm
+
+BLOCK_CIPHER_def1(kuznyechik, mgm, mgm, GCM, EVP_KUZNYECHIK_MGM_CTX,
+ NID_kuznyechik, 1, 32, 16,
+ EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS,
+ kuznyechik_mgm_init_key, kuznyechik_mgm_cleanup,
+ EVP_CIPHER_set_asn1_iv,
+ EVP_CIPHER_get_asn1_iv,
+ kuznyechik_mgm_ctrl)
+
static int
aead_kuznyechik_mgm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len,
size_t tag_len)
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 88d9b1989..334ce1cd3 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -385,6 +385,8 @@ struct evp_cipher_st {
#define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG
#define EVP_CTRL_CCM_SET_L 0x14
#define EVP_CTRL_CCM_SET_MSGLEN 0x15
+#define EVP_CTRL_MGM_GET_TAG EVP_CTRL_GCM_GET_TAG
+#define EVP_CTRL_MGM_SET_TAG EVP_CTRL_GCM_SET_TAG
/* AEAD cipher deduces payload length and returns number of bytes
* required to store MAC and eventual padding. Subsequent call to
* EVP_Cipher even appends/verifies MAC.
@@ -860,6 +862,7 @@ 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);
+const EVP_CIPHER *EVP_kuznyechik_mgm(void);
#endif
#ifndef OPENSSL_NO_SM4
diff --git a/src/regress/lib/libcrypto/evp/evpaeadtests.txt b/src/regress/lib/libcrypto/evp/evpaeadtests.txt
index 68156e7a5..69ccd8c17 100644
--- a/src/regress/lib/libcrypto/evp/evpaeadtests.txt
+++ b/src/regress/lib/libcrypto/evp/evpaeadtests.txt
@@ -12,3 +12,6 @@ aes-128-gcm:88EE087FD95DA9FBF6725AA9D757B0CD:7AE8E2CA4EC500012E58495C:68F2E77696
aes-256-gcm:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5:7AE8E2CA4EC500012E58495C:68F2E77696CE7AE8E2CA4EC588E54D002E58495C:08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008:BA8AE31BC506486D6873E4FCE460E7DC57591FF00611F31C3834FE1C04AD80B66803AFCF5B27E6333FA67C99DA47C2F0CED68D531BD741A943CFF7A6713BD0:2611CD7DAA01D61C5C886DC1A8170107:1
aes-256-gcm:4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5:7AE8E2CA4EC500012E58495C:68F2E77696CE7AE8E2CA4EC588E54D002E58495C:08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008:BA8AE31BC506486D6873E4FCE460E7DC57591FF00611F31C3834FE1C04AD80B66803AFCF5B27E6333FA67C99DA47C2F0CED68D531BD741A943CFF7A6713BD0:2611CD7DAA01D61C5C886DC1A8170107:0
+
+kuznyechik-mgm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1122334455667700ffeeddccbbaa9988:0202020202020202010101010101010104040404040404040303030303030303ea0505050505050505:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011aabbcc:a9757b8147956e9055b8a33de89f42fc8075d2212bf9fd5bd3f7069aadc16b39497ab15915a6ba85936b5d0ea9f6851cc60c14d4d3f883d0ab94420695c76deb2c7552:cf5d656f40c34f5c46e8bb0e29fcdb4c:1
+kuznyechik-mgm:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef:1122334455667700ffeeddccbbaa9988:0202020202020202010101010101010104040404040404040303030303030303ea0505050505050505:1122334455667700ffeeddccbbaa998800112233445566778899aabbcceeff0a112233445566778899aabbcceeff0a002233445566778899aabbcceeff0a0011aabbcc:a9757b8147956e9055b8a33de89f42fc8075d2212bf9fd5bd3f7069aadc16b39497ab15915a6ba85936b5d0ea9f6851cc60c14d4d3f883d0ab94420695c76deb2c7552:cf5d656f40c34f5c46e8bb0e29fcdb4c:0
--
2.17.1