From ebf9c1fec3c58cdf7e2b56220d384ab90647f966 Mon Sep 17 00:00:00 2001 From: Sergei Ianovich Date: Sat, 24 Sep 2022 18:11:26 +0300 Subject: [PATCH] provider wrapping for -mgm ciphers Signed-off-by: Sergei Ianovich --- CMakeLists.txt | 9 ++++++--- gost_prov_cipher.c | 38 ++++++++++++++++++++++++++++++++++++++ test_mgm.c | 5 ++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d21dfc1ef..5053ae454 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 ea42f2397..ce9665ea4 100644 --- a/gost_prov_cipher.c +++ b/gost_prov_cipher.c @@ -10,6 +10,7 @@ #include #include +#include #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 b61a8e3d5..31f8570e8 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) {