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