From bb27f7693c10da305d547b100e694823cac097f9 Mon Sep 17 00:00:00 2001 From: arx11 <> Date: Sun, 24 Mar 2024 06:33:44 -0400 Subject: [PATCH 1/5] Added support for magma-ctracpkm-omac. Magma OMAC is implemented the same way as NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac. And with test vectors. --- gost_crypt.c | 11 +++++++---- gost_eng.c | 1 + gost_lcl.h | 3 +++ gost_omac_acpkm.c | 36 +++++++++++++++++++++++++++++++++-- gost_pmeth.c | 1 + gost_prov_mac.c | 9 ++++++++- test_context.c | 1 + test_digest.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 103 insertions(+), 7 deletions(-) diff --git a/gost_crypt.c b/gost_crypt.c index 516e598d4..85b194a99 100644 --- a/gost_crypt.c +++ b/gost_crypt.c @@ -519,6 +519,7 @@ static int magma_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, c->key_meshing = 0; } + c->count = 0; return 1; } @@ -1273,10 +1274,6 @@ static int magma_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) return -1; } - if (c->count != 0) { - return -1; - } - c->key_meshing = arg; return 1; } @@ -1650,4 +1647,10 @@ static int gost_imit_cleanup(EVP_MD_CTX *ctx) memset(EVP_MD_CTX_md_data(ctx), 0, sizeof(struct ossl_gost_imit_ctx)); return 1; } + +/* Called directly by CMAC_ACPKM_Init() */ +const EVP_CIPHER *cipher_gost_magma_ctracpkm() +{ + return GOST_init_cipher(&magma_ctr_acpkm_cipher); +} /* vim: set expandtab cinoptions=\:0,l1,t0,g0,(0 sw=4 : */ diff --git a/gost_eng.c b/gost_eng.c index 7ca552372..4df83e8a0 100644 --- a/gost_eng.c +++ b/gost_eng.c @@ -80,6 +80,7 @@ GOST_digest *gost_digest_array[] = { &magma_mac_digest, &grasshopper_mac_digest, &kuznyechik_ctracpkm_omac_digest, + &magma_ctracpkm_omac_digest, }; GOST_cipher *gost_cipher_array[] = { diff --git a/gost_lcl.h b/gost_lcl.h index ffa8c76d1..21a519782 100644 --- a/gost_lcl.h +++ b/gost_lcl.h @@ -342,6 +342,8 @@ typedef struct gost_cipher_st GOST_cipher; EVP_CIPHER *GOST_init_cipher(GOST_cipher *c); void GOST_deinit_cipher(GOST_cipher *c); +const EVP_CIPHER *cipher_gost_magma_ctracpkm(); + /* ENGINE implementation data */ extern GOST_cipher Gost28147_89_cipher; extern GOST_cipher Gost28147_89_cbc_cipher; @@ -398,6 +400,7 @@ extern GOST_digest GostR3411_2012_512_digest; extern GOST_digest magma_mac_digest; extern GOST_digest grasshopper_mac_digest; extern GOST_digest kuznyechik_ctracpkm_omac_digest; +extern GOST_digest magma_ctracpkm_omac_digest; /* Provider implementation data */ extern const OSSL_ALGORITHM GOST_prov_digests[]; diff --git a/gost_omac_acpkm.c b/gost_omac_acpkm.c index 8a3c841ad..79cfa2242 100644 --- a/gost_omac_acpkm.c +++ b/gost_omac_acpkm.c @@ -138,9 +138,16 @@ static int CMAC_ACPKM_Init(CMAC_ACPKM_CTX *ctx, const void *key, size_t keylen, if (!EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL)) return 0; - if (!EVP_CIPHER_is_a(cipher, SN_grasshopper_cbc)) + /* EVP_CIPHER_is_a doesn't work, checking by NID */ + if (EVP_CIPHER_is_a(cipher, SN_magma_cbc) + && EVP_CIPHER_nid(cipher) == NID_magma_cbc) + acpkm = cipher_gost_magma_ctracpkm(); + else if (EVP_CIPHER_is_a(cipher, SN_grasshopper_cbc) + && EVP_CIPHER_nid(cipher) == NID_grasshopper_cbc) + acpkm = cipher_gost_grasshopper_ctracpkm(); + else return 0; - acpkm = cipher_gost_grasshopper_ctracpkm(); + if (!EVP_EncryptInit_ex(ctx->actx, acpkm, impl, NULL, NULL)) return 0; } @@ -319,6 +326,9 @@ static int omac_acpkm_init(EVP_MD_CTX *ctx, const char *cipher_name) case NID_grasshopper_cbc: c->dgst_size = 16; break; + case NID_magma_cbc: + c->dgst_size = 8; + break; } return 1; @@ -329,6 +339,11 @@ static int grasshopper_omac_acpkm_init(EVP_MD_CTX *ctx) return omac_acpkm_init(ctx, SN_grasshopper_cbc); } +static int magma_omac_acpkm_init(EVP_MD_CTX *ctx) +{ + return omac_acpkm_init(ctx, SN_magma_cbc); +} + static int omac_acpkm_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) { @@ -432,6 +447,9 @@ int omac_acpkm_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) if (EVP_MD_is_a(md, SN_grasshopper_mac) || EVP_MD_is_a(md, SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac)) c->cipher_name = SN_grasshopper_cbc; + else if (EVP_MD_is_a(md, SN_magma_mac) + || EVP_MD_is_a(md, SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac)) + c->cipher_name = SN_magma_cbc; } if ((cipher = (EVP_CIPHER *)EVP_get_cipherbyname(c->cipher_name)) == NULL @@ -527,3 +545,17 @@ GOST_digest kuznyechik_ctracpkm_omac_digest = { .cleanup = omac_acpkm_imit_cleanup, .ctrl = omac_acpkm_imit_ctrl, }; + +GOST_digest magma_ctracpkm_omac_digest = { + .nid = NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac, + .result_size = 8, + .input_blocksize = 8, + .app_datasize = sizeof(OMAC_ACPKM_CTX), + .flags = EVP_MD_FLAG_XOF, + .init = magma_omac_acpkm_init, + .update = omac_acpkm_imit_update, + .final = omac_acpkm_imit_final, + .copy = omac_acpkm_imit_copy, + .cleanup = omac_acpkm_imit_cleanup, + .ctrl = omac_acpkm_imit_ctrl, +}; diff --git a/gost_pmeth.c b/gost_pmeth.c index 44bfc75ff..bf7528c0e 100644 --- a/gost_pmeth.c +++ b/gost_pmeth.c @@ -1131,6 +1131,7 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy); return 1; case NID_magma_mac: + case NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac: /* FIXME beldmit */ EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_magma_mac_ctrl, pkey_gost_magma_mac_ctrl_str); EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_magma_mac_signctx_init, diff --git a/gost_prov_mac.c b/gost_prov_mac.c index ab04a9c24..77dcb7bff 100644 --- a/gost_prov_mac.c +++ b/gost_prov_mac.c @@ -282,6 +282,8 @@ static int mac_set_ctx_params(void *mctx, const OSSL_PARAM params[]) #define gost_mac_12_digest Gost28147_89_mac_12_digest #define id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac_digest \ kuznyechik_ctracpkm_omac_digest +#define id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac_digest \ + magma_ctracpkm_omac_digest typedef void (*fptr_t)(void); #define MAKE_FUNCTIONS(name, macsize) \ @@ -331,6 +333,7 @@ MAKE_FUNCTIONS(gost_mac_12, 4); MAKE_FUNCTIONS(magma_mac, 8); MAKE_FUNCTIONS(grasshopper_mac, 16); MAKE_FUNCTIONS(id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac, 16); +MAKE_FUNCTIONS(id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac, 8); /* The OSSL_ALGORITHM for the provider's operation query function */ const OSSL_ALGORITHM GOST_prov_macs[] = { @@ -342,6 +345,9 @@ const OSSL_ALGORITHM GOST_prov_macs[] = { { SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac ":1.2.643.7.1.1.5.2.2", NULL, id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac_functions }, + { SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac + ":1.2.643.7.1.1.5.1.2", NULL, + id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac_functions }, { NULL , NULL, NULL } }; @@ -351,7 +357,8 @@ void GOST_prov_deinit_mac_digests(void) { &Gost28147_89_mac_12_digest, &magma_mac_digest, &grasshopper_mac_digest, - &kuznyechik_ctracpkm_omac_digest + &kuznyechik_ctracpkm_omac_digest, + &magma_ctracpkm_omac_digest }; size_t i; #define elems(l) (sizeof(l) / sizeof(l[0])) diff --git a/test_context.c b/test_context.c index d9ef57926..5f710efb1 100644 --- a/test_context.c +++ b/test_context.c @@ -333,6 +333,7 @@ static struct testcase_digest { { SN_magma_mac, 1 }, { SN_grasshopper_mac, 1 }, { SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac, 1 }, + { SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac, 1 }, { 0 }, }; int main(int argc, char **argv) diff --git a/test_digest.c b/test_digest.c index 68c0e3253..d630e72e6 100644 --- a/test_digest.c +++ b/test_digest.c @@ -108,6 +108,30 @@ static const char MAC_omac[] = { 0x33,0x6f,0x4d,0x29,0x60,0x59,0xfb,0xe3 }; */ static const char MAC_magma_omac[] = { 0x15,0x4e,0x72,0x10 }; +/* + * OMAC-ACPKM test vector from R 1323565.1.017-2018 A.3.1 + */ +static const char P_omac_acpkm01[] = { + 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0xFF,0xEE,0xDD,0xCC, +}; + +static const char MAC_omac_acpkm01[] = { + 0xA0,0x54,0x0E,0x37,0x30,0xAC,0xBC,0xF3, +}; + +/* + * OMAC-ACPKM test vector from R 1323565.1.017-2018 A.3.2 + */ +static const char P_omac_acpkm02[] = { + 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x00,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,0x99,0x88, + 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xEE,0xFF,0x0A, + 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88, +}; + +static const char MAC_omac_acpkm02[] = { + 0x34,0x00,0x8D,0xAD,0x54,0x96,0xBB,0x8E, +}; + /* * OMAC-ACPKM test vector from R 1323565.1.017-2018 A.4.1 */ @@ -277,6 +301,30 @@ static const struct hash_testvec testvecs[] = { .outsize = 64 / 8, .truncate = sizeof(MAC_magma_omac), }, + { + .algname = SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac, + .name = "M from R 1323565.1.017-2018 (A.3.1)", + .plaintext = P_omac_acpkm01, + .psize = sizeof(P_omac_acpkm01), + .key = K, + .key_size = sizeof(K), + .acpkm = 128 / 8, + .acpkm_t = 640 / 8, + .digest = MAC_omac_acpkm01, + .outsize = sizeof(MAC_omac_acpkm01), + }, + { + .algname = SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac, + .name = "M from R 1323565.1.017-2018 (A.3.2)", + .plaintext = P_omac_acpkm02, + .psize = sizeof(P_omac_acpkm02), + .key = K, + .key_size = sizeof(K), + .acpkm = 128 / 8, + .acpkm_t = 640 / 8, + .digest = MAC_omac_acpkm02, + .outsize = sizeof(MAC_omac_acpkm02), + }, { .algname = SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac, .name = "M from R 1323565.1.017-2018 (A.4.1)", From d9070388cbefc6958bbf050ca2a71b3b4329825f Mon Sep 17 00:00:00 2001 From: arx11 <> Date: Mon, 25 Mar 2024 15:02:47 -0400 Subject: [PATCH 2/5] Fixed algorithm detection between magma and kuznyechik in OMAC. --- gost_omac_acpkm.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/gost_omac_acpkm.c b/gost_omac_acpkm.c index 79cfa2242..f10b11865 100644 --- a/gost_omac_acpkm.c +++ b/gost_omac_acpkm.c @@ -134,18 +134,27 @@ static int CMAC_ACPKM_Init(CMAC_ACPKM_CTX *ctx, const void *key, size_t keylen, } /* Initialise context */ if (cipher) { - const EVP_CIPHER *acpkm; + const EVP_CIPHER *acpkm = NULL; if (!EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL)) return 0; - /* EVP_CIPHER_is_a doesn't work, checking by NID */ - if (EVP_CIPHER_is_a(cipher, SN_magma_cbc) - && EVP_CIPHER_nid(cipher) == NID_magma_cbc) - acpkm = cipher_gost_magma_ctracpkm(); - else if (EVP_CIPHER_is_a(cipher, SN_grasshopper_cbc) - && EVP_CIPHER_nid(cipher) == NID_grasshopper_cbc) - acpkm = cipher_gost_grasshopper_ctracpkm(); - else + /* Unfortunately, EVP_CIPHER_is_a is bugged for an engine, EVP_CIPHER_nid is bugged for a provider. */ + if (EVP_CIPHER_nid(cipher) == NID_undef) { + /* Looks like a provider */ + if (EVP_CIPHER_is_a(cipher, SN_magma_cbc)) + acpkm = cipher_gost_magma_ctracpkm(); + else if (EVP_CIPHER_is_a(cipher, SN_grasshopper_cbc)) + acpkm = cipher_gost_grasshopper_ctracpkm(); + } + else { + /* Looks like an engine */ + if (EVP_CIPHER_nid(cipher) == NID_magma_cbc) + acpkm = cipher_gost_magma_ctracpkm(); + else if (EVP_CIPHER_nid(cipher) == NID_grasshopper_cbc) + acpkm = cipher_gost_grasshopper_ctracpkm(); + } + + if (acpkm == NULL) return 0; if (!EVP_EncryptInit_ex(ctx->actx, acpkm, impl, NULL, NULL)) @@ -486,9 +495,13 @@ int omac_acpkm_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) return -1; c->cmac_ctx->section_size = arg; if (ptr && *(int *)ptr) { + const EVP_CIPHER *cipher; + if ((cipher = EVP_CIPHER_CTX_cipher(c->cmac_ctx->actx)) == NULL) { + return 0; + } + /* Set parameter T */ - if (EVP_CIPHER_get0_provider(EVP_CIPHER_CTX_cipher(c->cmac_ctx->actx)) - == NULL) { + if (EVP_CIPHER_get0_provider(cipher) == NULL) { if (!EVP_CIPHER_CTX_ctrl(c->cmac_ctx->actx, EVP_CTRL_KEY_MESH, *(int *)ptr, NULL)) return 0; From 18ad998eb111bfda7ce13bc80a9bfea3f71be66e Mon Sep 17 00:00:00 2001 From: arx11 <> Date: Tue, 26 Mar 2024 06:47:06 -0400 Subject: [PATCH 3/5] Fix "openssl engine" check --- test/00-engine.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/00-engine.t b/test/00-engine.t index 0904a21aa..e2d9d0f13 100644 --- a/test/00-engine.t +++ b/test/00-engine.t @@ -40,7 +40,7 @@ if ( -f $engine . ".info") { $engine_info= < Date: Tue, 26 Mar 2024 14:31:56 -0400 Subject: [PATCH 4/5] Fix "openssl engine" check (again) --- test/00-engine.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/00-engine.t b/test/00-engine.t index e2d9d0f13..50896fa27 100644 --- a/test/00-engine.t +++ b/test/00-engine.t @@ -40,7 +40,7 @@ if ( -f $engine . ".info") { $engine_info= < Date: Wed, 27 Mar 2024 14:14:40 -0400 Subject: [PATCH 5/5] Fix another "openssl engine" check --- tcl_tests/engine.try | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcl_tests/engine.try b/tcl_tests/engine.try index 83d9ab978..f42dbf087 100644 --- a/tcl_tests/engine.try +++ b/tcl_tests/engine.try @@ -6,7 +6,7 @@ start_tests "Тесты на команду engine" switch -exact [engine_name] { "ccore" {set list " \[RAND, gost89, gost89-cnt, gost89-cnt-12, gost89-cbc, id-tc26-cipher-gostr3412-2015-magma-ctracpkm, magma-ctr, magma-ofb, magma-ecb, magma-cbc, magma-cfb, grasshopper-ecb, grasshopper-cbc, grasshopper-ofb, grasshopper-cfb, grasshopper-ctr, id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm, md_gost94, gost-mac, md_gost12_256, md_gost12_512, gost-mac-12, gost2001, id-GostR3410-2001DH, gost-mac, gost2012_256, gost2012_512, gost-mac-12\]\n"} - "open" {set list "(gost) Reference implementation of GOST engine\n \[gost89, gost89-cnt, gost89-cnt-12, gost89-cbc, kuznyechik-ecb, kuznyechik-cbc, kuznyechik-cfb, kuznyechik-ofb, kuznyechik-ctr, magma-ecb, kuznyechik-mgm, magma-cbc, magma-ctr, magma-ctr-acpkm, magma-ctr-acpkm-omac, magma-mgm, kuznyechik-ctr-acpkm, kuznyechik-ctr-acpkm-omac, magma-kexp15, kuznyechik-kexp15, md_gost94, gost-mac, md_gost12_256, md_gost12_512, gost-mac-12, magma-mac, kuznyechik-mac, kuznyechik-ctr-acpkm-omac, gost2001, id-GostR3410-2001DH, gost-mac, gost2012_256, gost2012_512, gost-mac-12, magma-mac, kuznyechik-mac, magma-ctr-acpkm-omac, kuznyechik-ctr-acpkm-omac]\n"} + "open" {set list "(gost) Reference implementation of GOST engine\n \[gost89, gost89-cnt, gost89-cnt-12, gost89-cbc, kuznyechik-ecb, kuznyechik-cbc, kuznyechik-cfb, kuznyechik-ofb, kuznyechik-ctr, magma-ecb, kuznyechik-mgm, magma-cbc, magma-ctr, magma-ctr-acpkm, magma-ctr-acpkm-omac, magma-mgm, kuznyechik-ctr-acpkm, kuznyechik-ctr-acpkm-omac, magma-kexp15, kuznyechik-kexp15, md_gost94, gost-mac, md_gost12_256, md_gost12_512, gost-mac-12, magma-mac, kuznyechik-mac, kuznyechik-ctr-acpkm-omac, magma-ctr-acpkm-omac, gost2001, id-GostR3410-2001DH, gost-mac, gost2012_256, gost2012_512, gost-mac-12, magma-mac, kuznyechik-mac, magma-ctr-acpkm-omac, kuznyechik-ctr-acpkm-omac]\n"} }