+ if (arg == 0) {
+ struct gost_mac_key *key = (struct gost_mac_key *)ptr;
+ ret = omac_key(c, cipher, key->key, 32);
+ if (ret > 0)
+ memcpy(c->key, key->key, 32);
+ return ret;
+ } else if (arg == 32) {
+ ret = omac_key(c, cipher, ptr, 32);
+ if (ret > 0)
+ memcpy(c->key, ptr, 32);
+ return ret;
+ }
+ GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_SIZE);
+ return 0;
+ }
+ 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) ?
+ 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;
+ }
+ return 0;
+#endif