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
27 typedef struct {
28 HcfMacSpi base;
29
30 HMAC_CTX *ctx;
31
32 char opensslAlgoName[HCF_MAX_ALGO_NAME_LEN];
33 } HcfMacSpiImpl;
34
OpensslGetMacClass(void)35 static const char *OpensslGetMacClass(void)
36 {
37 return "OpensslMac";
38 }
39
OpensslGetMacCtx(HcfMacSpi * self)40 static HMAC_CTX *OpensslGetMacCtx(HcfMacSpi *self)
41 {
42 if (!HcfIsClassMatch((HcfObjectBase *)self, OpensslGetMacClass())) {
43 LOGE("Class is not match.");
44 return NULL;
45 }
46 return ((HcfMacSpiImpl *)self)->ctx;
47 }
48
OpensslGetMacAlgoFromString(const char * mdName)49 static const EVP_MD *OpensslGetMacAlgoFromString(const char *mdName)
50 {
51 if (strcmp(mdName, "SHA1") == 0) {
52 return OpensslEvpSha1();
53 } else if (strcmp(mdName, "SHA224") == 0) {
54 return OpensslEvpSha224();
55 } else if (strcmp(mdName, "SHA256") == 0) {
56 return OpensslEvpSha256();
57 } else if (strcmp(mdName, "SHA384") == 0) {
58 return OpensslEvpSha384();
59 } else if (strcmp(mdName, "SHA512") == 0) {
60 return OpensslEvpSha512();
61 } else if (strcmp(mdName, "SM3") == 0) {
62 return OpensslEvpSm3();
63 } else if (strcmp(mdName, "MD5") == 0) {
64 return OpensslEvpMd5();
65 }
66 return NULL;
67 }
68
OpensslEngineInitMac(HcfMacSpi * self,const HcfSymKey * key)69 static HcfResult OpensslEngineInitMac(HcfMacSpi *self, const HcfSymKey *key)
70 {
71 if (OpensslGetMacCtx(self) == NULL) {
72 LOGD("[error] The CTX is NULL!");
73 return HCF_ERR_CRYPTO_OPERATION;
74 }
75 if (!HcfIsClassMatch((const HcfObjectBase *)key, OPENSSL_SYM_KEY_CLASS)) {
76 LOGE("Class is not match.");
77 return HCF_INVALID_PARAMS;
78 }
79 if (!HcfIsClassMatch((HcfObjectBase *)self, OpensslGetMacClass())) {
80 LOGE("Class is not match.");
81 return HCF_INVALID_PARAMS;
82 }
83 HcfBlob keyBlob = ((SymKeyImpl *)key)->keyMaterial;
84 if (!HcfIsBlobValid(&keyBlob)) {
85 LOGE("Invalid keyMaterial");
86 return HCF_INVALID_PARAMS;
87 }
88 const EVP_MD *mdfunc = OpensslGetMacAlgoFromString(((HcfMacSpiImpl *)self)->opensslAlgoName);
89 int32_t ret = OpensslHmacInitEx(OpensslGetMacCtx(self), keyBlob.data, keyBlob.len, mdfunc, NULL);
90 if (ret != HCF_OPENSSL_SUCCESS) {
91 LOGD("[error] HMAC_Init_ex return error!");
92 HcfPrintOpensslError();
93 return HCF_ERR_CRYPTO_OPERATION;
94 }
95 return HCF_SUCCESS;
96 }
97
OpensslEngineUpdateMac(HcfMacSpi * self,HcfBlob * input)98 static HcfResult OpensslEngineUpdateMac(HcfMacSpi *self, HcfBlob *input)
99 {
100 if (OpensslGetMacCtx(self) == NULL) {
101 LOGD("[error] The CTX is NULL!");
102 return HCF_ERR_CRYPTO_OPERATION;
103 }
104 if (HMAC_Update(OpensslGetMacCtx(self), input->data, input->len) != HCF_OPENSSL_SUCCESS) {
105 LOGD("[error] HMAC_Update return error!");
106 HcfPrintOpensslError();
107 return HCF_ERR_CRYPTO_OPERATION;
108 }
109 return HCF_SUCCESS;
110 }
111
OpensslEngineDoFinalMac(HcfMacSpi * self,HcfBlob * output)112 static HcfResult OpensslEngineDoFinalMac(HcfMacSpi *self, HcfBlob *output)
113 {
114 if (OpensslGetMacCtx(self) == NULL) {
115 LOGD("[error] The CTX is NULL!");
116 return HCF_ERR_CRYPTO_OPERATION;
117 }
118 unsigned char outputBuf[EVP_MAX_MD_SIZE];
119 uint32_t outputLen;
120 int32_t ret = OpensslHmacFinal(OpensslGetMacCtx(self), outputBuf, &outputLen);
121 if (ret != HCF_OPENSSL_SUCCESS) {
122 LOGD("[error] HMAC_Final return error!");
123 HcfPrintOpensslError();
124 return HCF_ERR_CRYPTO_OPERATION;
125 }
126 output->data = (uint8_t *)HcfMalloc(outputLen, 0);
127 if (output->data == NULL) {
128 LOGE("Failed to allocate output->data memory!");
129 return HCF_ERR_MALLOC;
130 }
131 (void)memcpy_s(output->data, outputLen, outputBuf, outputLen);
132 output->len = outputLen;
133 return HCF_SUCCESS;
134 }
135
OpensslEngineGetMacLength(HcfMacSpi * self)136 static uint32_t OpensslEngineGetMacLength(HcfMacSpi *self)
137 {
138 if (OpensslGetMacCtx(self) == NULL) {
139 LOGD("[error] The CTX is NULL!");
140 return HCF_OPENSSL_INVALID_MAC_LEN;
141 }
142 return OpensslHmacSize(OpensslGetMacCtx(self));
143 }
144
OpensslDestroyMac(HcfObjectBase * self)145 static void OpensslDestroyMac(HcfObjectBase *self)
146 {
147 if (self == NULL) {
148 LOGE("Self ptr is NULL");
149 return;
150 }
151 if (!HcfIsClassMatch(self, OpensslGetMacClass())) {
152 LOGE("Class is not match.");
153 return;
154 }
155 if (OpensslGetMacCtx((HcfMacSpi *)self) != NULL) {
156 OpensslHmacCtxFree(OpensslGetMacCtx((HcfMacSpi *)self));
157 }
158 HcfFree(self);
159 }
160
OpensslMacSpiCreate(const char * opensslAlgoName,HcfMacSpi ** spiObj)161 HcfResult OpensslMacSpiCreate(const char *opensslAlgoName, HcfMacSpi **spiObj)
162 {
163 if (spiObj == NULL) {
164 LOGE("Invalid input parameter.");
165 return HCF_INVALID_PARAMS;
166 }
167 HcfMacSpiImpl *returnSpiImpl = (HcfMacSpiImpl *)HcfMalloc(sizeof(HcfMacSpiImpl), 0);
168 if (returnSpiImpl == NULL) {
169 LOGE("Failed to allocate returnImpl memory!");
170 return HCF_ERR_MALLOC;
171 }
172 if (strcpy_s(returnSpiImpl->opensslAlgoName, HCF_MAX_ALGO_NAME_LEN, opensslAlgoName) != EOK) {
173 LOGE("Failed to copy algoName!");
174 HcfFree(returnSpiImpl);
175 return HCF_INVALID_PARAMS;
176 }
177 returnSpiImpl->ctx = OpensslHmacCtxNew();
178 if (returnSpiImpl->ctx == NULL) {
179 LOGD("[error] Failed to create ctx!");
180 HcfFree(returnSpiImpl);
181 return HCF_ERR_CRYPTO_OPERATION;
182 }
183 returnSpiImpl->base.base.getClass = OpensslGetMacClass;
184 returnSpiImpl->base.base.destroy = OpensslDestroyMac;
185 returnSpiImpl->base.engineInitMac = OpensslEngineInitMac;
186 returnSpiImpl->base.engineUpdateMac = OpensslEngineUpdateMac;
187 returnSpiImpl->base.engineDoFinalMac = OpensslEngineDoFinalMac;
188 returnSpiImpl->base.engineGetMacLength = OpensslEngineGetMacLength;
189 *spiObj = (HcfMacSpi *)returnSpiImpl;
190 return HCF_SUCCESS;
191 }