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