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 "md_openssl.h"
17
18 #include "openssl_adapter.h"
19 #include "openssl_common.h"
20 #include "securec.h"
21 #include "log.h"
22 #include "memory.h"
23 #include "config.h"
24 #include "utils.h"
25
26 typedef struct {
27 HcfMdSpi base;
28
29 EVP_MD_CTX *ctx;
30
31 char opensslAlgoName[HCF_MAX_ALGO_NAME_LEN];
32 } OpensslMdSpiImpl;
33
OpensslGetMdClass(void)34 static const char *OpensslGetMdClass(void)
35 {
36 return "OpensslMd";
37 }
38
OpensslGetMdCtx(HcfMdSpi * self)39 static EVP_MD_CTX *OpensslGetMdCtx(HcfMdSpi *self)
40 {
41 if (!IsClassMatch((HcfObjectBase *)self, OpensslGetMdClass())) {
42 LOGE("Class is not match.");
43 return NULL;
44 }
45 return ((OpensslMdSpiImpl *)self)->ctx;
46 }
47
OpensslGetMdAlgoFromString(const char * mdName)48 static const EVP_MD *OpensslGetMdAlgoFromString(const char *mdName)
49 {
50 if (strcmp(mdName, "SHA1") == 0) {
51 return Openssl_EVP_sha1();
52 } else if (strcmp(mdName, "SHA224") == 0) {
53 return Openssl_EVP_sha224();
54 } else if (strcmp(mdName, "SHA256") == 0) {
55 return Openssl_EVP_sha256();
56 } else if (strcmp(mdName, "SHA384") == 0) {
57 return Openssl_EVP_sha384();
58 } else if (strcmp(mdName, "SHA512") == 0) {
59 return Openssl_EVP_sha512();
60 } else if (strcmp(mdName, "MD5") == 0) {
61 return Openssl_EVP_md5();
62 } else if (strcmp(mdName, "SM3") == 0) {
63 return Openssl_EVP_sm3();
64 }
65 return NULL;
66 }
67
OpensslEngineUpdateMd(HcfMdSpi * self,HcfBlob * input)68 static HcfResult OpensslEngineUpdateMd(HcfMdSpi *self, HcfBlob *input)
69 {
70 if (OpensslGetMdCtx(self) == NULL) {
71 LOGE("The CTX is NULL!");
72 return HCF_ERR_CRYPTO_OPERATION;
73 }
74 if (EVP_DigestUpdate(OpensslGetMdCtx(self), input->data, input->len) != HCF_OPENSSL_SUCCESS) {
75 LOGE("EVP_DigestUpdate return error!");
76 HcfPrintOpensslError();
77 return HCF_ERR_CRYPTO_OPERATION;
78 }
79 return HCF_SUCCESS;
80 }
81
OpensslEngineDoFinalMd(HcfMdSpi * self,HcfBlob * output)82 static HcfResult OpensslEngineDoFinalMd(HcfMdSpi *self, HcfBlob *output)
83 {
84 EVP_MD_CTX *localCtx = OpensslGetMdCtx(self);
85 if (localCtx == NULL) {
86 LOGE("The CTX is NULL!");
87 return HCF_ERR_CRYPTO_OPERATION;
88 }
89 unsigned char outputBuf[EVP_MAX_MD_SIZE];
90 uint32_t outputLen;
91 int32_t ret = Openssl_EVP_DigestFinal_ex(localCtx, outputBuf, &outputLen);
92 if (ret != HCF_OPENSSL_SUCCESS) {
93 LOGE("EVP_DigestFinal_ex return error!");
94 HcfPrintOpensslError();
95 return HCF_ERR_CRYPTO_OPERATION;
96 }
97 output->data = (uint8_t *)HcfMalloc(outputLen, 0);
98 if (output->data == NULL) {
99 LOGE("Failed to allocate output->data memory!");
100 return HCF_ERR_MALLOC;
101 }
102 (void)memcpy_s(output->data, outputLen, outputBuf, outputLen);
103 output->len = outputLen;
104 return HCF_SUCCESS;
105 }
106
OpensslEngineGetMdLength(HcfMdSpi * self)107 static uint32_t OpensslEngineGetMdLength(HcfMdSpi *self)
108 {
109 if (OpensslGetMdCtx(self) == NULL) {
110 LOGE("The CTX is NULL!");
111 return HCF_OPENSSL_INVALID_MD_LEN;
112 }
113 int32_t size = Openssl_EVP_MD_CTX_size(OpensslGetMdCtx(self));
114 if (size < 0) {
115 LOGE("Get the overflow path length in openssl!");
116 return HCF_OPENSSL_INVALID_MD_LEN;
117 }
118 return size;
119 }
120
OpensslDestroyMd(HcfObjectBase * self)121 static void OpensslDestroyMd(HcfObjectBase *self)
122 {
123 if (self == NULL) {
124 LOGE("Self ptr is NULL!");
125 return;
126 }
127 if (!IsClassMatch(self, OpensslGetMdClass())) {
128 LOGE("Class is not match.");
129 return;
130 }
131 if (OpensslGetMdCtx((HcfMdSpi *)self) != NULL) {
132 Openssl_EVP_MD_CTX_free(OpensslGetMdCtx((HcfMdSpi *)self));
133 }
134 HcfFree(self);
135 }
136
OpensslMdSpiCreate(const char * opensslAlgoName,HcfMdSpi ** spiObj)137 HcfResult OpensslMdSpiCreate(const char *opensslAlgoName, HcfMdSpi **spiObj)
138 {
139 if (spiObj == NULL) {
140 LOGE("Invalid input parameter.");
141 return HCF_INVALID_PARAMS;
142 }
143 OpensslMdSpiImpl *returnSpiImpl = (OpensslMdSpiImpl *)HcfMalloc(sizeof(OpensslMdSpiImpl), 0);
144 if (returnSpiImpl == NULL) {
145 LOGE("Failed to allocate returnImpl memory!");
146 return HCF_ERR_MALLOC;
147 }
148 returnSpiImpl->ctx = Openssl_EVP_MD_CTX_new();
149 if (returnSpiImpl->ctx == NULL) {
150 LOGE("Failed to create ctx!");
151 HcfFree(returnSpiImpl);
152 return HCF_ERR_MALLOC;
153 }
154 const EVP_MD *mdfunc = OpensslGetMdAlgoFromString(opensslAlgoName);
155 int32_t ret = Openssl_EVP_DigestInit_ex(returnSpiImpl->ctx, mdfunc, NULL);
156 if (ret != HCF_OPENSSL_SUCCESS) {
157 LOGE("Failed to init MD!");
158 HcfFree(returnSpiImpl);
159 Openssl_EVP_MD_CTX_free(returnSpiImpl->ctx);
160 return HCF_ERR_CRYPTO_OPERATION;
161 }
162 returnSpiImpl->base.base.getClass = OpensslGetMdClass;
163 returnSpiImpl->base.base.destroy = OpensslDestroyMd;
164 returnSpiImpl->base.engineUpdateMd = OpensslEngineUpdateMd;
165 returnSpiImpl->base.engineDoFinalMd = OpensslEngineDoFinalMd;
166 returnSpiImpl->base.engineGetMdLength = OpensslEngineGetMdLength;
167 *spiObj = (HcfMdSpi *)returnSpiImpl;
168 return HCF_SUCCESS;
169 }