diff --git a/CMakeLists.txt b/CMakeLists.txt index d21dfc1e..5053ae45 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_eng.c b/gost_eng.c index a0961aaf..e7d5a879 100644 --- a/gost_eng.c +++ b/gost_eng.c @@ -341,6 +341,7 @@ static int create_NIDs() { ASN1_OBJECT_create(new_nid + i, NULL, 0, job->sn, job->ln); if (!obj || OBJ_add_object(obj) == NID_undef) { OPENSSL_free(obj); + fprintf(stderr, "failed NID for %s\n", job->sn); return 0; } (*missing_NIDs[i]->callback)(new_nid + i); diff --git a/gost_prov_cipher.c b/gost_prov_cipher.c index ea42f239..07702bc5 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,20 @@ 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) { + 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_GET_TAG, + taglen, &tag) <= 0) + return 0; + + if (!OSSL_PARAM_set_octet_ptr(p, tag, taglen) + && !OSSL_PARAM_set_octet_string(p, tag, taglen)) + return 0; + } return 1; } @@ -176,6 +191,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 +223,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 +281,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 +313,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 +329,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 +352,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 +382,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 6b009f2a..d62f85e7 100644 --- a/test_mgm.c +++ b/test_mgm.c @@ -233,21 +233,18 @@ int main(void) int ret = 0; const struct testcase *t; - setenv("OPENSSL_ENGINES", ENGINE_DIR, 0); OPENSSL_add_all_algorithms_conf(); - ERR_load_crypto_strings(); - ENGINE *eng; - T(eng = ENGINE_by_id("gost")); - T(ENGINE_init(eng)); - T(ENGINE_set_default(eng, ENGINE_METHOD_ALL)); for (t = testcases; t->sn; t++) { int small; const EVP_CIPHER *ciph = EVP_get_cipherbyname(t->sn); const char *name; if (!ciph) { - printf("failed to load %s\n", t->sn); - return 1; + ciph = EVP_CIPHER_fetch(NULL, t->sn, NULL); + if (!ciph) { + printf("failed to load %s\n", t->sn); + return 1; + } } name = EVP_CIPHER_name(ciph); @@ -258,9 +255,6 @@ int main(void) t->expected, t->expected_tag, t->key, small); } - ENGINE_finish(eng); - ENGINE_free(eng); - if (ret) { printf("Some tests FAILED!\n"); } else {