1 /*
2 * Copyright (C) 2022 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 (!IsClassMatch((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 Openssl_EVP_sha1();
53 } else if (strcmp(mdName, "SHA224") == 0) {
54 return Openssl_EVP_sha224();
55 } else if (strcmp(mdName, "SHA256") == 0) {
56 return Openssl_EVP_sha256();
57 } else if (strcmp(mdName, "SHA384") == 0) {
58 return Openssl_EVP_sha384();
59 } else if (strcmp(mdName, "SHA512") == 0) {
60 return Openssl_EVP_sha512();
61 } else if (strcmp(mdName, "SM3") == 0) {
62 return Openssl_EVP_sm3();
63 }
64 return NULL;
65 }
66
OpensslEngineInitMac(HcfMacSpi * self,const HcfSymKey * key)67 static HcfResult OpensslEngineInitMac(HcfMacSpi *self, const HcfSymKey *key)
68 {
69 if (OpensslGetMacCtx(self) == NULL) {
70 LOGD("[error] The CTX is NULL!");
71 return HCF_ERR_CRYPTO_OPERATION;
72 }
73 if (!IsClassMatch((const HcfObjectBase *)key, OPENSSL_SYM_KEY_CLASS)) {
74 LOGE("Class is not match.");
75 return HCF_INVALID_PARAMS;
76 }
77 if (!IsClassMatch((HcfObjectBase *)self, OpensslGetMacClass())) {
78 LOGE("Class is not match.");
79 return HCF_INVALID_PARAMS;
80 }
81 HcfBlob keyBlob = ((SymKeyImpl *)key)->keyMaterial;
82 if (!IsBlobValid(&keyBlob)) {
83 LOGE("Invalid keyMaterial");
84 return HCF_INVALID_PARAMS;
85 }
86 const EVP_MD *mdfunc = OpensslGetMacAlgoFromString(((HcfMacSpiImpl *)self)->opensslAlgoName);
87 int32_t ret = Openssl_HMAC_Init_ex(OpensslGetMacCtx(self), keyBlob.data, keyBlob.len, mdfunc, NULL);
88 if (ret != HCF_OPENSSL_SUCCESS) {
89 LOGD("[error] HMAC_Init_ex return error!");
90 HcfPrintOpensslError();
91 return HCF_ERR_CRYPTO_OPERATION;
92 }
93 return HCF_SUCCESS;
94 }
95
OpensslEngineUpdateMac(HcfMacSpi * self,HcfBlob * input)96 static HcfResult OpensslEngineUpdateMac(HcfMacSpi *self, HcfBlob *input)
97 {
98 if (OpensslGetMacCtx(self) == NULL) {
99 LOGD("[error] The CTX is NULL!");
100 return HCF_ERR_CRYPTO_OPERATION;
101 }
102 if (HMAC_Update(OpensslGetMacCtx(self), input->data, input->len) != HCF_OPENSSL_SUCCESS) {
103 LOGD("[error] HMAC_Update return error!");
104 HcfPrintOpensslError();
105 return HCF_ERR_CRYPTO_OPERATION;
106 }
107 return HCF_SUCCESS;
108 }
109
OpensslEngineDoFinalMac(HcfMacSpi * self,HcfBlob * output)110 static HcfResult OpensslEngineDoFinalMac(HcfMacSpi *self, HcfBlob *output)
111 {
112 if (OpensslGetMacCtx(self) == NULL) {
113 LOGD("[error] The CTX is NULL!");
114 return HCF_ERR_CRYPTO_OPERATION;
115 }
116 unsigned char outputBuf[EVP_MAX_MD_SIZE];
117 uint32_t outputLen;
118 int32_t ret = Openssl_HMAC_Final(OpensslGetMacCtx(self), outputBuf, &outputLen);
119 if (ret != HCF_OPENSSL_SUCCESS) {
120 LOGD("[error] HMAC_Final return error!");
121 HcfPrintOpensslError();
122 return HCF_ERR_CRYPTO_OPERATION;
123 }
124 output->data = (uint8_t *)HcfMalloc(outputLen, 0);
125 if (output->data == NULL) {
126 LOGE("Failed to allocate output->data memory!");
127 return HCF_ERR_MALLOC;
128 }
129 (void)memcpy_s(output->data, outputLen, outputBuf, outputLen);
130 output->len = outputLen;
131 return HCF_SUCCESS;
132 }
133
OpensslEngineGetMacLength(HcfMacSpi * self)134 static uint32_t OpensslEngineGetMacLength(HcfMacSpi *self)
135 {
136 if (OpensslGetMacCtx(self) == NULL) {
137 LOGD("[error] The CTX is NULL!");
138 return HCF_OPENSSL_INVALID_MAC_LEN;
139 }
140 return Openssl_HMAC_size(OpensslGetMacCtx(self));
141 }
142
OpensslDestroyMac(HcfObjectBase * self)143 static void OpensslDestroyMac(HcfObjectBase *self)
144 {
145 if (self == NULL) {
146 LOGE("Self ptr is NULL");
147 return;
148 }
149 if (!IsClassMatch(self, OpensslGetMacClass())) {
150 LOGE("Class is not match.");
151 return;
152 }
153 if (OpensslGetMacCtx((HcfMacSpi *)self) != NULL) {
154 Openssl_HMAC_CTX_free(OpensslGetMacCtx((HcfMacSpi *)self));
155 }
156 HcfFree(self);
157 }
158
OpensslMacSpiCreate(const char * opensslAlgoName,HcfMacSpi ** spiObj)159 HcfResult OpensslMacSpiCreate(const char *opensslAlgoName, HcfMacSpi **spiObj)
160 {
161 if (spiObj == NULL) {
162 LOGE("Invalid input parameter.");
163 return HCF_INVALID_PARAMS;
164 }
165 HcfMacSpiImpl *returnSpiImpl = (HcfMacSpiImpl *)HcfMalloc(sizeof(HcfMacSpiImpl), 0);
166 if (returnSpiImpl == NULL) {
167 LOGE("Failed to allocate returnImpl memory!");
168 return HCF_ERR_MALLOC;
169 }
170 if (strcpy_s(returnSpiImpl->opensslAlgoName, HCF_MAX_ALGO_NAME_LEN, opensslAlgoName) != EOK) {
171 LOGE("Failed to copy algoName!");
172 HcfFree(returnSpiImpl);
173 return HCF_INVALID_PARAMS;
174 }
175 returnSpiImpl->ctx = Openssl_HMAC_CTX_new();
176 if (returnSpiImpl->ctx == NULL) {
177 LOGD("[error] Failed to create ctx!");
178 HcfFree(returnSpiImpl);
179 return HCF_ERR_CRYPTO_OPERATION;
180 }
181 returnSpiImpl->base.base.getClass = OpensslGetMacClass;
182 returnSpiImpl->base.base.destroy = OpensslDestroyMac;
183 returnSpiImpl->base.engineInitMac = OpensslEngineInitMac;
184 returnSpiImpl->base.engineUpdateMac = OpensslEngineUpdateMac;
185 returnSpiImpl->base.engineDoFinalMac = OpensslEngineDoFinalMac;
186 returnSpiImpl->base.engineGetMacLength = OpensslEngineGetMacLength;
187 *spiObj = (HcfMacSpi *)returnSpiImpl;
188 return HCF_SUCCESS;
189 }