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