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 (!HcfIsClassMatch(self, self->getClass())) {
67         LOGE("Class not match.");
68         return;
69     }
70     HcfSignSpiEd25519OpensslImpl *impl = (HcfSignSpiEd25519OpensslImpl *)self;
71     if (impl->mdCtx != NULL) {
72         OpensslEvpMdCtxFree(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 (!HcfIsClassMatch(self, self->getClass())) {
85         LOGE("Class not match.");
86         return;
87     }
88     HcfVerifySpiEd25519OpensslImpl *impl = (HcfVerifySpiEd25519OpensslImpl *)self;
89     if (impl->mdCtx != NULL) {
90         OpensslEvpMdCtxFree(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 ((!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) ||
104         (!HcfIsClassMatch((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 
115     if (OpensslEvpDigestSignInit(impl->mdCtx, NULL, NULL, NULL,
116         ((HcfOpensslAlg25519PriKey *)privateKey)->pkey) != HCF_OPENSSL_SUCCESS) {
117         HcfPrintOpensslError();
118         LOGD("[error] EVP_DigestSignInit failed.");
119         return HCF_ERR_CRYPTO_OPERATION;
120     }
121     impl->status = INITIALIZED;
122     return HCF_SUCCESS;
123 }
124 
EngineSignUpdate(HcfSignSpi * self,HcfBlob * data)125 static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data)
126 {
127     (void)self;
128     (void)data;
129     return HCF_INVALID_PARAMS;
130 }
131 
EngineSignDoFinal(HcfSignSpi * self,HcfBlob * data,HcfBlob * returnSignatureData)132 static HcfResult EngineSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData)
133 {
134     if ((self == NULL) || (returnSignatureData == NULL)) {
135         LOGE("Invalid input parameter.");
136         return HCF_INVALID_PARAMS;
137     }
138     if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
139         LOGE("Class not match.");
140         return HCF_INVALID_PARAMS;
141     }
142     if (!HcfIsBlobValid(data)) {
143         LOGE("Invalid sign data.");
144         return HCF_INVALID_PARAMS;
145     }
146     HcfSignSpiEd25519OpensslImpl *impl = (HcfSignSpiEd25519OpensslImpl *)self;
147     if (impl->status != INITIALIZED) {
148         LOGE("The message has not been initialized.");
149         return HCF_INVALID_PARAMS;
150     }
151     size_t siglen;
152     if (OpensslEvpDigestSign(impl->mdCtx, NULL, &siglen, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
153         HcfPrintOpensslError();
154         LOGD("[error] EVP_DigestSign failed.");
155         return HCF_ERR_CRYPTO_OPERATION;
156     }
157     uint8_t *signatureData = (uint8_t *)HcfMalloc(siglen, 0);
158     if (signatureData == NULL) {
159         LOGE("Failed to allocate signatureData memory!");
160         return HCF_ERR_MALLOC;
161     }
162     if (OpensslEvpDigestSign(impl->mdCtx, signatureData, &siglen, data->data, data->len) != HCF_OPENSSL_SUCCESS) {
163         HcfPrintOpensslError();
164         LOGD("[error] EVP_DigestSign failed.");
165         HcfFree(signatureData);
166         return HCF_ERR_CRYPTO_OPERATION;
167     }
168     returnSignatureData->data = signatureData;
169     returnSignatureData->len = (uint32_t)siglen;
170     return HCF_SUCCESS;
171 }
172 
EngineVerifyInit(HcfVerifySpi * self,HcfParamsSpec * params,HcfPubKey * publicKey)173 static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey)
174 {
175     (void)params;
176     if ((self == NULL) || (publicKey == NULL)) {
177         LOGE("Invalid input parameter.");
178         return HCF_INVALID_PARAMS;
179     }
180     if ((!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) ||
181         (!HcfIsClassMatch((HcfObjectBase *)publicKey, OPENSSL_ALG25519_PUBKEY_CLASS))) {
182         LOGE("Class not match.");
183         return HCF_INVALID_PARAMS;
184     }
185 
186     HcfVerifySpiEd25519OpensslImpl *impl = (HcfVerifySpiEd25519OpensslImpl *)self;
187     if (impl->status != UNINITIALIZED) {
188         LOGE("Repeated initialization is not allowed.");
189         return HCF_INVALID_PARAMS;
190     }
191     EVP_PKEY *pKey = OpensslEvpPkeyDup(((HcfOpensslAlg25519PubKey *)publicKey)->pkey);
192     if (pKey == NULL) {
193         HcfPrintOpensslError();
194         LOGD("[error] Dup pkey failed.");
195         return HCF_ERR_CRYPTO_OPERATION;
196     }
197     if (OpensslEvpDigestVerifyInit(impl->mdCtx, NULL, NULL, NULL, pKey) != HCF_OPENSSL_SUCCESS) {
198         HcfPrintOpensslError();
199         LOGD("[error] EVP_DigestVerifyInit failed.");
200         OpensslEvpPkeyFree(pKey);
201         return HCF_ERR_CRYPTO_OPERATION;
202     }
203     OpensslEvpPkeyFree(pKey);
204     impl->status = INITIALIZED;
205     return HCF_SUCCESS;
206 }
207 
EngineVerifyUpdate(HcfVerifySpi * self,HcfBlob * data)208 static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data)
209 {
210     (void)self;
211     (void)data;
212     return HCF_INVALID_PARAMS;
213 }
214 
EngineVerifyDoFinal(HcfVerifySpi * self,HcfBlob * data,HcfBlob * signatureData)215 static bool EngineVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData)
216 {
217     if ((self == NULL) || (!HcfIsBlobValid(signatureData))) {
218         LOGE("Invalid input parameter.");
219         return false;
220     }
221     if (!HcfIsClassMatch((HcfObjectBase *)self, self->base.getClass())) {
222         LOGE("Class not match.");
223         return false;
224     }
225     if (!HcfIsBlobValid(data)) {
226         LOGE("Invalid verify data.");
227         return false;
228     }
229     HcfVerifySpiEd25519OpensslImpl *impl = (HcfVerifySpiEd25519OpensslImpl *)self;
230     if (impl->status != INITIALIZED) {
231         LOGE("The message has not been initialized.");
232         return false;
233     }
234     if (OpensslEvpDigestVerify(impl->mdCtx, signatureData->data, signatureData->len,
235         data->data, data->len) != HCF_OPENSSL_SUCCESS) {
236         HcfPrintOpensslError();
237         LOGD("[error] EVP_DigestVerify failed.");
238         return false;
239     }
240     return true;
241 }
242 
EngineGetSignSpecString(HcfSignSpi * self,SignSpecItem item,char ** returnString)243 static HcfResult EngineGetSignSpecString(HcfSignSpi *self, SignSpecItem item, char **returnString)
244 {
245     (void)self;
246     (void)item;
247     (void)returnString;
248     return HCF_NOT_SUPPORT;
249 }
250 
EngineSetSignSpecUint8Array(HcfSignSpi * self,SignSpecItem item,HcfBlob userId)251 static HcfResult EngineSetSignSpecUint8Array(HcfSignSpi *self, SignSpecItem item, HcfBlob userId)
252 {
253     (void)self;
254     (void)item;
255     (void)userId;
256     return HCF_NOT_SUPPORT;
257 }
258 
EngineGetSignSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t * returnInt)259 static HcfResult EngineGetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt)
260 {
261     (void)self;
262     (void)item;
263     (void)returnInt;
264     return HCF_NOT_SUPPORT;
265 }
266 
EngineSetSignSpecInt(HcfSignSpi * self,SignSpecItem item,int32_t saltLen)267 static HcfResult EngineSetSignSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t saltLen)
268 {
269     (void)self;
270     (void)item;
271     (void)saltLen;
272     return HCF_NOT_SUPPORT;
273 }
274 
EngineGetVerifySpecString(HcfVerifySpi * self,SignSpecItem item,char ** returnString)275 static HcfResult EngineGetVerifySpecString(HcfVerifySpi *self, SignSpecItem item, char **returnString)
276 {
277     (void)self;
278     (void)item;
279     (void)returnString;
280     return HCF_NOT_SUPPORT;
281 }
282 
EngineSetVerifySpecUint8Array(HcfVerifySpi * self,SignSpecItem item,HcfBlob userId)283 static HcfResult EngineSetVerifySpecUint8Array(HcfVerifySpi *self, SignSpecItem item, HcfBlob userId)
284 {
285     (void)self;
286     (void)item;
287     (void)userId;
288     return HCF_NOT_SUPPORT;
289 }
290 
EngineGetVerifySpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t * returnInt)291 static HcfResult EngineGetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt)
292 {
293     (void)self;
294     (void)item;
295     (void)returnInt;
296     return HCF_NOT_SUPPORT;
297 }
298 
EngineSetVerifySpecInt(HcfVerifySpi * self,SignSpecItem item,int32_t saltLen)299 static HcfResult EngineSetVerifySpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen)
300 {
301     (void)self;
302     (void)item;
303     (void)saltLen;
304     return HCF_NOT_SUPPORT;
305 }
306 
HcfSignSpiEd25519Create(HcfSignatureParams * params,HcfSignSpi ** returnObj)307 HcfResult HcfSignSpiEd25519Create(HcfSignatureParams *params, HcfSignSpi **returnObj)
308 {
309     (void)params;
310     if ((params == NULL) || (returnObj == NULL)) {
311         LOGE("Invalid input parameter.");
312         return HCF_INVALID_PARAMS;
313     }
314 
315     HcfSignSpiEd25519OpensslImpl *returnImpl = (HcfSignSpiEd25519OpensslImpl *)HcfMalloc(
316         sizeof(HcfSignSpiEd25519OpensslImpl), 0);
317     if (returnImpl == NULL) {
318         LOGE("Failed to allocate returnImpl memroy!");
319         return HCF_ERR_MALLOC;
320     }
321     returnImpl->base.base.getClass = GetEd25519SignClass;
322     returnImpl->base.base.destroy = DestroyEd25519Sign;
323     returnImpl->base.engineInit = EngineSignInit;
324     returnImpl->base.engineUpdate = EngineSignUpdate;
325     returnImpl->base.engineSign = EngineSignDoFinal;
326     returnImpl->base.engineGetSignSpecString = EngineGetSignSpecString;
327     returnImpl->base.engineSetSignSpecUint8Array = EngineSetSignSpecUint8Array;
328     returnImpl->base.engineGetSignSpecInt = EngineGetSignSpecInt;
329     returnImpl->base.engineSetSignSpecInt = EngineSetSignSpecInt;
330     returnImpl->status = UNINITIALIZED;
331     returnImpl->mdCtx = OpensslEvpMdCtxNew();
332     if (returnImpl->mdCtx == NULL) {
333         LOGE("Failed to allocate mdCtx memory!");
334         HcfFree(returnImpl);
335         return HCF_ERR_MALLOC;
336     }
337 
338     *returnObj = (HcfSignSpi *)returnImpl;
339     return HCF_SUCCESS;
340 }
341 
HcfVerifySpiEd25519Create(HcfSignatureParams * params,HcfVerifySpi ** returnObj)342 HcfResult HcfVerifySpiEd25519Create(HcfSignatureParams *params, HcfVerifySpi **returnObj)
343 {
344     (void)params;
345     if ((params == NULL) || (returnObj == NULL)) {
346         LOGE("Invalid input parameter.");
347         return HCF_INVALID_PARAMS;
348     }
349 
350     HcfVerifySpiEd25519OpensslImpl *returnImpl = (HcfVerifySpiEd25519OpensslImpl *)HcfMalloc(
351         sizeof(HcfVerifySpiEd25519OpensslImpl), 0);
352     if (returnImpl == NULL) {
353         LOGE("Failed to allocate returnImpl memroy!");
354         return HCF_ERR_MALLOC;
355     }
356     returnImpl->base.base.getClass = GetEd25519VerifyClass;
357     returnImpl->base.base.destroy = DestroyEd25519Verify;
358     returnImpl->base.engineInit = EngineVerifyInit;
359     returnImpl->base.engineUpdate = EngineVerifyUpdate;
360     returnImpl->base.engineVerify = EngineVerifyDoFinal;
361     returnImpl->base.engineGetVerifySpecString = EngineGetVerifySpecString;
362     returnImpl->base.engineSetVerifySpecUint8Array = EngineSetVerifySpecUint8Array;
363     returnImpl->base.engineGetVerifySpecInt = EngineGetVerifySpecInt;
364     returnImpl->base.engineSetVerifySpecInt = EngineSetVerifySpecInt;
365     returnImpl->status = UNINITIALIZED;
366     returnImpl->mdCtx = OpensslEvpMdCtxNew();
367     if (returnImpl->mdCtx == NULL) {
368         LOGE("Failed to allocate mdCtx memory!");
369         HcfFree(returnImpl);
370         return HCF_ERR_MALLOC;
371     }
372 
373     *returnObj = (HcfVerifySpi *)returnImpl;
374     return HCF_SUCCESS;
375 }
376