1 /*
2 * Copyright (C) 2024 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 "crypto_signature.h"
17 #include "sm2_ec_signature_data.h"
18 #include "securec.h"
19 #include <string.h>
20 #include <stdlib.h>
21 #include "signature.h"
22 #include "memory.h"
23 #include "crypto_common.h"
24 #include "blob.h"
25 #include "object_base.h"
26 #include "result.h"
27 #include "native_common.h"
28
29 struct OH_CryptoVerify {
30 HcfObjectBase base;
31
32 HcfResult (*init)(HcfVerify *self, HcfParamsSpec *params, HcfPubKey *publicKey);
33
34 HcfResult (*update)(HcfVerify *self, HcfBlob *data);
35
36 bool (*verify)(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData);
37
38 HcfResult (*recover)(HcfVerify *self, HcfBlob *signatureData, HcfBlob *rawSignatureData);
39
40 const char *(*getAlgoName)(HcfVerify *self);
41
42 HcfResult (*setVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t saltLen);
43
44 HcfResult (*getVerifySpecString)(HcfVerify *self, SignSpecItem item, char **returnString);
45
46 HcfResult (*getVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t *returnInt);
47
48 HcfResult (*setVerifySpecUint8Array)(HcfVerify *self, SignSpecItem item, HcfBlob blob);
49 };
50
51 struct OH_CryptoSign {
52 HcfObjectBase base;
53
54 HcfResult (*init)(HcfSign *self, HcfParamsSpec *params, HcfPriKey *privateKey);
55
56 HcfResult (*update)(HcfSign *self, HcfBlob *data);
57
58 HcfResult (*sign)(HcfSign *self, HcfBlob *data, HcfBlob *returnSignatureData);
59
60 const char *(*getAlgoName)(HcfSign *self);
61
62 HcfResult (*setSignSpecInt)(HcfSign *self, SignSpecItem item, int32_t saltLen);
63
64 HcfResult (*getSignSpecString)(HcfSign *self, SignSpecItem item, char **returnString);
65
66 HcfResult (*getSignSpecInt)(HcfSign *self, SignSpecItem item, int32_t *returnInt);
67
68 HcfResult (*setSignSpecUint8Array)(HcfSign *self, SignSpecItem item, HcfBlob blob);
69 };
70
OH_CryptoVerify_Create(const char * algoName,OH_CryptoVerify ** verify)71 OH_Crypto_ErrCode OH_CryptoVerify_Create(const char *algoName, OH_CryptoVerify **verify)
72 {
73 if (verify == NULL) {
74 return CRYPTO_INVALID_PARAMS;
75 }
76 HcfResult ret = HcfVerifyCreate(algoName, (HcfVerify **)verify);
77 return GetOhCryptoErrCode(ret);
78 }
79
OH_CryptoVerify_Init(OH_CryptoVerify * ctx,OH_CryptoPubKey * pubKey)80 OH_Crypto_ErrCode OH_CryptoVerify_Init(OH_CryptoVerify *ctx, OH_CryptoPubKey *pubKey)
81 {
82 if ((ctx == NULL) || (ctx->init == NULL) || (pubKey == NULL)) {
83 return CRYPTO_INVALID_PARAMS;
84 }
85 HcfResult ret = ctx->init((HcfVerify *)ctx, NULL, (HcfPubKey *)pubKey);
86 return GetOhCryptoErrCode(ret);
87 }
88
OH_CryptoVerify_Update(OH_CryptoVerify * ctx,Crypto_DataBlob * in)89 OH_Crypto_ErrCode OH_CryptoVerify_Update(OH_CryptoVerify *ctx, Crypto_DataBlob *in)
90 {
91 if ((ctx == NULL) || (ctx->update == NULL) || (in == NULL)) {
92 return CRYPTO_INVALID_PARAMS;
93 }
94 HcfResult ret = ctx->update((HcfVerify *)ctx, (HcfBlob *)in);
95 return GetOhCryptoErrCode(ret);
96 }
97
OH_CryptoVerify_Final(OH_CryptoVerify * ctx,Crypto_DataBlob * in,Crypto_DataBlob * signData)98 bool OH_CryptoVerify_Final(OH_CryptoVerify *ctx, Crypto_DataBlob *in, Crypto_DataBlob *signData)
99 {
100 if ((ctx == NULL) || (ctx->verify == NULL) || (signData == NULL)) {
101 return false;
102 }
103 bool ret = ctx->verify((HcfVerify *)ctx, (HcfBlob *)in, (HcfBlob *)signData);
104 if (ret != true) {
105 return false;
106 }
107
108 return ret;
109 }
110
OH_CryptoVerify_Recover(OH_CryptoVerify * ctx,Crypto_DataBlob * signData,Crypto_DataBlob * rawSignData)111 OH_Crypto_ErrCode OH_CryptoVerify_Recover(OH_CryptoVerify *ctx, Crypto_DataBlob *signData,
112 Crypto_DataBlob *rawSignData)
113 {
114 if ((ctx == NULL) || (ctx->recover == NULL) || (signData == NULL) || (rawSignData == NULL)) {
115 return CRYPTO_INVALID_PARAMS;
116 }
117 HcfResult ret = ctx->recover((HcfVerify *)ctx, (HcfBlob *)signData, (HcfBlob *)rawSignData);
118 return GetOhCryptoErrCode(ret);
119 }
120
OH_CryptoVerify_GetAlgoName(OH_CryptoVerify * ctx)121 const char *OH_CryptoVerify_GetAlgoName(OH_CryptoVerify *ctx)
122 {
123 if ((ctx == NULL) || (ctx->getAlgoName == NULL)) {
124 return NULL;
125 }
126 return ctx->getAlgoName((HcfVerify *)ctx);
127 }
128
OH_CryptoVerify_SetParam(OH_CryptoVerify * ctx,CryptoSignature_ParamType type,Crypto_DataBlob * value)129 OH_Crypto_ErrCode OH_CryptoVerify_SetParam(OH_CryptoVerify *ctx, CryptoSignature_ParamType type,
130 Crypto_DataBlob *value)
131 {
132 if ((ctx == NULL) || (value == NULL)) {
133 return CRYPTO_INVALID_PARAMS;
134 }
135 HcfResult ret = HCF_INVALID_PARAMS;
136 switch (type) {
137 case CRYPTO_PSS_SALT_LEN_INT:
138 case CRYPTO_PSS_TRAILER_FIELD_INT:
139 if ((value->data == NULL) || (value->len != sizeof(int32_t)) || (ctx->setVerifySpecInt == NULL)) {
140 ret = HCF_INVALID_PARAMS;
141 break;
142 }
143 ret = ctx->setVerifySpecInt((HcfVerify *)ctx, (SignSpecItem)type, *((int32_t *)value->data));
144 break;
145 case CRYPTO_SM2_USER_ID_DATABLOB:
146 case CRYPTO_PSS_MGF1_NAME_STR:
147 case CRYPTO_PSS_MGF_NAME_STR:
148 case CRYPTO_PSS_MD_NAME_STR:
149 if (ctx->setVerifySpecUint8Array == NULL) {
150 ret = HCF_INVALID_PARAMS;
151 break;
152 }
153 ret = ctx->setVerifySpecUint8Array((HcfVerify *)ctx, (SignSpecItem)type, *((HcfBlob *)value));
154 break;
155 default:
156 return CRYPTO_INVALID_PARAMS;
157 }
158 return GetOhCryptoErrCode(ret);
159 }
160
OH_CryptoVerify_GetParam(OH_CryptoVerify * ctx,CryptoSignature_ParamType type,Crypto_DataBlob * value)161 OH_Crypto_ErrCode OH_CryptoVerify_GetParam(OH_CryptoVerify *ctx, CryptoSignature_ParamType type,
162 Crypto_DataBlob *value)
163 {
164 if ((ctx == NULL) || (value == NULL)) {
165 return CRYPTO_INVALID_PARAMS;
166 }
167 int32_t *returnInt = NULL;
168 char *returnStr = NULL;
169 HcfResult ret = HCF_INVALID_PARAMS;
170 switch (type) {
171 case CRYPTO_PSS_SALT_LEN_INT:
172 case CRYPTO_PSS_TRAILER_FIELD_INT:
173 case CRYPTO_SM2_USER_ID_DATABLOB:
174 if (ctx->getVerifySpecInt == NULL) {
175 ret = HCF_INVALID_PARAMS;
176 break;
177 }
178 returnInt = (int32_t *)HcfMalloc(sizeof(int32_t), 0);
179 if (returnInt == NULL) {
180 return CRYPTO_MEMORY_ERROR;
181 }
182 ret = ctx->getVerifySpecInt((HcfVerify *)ctx, (SignSpecItem)type, returnInt);
183 if (ret != HCF_SUCCESS) {
184 HcfFree(returnInt);
185 returnInt = NULL;
186 break;
187 }
188 value->data = (uint8_t *)returnInt;
189 value->len = sizeof(int32_t);
190 break;
191 case CRYPTO_PSS_MD_NAME_STR:
192 case CRYPTO_PSS_MGF_NAME_STR:
193 case CRYPTO_PSS_MGF1_NAME_STR:
194 if (ctx->getVerifySpecString == NULL) {
195 ret = HCF_INVALID_PARAMS;
196 break;
197 }
198 ret = ctx->getVerifySpecString((HcfVerify *)ctx, (SignSpecItem)type, &returnStr);
199 if (ret != HCF_SUCCESS) {
200 break;
201 }
202 value->data = (uint8_t *)returnStr;
203 value->len = strlen(returnStr);
204 break;
205 default:
206 return CRYPTO_INVALID_PARAMS;
207 }
208 return GetOhCryptoErrCode(ret);
209 }
210
211
OH_CryptoVerify_Destroy(OH_CryptoVerify * ctx)212 void OH_CryptoVerify_Destroy(OH_CryptoVerify *ctx)
213 {
214 if (ctx == NULL || ctx->base.destroy == NULL) {
215 return;
216 }
217 ctx->base.destroy((HcfObjectBase *)ctx);
218 }
219
OH_CryptoSign_Create(const char * algoName,OH_CryptoSign ** sign)220 OH_Crypto_ErrCode OH_CryptoSign_Create(const char *algoName, OH_CryptoSign **sign)
221 {
222 if (sign == NULL) {
223 return CRYPTO_PARAMETER_CHECK_FAILED;
224 }
225 HcfResult ret = HcfSignCreate(algoName, (HcfSign **)sign);
226 return GetOhCryptoErrCodeNew(ret);
227 }
228
OH_CryptoSign_Init(OH_CryptoSign * ctx,OH_CryptoPrivKey * privKey)229 OH_Crypto_ErrCode OH_CryptoSign_Init(OH_CryptoSign *ctx, OH_CryptoPrivKey *privKey)
230 {
231 if ((ctx == NULL) || (ctx->init == NULL) || (privKey == NULL)) {
232 return CRYPTO_PARAMETER_CHECK_FAILED;
233 }
234 HcfResult ret = ctx->init((HcfSign *)ctx, NULL, (HcfPriKey *)privKey);
235 return GetOhCryptoErrCodeNew(ret);
236 }
237
OH_CryptoSign_Update(OH_CryptoSign * ctx,const Crypto_DataBlob * in)238 OH_Crypto_ErrCode OH_CryptoSign_Update(OH_CryptoSign *ctx, const Crypto_DataBlob *in)
239 {
240 if ((ctx == NULL) || (ctx->update == NULL) || (in == NULL)) {
241 return CRYPTO_PARAMETER_CHECK_FAILED;
242 }
243 HcfResult ret = ctx->update((HcfSign *)ctx, (HcfBlob *)in);
244 return GetOhCryptoErrCodeNew(ret);
245 }
246
OH_CryptoSign_Final(OH_CryptoSign * ctx,const Crypto_DataBlob * in,Crypto_DataBlob * out)247 OH_Crypto_ErrCode OH_CryptoSign_Final(OH_CryptoSign *ctx, const Crypto_DataBlob *in, Crypto_DataBlob *out)
248 {
249 if ((ctx == NULL) || (ctx->sign == NULL) || (out == NULL)) {
250 return CRYPTO_PARAMETER_CHECK_FAILED;
251 }
252 HcfResult ret = ctx->sign((HcfSign *)ctx, (HcfBlob *)in, (HcfBlob *)out);
253 return GetOhCryptoErrCodeNew(ret);
254 }
255
OH_CryptoSign_GetAlgoName(OH_CryptoSign * ctx)256 const char *OH_CryptoSign_GetAlgoName(OH_CryptoSign *ctx)
257 {
258 if ((ctx == NULL) || (ctx->getAlgoName == NULL)) {
259 return NULL;
260 }
261 return ctx->getAlgoName((HcfSign *)ctx);
262 }
263
OH_CryptoSign_SetParam(OH_CryptoSign * ctx,CryptoSignature_ParamType type,const Crypto_DataBlob * value)264 OH_Crypto_ErrCode OH_CryptoSign_SetParam(OH_CryptoSign *ctx, CryptoSignature_ParamType type,
265 const Crypto_DataBlob *value)
266 {
267 if ((ctx == NULL) || (value == NULL)) {
268 return CRYPTO_PARAMETER_CHECK_FAILED;
269 }
270 HcfResult ret = HCF_INVALID_PARAMS;
271 switch (type) {
272 case CRYPTO_PSS_SALT_LEN_INT:
273 case CRYPTO_PSS_TRAILER_FIELD_INT:
274 if ((value->data == NULL) || (value->len != sizeof(int32_t)) || (ctx->setSignSpecInt == NULL)) {
275 ret = HCF_INVALID_PARAMS;
276 break;
277 }
278 ret = ctx->setSignSpecInt((HcfSign *)ctx, (SignSpecItem)type, *((int32_t *)value->data));
279 break;
280 case CRYPTO_SM2_USER_ID_DATABLOB:
281 case CRYPTO_PSS_MGF1_NAME_STR:
282 case CRYPTO_PSS_MGF_NAME_STR:
283 case CRYPTO_PSS_MD_NAME_STR:
284 if (ctx->setSignSpecUint8Array == NULL) {
285 ret = HCF_INVALID_PARAMS;
286 break;
287 }
288 ret = ctx->setSignSpecUint8Array((HcfSign *)ctx, (SignSpecItem)type, *((HcfBlob *)value));
289 break;
290 default:
291 return CRYPTO_PARAMETER_CHECK_FAILED;
292 }
293 return GetOhCryptoErrCodeNew(ret);
294 }
295
OH_CryptoSign_GetParam(OH_CryptoSign * ctx,CryptoSignature_ParamType type,Crypto_DataBlob * value)296 OH_Crypto_ErrCode OH_CryptoSign_GetParam(OH_CryptoSign *ctx, CryptoSignature_ParamType type, Crypto_DataBlob *value)
297 {
298 if ((ctx == NULL) || (value == NULL)) {
299 return CRYPTO_PARAMETER_CHECK_FAILED;
300 }
301 int32_t *returnInt = NULL;
302 char *returnStr = NULL;
303 HcfResult ret = HCF_INVALID_PARAMS;
304 switch (type) {
305 case CRYPTO_PSS_SALT_LEN_INT:
306 case CRYPTO_PSS_TRAILER_FIELD_INT:
307 case CRYPTO_SM2_USER_ID_DATABLOB:
308 if (ctx->getSignSpecInt == NULL) {
309 ret = HCF_INVALID_PARAMS;
310 break;
311 }
312 returnInt = (int32_t *)HcfMalloc(sizeof(int32_t), 0);
313 if (returnInt == NULL) {
314 return CRYPTO_MEMORY_ERROR;
315 }
316 ret = ctx->getSignSpecInt((HcfSign *)ctx, (SignSpecItem)type, returnInt);
317 if (ret != HCF_SUCCESS) {
318 HcfFree(returnInt);
319 returnInt = NULL;
320 break;
321 }
322 value->data = (uint8_t *)returnInt;
323 value->len = sizeof(int32_t);
324 break;
325 case CRYPTO_PSS_MD_NAME_STR:
326 case CRYPTO_PSS_MGF_NAME_STR:
327 case CRYPTO_PSS_MGF1_NAME_STR:
328 if (ctx->getSignSpecString == NULL) {
329 ret = HCF_INVALID_PARAMS;
330 break;
331 }
332 ret = ctx->getSignSpecString((HcfSign *)ctx, (SignSpecItem)type, &returnStr);
333 if (ret != HCF_SUCCESS) {
334 break;
335 }
336 value->data = (uint8_t *)returnStr;
337 value->len = strlen(returnStr);
338 break;
339 default:
340 return CRYPTO_PARAMETER_CHECK_FAILED;
341 }
342 return GetOhCryptoErrCodeNew(ret);
343 }
344
OH_CryptoSign_Destroy(OH_CryptoSign * ctx)345 void OH_CryptoSign_Destroy(OH_CryptoSign *ctx)
346 {
347 if (ctx == NULL || ctx->base.destroy == NULL) {
348 return;
349 }
350 ctx->base.destroy((HcfObjectBase *)ctx);
351 }
352
353 struct OH_CryptoEccSignatureSpec {
354 HcfBigInteger r;
355 HcfBigInteger s;
356 };
357
358
OH_CryptoEccSignatureSpec_Create(Crypto_DataBlob * eccSignature,OH_CryptoEccSignatureSpec ** spec)359 OH_Crypto_ErrCode OH_CryptoEccSignatureSpec_Create(Crypto_DataBlob *eccSignature, OH_CryptoEccSignatureSpec **spec)
360 {
361 if (spec == NULL) {
362 return CRYPTO_PARAMETER_CHECK_FAILED;
363 }
364 HcfResult ret = HCF_INVALID_PARAMS;
365 if (eccSignature == NULL) {
366 *spec = (OH_CryptoEccSignatureSpec *)HcfMalloc(sizeof(OH_CryptoEccSignatureSpec), 0);
367 if (*spec == NULL) {
368 return CRYPTO_MEMORY_ERROR;
369 }
370 return GetOhCryptoErrCodeNew(HCF_SUCCESS);
371 }
372 ret = HcfGenEcSignatureSpecByData((HcfBlob *)eccSignature, (Sm2EcSignatureDataSpec **)spec);
373 return GetOhCryptoErrCodeNew(ret);
374 }
375
OH_CryptoEccSignatureSpec_GetRAndS(OH_CryptoEccSignatureSpec * spec,Crypto_DataBlob * r,Crypto_DataBlob * s)376 OH_Crypto_ErrCode OH_CryptoEccSignatureSpec_GetRAndS(OH_CryptoEccSignatureSpec *spec, Crypto_DataBlob *r,
377 Crypto_DataBlob *s)
378 {
379 if ((spec == NULL) || (r == NULL) || (s == NULL)) {
380 return CRYPTO_PARAMETER_CHECK_FAILED;
381 }
382 if ((spec->r.data == NULL) || (spec->s.data == NULL)) {
383 return CRYPTO_PARAMETER_CHECK_FAILED;
384 }
385
386 // Allocate memory for r->data
387 r->data = (uint8_t *)HcfMalloc(spec->r.len, 0);
388 if (r->data == NULL) {
389 return CRYPTO_MEMORY_ERROR;
390 }
391
392 // Copy data for r
393 if (memcpy_s(r->data, spec->r.len, spec->r.data, spec->r.len) != 0) {
394 HcfFree(r->data);
395 r->data = NULL; // Ensure pointer is null after freeing
396 return CRYPTO_MEMORY_ERROR;
397 }
398 r->len = (size_t)spec->r.len;
399
400 // Allocate memory for s->data
401 s->data = (uint8_t *)HcfMalloc(spec->s.len, 0);
402 if (s->data == NULL) {
403 HcfFree(r->data);
404 r->data = NULL; // Ensure pointer is null after freeing
405 return CRYPTO_MEMORY_ERROR;
406 }
407
408 // Copy data for s
409 if (memcpy_s(s->data, spec->s.len, spec->s.data, spec->s.len) != 0) {
410 HcfFree(r->data);
411 r->data = NULL; // Ensure pointer is null after freeing
412 HcfFree(s->data);
413 s->data = NULL; // Ensure pointer is null after freeing
414 return CRYPTO_MEMORY_ERROR;
415 }
416 s->len = (size_t)spec->s.len;
417
418 return GetOhCryptoErrCodeNew(HCF_SUCCESS);
419 }
420
OH_CryptoEccSignatureSpec_SetRAndS(OH_CryptoEccSignatureSpec * spec,Crypto_DataBlob * r,Crypto_DataBlob * s)421 OH_Crypto_ErrCode OH_CryptoEccSignatureSpec_SetRAndS(OH_CryptoEccSignatureSpec *spec, Crypto_DataBlob *r,
422 Crypto_DataBlob *s)
423 {
424 if ((spec == NULL) || (r == NULL) || (s == NULL)) {
425 return CRYPTO_PARAMETER_CHECK_FAILED;
426 }
427 if (r->data == NULL || s->data == NULL) {
428 return CRYPTO_PARAMETER_CHECK_FAILED;
429 }
430
431 // Allocate memory for r->data
432 spec->r.data = (unsigned char *)HcfMalloc(r->len, 0);
433 if (spec->r.data == NULL) {
434 return CRYPTO_MEMORY_ERROR;
435 }
436 if (memcpy_s(spec->r.data, r->len, r->data, r->len) != 0) {
437 HcfFree(spec->r.data);
438 spec->r.data = NULL;
439 return CRYPTO_MEMORY_ERROR;
440 }
441 spec->r.len = (uint32_t)r->len;
442
443 // Allocate memory for s->data
444 spec->s.data = (unsigned char *)HcfMalloc(s->len, 0);
445 if (spec->s.data == NULL) {
446 HcfFree(spec->r.data);
447 spec->r.data = NULL;
448 return CRYPTO_MEMORY_ERROR;
449 }
450 if (memcpy_s(spec->s.data, s->len, s->data, s->len) != 0) {
451 HcfFree(spec->r.data);
452 HcfFree(spec->s.data);
453 spec->r.data = NULL;
454 spec->s.data = NULL;
455 return CRYPTO_MEMORY_ERROR;
456 }
457 spec->s.len = (uint32_t)s->len;
458
459 return GetOhCryptoErrCodeNew(HCF_SUCCESS);
460 }
461
OH_CryptoEccSignatureSpec_Encode(OH_CryptoEccSignatureSpec * spec,Crypto_DataBlob * out)462 OH_Crypto_ErrCode OH_CryptoEccSignatureSpec_Encode(OH_CryptoEccSignatureSpec *spec, Crypto_DataBlob *out)
463 {
464 if ((spec == NULL) || (out == NULL)) {
465 return CRYPTO_PARAMETER_CHECK_FAILED;
466 }
467 HcfBlob *outBlob = (HcfBlob *)HcfMalloc(sizeof(HcfBlob), 0);
468 if (outBlob == NULL) {
469 return CRYPTO_MEMORY_ERROR;
470 }
471
472 HcfResult ret = HcfGenEcSignatureDataBySpec((Sm2EcSignatureDataSpec *)spec, outBlob);
473 if (ret != HCF_SUCCESS) {
474 HcfFree(outBlob);
475 outBlob = NULL;
476 return GetOhCryptoErrCode(ret);
477 }
478 out->data = outBlob->data;
479 out->len = outBlob->len;
480 HcfFree(outBlob);
481 outBlob = NULL;
482 return GetOhCryptoErrCodeNew(HCF_SUCCESS);
483 }
484
OH_CryptoEccSignatureSpec_Destroy(OH_CryptoEccSignatureSpec * spec)485 void OH_CryptoEccSignatureSpec_Destroy(OH_CryptoEccSignatureSpec *spec)
486 {
487 if (spec == NULL) {
488 return;
489 }
490 if (spec->r.data != NULL) {
491 HcfFree(spec->r.data);
492 spec->r.data = NULL;
493 }
494 if (spec->s.data != NULL) {
495 HcfFree(spec->s.data);
496 spec->s.data = NULL;
497 }
498 HcfFree(spec);
499 }
500