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