• 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         return HCF_INVALID_PARAMS;
200     }
201     returnSpiImpl->ctx = OpensslHmacCtxNew();
202     if (returnSpiImpl->ctx == NULL) {
203         LOGD("[error] Failed to create ctx!");
204         HcfFree(returnSpiImpl);
205         return HCF_ERR_CRYPTO_OPERATION;
206     }
207     returnSpiImpl->base.base.getClass = OpensslGetHmacClass;
208     returnSpiImpl->base.base.destroy = OpensslDestroyHmac;
209     returnSpiImpl->base.engineInitMac = OpensslEngineInitHmac;
210     returnSpiImpl->base.engineUpdateMac = OpensslEngineUpdateHmac;
211     returnSpiImpl->base.engineDoFinalMac = OpensslEngineDoFinalHmac;
212     returnSpiImpl->base.engineGetMacLength = OpensslEngineGetHmacLength;
213     *spiObj = (HcfMacSpi *)returnSpiImpl;
214     return HCF_SUCCESS;
215 }
216 
OpensslEngineInitCmac(HcfMacSpi * self,const HcfSymKey * key)217 static HcfResult OpensslEngineInitCmac(HcfMacSpi *self, const HcfSymKey *key)
218 {
219     OSSL_PARAM params[4] = {};
220     OSSL_PARAM *p = params;
221     if (OpensslGetCmacCtx(self) == NULL) {
222         LOGD("[error] The CTX is NULL!");
223         return HCF_ERR_CRYPTO_OPERATION;
224     }
225     if (!HcfIsClassMatch((const HcfObjectBase *)key, OPENSSL_SYM_KEY_CLASS)) {
226         LOGE("Class is not match.");
227         return HCF_INVALID_PARAMS;
228     }
229     if (!HcfIsClassMatch((HcfObjectBase *)self, OpensslGetCmacClass())) {
230         LOGE("Class is not match.");
231         return HCF_INVALID_PARAMS;
232     }
233     HcfBlob keyBlob = ((SymKeyImpl *)key)->keyMaterial;
234     if (!HcfIsBlobValid(&keyBlob)) {
235         LOGE("Invalid keyMaterial");
236         return HCF_INVALID_PARAMS;
237     }
238     *p++ = OpensslOsslParamConstructUtf8String("cipher", ((HcfCmacSpiImpl *)self)->opensslCipherName,
239         strlen(((HcfCmacSpiImpl *)self)->opensslCipherName));
240     *p++ = OpensslOsslParamConstructEnd();
241     int32_t ret = OpensslCmacInit(OpensslGetCmacCtx(self), keyBlob.data, keyBlob.len, params);
242     if (ret != HCF_OPENSSL_SUCCESS) {
243         LOGE("CMAC_Init return error!");
244         HcfPrintOpensslError();
245         return HCF_ERR_CRYPTO_OPERATION;
246     }
247     return HCF_SUCCESS;
248 }
249 
OpensslEngineUpdateCmac(HcfMacSpi * self,HcfBlob * input)250 static HcfResult OpensslEngineUpdateCmac(HcfMacSpi *self, HcfBlob *input)
251 {
252     if (OpensslGetCmacCtx(self) == NULL) {
253         LOGE("The CTX is NULL!");
254         return HCF_ERR_CRYPTO_OPERATION;
255     }
256     if (OpensslCmacUpdate(OpensslGetCmacCtx(self), input->data, input->len) != HCF_OPENSSL_SUCCESS) {
257         LOGE("CMAC_Update return error!");
258         HcfPrintOpensslError();
259         return HCF_ERR_CRYPTO_OPERATION;
260     }
261     return HCF_SUCCESS;
262 }
263 
OpensslEngineDoFinalCmac(HcfMacSpi * self,HcfBlob * output)264 static HcfResult OpensslEngineDoFinalCmac(HcfMacSpi *self, HcfBlob *output)
265 {
266     if (OpensslGetCmacCtx(self) == NULL) {
267         LOGE("The CTX is NULL!");
268         return HCF_ERR_CRYPTO_OPERATION;
269     }
270     size_t outputLen = 0;
271     unsigned char outputBuf[EVP_MAX_MD_SIZE];
272     int32_t ret = OpensslCmacFinal(OpensslGetCmacCtx(self), NULL, &outputLen, 0);
273     if (ret != HCF_OPENSSL_SUCCESS) {
274         LOGE("CMAC_Final return error!");
275         HcfPrintOpensslError();
276         return HCF_ERR_CRYPTO_OPERATION;
277     }
278     ret = OpensslCmacFinal(OpensslGetCmacCtx(self), outputBuf, &outputLen, outputLen);
279     if (ret != HCF_OPENSSL_SUCCESS) {
280         LOGE("CMAC_Final return error!");
281         HcfPrintOpensslError();
282         return HCF_ERR_CRYPTO_OPERATION;
283     }
284     output->data = (uint8_t *)HcfMalloc(outputLen, 0);
285     if (output->data == NULL) {
286         LOGE("Failed to allocate output->data memory!");
287         return HCF_ERR_MALLOC;
288     }
289     (void)memcpy_s(output->data, outputLen, outputBuf, outputLen);
290     output->len = outputLen;
291     return HCF_SUCCESS;
292 }
293 
OpensslEngineGetCmacLength(HcfMacSpi * self)294 static uint32_t OpensslEngineGetCmacLength(HcfMacSpi *self)
295 {
296     if (OpensslGetCmacCtx(self) == NULL) {
297         LOGE("The CTX is NULL!");
298         return HCF_OPENSSL_INVALID_MAC_LEN;
299     }
300     return OpensslCmacSize(OpensslGetCmacCtx(self));
301 }
302 
OpensslDestroyCmac(HcfObjectBase * self)303 static void OpensslDestroyCmac(HcfObjectBase *self)
304 {
305     if (self == NULL) {
306         LOGE("Self ptr is NULL");
307         return;
308     }
309     if (!HcfIsClassMatch(self, OpensslGetCmacClass())) {
310         LOGE("Class is not match.");
311         return;
312     }
313     if (OpensslGetCmacCtx((HcfMacSpi *)self) != NULL) {
314         OpensslCmacCtxFree(OpensslGetCmacCtx((HcfMacSpi *)self));
315     }
316     HcfFree(self);
317 }
318 
OpensslCmacSpiCreate(HcfMacParamsSpec * paramsSpec,HcfMacSpi ** spiObj)319 HcfResult OpensslCmacSpiCreate(HcfMacParamsSpec *paramsSpec, HcfMacSpi **spiObj)
320 {
321     if (paramsSpec == NULL || spiObj == NULL) {
322         LOGE("Invalid input parameter.");
323         return HCF_INVALID_PARAMS;
324     }
325     HcfCmacSpiImpl *returnSpiImpl = (HcfCmacSpiImpl *)HcfMalloc(sizeof(HcfCmacSpiImpl), 0);
326     if (returnSpiImpl == NULL) {
327         LOGE("Failed to allocate returnImpl memory!");
328         return HCF_ERR_MALLOC;
329     }
330     if (strcpy_s(returnSpiImpl->opensslCipherName, HCF_MAX_CIPHER_NAME_LEN,
331         ((HcfCmacParamsSpec *)paramsSpec)->cipherName) != EOK) {
332         LOGE("Failed to copy algoName!");
333         HcfFree(returnSpiImpl);
334         return HCF_INVALID_PARAMS;
335     }
336     EVP_MAC *mac = EVP_MAC_fetch(NULL, "CMAC", NULL);
337     if (mac == NULL) {
338         LOGD("fetch failed");
339         return HCF_ERR_CRYPTO_OPERATION;
340     }
341     returnSpiImpl->ctx = EVP_MAC_CTX_new(mac);
342     if (returnSpiImpl->ctx == NULL) {
343         LOGD("[error] Failed to create ctx!");
344         HcfFree(returnSpiImpl);
345         return HCF_ERR_CRYPTO_OPERATION;
346     }
347     OpensslMacFree(mac);
348     returnSpiImpl->base.base.getClass = OpensslGetCmacClass;
349     returnSpiImpl->base.base.destroy = OpensslDestroyCmac;
350     returnSpiImpl->base.engineInitMac = OpensslEngineInitCmac;
351     returnSpiImpl->base.engineUpdateMac = OpensslEngineUpdateCmac;
352     returnSpiImpl->base.engineDoFinalMac = OpensslEngineDoFinalCmac;
353     returnSpiImpl->base.engineGetMacLength = OpensslEngineGetCmacLength;
354     *spiObj = (HcfMacSpi *)returnSpiImpl;
355     return HCF_SUCCESS;
356 }