OPENSSL_free(ctx);
}
-int CMAC_ACPKM_CTX_copy(CMAC_ACPKM_CTX *out, const CMAC_ACPKM_CTX *in)
+static int CMAC_ACPKM_CTX_copy(CMAC_ACPKM_CTX *out, const CMAC_ACPKM_CTX *in)
{
int bl;
if (in->nlast_block == -1)
}
/* 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;
- if (!EVP_CIPHER_is_a(cipher, SN_grasshopper_cbc))
+ /* 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;
- acpkm = cipher_gost_grasshopper_ctracpkm();
+
if (!EVP_EncryptInit_ex(ctx->actx, acpkm, impl, NULL, NULL))
return 0;
}
}
+/* Return value is propagated to EVP_DigestFinal_ex */
static int CMAC_ACPKM_Final(CMAC_ACPKM_CTX *ctx, unsigned char *out,
size_t *poutlen)
{
if (ctx->nlast_block == -1)
return 0;
bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
+ if (bl != 8 && bl != 16) {
+ GOSTerr(GOST_F_OMAC_ACPKM_IMIT_FINAL, GOST_R_INVALID_MAC_PARAMS);
+ return 0;
+ }
*poutlen = (size_t) bl;
if (!out)
return 1;
case NID_grasshopper_cbc:
c->dgst_size = 16;
break;
+ case NID_magma_cbc:
+ c->dgst_size = 8;
+ break;
}
return 1;
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)
{
OMAC_ACPKM_CTX *c = EVP_MD_CTX_md_data(ctx);
unsigned char mac[MAX_GOST_OMAC_ACPKM_SIZE];
size_t mac_size = sizeof(mac);
+ int ret;
if (!c->key_set) {
GOSTerr(GOST_F_OMAC_ACPKM_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
return 0;
}
- CMAC_ACPKM_Final(c->cmac_ctx, mac, &mac_size);
+ ret = CMAC_ACPKM_Final(c->cmac_ctx, mac, &mac_size);
memcpy(md, mac, c->dgst_size);
- return 1;
+ return ret;
}
static int omac_acpkm_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
if ((c_to->cmac_ctx == c_from->cmac_ctx) || (c_to->cmac_ctx == NULL)) {
c_to->cmac_ctx = CMAC_ACPKM_CTX_new();
}
- return CMAC_ACPKM_CTX_copy(c_to->cmac_ctx, c_from->cmac_ctx);
+
+ return (c_to->cmac_ctx) ? CMAC_ACPKM_CTX_copy(c_to->cmac_ctx, c_from->cmac_ctx) : 0;
}
/* Clean up imit ctx */
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
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;
.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,
+};