• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2024 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 "mac_openssl.h"
17 
18 #include "openssl_adapter.h"
19 #include "sym_common_defines.h"
20 #include "openssl_common.h"
21 #include "securec.h"
22 #include "log.h"
23 #include "memory.h"
24 #include "config.h"
25 #include "utils.h"
26 #include "detailed_hmac_params.h"
27 #include "detailed_cmac_params.h"
28 
29 typedef struct {
30     HcfMacSpi base;
31 
32     HMAC_CTX *ctx;
33 
34     char opensslMdName[HCF_MAX_MD_NAME_LEN];
35 } HcfHmacSpiImpl;
36 
37 typedef struct {
38     HcfMacSpi base;
39 
40     EVP_MAC_CTX *ctx;
41 
42     char opensslCipherName[HCF_MAX_CIPHER_NAME_LEN];
43 } HcfCmacSpiImpl;
44 
OpensslGetHmacClass(void)45 static const char *OpensslGetHmacClass(void)
46 {
47     return "OpensslHmac";
48 }
49 
OpensslGetCmacClass(void)50 static const char *OpensslGetCmacClass(void)
51 {
52     return "OpensslCmac";
53 }
54 
OpensslGetHmacCtx(HcfMacSpi * self)55 static HMAC_CTX *OpensslGetHmacCtx(HcfMacSpi *self)
56 {
57     if (!HcfIsClassMatch((HcfObjectBase *)self, OpensslGetHmacClass())) {
58         LOGE("Class is not match.");
59         return NULL;
60     }
61     return ((HcfHmacSpiImpl *)self)->ctx;
62 }
63 
OpensslGetCmacCtx(HcfMacSpi * self)64 static EVP_MAC_CTX *OpensslGetCmacCtx(HcfMacSpi *self)
65 {
66     if (!HcfIsClassMatch((HcfObjectBase *)self, OpensslGetCmacClass())) {
67         LOGE("Class is not match.");
68         return NULL;
69     }
70     return ((HcfCmacSpiImpl *)self)->ctx;
71 }
72 
OpensslGetHmacAlgoFromString(const char * mdName)73 static const EVP_MD *OpensslGetHmacAlgoFromString(const char *mdName)
74 {
75     if (strcmp(mdName, "SHA1") == 0) {
76         return OpensslEvpSha1();
77     } else if (strcmp(mdName, "SHA224") == 0) {
78         return OpensslEvpSha224();
79     } else if (strcmp(mdName, "SHA256") == 0) {
80         return OpensslEvpSha256();
81     } else if (strcmp(mdName, "SHA384") == 0) {
82         return OpensslEvpSha384();
83     } else if (strcmp(mdName, "SHA512") == 0) {
84         return OpensslEvpSha512();
85     } else if (strcmp(mdName, "SM3") == 0) {
86         return OpensslEvpSm3();
87     } else if (strcmp(mdName, "MD5") == 0) {
88         return OpensslEvpMd5();
89     }
90     return NULL;
91 }
92 
OpensslEngineInitHmac(HcfMacSpi * self,const HcfSymKey * key)93 static HcfResult OpensslEngineInitHmac(HcfMacSpi *self, const HcfSymKey *key)
94 {
95     if (OpensslGetHmacCtx(self) == NULL) {
96         LOGD("[error] The CTX is NULL!");
97         return HCF_ERR_CRYPTO_OPERATION;
98     }
99     if (!HcfIsClassMatch((const HcfObjectBase *)key, OPENSSL_SYM_KEY_CLASS)) {
100         LOGE("Class is not match.");
101         return HCF_INVALID_PARAMS;
102     }
103     if (!HcfIsClassMatch((HcfObjectBase *)self, OpensslGetHmacClass())) {
104         LOGE("Class is not match.");
105         return HCF_INVALID_PARAMS;
106     }
107     HcfBlob keyBlob = ((SymKeyImpl *)key)->keyMaterial;
108     if (!HcfIsBlobValid(&keyBlob)) {
109         LOGE("Invalid keyMaterial");
110         return HCF_INVALID_PARAMS;
111     }
112     const EVP_MD *mdfunc = OpensslGetHmacAlgoFromString(((HcfHmacSpiImpl *)self)->opensslMdName);
113     int32_t ret = OpensslHmacInitEx(OpensslGetHmacCtx(self), keyBlob.data, keyBlob.len, mdfunc, NULL);
114     if (ret != HCF_OPENSSL_SUCCESS) {
115         LOGD("[error] HMAC_Init_ex return error!");
116         HcfPrintOpensslError();
117         return HCF_ERR_CRYPTO_OPERATION;
118     }
119     return HCF_SUCCESS;
120 }
121 
OpensslEngineUpdateHmac(HcfMacSpi * self,HcfBlob * input)122 static HcfResult OpensslEngineUpdateHmac(HcfMacSpi *self, HcfBlob *input)
123 {
124     if (OpensslGetHmacCtx(self) == NULL) {
125         LOGD("[error] The CTX is NULL!");
126         return HCF_ERR_CRYPTO_OPERATION;
127     }
128     if (HMAC_Update(OpensslGetHmacCtx(self), input->data, input->len) != HCF_OPENSSL_SUCCESS) {
129         LOGD("[error] HMAC_Update return error!");
130         HcfPrintOpensslError();
131         return HCF_ERR_CRYPTO_OPERATION;
132     }
133     return HCF_SUCCESS;
134 }
135 
OpensslEngineDoFinalHmac(HcfMacSpi * self,HcfBlob * output)136 static HcfResult OpensslEngineDoFinalHmac(HcfMacSpi *self, HcfBlob *output)
137 {
138     if (OpensslGetHmacCtx(self) == NULL) {
139         LOGD("[error] The CTX is NULL!");
140         return HCF_ERR_CRYPTO_OPERATION;
141     }
142     unsigned char outputBuf[EVP_MAX_MD_SIZE];
143     uint32_t outputLen;
144     int32_t ret = OpensslHmacFinal(OpensslGetHmacCtx(self), outputBuf, &outputLen);
145     if (ret != HCF_OPENSSL_SUCCESS) {
146         LOGD("[error] HMAC_Final return error!");
147         HcfPrintOpensslError();
148         return HCF_ERR_CRYPTO_OPERATION;
149     }
150     output->data = (uint8_t *)HcfMalloc(outputLen, 0);
151     if (output->data == NULL) {
152         LOGE("Failed to allocate output->data memory!");
153         return HCF_ERR_MALLOC;
154     }
155     (void)memcpy_s(output->data, outputLen, outputBuf, outputLen);
156     output->len = outputLen;
157     return HCF_SUCCESS;
158 }
159 
OpensslEngineGetHmacLength(HcfMacSpi * self)160 static uint32_t OpensslEngineGetHmacLength(HcfMacSpi *self)
161 {
162     if (OpensslGetHmacCtx(self) == NULL) {
163         LOGD("[error] The CTX is NULL!");
164         return HCF_OPENSSL_INVALID_MAC_LEN;
165     }
166     return OpensslHmacSize(OpensslGetHmacCtx(self));
167 }
168 
OpensslDestroyHmac(HcfObjectBase * self)169 static void OpensslDestroyHmac(HcfObjectBase *self)
170 {
171     if (self == NULL) {
172         LOGE("Self ptr is NULL");
173         return;
174     }
175     if (!HcfIsClassMatch(self, OpensslGetHmacClass())) {
176         LOGE("Class is not match.");
177         return;
178     }
179     if (OpensslGetHmacCtx((HcfMacSpi *)self) != NULL) {
180         OpensslHmacCtxFree(OpensslGetHmacCtx((HcfMacSpi *)self));
181     }
182     HcfFree(self);
183 }
184 
OpensslHmacSpiCreate(HcfMacParamsSpec * paramsSpec,HcfMacSpi ** spiObj)185 HcfResult OpensslHmacSpiCreate(HcfMacParamsSpec *paramsSpec, HcfMacSpi **spiObj)
186 {
187     if (paramsSpec == NULL || spiObj == NULL) {
188         LOGE("Invalid input parameter.");
189         return HCF_INVALID_PARAMS;
190     }
191     HcfHmacSpiImpl *returnSpiImpl = (HcfHmacSpiImpl *)HcfMalloc(sizeof(HcfHmacSpiImpl), 0);
192     if (returnSpiImpl == NULL) {
193         LOGE("Failed to allocate returnImpl memory!");
194         return HCF_ERR_MALLOC;
195     }
196     if (strcpy_s(returnSpiImpl->opensslMdName, HCF_MAX_MD_NAME_LEN, ((HcfHmacParamsSpec *)paramsSpec)->mdName) != EOK) {
197         LOGE("Failed to copy algoName!");
198         HcfFree(returnSpiImpl);
199         returnSpiImpl = NULL;
200         return HCF_INVALID_PARAMS;
201     }
202     returnSpiImpl->ctx = OpensslHmacCtxNew();
203     if (returnSpiImpl->ctx == NULL) {
204         LOGD("[error] Failed to create ctx!");
205         HcfFree(returnSpiImpl);
206         returnSpiImpl = NULL;
207         return HCF_ERR_CRYPTO_OPERATION;
208     }
209     returnSpiImpl->base.base.getClass = OpensslGetHmacClass;
210     returnSpiImpl->base.base.destroy = OpensslDestroyHmac;
211     returnSpiImpl->base.engineInitMac = OpensslEngineInitHmac;
212     returnSpiImpl->base.engineUpdateMac = OpensslEngineUpdateHmac;
213     returnSpiImpl->base.engineDoFinalMac = OpensslEngineDoFinalHmac;
214     returnSpiImpl->base.engineGetMacLength = OpensslEngineGetHmacLength;
215     *spiObj = (HcfMacSpi *)returnSpiImpl;
216     return HCF_SUCCESS;
217 }
218 
OpensslEngineInitCmac(HcfMacSpi * self,const HcfSymKey * key)219 static HcfResult OpensslEngineInitCmac(HcfMacSpi *self, const HcfSymKey *key)
220 {
221     OSSL_PARAM params[4] = {};
222     OSSL_PARAM *p = params;
223     if (OpensslGetCmacCtx(self) == NULL) {
224         LOGD("[error] The CTX is NULL!");
225         return HCF_ERR_CRYPTO_OPERATION;
226     }
227     if (!HcfIsClassMatch((const HcfObjectBase *)key, OPENSSL_SYM_KEY_CLASS)) {
228         LOGE("Class is not match.");
229         return HCF_INVALID_PARAMS;
230     }
231     if (!HcfIsClassMatch((HcfObjectBase *)self, OpensslGetCmacClass())) {
232         LOGE("Class is not match.");
233         return HCF_INVALID_PARAMS;
234     }
235     HcfBlob keyBlob = ((SymKeyImpl *)key)->keyMaterial;
236     if (!HcfIsBlobValid(&keyBlob)) {
237         LOGE("Invalid keyMaterial");
238         return HCF_INVALID_PARAMS;
239     }
240     *p++ = OpensslOsslParamConstructUtf8String("cipher", ((HcfCmacSpiImpl *)self)->opensslCipherName,
241         strlen(((HcfCmacSpiImpl *)self)->opensslCipherName));
242     *p++ = OpensslOsslParamConstructEnd();
243     int32_t ret = OpensslCmacInit(OpensslGetCmacCtx(self), keyBlob.data, keyBlob.len, params);
244     if (ret != HCF_OPENSSL_SUCCESS) {
245         LOGE("CMAC_Init return error!");
246         HcfPrintOpensslError();
247         return HCF_ERR_CRYPTO_OPERATION;
248     }
249     return HCF_SUCCESS;
250 }
251 
OpensslEngineUpdateCmac(HcfMacSpi * self,HcfBlob * input)252 static HcfResult OpensslEngineUpdateCmac(HcfMacSpi *self, HcfBlob *input)
253 {
254     if (OpensslGetCmacCtx(self) == NULL) {
255         LOGE("The CTX is NULL!");
256         return HCF_ERR_CRYPTO_OPERATION;
257     }
258     if (OpensslCmacUpdate(OpensslGetCmacCtx(self), input->data, input->len) != HCF_OPENSSL_SUCCESS) {
259         LOGE("CMAC_Update return error!");
260         HcfPrintOpensslError();
261         return HCF_ERR_CRYPTO_OPERATION;
262     }
263     return HCF_SUCCESS;
264 }
265 
OpensslEngineDoFinalCmac(HcfMacSpi * self,HcfBlob * output)266 static HcfResult OpensslEngineDoFinalCmac(HcfMacSpi *self, HcfBlob *output)
267 {
268     if (OpensslGetCmacCtx(self) == NULL) {
269         LOGE("The CTX is NULL!");
270         return HCF_ERR_CRYPTO_OPERATION;
271     }
272     size_t outputLen = 0;
273     unsigned char outputBuf[EVP_MAX_MD_SIZE];
274     int32_t ret = OpensslCmacFinal(OpensslGetCmacCtx(self), NULL, &outputLen, 0);
275     if (ret != HCF_OPENSSL_SUCCESS) {
276         LOGE("CMAC_Final return error!");
277         HcfPrintOpensslError();
278         return HCF_ERR_CRYPTO_OPERATION;
279     }
280     ret = OpensslCmacFinal(OpensslGetCmacCtx(self), outputBuf, &outputLen, outputLen);
281     if (ret != HCF_OPENSSL_SUCCESS) {
282         LOGE("CMAC_Final return error!");
283         HcfPrintOpensslError();
284         return HCF_ERR_CRYPTO_OPERATION;
285     }
286     output->data = (uint8_t *)HcfMalloc(outputLen, 0);
287     if (output->data == NULL) {
288         LOGE("Failed to allocate output->data memory!");
289         return HCF_ERR_MALLOC;
290     }
291     (void)memcpy_s(output->data, outputLen, outputBuf, outputLen);
292     output->len = outputLen;
293     return HCF_SUCCESS;
294 }
295 
OpensslEngineGetCmacLength(HcfMacSpi * self)296 static uint32_t OpensslEngineGetCmacLength(HcfMacSpi *self)
297 {
298     if (OpensslGetCmacCtx(self) == NULL) {
299         LOGE("The CTX is NULL!");
300         return HCF_OPENSSL_INVALID_MAC_LEN;
301     }
302     return OpensslCmacSize(OpensslGetCmacCtx(self));
303 }
304 
OpensslDestroyCmac(HcfObjectBase * self)305 static void OpensslDestroyCmac(HcfObjectBase *self)
306 {
307     if (self == NULL) {
308         LOGE("Self ptr is NULL");
309         return;
310     }
311     if (!HcfIsClassMatch(self, OpensslGetCmacClass())) {
312         LOGE("Class is not match.");
313         return;
314     }
315     if (OpensslGetCmacCtx((HcfMacSpi *)self) != NULL) {
316         OpensslCmacCtxFree(OpensslGetCmacCtx((HcfMacSpi *)self));
317     }
318     HcfFree(self);
319 }
320 
OpensslCmacSpiCreate(HcfMacParamsSpec * paramsSpec,HcfMacSpi ** spiObj)321 HcfResult OpensslCmacSpiCreate(HcfMacParamsSpec *paramsSpec, HcfMacSpi **spiObj)
322 {
323     if (paramsSpec == NULL || spiObj == NULL) {
324         LOGE("Invalid input parameter.");
325         return HCF_INVALID_PARAMS;
326     }
327     HcfCmacSpiImpl *returnSpiImpl = (HcfCmacSpiImpl *)HcfMalloc(sizeof(HcfCmacSpiImpl), 0);
328     if (returnSpiImpl == NULL) {
329         LOGE("Failed to allocate returnImpl memory!");
330         return HCF_ERR_MALLOC;
331     }
332     if (strcpy_s(returnSpiImpl->opensslCipherName, HCF_MAX_CIPHER_NAME_LEN,
333         ((HcfCmacParamsSpec *)paramsSpec)->cipherName) != EOK) {
334         LOGE("Failed to copy algoName!");
335         HcfFree(returnSpiImpl);
336         returnSpiImpl = NULL;
337         return HCF_INVALID_PARAMS;
338     }
339     EVP_MAC *mac = EVP_MAC_fetch(NULL, "CMAC", NULL);
340     if (mac == NULL) {
341         LOGE("fetch failed");
342         HcfFree(returnSpiImpl);
343         returnSpiImpl = NULL;
344         return HCF_ERR_CRYPTO_OPERATION;
345     }
346     returnSpiImpl->ctx = EVP_MAC_CTX_new(mac);
347     if (returnSpiImpl->ctx == NULL) {
348         LOGD("[error] Failed to create ctx!");
349         HcfFree(returnSpiImpl);
350         returnSpiImpl = NULL;
351         OpensslMacFree(mac);
352         return HCF_ERR_CRYPTO_OPERATION;
353     }
354     OpensslMacFree(mac);
355     returnSpiImpl->base.base.getClass = OpensslGetCmacClass;
356     returnSpiImpl->base.base.destroy = OpensslDestroyCmac;
357     returnSpiImpl->base.engineInitMac = OpensslEngineInitCmac;
358     returnSpiImpl->base.engineUpdateMac = OpensslEngineUpdateCmac;
359     returnSpiImpl->base.engineDoFinalMac = OpensslEngineDoFinalCmac;
360     returnSpiImpl->base.engineGetMacLength = OpensslEngineGetCmacLength;
361     *spiObj = (HcfMacSpi *)returnSpiImpl;
362     return HCF_SUCCESS;
363 }