1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "crypto_mac.h"
17 #include <string.h>
18 #include <securec.h>
19 #include "memory.h"
20 #include "crypto_common.h"
21 #include "crypto_sym_key.h"
22 #include "native_common.h"
23 #include "mac.h"
24 #include "mac_params.h"
25 #include "detailed_cmac_params.h"
26 #include "detailed_hmac_params.h"
27
28 typedef struct OH_CryptoMac {
29 HcfMacParamsSpec *paramsSpec;
30 HcfMac *macObj;
31 } OH_CryptoMac;
32
33 static const char *CMAC_NAME = "CMAC";
34 static const char *HMAC_NAME = "HMAC";
35
OH_CryptoMac_Create(const char * algoName,OH_CryptoMac ** ctx)36 OH_Crypto_ErrCode OH_CryptoMac_Create(const char *algoName, OH_CryptoMac **ctx)
37 {
38 if ((algoName == NULL) || (ctx == NULL)) {
39 return CRYPTO_PARAMETER_CHECK_FAILED;
40 }
41 OH_CryptoMac *tmpCtx = (OH_CryptoMac *)HcfMalloc(sizeof(OH_CryptoMac), 0);
42 if (tmpCtx == NULL) {
43 return CRYPTO_MEMORY_ERROR;
44 }
45 HcfMacParamsSpec *paramsSpec = NULL;
46 const char *algName = NULL;
47 if (strcmp(algoName, CMAC_NAME) == 0) {
48 paramsSpec = (HcfMacParamsSpec *)HcfMalloc(sizeof(HcfCmacParamsSpec), 0);
49 algName = CMAC_NAME;
50 } else if (strcmp(algoName, HMAC_NAME) == 0) {
51 paramsSpec = (HcfMacParamsSpec *)HcfMalloc(sizeof(HcfHmacParamsSpec), 0);
52 algName = HMAC_NAME;
53 } else {
54 HcfFree(tmpCtx);
55 tmpCtx = NULL;
56 return CRYPTO_PARAMETER_CHECK_FAILED;
57 }
58
59 if (paramsSpec == NULL) {
60 HcfFree(tmpCtx);
61 tmpCtx = NULL;
62 return CRYPTO_MEMORY_ERROR;
63 }
64
65 paramsSpec->algName = algName;
66 tmpCtx->paramsSpec = paramsSpec;
67 *ctx = tmpCtx;
68 return CRYPTO_SUCCESS;
69 }
70
SetCmacParam(HcfCmacParamsSpec * paramsSpec,CryptoMac_ParamType type,const Crypto_DataBlob * value)71 static OH_Crypto_ErrCode SetCmacParam(HcfCmacParamsSpec *paramsSpec, CryptoMac_ParamType type,
72 const Crypto_DataBlob *value)
73 {
74 switch (type) {
75 case CRYPTO_MAC_CIPHER_NAME_STR: {
76 char *data = (char *)HcfMalloc(value->len + 1, 0);
77 if (data == NULL) {
78 return CRYPTO_MEMORY_ERROR;
79 }
80 (void)memcpy_s(data, value->len, value->data, value->len);
81 HcfFree((void *)(paramsSpec->cipherName));
82 paramsSpec->cipherName = NULL;
83 paramsSpec->cipherName = data;
84 return CRYPTO_SUCCESS;
85 }
86 default:
87 return CRYPTO_PARAMETER_CHECK_FAILED;
88 }
89 }
90
SetHmacParam(HcfHmacParamsSpec * paramsSpec,CryptoMac_ParamType type,const Crypto_DataBlob * value)91 static OH_Crypto_ErrCode SetHmacParam(HcfHmacParamsSpec *paramsSpec, CryptoMac_ParamType type,
92 const Crypto_DataBlob *value)
93 {
94 switch (type) {
95 case CRYPTO_MAC_DIGEST_NAME_STR: {
96 char *data = (char *)HcfMalloc(value->len + 1, 0);
97 if (data == NULL) {
98 return CRYPTO_MEMORY_ERROR;
99 }
100 (void)memcpy_s(data, value->len, value->data, value->len);
101 HcfFree((void *)(paramsSpec->mdName));
102 paramsSpec->mdName = NULL;
103 paramsSpec->mdName = data;
104 return CRYPTO_SUCCESS;
105 }
106 default:
107 return CRYPTO_PARAMETER_CHECK_FAILED;
108 }
109 }
110
OH_CryptoMac_SetParam(OH_CryptoMac * ctx,CryptoMac_ParamType type,const Crypto_DataBlob * value)111 OH_Crypto_ErrCode OH_CryptoMac_SetParam(OH_CryptoMac *ctx, CryptoMac_ParamType type, const Crypto_DataBlob *value)
112 {
113 if ((ctx == NULL) || (ctx->paramsSpec == NULL) || (ctx->paramsSpec->algName == NULL) || (value == NULL) ||
114 (value->data == NULL)) {
115 return CRYPTO_PARAMETER_CHECK_FAILED;
116 }
117 OH_Crypto_ErrCode res = CRYPTO_PARAMETER_CHECK_FAILED;
118 if (strcmp(ctx->paramsSpec->algName, "CMAC") == 0) {
119 res = SetCmacParam((HcfCmacParamsSpec*)(ctx->paramsSpec), type, value);
120 } else if (strcmp(ctx->paramsSpec->algName, "HMAC") == 0) {
121 res = SetHmacParam((HcfHmacParamsSpec*)(ctx->paramsSpec), type, value);
122 }
123
124 if (res != CRYPTO_SUCCESS) {
125 return res;
126 }
127
128 HcfMac *macObj = NULL;
129 HcfResult ret = HcfMacCreate(ctx->paramsSpec, &macObj);
130 if (ret != HCF_SUCCESS) {
131 return GetOhCryptoErrCodeNew(ret);
132 }
133 ctx->macObj = macObj;
134 return CRYPTO_SUCCESS;
135 }
136
OH_CryptoMac_Init(OH_CryptoMac * ctx,const OH_CryptoSymKey * key)137 OH_Crypto_ErrCode OH_CryptoMac_Init(OH_CryptoMac *ctx, const OH_CryptoSymKey *key)
138 {
139 if ((ctx == NULL) || (ctx->macObj == NULL) || (ctx->macObj->init == NULL) || (key == NULL)) {
140 return CRYPTO_PARAMETER_CHECK_FAILED;
141 }
142 HcfResult ret = ctx->macObj->init(ctx->macObj, (const HcfSymKey *)key);
143 return GetOhCryptoErrCodeNew(ret);
144 }
145
OH_CryptoMac_Update(OH_CryptoMac * ctx,const Crypto_DataBlob * in)146 OH_Crypto_ErrCode OH_CryptoMac_Update(OH_CryptoMac *ctx, const Crypto_DataBlob *in)
147 {
148 if ((ctx == NULL) || (ctx->macObj == NULL) || (ctx->macObj->update == NULL) || (in == NULL)) {
149 return CRYPTO_PARAMETER_CHECK_FAILED;
150 }
151 HcfResult ret = ctx->macObj->update(ctx->macObj, (HcfBlob *)in);
152 return GetOhCryptoErrCodeNew(ret);
153 }
154
OH_CryptoMac_Final(OH_CryptoMac * ctx,Crypto_DataBlob * out)155 OH_Crypto_ErrCode OH_CryptoMac_Final(OH_CryptoMac *ctx, Crypto_DataBlob *out)
156 {
157 if ((ctx == NULL) || (ctx->macObj == NULL) || (ctx->macObj->doFinal == NULL) || (out == NULL)) {
158 return CRYPTO_PARAMETER_CHECK_FAILED;
159 }
160 HcfResult ret = ctx->macObj->doFinal(ctx->macObj, (HcfBlob *)out);
161 return GetOhCryptoErrCodeNew(ret);
162 }
163
OH_CryptoMac_GetLength(OH_CryptoMac * ctx,uint32_t * length)164 OH_Crypto_ErrCode OH_CryptoMac_GetLength(OH_CryptoMac *ctx, uint32_t *length)
165 {
166 if ((ctx == NULL) || (ctx->macObj == NULL) || (ctx->macObj->getMacLength == NULL) || (length == NULL)) {
167 return CRYPTO_PARAMETER_CHECK_FAILED;
168 }
169 *length = ctx->macObj->getMacLength(ctx->macObj);
170 return CRYPTO_SUCCESS;
171 }
172
FreeMacParams(HcfMacParamsSpec * params)173 static void FreeMacParams(HcfMacParamsSpec *params)
174 {
175 if ((params == NULL) || (params->algName == NULL)) {
176 return;
177 }
178 if (strcmp(params->algName, "CMAC") == 0) {
179 HcfFree((void *)(((HcfCmacParamsSpec *)params)->cipherName));
180 ((HcfCmacParamsSpec *)params)->cipherName = NULL;
181 } else if (strcmp(params->algName, "HMAC") == 0) {
182 HcfFree((void *)(((HcfHmacParamsSpec *)params)->mdName));
183 ((HcfHmacParamsSpec *)params)->mdName = NULL;
184 }
185 params->algName = NULL;
186 HcfFree(params);
187 }
188
OH_CryptoMac_Destroy(OH_CryptoMac * ctx)189 void OH_CryptoMac_Destroy(OH_CryptoMac *ctx)
190 {
191 if (ctx == NULL) {
192 return;
193 }
194 FreeMacParams(ctx->paramsSpec);
195 ctx->paramsSpec = NULL;
196 HcfObjDestroy(ctx->macObj);
197 ctx->macObj = NULL;
198 HcfFree(ctx);
199 }