- _hidden_magma_mac_md = md;
- }
- return _hidden_magma_mac_md;
-}
-
-void magma_omac_destroy(void)
-{
- EVP_MD_meth_free(_hidden_magma_mac_md);
- _hidden_magma_mac_md = NULL;
-}
-
-static EVP_MD *_hidden_grasshopper_mac_md = NULL;
-
-EVP_MD *grasshopper_omac(void)
-{
- if (_hidden_grasshopper_mac_md == NULL) {
- EVP_MD *md;
-
- if ((md = EVP_MD_meth_new(NID_grasshopper_mac, NID_undef)) == NULL
- || !EVP_MD_meth_set_result_size(md, 4)
- || !EVP_MD_meth_set_input_blocksize(md, 8)
- || !EVP_MD_meth_set_app_datasize(md, sizeof(OMAC_CTX))
- || !EVP_MD_meth_set_flags(md, 0)
- || !EVP_MD_meth_set_init(md, grasshopper_imit_init)
- || !EVP_MD_meth_set_update(md, omac_imit_update)
- || !EVP_MD_meth_set_final(md, omac_imit_final)
- || !EVP_MD_meth_set_copy(md, omac_imit_copy)
- || !EVP_MD_meth_set_cleanup(md, omac_imit_cleanup)
- || !EVP_MD_meth_set_ctrl(md, omac_imit_ctrl)) {
- EVP_MD_meth_free(md);
- md = NULL;
+ case EVP_MD_CTRL_XOF_LEN: /* Supported in OpenSSL */
+ {
+ OMAC_CTX *c = EVP_MD_CTX_md_data(ctx);
+ switch (c->cipher_nid) {
+ case NID_magma_cbc:
+ if (arg < 1 || arg > 8) {
+ GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_INVALID_MAC_SIZE);
+ return 0;
+ }
+ c->dgst_size = arg;
+ break;
+ case NID_grasshopper_cbc:
+ if (arg < 1 || arg > 16) {
+ GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_INVALID_MAC_SIZE);
+ return 0;
+ }
+ c->dgst_size = arg;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+ }
+#ifdef EVP_MD_CTRL_TLSTREE
+ case EVP_MD_CTRL_TLSTREE:
+ {
+ OMAC_CTX *c = EVP_MD_CTX_md_data(ctx);
+ if (c->key_set) {
+ unsigned char diversed_key[32];
+ return gost_tlstree(c->cipher_nid, c->key, diversed_key,
+ (const unsigned char *)ptr, TLSTREE_MODE_NONE) ?
+ omac_key(c, EVP_get_cipherbynid(c->cipher_nid),
+ diversed_key, 32) : 0;
+ }
+ GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_BAD_ORDER);
+ return 0;