aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Ianovich <s@elektroplus.ru>2022-09-24 18:11:26 +0300
committerDmitry Belyavskiy <beldmit@users.noreply.github.com>2022-12-02 18:56:55 +0100
commitebf9c1fec3c58cdf7e2b56220d384ab90647f966 (patch)
tree66d386f64a450f75afdfe84878031248101901c4
parent39dc6de6a9474e10560ebfb0a9cecc05867b9c7b (diff)
downloadgost-engine-ebf9c1fec3c58cdf7e2b56220d384ab90647f966.zip
gost-engine-ebf9c1fec3c58cdf7e2b56220d384ab90647f966.tar.gz
gost-engine-ebf9c1fec3c58cdf7e2b56220d384ab90647f966.tar.bz2
provider wrapping for -mgm ciphers
Signed-off-by: Sergei Ianovich <sergei.ianovich@ya.ru>
-rw-r--r--CMakeLists.txt9
-rw-r--r--gost_prov_cipher.c38
-rw-r--r--test_mgm.c5
3 files changed, 48 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d21dfc1..5053ae4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -296,10 +296,13 @@ target_link_libraries(test_gost89 gost_core gost_err)
add_test(NAME gost89 COMMAND test_gost89)
add_executable(test_mgm test_mgm.c)
-target_link_libraries(test_mgm gost_core gost_err)
-add_test(NAME mgm COMMAND test_mgm)
-set_tests_properties(mgm
+target_link_libraries(test_mgm OpenSSL::Crypto)
+add_test(NAME mgm-with-engine COMMAND test_mgm)
+set_tests_properties(mgm-with-engine
PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+add_test(NAME mgm-with-provider COMMAND test_mgm)
+set_tests_properties(mgm-with-provider
+ PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}")
if(NOT SKIP_PERL_TESTS)
execute_process(COMMAND perl -MTest2::V0 -e ""
diff --git a/gost_prov_cipher.c b/gost_prov_cipher.c
index ea42f23..ce9665e 100644
--- a/gost_prov_cipher.c
+++ b/gost_prov_cipher.c
@@ -10,6 +10,7 @@
#include <openssl/core.h>
#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
#include "gost_prov.h"
#include "gost_lcl.h"
@@ -140,6 +141,15 @@ static int cipher_get_ctx_params(void *vgctx, OSSL_PARAM params[])
&& !OSSL_PARAM_set_octet_string(p, iv, ivlen))
return 0;
}
+ if ((p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG)) != NULL) {
+ void *tag = NULL;
+ size_t taglen = 0;
+
+ if (!OSSL_PARAM_get_octet_string_ptr(p, (const void**)&tag, &taglen)
+ || EVP_CIPHER_CTX_ctrl(gctx->cctx, EVP_CTRL_AEAD_GET_TAG,
+ taglen, tag) <= 0)
+ return 0;
+ }
return 1;
}
@@ -176,6 +186,24 @@ static int cipher_set_ctx_params(void *vgctx, const OSSL_PARAM params[])
key_mesh, NULL) <= 0)
return 0;
}
+ if ((p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN)) != NULL) {
+ size_t ivlen = 0;
+
+ if (!OSSL_PARAM_get_size_t(p, &ivlen)
+ || EVP_CIPHER_CTX_ctrl(gctx->cctx, EVP_CTRL_AEAD_SET_IVLEN,
+ ivlen, NULL) <= 0)
+ return 0;
+ }
+ if ((p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG)) != NULL) {
+ char tag[1024];
+ void *val = (void *) tag;
+ size_t taglen = 0;
+
+ if (!OSSL_PARAM_get_octet_string(p, &val, 1024, &taglen)
+ || EVP_CIPHER_CTX_ctrl(gctx->cctx, EVP_CTRL_AEAD_SET_TAG,
+ taglen, &tag) <= 0)
+ return 0;
+ }
return 1;
}
@@ -190,6 +218,7 @@ static int cipher_encrypt_init(void *vgctx,
|| keylen > EVP_CIPHER_key_length(gctx->cipher)
|| ivlen > EVP_CIPHER_iv_length(gctx->cipher))
return 0;
+
return EVP_CipherInit_ex(gctx->cctx, gctx->cipher, gctx->provctx->e,
key, iv, 1);
}
@@ -247,8 +276,10 @@ static const OSSL_PARAM *known_magma_ctr_cipher_params;
static const OSSL_PARAM *known_magma_ctr_acpkm_cipher_params;
static const OSSL_PARAM *known_magma_ctr_acpkm_omac_cipher_params;
static const OSSL_PARAM *known_magma_cbc_cipher_params;
+static const OSSL_PARAM *known_magma_mgm_cipher_params;
static const OSSL_PARAM *known_grasshopper_ctr_acpkm_cipher_params;
static const OSSL_PARAM *known_grasshopper_ctr_acpkm_omac_cipher_params;
+static const OSSL_PARAM *known_grasshopper_mgm_cipher_params;
/*
* These are named like the EVP_CIPHER templates in gost_crypt.c, with the
* added suffix "_functions". Hopefully, that makes it easy to find the
@@ -277,6 +308,7 @@ typedef void (*fptr_t)(void);
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (fptr_t)cipher_decrypt_init }, \
{ OSSL_FUNC_CIPHER_UPDATE, (fptr_t)cipher_update }, \
{ OSSL_FUNC_CIPHER_FINAL, (fptr_t)cipher_final }, \
+ { 0, NULL }, \
}
MAKE_FUNCTIONS(Gost28147_89_cipher);
@@ -292,8 +324,10 @@ MAKE_FUNCTIONS(magma_cbc_cipher);
MAKE_FUNCTIONS(magma_ctr_cipher);
MAKE_FUNCTIONS(magma_ctr_acpkm_cipher);
MAKE_FUNCTIONS(magma_ctr_acpkm_omac_cipher);
+MAKE_FUNCTIONS(magma_mgm_cipher);
MAKE_FUNCTIONS(grasshopper_ctr_acpkm_cipher);
MAKE_FUNCTIONS(grasshopper_ctr_acpkm_omac_cipher);
+MAKE_FUNCTIONS(grasshopper_mgm_cipher);
/* The OSSL_ALGORITHM for the provider's operation query function */
const OSSL_ALGORITHM GOST_prov_ciphers[] = {
@@ -313,10 +347,12 @@ const OSSL_ALGORITHM GOST_prov_ciphers[] = {
magma_ctr_acpkm_cipher_functions },
{ SN_magma_ctr_acpkm_omac ":1.2.643.7.1.1.5.1.2", NULL,
magma_ctr_acpkm_omac_cipher_functions },
+ { "magma-mgm", NULL, magma_mgm_cipher_functions },
{ SN_kuznyechik_ctr_acpkm ":1.2.643.7.1.1.5.2.1", NULL,
grasshopper_ctr_acpkm_cipher_functions },
{ SN_kuznyechik_ctr_acpkm_omac ":1.2.643.7.1.1.5.2.2", NULL,
grasshopper_ctr_acpkm_omac_cipher_functions },
+ { "kuznyechik-mgm", NULL, grasshopper_mgm_cipher_functions },
#if 0 /* Not yet implemented */
{ SN_magma_kexp15 ":1.2.643.7.1.1.7.1.1", NULL,
magma_kexp15_cipher_functions },
@@ -341,8 +377,10 @@ void GOST_prov_deinit_ciphers(void) {
&magma_ctr_cipher,
&magma_ctr_acpkm_cipher,
&magma_ctr_acpkm_omac_cipher,
+ &magma_mgm_cipher,
&grasshopper_ctr_acpkm_cipher,
&grasshopper_ctr_acpkm_omac_cipher,
+ &grasshopper_mgm_cipher,
};
size_t i;
#define elems(l) (sizeof(l) / sizeof(l[0]))
diff --git a/test_mgm.c b/test_mgm.c
index b61a8e3..31f8570 100644
--- a/test_mgm.c
+++ b/test_mgm.c
@@ -243,7 +243,9 @@ int main(void)
for (t = testcases; t->sn; t++) {
int small;
- const EVP_CIPHER *ciph = EVP_get_cipherbyname(t->sn);
+ const EVP_CIPHER *ciph_eng = EVP_get_cipherbyname(t->sn);
+ EVP_CIPHER *ciph_prov = EVP_CIPHER_fetch(NULL, t->sn, NULL);
+ const EVP_CIPHER *ciph = ciph_eng ? ciph_eng : ciph_prov;
const char *name;
if (!ciph) {
printf("failed to load %s\n", t->sn);
@@ -256,6 +258,7 @@ int main(void)
ret |= test_block(ciph, name, t->nonce, t->nonce_len,
t->aad, t->aad_len, t->plaintext, t->ptext_len,
t->expected, t->expected_tag, t->key, small);
+ EVP_CIPHER_free(ciph_prov);
}
if (ret) {