• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }