• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "ed25519_openssl.h"
17 
18 #include <openssl/bio.h>
19 #include <openssl/err.h>
20 
21 #include "securec.h"
22 
23 #include "algorithm_parameter.h"
24 #include "openssl_adapter.h"
25 #include "openssl_class.h"
26 #include "openssl_common.h"
27 #include "log.h"
28 #include "memory.h"
29 #include "utils.h"
30 
31 #define OPENSSL_ED25519_SIGN_CLASS "OPENSSL.ED25519.SIGN"
32 #define OPENSSL_ED25519_VERIFY_CLASS "OPENSSL.ED25519.VERIFY"
33 
34 typedef struct {
35     HcfSignSpi base;
36 
37     EVP_MD_CTX *mdCtx;
38 
39     CryptoStatus status;
40 } HcfSignSpiEd25519OpensslImpl;
41 
42 typedef struct {
43     HcfVerifySpi base;
44 
45     EVP_MD_CTX *mdCtx;
46 
47     CryptoStatus status;
48 } HcfVerifySpiEd25519OpensslImpl;
49 
GetEd25519SignClass(void)50 static const char *GetEd25519SignClass(void)
51 {
52     return OPENSSL_ED25519_SIGN_CLASS;
53 }
54 
GetEd25519VerifyClass(void)55 static const char *GetEd25519VerifyClass(void)
56 {
57     return OPENSSL_ED25519_VERIFY_CLASS;
58 }
59 
DestroyEd25519Sign(HcfObjectBase * self)60 static void DestroyEd25519Sign(HcfObjectBase *self)
61 {
62     if (self == NULL) {
63         LOGE("Class is null.");
64         return;
65     }
66     if (!IsClassMatch(self, self->getClass())) {
67         LOGE("Class not match.");
68         return;
69     }
70     HcfSignSpiEd25519OpensslImpl *impl = (HcfSignSpiEd25519OpensslImpl *)self;
71     if (impl->mdCtx != NULL) {
72         Openssl_EVP_MD_CTX_free(impl->mdCtx);
73         impl->mdCtx = NULL;
74     }
75     HcfFree(impl);
76 }
77 
DestroyEd25519Verify(HcfObjectBase * self)78 static void DestroyEd25519Verify(HcfObjectBase *self)
79 {
80     if (self == NULL) {
81         LOGE("Class is null.");
82         return;
83     }
84     if (!IsClassMatch(self, self->getClass())) {
85         LOGE("Class not match.");
86         return;
87     }
88     HcfVerifySpiEd25519OpensslImpl *impl = (HcfVerifySpiEd25519OpensslImpl *)self;
89     if (impl->mdCtx != NULL) {
90         Openssl_EVP_MD_CTX_free(impl->mdCtx);
91         impl->mdCtx = NULL;
92     }
93     HcfFree(impl);
94 }
95 
EngineSignInit(HcfSignSpi * self,HcfParamsSpec * params,HcfPriKey * privateKey)96 static HcfResult EngineSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey)
97 {
98     (void)params;
99     if ((self == NULL) || (privateKey == NULL)) {
100         LOGE("Invalid input parameter.");
101         return HCF_INVALID_PARAMS;
102     }
103     if ((!IsClassMatch((HcfObjectBase *)self, self->base.getClass())) ||
104         (!IsClassMatch((HcfObjectBase *)privateKey, OPENSSL_ALG25519_PRIKEY_CLASS))) {
105         LOGE("Class not match.");
106         return HCF_INVALID_PARAMS;
107     }
108 
109     HcfSignSpiEd25519OpensslImpl *impl = (HcfSignSpiEd25519OpensslImpl *)self;
110     if (impl->status != UNINITIALIZED) {
111         LOGE("Repeated initialization is not allowed.");
112         return HCF_INVALID_PARAMS;
113     }
114     EVP_PKEY *pKey = Openssl_EVP_PKEY_dup(((HcfOpensslAlg25519PriKey *)privateKey)->pkey);
115     if (pKey == NULL) {
116         HcfPrintOpensslError();
117         LOGD("[error] Dup pkey failed.");
118         return HCF_ERR_CRYPTO_OPERATION;
119     }
120     if (Openssl_EVP_DigestSignInit(impl->mdCtx, NULL, NULL, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
121         HcfPrintOpensslError();
122         LOGD("[error] EVP_DigestSignInit failed.");
123         Openssl_EVP_PKEY_free(pKey);
124         return HCF_ERR_CRYPTO_OPERATION;
125     }
126     Openssl_EVP_PKEY_free(pKey);
127     impl->status = INITIALIZED;
128     return HCF_SUCCESS;
129 }
130 
EngineSignUpdate(HcfSignSpi * self,HcfBlob * data)131 static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data)
132 {
133     (void)self;
134     (void)data;
135     return HCF_INVALID_PARAMS;
136 }
137 
EngineSignDoFinal(HcfSignSpi * self,HcfBlob * data,HcfBlob * returnSignatureData)138 static HcfResult EngineSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData)
139 {
140     if ((self == NULL) || (returnSignatureData == NULL)) {
141         LOGE("Invalid input parameter.");
142         return HCF_INVALID_PARAMS;
143     }
144     if (!IsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
145         LOGE("Class not match.");
146         return HCF_INVALID_PARAMS;
147     }
148     if (!IsBlobValid(data)) {
149         LOGE("Invalid sign data.");
150         return HCF_INVALID_PARAMS;
151     }
152     HcfSignSpiEd25519OpensslImpl *impl = (HcfSignSpiEd25519OpensslImpl *)self;
153     if (impl->status != INITIALIZED) {
154         LOGE("The message has not been initialized.");
155         return HCF_INVALID_PARAMS;
156     }
157     size_t siglen;
158     if (Openssl_EVP_DigestSign(impl->mdCtx, NULL, &siglen, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
159         HcfPrintOpensslError();
160         LOGD("[error] EVP_DigestSign failed.");
161         return HCF_ERR_CRYPTO_OPERATION;
162     }
163     uint8_t *signatureData = (uint8_t *)HcfMalloc(siglen, 0);
164     if (signatureData == NULL) {
165         LOGE("Failed to allocate signatureData memory!");
166         return HCF_ERR_MALLOC;
167     }
168     if (Openssl_EVP_DigestSign(impl->mdCtx, signatureData, &siglen, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
169         HcfPrintOpensslError();
170         LOGD("[error] EVP_DigestSign failed.");
171         HcfFree(signatureData);
172         return HCF_ERR_CRYPTO_OPERATION;
173     }
174     returnSignatureData->data = signatureData;
175     returnSignatureData->len = (uint32_t)siglen;
176     return HCF_SUCCESS;
177 }
178 
EngineVerifyInit(HcfVerifySpi * self,HcfParamsSpec * params,HcfPubKey * publicKey)179 static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey)
180 {
181     (void)params;
182     if ((self == NULL) || (publicKey == NULL)) {
183         LOGE("Invalid input parameter.");
184         return HCF_INVALID_PARAMS;
185     }
186     if ((!IsClassMatch((HcfObjectBase *)self, self->base.getClass())) ||
187         (!IsClassMatch((HcfObjectBase *)publicKey, OPENSSL_ALG25519_PUBKEY_CLASS))) {
188         LOGE("Class not match.");
189         return HCF_INVALID_PARAMS;
190     }
191 
192     HcfVerifySpiEd25519OpensslImpl *impl = (HcfVerifySpiEd25519OpensslImpl *)self;
193     if (impl->status != UNINITIALIZED) {
194         LOGE("Repeated initialization is not allowed.");
195         return HCF_INVALID_PARAMS;
196     }
197     EVP_PKEY *pKey = Openssl_EVP_PKEY_dup(((HcfOpensslAlg25519PubKey *)publicKey)->pkey);
198     if (pKey == NULL) {
199         HcfPrintOpensslError();
200         LOGD("[error] Dup pkey failed.");
201         return HCF_ERR_CRYPTO_OPERATION;
202     }
203     if (Openssl_EVP_DigestVerifyInit(impl->mdCtx, NULL, NULL, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
204         HcfPrintOpensslError();
205         LOGD("[error] EVP_DigestVerifyInit failed.");
206         Openssl_EVP_PKEY_free(pKey);
207         return HCF_ERR_CRYPTO_OPERATION;
208     }
209     Openssl_EVP_PKEY_free(pKey);
210     impl->status = INITIALIZED;
211     return HCF_SUCCESS;
212 }
213 
EngineVerifyUpdate(HcfVerifySpi * self,HcfBlob * data)214 static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data)
215 {
216     (void)self;
217     (void)data;
218     return HCF_INVALID_PARAMS;
219 }
220 
EngineVerifyDoFinal(HcfVerifySpi * self,HcfBlob * data,HcfBlob * signatureData)221 static bool EngineVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData)
222 {
223     if ((self == NULL) || (!IsBlobValid(signatureData))) {
224         LOGE("Invalid input parameter.");
225         return false;
226     }
227     if (!IsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
228         LOGE("Class not match.");
229         return false;
230     }
231     if (!IsBlobValid(data)) {
232         LOGE("Invalid verify data.");
233         return false;
234     }
235     HcfVerifySpiEd25519OpensslImpl *impl = (HcfVerifySpiEd25519OpensslImpl *)self;
236     if (impl->status != INITIALIZED) {
237         LOGE("The message has not been initialized.");
238         return false;
239     }
240     if (Openssl_EVP_DigestVerify(impl->mdCtx, signatureData->data, signatureData->len,
241         data->data, data->len) != HCF_OPENSSL_SUCCESS) {
242         HcfPrintOpensslError();
243         LOGD("[error] EVP_DigestVerify failed.");
244         return false;
245     }
246     return true;
247 }
248 
EngineGetSignSpecString(HcfSignSpi * self,SignSpecItem item,char ** returnString)249 static HcfResult EngineGetSignSpecString(HcfSignSpi *self, SignSpecItem item, char **returnString)
250 {
251     (void)self;
252     (void)item;
253     (void)returnString;
254     return HCF_NOT_SUPPORT;
255 }
256 
EngineSetSignSpecUint8Array(HcfSignSpi * self,SignSpecItem item,HcfBlob userId)257 static HcfResult EngineSetSignSpecUint8Array(HcfSignSpi *self, SignSpecItem item, HcfBlob userId)
258 {
259     (void)self;
260     (void)item;
261     (void)userId;
262     return HCF_NOT_SUPPORT;
263 }
264 
EngineGetSignSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t * returnInt)265 static HcfResult EngineGetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt)
266 {
267     (void)self;
268     (void)item;
269     (void)returnInt;
270     return HCF_NOT_SUPPORT;
271 }
272 
EngineSetSignSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t saltLen)273 static HcfResult EngineSetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t saltLen)
274 {
275     (void)self;
276     (void)item;
277     (void)saltLen;
278     return HCF_NOT_SUPPORT;
279 }
280 
EngineGetVerifySpecString(HcfVerifySpi * self,SignSpecItem item,char ** returnString)281 static HcfResult EngineGetVerifySpecString(HcfVerifySpi *self, SignSpecItem item, char **returnString)
282 {
283     (void)self;
284     (void)item;
285     (void)returnString;
286     return HCF_NOT_SUPPORT;
287 }
288 
EngineSetVerifySpecUint8Array(HcfVerifySpi * self,SignSpecItem item,HcfBlob userId)289 static HcfResult EngineSetVerifySpecUint8Array(HcfVerifySpi *self, SignSpecItem item, HcfBlob userId)
290 {
291     (void)self;
292     (void)item;
293     (void)userId;
294     return HCF_NOT_SUPPORT;
295 }
296 
EngineGetVerifySpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t * returnInt)297 static HcfResult EngineGetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt)
298 {
299     (void)self;
300     (void)item;
301     (void)returnInt;
302     return HCF_NOT_SUPPORT;
303 }
304 
EngineSetVerifySpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t saltLen)305 static HcfResult EngineSetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen)
306 {
307     (void)self;
308     (void)item;
309     (void)saltLen;
310     return HCF_NOT_SUPPORT;
311 }
312 
HcfSignSpiEd25519Create(HcfSignatureParams * params,HcfSignSpi ** returnObj)313 HcfResult HcfSignSpiEd25519Create(HcfSignatureParams *params, HcfSignSpi **returnObj)
314 {
315     (void)params;
316     if ((params == NULL) || (returnObj == NULL)) {
317         LOGE("Invalid input parameter.");
318         return HCF_INVALID_PARAMS;
319     }
320 
321     HcfSignSpiEd25519OpensslImpl *returnImpl = (HcfSignSpiEd25519OpensslImpl *)HcfMalloc(
322         sizeof(HcfSignSpiEd25519OpensslImpl), 0);
323     if (returnImpl == NULL) {
324         LOGE("Failed to allocate returnImpl memroy!");
325         return HCF_ERR_MALLOC;
326     }
327     returnImpl->base.base.getClass = GetEd25519SignClass;
328     returnImpl->base.base.destroy = DestroyEd25519Sign;
329     returnImpl->base.engineInit = EngineSignInit;
330     returnImpl->base.engineUpdate = EngineSignUpdate;
331     returnImpl->base.engineSign = EngineSignDoFinal;
332     returnImpl->base.engineGetSignSpecString = EngineGetSignSpecString;
333     returnImpl->base.engineSetSignSpecUint8Array = EngineSetSignSpecUint8Array;
334     returnImpl->base.engineGetSignSpecInt = EngineGetSignSpecInt;
335     returnImpl->base.engineSetSignSpecInt = EngineSetSignSpecInt;
336     returnImpl->status = UNINITIALIZED;
337     returnImpl->mdCtx = Openssl_EVP_MD_CTX_new();
338     if (returnImpl->mdCtx == NULL) {
339         LOGE("Failed to allocate mdCtx memory!");
340         HcfFree(returnImpl);
341         return HCF_ERR_MALLOC;
342     }
343 
344     *returnObj = (HcfSignSpi *)returnImpl;
345     return HCF_SUCCESS;
346 }
347 
HcfVerifySpiEd25519Create(HcfSignatureParams * params,HcfVerifySpi ** returnObj)348 HcfResult HcfVerifySpiEd25519Create(HcfSignatureParams *params, HcfVerifySpi **returnObj)
349 {
350     (void)params;
351     if ((params == NULL) || (returnObj == NULL)) {
352         LOGE("Invalid input parameter.");
353         return HCF_INVALID_PARAMS;
354     }
355 
356     HcfVerifySpiEd25519OpensslImpl *returnImpl = (HcfVerifySpiEd25519OpensslImpl *)HcfMalloc(
357         sizeof(HcfVerifySpiEd25519OpensslImpl), 0);
358     if (returnImpl == NULL) {
359         LOGE("Failed to allocate returnImpl memroy!");
360         return HCF_ERR_MALLOC;
361     }
362     returnImpl->base.base.getClass = GetEd25519VerifyClass;
363     returnImpl->base.base.destroy = DestroyEd25519Verify;
364     returnImpl->base.engineInit = EngineVerifyInit;
365     returnImpl->base.engineUpdate = EngineVerifyUpdate;
366     returnImpl->base.engineVerify = EngineVerifyDoFinal;
367     returnImpl->base.engineGetVerifySpecString = EngineGetVerifySpecString;
368     returnImpl->base.engineSetVerifySpecUint8Array = EngineSetVerifySpecUint8Array;
369     returnImpl->base.engineGetVerifySpecInt = EngineGetVerifySpecInt;
370     returnImpl->base.engineSetVerifySpecInt = EngineSetVerifySpecInt;
371     returnImpl->status = UNINITIALIZED;
372     returnImpl->mdCtx = Openssl_EVP_MD_CTX_new();
373     if (returnImpl->mdCtx == NULL) {
374         LOGE("Failed to allocate mdCtx memory!");
375         HcfFree(returnImpl);
376         return HCF_ERR_MALLOC;
377     }
378 
379     *returnObj = (HcfVerifySpi *)returnImpl;
380     return HCF_SUCCESS;
381 }
382