/* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "crypto_mac.h" #include #include #include "memory.h" #include "crypto_common.h" #include "crypto_sym_key.h" #include "native_common.h" #include "mac.h" #include "mac_params.h" #include "detailed_cmac_params.h" #include "detailed_hmac_params.h" typedef struct OH_CryptoMac { HcfMacParamsSpec *paramsSpec; HcfMac *macObj; } OH_CryptoMac; static const char *CMAC_NAME = "CMAC"; static const char *HMAC_NAME = "HMAC"; OH_Crypto_ErrCode OH_CryptoMac_Create(const char *algoName, OH_CryptoMac **ctx) { if ((algoName == NULL) || (ctx == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } OH_CryptoMac *tmpCtx = (OH_CryptoMac *)HcfMalloc(sizeof(OH_CryptoMac), 0); if (tmpCtx == NULL) { return CRYPTO_MEMORY_ERROR; } HcfMacParamsSpec *paramsSpec = NULL; const char *algName = NULL; if (strcmp(algoName, CMAC_NAME) == 0) { paramsSpec = (HcfMacParamsSpec *)HcfMalloc(sizeof(HcfCmacParamsSpec), 0); algName = CMAC_NAME; } else if (strcmp(algoName, HMAC_NAME) == 0) { paramsSpec = (HcfMacParamsSpec *)HcfMalloc(sizeof(HcfHmacParamsSpec), 0); algName = HMAC_NAME; } else { HcfFree(tmpCtx); tmpCtx = NULL; return CRYPTO_PARAMETER_CHECK_FAILED; } if (paramsSpec == NULL) { HcfFree(tmpCtx); tmpCtx = NULL; return CRYPTO_MEMORY_ERROR; } paramsSpec->algName = algName; tmpCtx->paramsSpec = paramsSpec; *ctx = tmpCtx; return CRYPTO_SUCCESS; } static OH_Crypto_ErrCode SetCmacParam(HcfCmacParamsSpec *paramsSpec, CryptoMac_ParamType type, const Crypto_DataBlob *value) { switch (type) { case CRYPTO_MAC_CIPHER_NAME_STR: { char *data = (char *)HcfMalloc(value->len + 1, 0); if (data == NULL) { return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(data, value->len, value->data, value->len); HcfFree((void *)(paramsSpec->cipherName)); paramsSpec->cipherName = NULL; paramsSpec->cipherName = data; return CRYPTO_SUCCESS; } default: return CRYPTO_PARAMETER_CHECK_FAILED; } } static OH_Crypto_ErrCode SetHmacParam(HcfHmacParamsSpec *paramsSpec, CryptoMac_ParamType type, const Crypto_DataBlob *value) { switch (type) { case CRYPTO_MAC_DIGEST_NAME_STR: { char *data = (char *)HcfMalloc(value->len + 1, 0); if (data == NULL) { return CRYPTO_MEMORY_ERROR; } (void)memcpy_s(data, value->len, value->data, value->len); HcfFree((void *)(paramsSpec->mdName)); paramsSpec->mdName = NULL; paramsSpec->mdName = data; return CRYPTO_SUCCESS; } default: return CRYPTO_PARAMETER_CHECK_FAILED; } } OH_Crypto_ErrCode OH_CryptoMac_SetParam(OH_CryptoMac *ctx, CryptoMac_ParamType type, const Crypto_DataBlob *value) { if ((ctx == NULL) || (ctx->paramsSpec == NULL) || (ctx->paramsSpec->algName == NULL) || (value == NULL) || (value->data == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } OH_Crypto_ErrCode res = CRYPTO_PARAMETER_CHECK_FAILED; if (strcmp(ctx->paramsSpec->algName, "CMAC") == 0) { res = SetCmacParam((HcfCmacParamsSpec*)(ctx->paramsSpec), type, value); } else if (strcmp(ctx->paramsSpec->algName, "HMAC") == 0) { res = SetHmacParam((HcfHmacParamsSpec*)(ctx->paramsSpec), type, value); } if (res != CRYPTO_SUCCESS) { return res; } HcfMac *macObj = NULL; HcfResult ret = HcfMacCreate(ctx->paramsSpec, &macObj); if (ret != HCF_SUCCESS) { return GetOhCryptoErrCodeNew(ret); } ctx->macObj = macObj; return CRYPTO_SUCCESS; } OH_Crypto_ErrCode OH_CryptoMac_Init(OH_CryptoMac *ctx, const OH_CryptoSymKey *key) { if ((ctx == NULL) || (ctx->macObj == NULL) || (ctx->macObj->init == NULL) || (key == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfResult ret = ctx->macObj->init(ctx->macObj, (const HcfSymKey *)key); return GetOhCryptoErrCodeNew(ret); } OH_Crypto_ErrCode OH_CryptoMac_Update(OH_CryptoMac *ctx, const Crypto_DataBlob *in) { if ((ctx == NULL) || (ctx->macObj == NULL) || (ctx->macObj->update == NULL) || (in == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfResult ret = ctx->macObj->update(ctx->macObj, (HcfBlob *)in); return GetOhCryptoErrCodeNew(ret); } OH_Crypto_ErrCode OH_CryptoMac_Final(OH_CryptoMac *ctx, Crypto_DataBlob *out) { if ((ctx == NULL) || (ctx->macObj == NULL) || (ctx->macObj->doFinal == NULL) || (out == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } HcfResult ret = ctx->macObj->doFinal(ctx->macObj, (HcfBlob *)out); return GetOhCryptoErrCodeNew(ret); } OH_Crypto_ErrCode OH_CryptoMac_GetLength(OH_CryptoMac *ctx, uint32_t *length) { if ((ctx == NULL) || (ctx->macObj == NULL) || (ctx->macObj->getMacLength == NULL) || (length == NULL)) { return CRYPTO_PARAMETER_CHECK_FAILED; } *length = ctx->macObj->getMacLength(ctx->macObj); return CRYPTO_SUCCESS; } static void FreeMacParams(HcfMacParamsSpec *params) { if ((params == NULL) || (params->algName == NULL)) { return; } if (strcmp(params->algName, "CMAC") == 0) { HcfFree((void *)(((HcfCmacParamsSpec *)params)->cipherName)); ((HcfCmacParamsSpec *)params)->cipherName = NULL; } else if (strcmp(params->algName, "HMAC") == 0) { HcfFree((void *)(((HcfHmacParamsSpec *)params)->mdName)); ((HcfHmacParamsSpec *)params)->mdName = NULL; } params->algName = NULL; HcfFree(params); } void OH_CryptoMac_Destroy(OH_CryptoMac *ctx) { if (ctx == NULL) { return; } FreeMacParams(ctx->paramsSpec); ctx->paramsSpec = NULL; HcfObjDestroy(ctx->macObj); ctx->macObj = NULL; HcfFree(ctx); }