1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #ifdef HITLS_CRYPTO_MLDSA
18 #include "securec.h"
19 #include "crypt_errno.h"
20 #include "crypt_util_rand.h"
21 #include "crypt_utils.h"
22 #include "bsl_errno.h"
23 #include "bsl_sal.h"
24 #include "bsl_obj_internal.h"
25 #include "bsl_err_internal.h"
26 #include "ml_dsa_local.h"
27 #include "eal_md_local.h"
28
29 // These data from NIST.FIPS.204 Table 1 and Table 2.
30 static const CRYPT_ML_DSA_Info MLDSA_PARAMETERTER_44 = {4, 4, 2, 39, 78, (1 << 17), ((MLDSA_Q - 1) / 88),
31 80, 128, 1312, 2560, 2420};
32
33 static const CRYPT_ML_DSA_Info MLDSA_PARAMETERTER_65 = {6, 5, 4, 49, 196, (1 << 19), ((MLDSA_Q - 1) / 32),
34 55, 192, 1952, 4032, 3309};
35
36 static const CRYPT_ML_DSA_Info MLDSA_PARAMETERTER_87 = {8, 7, 2, 60, 120, (1 << 19), ((MLDSA_Q - 1) / 32),
37 75, 256, 2592, 4896, 4627};
38
39 static const CRYPT_ML_DSA_Info *g_mldsaInfo[] = {&MLDSA_PARAMETERTER_44, &MLDSA_PARAMETERTER_65,
40 &MLDSA_PARAMETERTER_87};
41
CRYPT_ML_DSA_GetInfo(uint32_t k)42 const CRYPT_ML_DSA_Info *CRYPT_ML_DSA_GetInfo(uint32_t k)
43 {
44 if (k == CRYPT_MLDSA_TYPE_MLDSA_44) {
45 return g_mldsaInfo[0];
46 } else if (k == CRYPT_MLDSA_TYPE_MLDSA_65) {
47 return g_mldsaInfo[1];
48 } else if (k == CRYPT_MLDSA_TYPE_MLDSA_87) {
49 return g_mldsaInfo[2];
50 }
51 return NULL;
52 }
53
CRYPT_ML_DSA_NewCtx(void)54 CRYPT_ML_DSA_Ctx *CRYPT_ML_DSA_NewCtx(void)
55 {
56 CRYPT_ML_DSA_Ctx *keyCtx = BSL_SAL_Calloc(1, sizeof(CRYPT_ML_DSA_Ctx));
57 if (keyCtx == NULL) {
58 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
59 return NULL;
60 }
61 keyCtx->needEncodeCtx = true;
62 keyCtx->isMuMsg = false;
63 keyCtx->deterministicSignFlag = false;
64 keyCtx->needPreHash = false;
65 BSL_SAL_ReferencesInit(&(keyCtx->references));
66 return keyCtx;
67 }
68
CRYPT_ML_DSA_NewCtxEx(void * libCtx)69 CRYPT_ML_DSA_Ctx *CRYPT_ML_DSA_NewCtxEx(void *libCtx)
70 {
71 CRYPT_ML_DSA_Ctx *ctx = CRYPT_ML_DSA_NewCtx();
72 if (ctx == NULL) {
73 return NULL;
74 }
75 ctx->libCtx = libCtx;
76 return ctx;
77 }
78
CRYPT_ML_DSA_FreeCtx(CRYPT_ML_DSA_Ctx * ctx)79 void CRYPT_ML_DSA_FreeCtx(CRYPT_ML_DSA_Ctx *ctx)
80 {
81 if (ctx == NULL) {
82 return;
83 }
84 int ret = 0;
85 BSL_SAL_AtomicDownReferences(&(ctx->references), &ret);
86 if (ret > 0) {
87 return;
88 }
89 BSL_SAL_ClearFree(ctx->prvKey, ctx->prvLen);
90 BSL_SAL_FREE(ctx->pubKey);
91 BSL_SAL_FREE(ctx->ctxInfo);
92 BSL_SAL_ReferencesFree(&(ctx->references));
93 BSL_SAL_Free(ctx);
94 }
95
CRYPT_ML_DSA_DupCtx(CRYPT_ML_DSA_Ctx * ctx)96 CRYPT_ML_DSA_Ctx *CRYPT_ML_DSA_DupCtx(CRYPT_ML_DSA_Ctx *ctx)
97 {
98 if (ctx == NULL) {
99 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
100 return NULL;
101 }
102 CRYPT_ML_DSA_Ctx *newCtx = CRYPT_ML_DSA_NewCtx();
103 if (newCtx == NULL) {
104 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
105 return NULL;
106 }
107 newCtx->info = ctx->info;
108 GOTO_ERR_IF_SRC_NOT_NULL(newCtx->pubKey, ctx->pubKey, BSL_SAL_Dump(ctx->pubKey, ctx->pubLen),
109 CRYPT_MEM_ALLOC_FAIL);
110 GOTO_ERR_IF_SRC_NOT_NULL(newCtx->prvKey, ctx->prvKey, BSL_SAL_Dump(ctx->prvKey, ctx->prvLen),
111 CRYPT_MEM_ALLOC_FAIL);
112 newCtx->pubLen = ctx->pubLen;
113 newCtx->prvLen = ctx->prvLen;
114 newCtx->needEncodeCtx = ctx->needEncodeCtx;
115 newCtx->isMuMsg = ctx->isMuMsg;
116 newCtx->deterministicSignFlag = ctx->deterministicSignFlag;
117 newCtx->needPreHash = ctx->needPreHash;
118 return newCtx;
119 ERR:
120 CRYPT_ML_DSA_FreeCtx(newCtx);
121 return NULL;
122 }
123
MlDSASetAlgInfo(CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)124 static int32_t MlDSASetAlgInfo(CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
125 {
126 if (len != sizeof(int32_t) || val == NULL) {
127 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
128 return CRYPT_INVALID_ARG;
129 }
130 if (ctx->info != NULL) {
131 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_CTRL_INIT_REPEATED);
132 return CRYPT_MLDSA_CTRL_INIT_REPEATED;
133 }
134 ctx->info = CRYPT_ML_DSA_GetInfo(*(int32_t *)val);
135 if (ctx->info == NULL) {
136 BSL_ERR_PUSH_ERROR(CRYPT_NOT_SUPPORT);
137 return CRYPT_NOT_SUPPORT;
138 }
139 return CRYPT_SUCCESS;
140 }
141
MLDSAGetSignLen(const CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)142 static int32_t MLDSAGetSignLen(const CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
143 {
144 if (ctx == NULL || val == NULL) {
145 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
146 return CRYPT_NULL_INPUT;
147 }
148 if (len != sizeof(int32_t)) {
149 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
150 return CRYPT_INVALID_ARG;
151 }
152 if (ctx->info == NULL) {
153 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYINFO_NOT_SET);
154 return CRYPT_MLDSA_KEYINFO_NOT_SET;
155 }
156 *(int32_t *)val = ctx->info->signatureLen;
157 return CRYPT_SUCCESS;
158 }
159
MLDSAGetSecBits(const CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)160 static int32_t MLDSAGetSecBits(const CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
161 {
162 if (ctx == NULL || val == NULL) {
163 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
164 return CRYPT_NULL_INPUT;
165 }
166 if (ctx->info == NULL) {
167 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYINFO_NOT_SET);
168 return CRYPT_MLDSA_KEYINFO_NOT_SET;
169 }
170 if (len != sizeof(int32_t)) {
171 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
172 return CRYPT_INVALID_ARG;
173 }
174 *(int32_t *)val = ctx->info->secBits;
175 return CRYPT_SUCCESS;
176 }
177
MlDSASetEncodeFlag(CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)178 static int32_t MlDSASetEncodeFlag(CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
179 {
180 if (len != sizeof(int32_t) || val == NULL) {
181 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
182 return CRYPT_INVALID_ARG;
183 }
184 ctx->needEncodeCtx = (*(int32_t *)val != 0);
185 return CRYPT_SUCCESS;
186 }
187
MlDSASetMsgFlag(CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)188 static int32_t MlDSASetMsgFlag(CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
189 {
190 if (len != sizeof(int32_t) || val == NULL) {
191 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
192 return CRYPT_INVALID_ARG;
193 }
194 ctx->isMuMsg = (*(int32_t *)val != 0);
195 return CRYPT_SUCCESS;
196 }
197
MlDSASetDeterministicSignFlag(CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)198 static int32_t MlDSASetDeterministicSignFlag(CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
199 {
200 if (len != sizeof(int32_t) || val == NULL) {
201 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
202 return CRYPT_INVALID_ARG;
203 }
204 ctx->deterministicSignFlag = (*(int32_t *)val != 0);
205 return CRYPT_SUCCESS;
206 }
207
MlDSASetPreHashFlag(CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)208 static int32_t MlDSASetPreHashFlag(CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
209 {
210 if (len != sizeof(int32_t) || val == NULL) {
211 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
212 return CRYPT_INVALID_ARG;
213 }
214 ctx->needPreHash = (*(int32_t *)val != 0);
215 return CRYPT_SUCCESS;
216 }
217
MLDSASetctxInfo(CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)218 int32_t MLDSASetctxInfo(CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
219 {
220 if (len > MLDSA_MAX_CTX_BYTES) {
221 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYLEN_ERROR);
222 return CRYPT_MLDSA_KEYLEN_ERROR;
223 }
224 if (ctx->ctxInfo != NULL) {
225 BSL_SAL_FREE(ctx->ctxInfo);
226 ctx->ctxLen = 0;
227 }
228 if (val == NULL && len == 0) {
229 ctx->needEncodeCtx = true;
230 return CRYPT_SUCCESS;
231 }
232
233 ctx->ctxInfo = BSL_SAL_Dump((uint8_t *)val, len);
234 if (ctx->ctxInfo == NULL) {
235 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
236 return CRYPT_MEM_ALLOC_FAIL;
237 }
238 ctx->ctxLen = len;
239 ctx->needEncodeCtx = true;
240 return CRYPT_SUCCESS;
241 }
242
MLDSAGetPubKeyLen(const CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)243 static int32_t MLDSAGetPubKeyLen(const CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
244 {
245 RETURN_RET_IF(val == NULL, CRYPT_NULL_INPUT);
246 RETURN_RET_IF((ctx->info == NULL), CRYPT_MLDSA_KEYINFO_NOT_SET);
247 RETURN_RET_IF((len != sizeof(uint32_t)), CRYPT_INVALID_ARG);
248 *(uint32_t *)val = ctx->info->publicKeyLen;
249 return CRYPT_SUCCESS;
250 }
251
MLDSAGetPrvKeyLen(const CRYPT_ML_DSA_Ctx * ctx,void * val,uint32_t len)252 static int32_t MLDSAGetPrvKeyLen(const CRYPT_ML_DSA_Ctx *ctx, void *val, uint32_t len)
253 {
254 RETURN_RET_IF(val == NULL, CRYPT_NULL_INPUT);
255 RETURN_RET_IF((ctx->info == NULL), CRYPT_MLDSA_KEYINFO_NOT_SET);
256 RETURN_RET_IF((len != sizeof(uint32_t)), CRYPT_INVALID_ARG);
257 *(uint32_t *)val = ctx->info->privateKeyLen;
258 return CRYPT_SUCCESS;
259 }
260
CRYPT_ML_DSA_Ctrl(CRYPT_ML_DSA_Ctx * ctx,CRYPT_PkeyCtrl opt,void * val,uint32_t len)261 int32_t CRYPT_ML_DSA_Ctrl(CRYPT_ML_DSA_Ctx *ctx, CRYPT_PkeyCtrl opt, void *val, uint32_t len)
262 {
263 if (ctx == NULL) {
264 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
265 return CRYPT_NULL_INPUT;
266 }
267 switch ((uint32_t)opt) {
268 case CRYPT_CTRL_SET_PARA_BY_ID:
269 return MlDSASetAlgInfo(ctx, val, len);
270 case CRYPT_CTRL_GET_SIGNLEN:
271 return MLDSAGetSignLen(ctx, val, len);
272 case CRYPT_CTRL_GET_SECBITS:
273 return MLDSAGetSecBits(ctx, val, len);
274 case CRYPT_CTRL_SET_CTX_INFO:
275 return MLDSASetctxInfo(ctx, val, len);
276 case CRYPT_CTRL_SET_MLDSA_ENCODE_FLAG:
277 return MlDSASetEncodeFlag(ctx, val, len);
278 case CRYPT_CTRL_SET_MLDSA_MUMSG_FLAG:
279 return MlDSASetMsgFlag(ctx, val, len);
280 case CRYPT_CTRL_SET_DETERMINISTIC_FLAG:
281 return MlDSASetDeterministicSignFlag(ctx, val, len);
282 case CRYPT_CTRL_SET_PREHASH_FLAG:
283 return MlDSASetPreHashFlag(ctx, val, len);
284 case CRYPT_CTRL_GET_PUBKEY_LEN:
285 return MLDSAGetPubKeyLen(ctx, val, len);
286 case CRYPT_CTRL_GET_PRVKEY_LEN:
287 return MLDSAGetPrvKeyLen(ctx, val, len);
288 default:
289 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_CTRL_NOT_SUPPORT);
290 return CRYPT_MLDSA_CTRL_NOT_SUPPORT;
291 }
292 }
293
MLDSACreateKeyBuf(CRYPT_ML_DSA_Ctx * ctx)294 static int32_t MLDSACreateKeyBuf(CRYPT_ML_DSA_Ctx *ctx)
295 {
296 if (ctx->pubKey == NULL) {
297 ctx->pubKey = BSL_SAL_Malloc(ctx->info->publicKeyLen);
298 if (ctx->pubKey == NULL) {
299 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
300 return CRYPT_MEM_ALLOC_FAIL;
301 }
302 ctx->pubLen = ctx->info->publicKeyLen;
303 }
304 if (ctx->prvKey == NULL) {
305 ctx->prvKey = BSL_SAL_Malloc(ctx->info->privateKeyLen);
306 if (ctx->prvKey == NULL) {
307 BSL_SAL_FREE(ctx->pubKey);
308 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
309 return CRYPT_MEM_ALLOC_FAIL;
310 }
311 ctx->prvLen = ctx->info->privateKeyLen;
312 }
313 return CRYPT_SUCCESS;
314 }
315
CRYPT_ML_DSA_GenKey(CRYPT_ML_DSA_Ctx * ctx)316 int32_t CRYPT_ML_DSA_GenKey(CRYPT_ML_DSA_Ctx *ctx)
317 {
318 if (ctx == NULL) {
319 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
320 return CRYPT_NULL_INPUT;
321 }
322 if (ctx->info == NULL) {
323 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYINFO_NOT_SET);
324 return CRYPT_MLDSA_KEYINFO_NOT_SET;
325 }
326 if (MLDSACreateKeyBuf(ctx) != CRYPT_SUCCESS) {
327 return CRYPT_MEM_ALLOC_FAIL;
328 }
329 uint8_t seed[MLDSA_SEED_BYTES_LEN];
330 int32_t ret = CRYPT_RandEx(ctx->libCtx, seed, MLDSA_SEED_BYTES_LEN);
331 if (ret != CRYPT_SUCCESS) {
332 BSL_ERR_PUSH_ERROR(ret);
333 return ret;
334 }
335 ret = MLDSA_KeyGenInternal(ctx, seed);
336 BSL_SAL_CleanseData(seed, MLDSA_SEED_BYTES_LEN);
337 return ret;
338 }
339
MLDSA_SignArgCheck(CRYPT_ML_DSA_Ctx * ctx,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t * signLen)340 static int32_t MLDSA_SignArgCheck(CRYPT_ML_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
341 uint8_t *sign, uint32_t *signLen)
342 {
343 if (ctx == NULL || data == NULL || dataLen == 0 || sign == NULL || signLen == NULL) {
344 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
345 return CRYPT_NULL_INPUT;
346 }
347 if (ctx->info == NULL) {
348 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYINFO_NOT_SET);
349 return CRYPT_MLDSA_KEYINFO_NOT_SET;
350 }
351 if (ctx->prvKey == NULL) {
352 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEY_NOT_SET);
353 return CRYPT_MLDSA_KEY_NOT_SET;
354 }
355 if (*signLen < ctx->info->signatureLen) {
356 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_LEN_NOT_ENOUGH);
357 return CRYPT_MLDSA_LEN_NOT_ENOUGH;
358 }
359 return CRYPT_SUCCESS;
360 }
361
MLDSA_VerifyArgCheck(CRYPT_ML_DSA_Ctx * ctx,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t signLen)362 static int32_t MLDSA_VerifyArgCheck(CRYPT_ML_DSA_Ctx *ctx, const uint8_t *data, uint32_t dataLen,
363 uint8_t *sign, uint32_t signLen)
364 {
365 if (ctx == NULL || data == NULL || dataLen == 0 || sign == NULL) {
366 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
367 return CRYPT_NULL_INPUT;
368 }
369 if (ctx->info == NULL) {
370 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYINFO_NOT_SET);
371 return CRYPT_MLDSA_KEYINFO_NOT_SET;
372 }
373
374 if (ctx->pubKey == NULL) {
375 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEY_NOT_SET);
376 return CRYPT_MLDSA_KEY_NOT_SET;
377 }
378 if (signLen != ctx->info->signatureLen) {
379 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_LEN_NOT_ENOUGH);
380 return CRYPT_MLDSA_LEN_NOT_ENOUGH;
381 }
382 return CRYPT_SUCCESS;
383 }
384
CRYPT_ML_DSA_SetPrvKey(CRYPT_ML_DSA_Ctx * ctx,const BSL_Param * param)385 int32_t CRYPT_ML_DSA_SetPrvKey(CRYPT_ML_DSA_Ctx *ctx, const BSL_Param *param)
386 {
387 if (ctx == NULL || param == NULL) {
388 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
389 return CRYPT_NULL_INPUT;
390 }
391 if (ctx->info == NULL) {
392 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYINFO_NOT_SET);
393 return CRYPT_MLDSA_KEYINFO_NOT_SET;
394 }
395 const BSL_Param *prv = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_ML_DSA_PRVKEY);
396 if (prv == NULL || prv->value == NULL) {
397 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
398 return CRYPT_NULL_INPUT;
399 }
400
401 if (prv->valueLen != ctx->info->privateKeyLen) {
402 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYLEN_ERROR);
403 return CRYPT_MLDSA_KEYLEN_ERROR;
404 }
405 if (ctx->prvKey != NULL) {
406 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_SET_KEY_FAILED);
407 return CRYPT_MLDSA_SET_KEY_FAILED;
408 }
409 ctx->prvKey = BSL_SAL_Malloc(ctx->info->privateKeyLen);
410 if (ctx->prvKey == NULL) {
411 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
412 return CRYPT_MEM_ALLOC_FAIL;
413 }
414 ctx->prvLen = ctx->info->privateKeyLen;
415 (void)memcpy_s(ctx->prvKey, ctx->prvLen, prv->value, prv->valueLen);
416 return CRYPT_SUCCESS;
417 }
418
CRYPT_ML_DSA_SetPubKey(CRYPT_ML_DSA_Ctx * ctx,const BSL_Param * param)419 int32_t CRYPT_ML_DSA_SetPubKey(CRYPT_ML_DSA_Ctx *ctx, const BSL_Param *param)
420 {
421 if (ctx == NULL || param == NULL) {
422 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
423 return CRYPT_NULL_INPUT;
424 }
425 if (ctx->info == NULL) {
426 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYINFO_NOT_SET);
427 return CRYPT_MLDSA_KEYINFO_NOT_SET;
428 }
429 const BSL_Param *pub = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_ML_DSA_PUBKEY);
430 if (pub == NULL || pub->value == NULL) {
431 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
432 return CRYPT_NULL_INPUT;
433 }
434
435 if (pub->valueLen != ctx->info->publicKeyLen) {
436 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEYLEN_ERROR);
437 return CRYPT_MLDSA_KEYLEN_ERROR;
438 }
439 if (ctx->pubKey != NULL) {
440 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_SET_KEY_FAILED);
441 return CRYPT_MLDSA_SET_KEY_FAILED;
442 }
443
444 ctx->pubKey = BSL_SAL_Malloc(ctx->info->publicKeyLen);
445 if (ctx->pubKey == NULL) {
446 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
447 return CRYPT_MEM_ALLOC_FAIL;
448 }
449 ctx->pubLen = ctx->info->publicKeyLen;
450 (void)memcpy_s(ctx->pubKey, ctx->pubLen, pub->value, pub->valueLen);
451 return CRYPT_SUCCESS;
452 }
453
CRYPT_ML_DSA_GetPrvKey(const CRYPT_ML_DSA_Ctx * ctx,BSL_Param * param)454 int32_t CRYPT_ML_DSA_GetPrvKey(const CRYPT_ML_DSA_Ctx *ctx, BSL_Param *param)
455 {
456 if (ctx == NULL || param == NULL) {
457 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
458 return CRYPT_NULL_INPUT;
459 }
460 if (ctx->prvKey == NULL) {
461 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEY_NOT_SET);
462 return CRYPT_MLDSA_KEY_NOT_SET;
463 }
464 BSL_Param *prv = BSL_PARAM_FindParam(param, CRYPT_PARAM_ML_DSA_PRVKEY);
465 if (prv == NULL || prv->value == NULL) {
466 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
467 return CRYPT_NULL_INPUT;
468 }
469
470 if (memcpy_s(prv->value, prv->valueLen, ctx->prvKey, ctx->prvLen) != EOK) {
471 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_LEN_NOT_ENOUGH);
472 return CRYPT_MLDSA_LEN_NOT_ENOUGH;
473 }
474 prv->useLen = ctx->prvLen;
475 return CRYPT_SUCCESS;
476 }
477
CRYPT_ML_DSA_GetPubKey(const CRYPT_ML_DSA_Ctx * ctx,BSL_Param * param)478 int32_t CRYPT_ML_DSA_GetPubKey(const CRYPT_ML_DSA_Ctx *ctx, BSL_Param *param)
479 {
480 if (ctx == NULL || param == NULL) {
481 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
482 return CRYPT_NULL_INPUT;
483 }
484 if (ctx->pubKey == NULL) {
485 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEY_NOT_SET);
486 return CRYPT_MLDSA_KEY_NOT_SET;
487 }
488 BSL_Param *pub = BSL_PARAM_FindParam(param, CRYPT_PARAM_ML_DSA_PUBKEY);
489 if (pub == NULL || pub->value == NULL) {
490 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
491 return CRYPT_NULL_INPUT;
492 }
493
494 if (memcpy_s(pub->value, pub->valueLen, ctx->pubKey, ctx->pubLen) != EOK) {
495 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_LEN_NOT_ENOUGH);
496 return CRYPT_MLDSA_LEN_NOT_ENOUGH;
497 }
498 pub->useLen = ctx->pubLen;
499 return CRYPT_SUCCESS;
500 }
501
MLDSACmpKey(uint8_t * a,uint32_t aLen,uint8_t * b,uint32_t bLen)502 static int32_t MLDSACmpKey(uint8_t *a, uint32_t aLen, uint8_t *b, uint32_t bLen)
503 {
504 if (aLen != bLen) {
505 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEY_NOT_EQUAL);
506 return CRYPT_MLDSA_KEY_NOT_EQUAL;
507 }
508 if (a != NULL && b != NULL) {
509 if (memcmp(a, b, aLen) != 0) {
510 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEY_NOT_EQUAL);
511 return CRYPT_MLDSA_KEY_NOT_EQUAL;
512 }
513 }
514 if (a == NULL && b == NULL) {
515 return CRYPT_SUCCESS;
516 }
517 if (a == NULL || b == NULL) {
518 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEY_NOT_EQUAL);
519 return CRYPT_MLDSA_KEY_NOT_EQUAL;
520 }
521 return CRYPT_SUCCESS;
522 }
523
CRYPT_ML_DSA_Cmp(const CRYPT_ML_DSA_Ctx * a,const CRYPT_ML_DSA_Ctx * b)524 int32_t CRYPT_ML_DSA_Cmp(const CRYPT_ML_DSA_Ctx *a, const CRYPT_ML_DSA_Ctx *b)
525 {
526 if (a == NULL || b == NULL) {
527 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
528 return CRYPT_NULL_INPUT;
529 }
530 if (a->info != b->info) { // The value of info must be one of the g_mldsaInfo arrays.
531 BSL_ERR_PUSH_ERROR(CRYPT_MLDSA_KEY_NOT_EQUAL);
532 return CRYPT_MLDSA_KEY_NOT_EQUAL;
533 }
534
535 if (MLDSACmpKey(a->prvKey, a->prvLen, b->prvKey, b->prvLen) != CRYPT_SUCCESS) {
536 return CRYPT_MLDSA_KEY_NOT_EQUAL;
537 }
538 if (MLDSACmpKey(a->pubKey, a->pubLen, b->pubKey, b->pubLen) != CRYPT_SUCCESS) {
539 return CRYPT_MLDSA_KEY_NOT_EQUAL;
540 }
541 return CRYPT_SUCCESS;
542 }
543
MLDSAGetMdSize(const EAL_MdMethod * hashMethod,int32_t hashId)544 static uint32_t MLDSAGetMdSize(const EAL_MdMethod *hashMethod, int32_t hashId)
545 {
546 if (hashId == CRYPT_MD_SHAKE128) {
547 return 32; // To use SHAKE128, generate a 32-byte digest.
548 } else if (hashId == CRYPT_MD_SHAKE256) {
549 return 64; // To use SHAKE256, generate a 64-byte digest.
550 }
551 return hashMethod->mdSize;
552 }
553
MLDSAPreHashEncode(CRYPT_ML_DSA_Ctx * ctx,int32_t hashId,const uint8_t * data,uint32_t dataLen,CRYPT_Data * msg)554 static int32_t MLDSAPreHashEncode(CRYPT_ML_DSA_Ctx *ctx, int32_t hashId, const uint8_t *data, uint32_t dataLen,
555 CRYPT_Data *msg)
556 {
557 int32_t ret = CRYPT_SUCCESS;
558 // The maximum value of ctx->ctxLen is 255.
559 if (dataLen > (UINT32_MAX - MLDSA_SIGN_PREFIX_BYTES - ctx->ctxLen)) {
560 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
561 return CRYPT_INVALID_ARG;
562 }
563 BslOidString *oidInfo = BSL_OBJ_GetOID(hashId);
564 RETURN_RET_IF(oidInfo == NULL, CRYPT_ERR_ALGID);
565
566 const EAL_MdMethod *hashMethod = EAL_MdFindMethod(hashId);
567 RETURN_RET_IF(hashMethod == NULL, CRYPT_EAL_ALG_NOT_SUPPORT);
568 uint32_t mdSize = MLDSAGetMdSize(hashMethod, hashId);
569 msg->len = MLDSA_SIGN_PREFIX_BYTES + ctx->ctxLen + MLDSA_SIGN_PREFIX_BYTES + oidInfo->octetLen + mdSize;
570 msg->data = BSL_SAL_Malloc(msg->len);
571 RETURN_RET_IF(msg->data == NULL, CRYPT_MEM_ALLOC_FAIL);
572
573 uint8_t *ptr = msg->data;
574 uint32_t tmpLen = msg->len;
575 ptr[0] = 1;
576 ptr[1] = (uint8_t)ctx->ctxLen;
577 ptr += MLDSA_SIGN_PREFIX_BYTES;
578 tmpLen -= MLDSA_SIGN_PREFIX_BYTES;
579
580 if (ctx->ctxInfo != NULL && ctx->ctxLen > 0) {
581 (void)memcpy_s(ptr, msg->len - MLDSA_SIGN_PREFIX_BYTES, ctx->ctxInfo, ctx->ctxLen);
582 ptr += ctx->ctxLen;
583 tmpLen -= ctx->ctxLen;
584 }
585 ptr[0] = 0x06; // tag of objectId
586 ptr[1] = (uint8_t)oidInfo->octetLen;
587 ptr += MLDSA_SIGN_PREFIX_BYTES;
588 tmpLen -= MLDSA_SIGN_PREFIX_BYTES;
589 (void)memcpy_s(ptr, tmpLen, oidInfo->octs, oidInfo->octetLen);
590 ptr += oidInfo->octetLen;
591 tmpLen -= oidInfo->octetLen;
592 void *mdCtx = hashMethod->newCtx();
593 if (mdCtx == NULL) {
594 BSL_SAL_Free(msg->data);
595 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
596 return CRYPT_MEM_ALLOC_FAIL;
597 }
598 GOTO_ERR_IF(hashMethod->init(mdCtx, NULL), ret);
599 GOTO_ERR_IF(hashMethod->update(mdCtx, data, dataLen), ret);
600 GOTO_ERR_IF(hashMethod->final(mdCtx, ptr, &tmpLen), ret);
601 ERR:
602 hashMethod->freeCtx(mdCtx);
603 if (ret != CRYPT_SUCCESS) {
604 BSL_SAL_FREE(msg->data);
605 }
606 return ret;
607 }
608
MLDSAEncodeInputData(CRYPT_ML_DSA_Ctx * ctx,int32_t hashId,const uint8_t * data,uint32_t dataLen,CRYPT_Data * msg)609 static int32_t MLDSAEncodeInputData(CRYPT_ML_DSA_Ctx *ctx, int32_t hashId, const uint8_t *data, uint32_t dataLen,
610 CRYPT_Data *msg)
611 {
612 int32_t ret;
613 if (ctx->isMuMsg || ctx->needEncodeCtx == false) {
614 msg->data = BSL_SAL_Dump(data, dataLen);
615 RETURN_RET_IF(msg->data == NULL, CRYPT_MEM_ALLOC_FAIL);
616 msg->len = dataLen;
617 return CRYPT_SUCCESS;
618 }
619
620 // The maximum value of ctx->ctxLen is 255.
621 if (dataLen > (UINT32_MAX - MLDSA_SIGN_PREFIX_BYTES - ctx->ctxLen)) {
622 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
623 return CRYPT_INVALID_ARG;
624 }
625 if (ctx->needPreHash) {
626 RETURN_RET_IF_ERR(MLDSAPreHashEncode(ctx, hashId, data, dataLen, msg), ret);
627 return CRYPT_SUCCESS;
628 }
629
630 msg->len = dataLen + ctx->ctxLen + MLDSA_SIGN_PREFIX_BYTES;
631 msg->data = BSL_SAL_Malloc(msg->len);
632 if (msg->data == NULL) {
633 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
634 return CRYPT_MEM_ALLOC_FAIL;
635 }
636
637 msg->data[0] = 0;
638 msg->data[1] = (uint8_t)ctx->ctxLen;
639 if (ctx->ctxInfo != NULL && ctx->ctxLen > 0) {
640 (void)memcpy_s(msg->data + MLDSA_SIGN_PREFIX_BYTES, msg->len - MLDSA_SIGN_PREFIX_BYTES,
641 ctx->ctxInfo, ctx->ctxLen);
642 }
643 (void)memcpy_s(msg->data + MLDSA_SIGN_PREFIX_BYTES + ctx->ctxLen,
644 msg->len - MLDSA_SIGN_PREFIX_BYTES - ctx->ctxLen, data, dataLen);
645 return CRYPT_SUCCESS;
646 }
647
648 // Algorithm 4 HashML-DSA.Sign(sk, M, ctx, PH)
CRYPT_ML_DSA_Sign(CRYPT_ML_DSA_Ctx * ctx,int32_t hashId,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t * signLen)649 int32_t CRYPT_ML_DSA_Sign(CRYPT_ML_DSA_Ctx *ctx, int32_t hashId, const uint8_t *data, uint32_t dataLen,
650 uint8_t *sign, uint32_t *signLen)
651 {
652 int32_t ret = MLDSA_SignArgCheck(ctx, data, dataLen, sign, signLen);
653 if (ret != CRYPT_SUCCESS) {
654 BSL_ERR_PUSH_ERROR(ret);
655 return ret;
656 }
657 uint8_t signSeed[MLDSA_SEED_BYTES_LEN] = { 0 };
658 if (ctx->deterministicSignFlag == false) {
659 ret = CRYPT_RandEx(ctx->libCtx, signSeed, MLDSA_SEED_BYTES_LEN);
660 RETURN_RET_IF(ret != CRYPT_SUCCESS, ret);
661 }
662 CRYPT_Data msg = { 0 };
663 RETURN_RET_IF_ERR(MLDSAEncodeInputData(ctx, hashId, data, dataLen, &msg), ret);
664 ret = MLDSA_SignInternal(ctx, &msg, sign, signLen, signSeed);
665 BSL_SAL_Free(msg.data);
666 BSL_SAL_CleanseData(signSeed, sizeof(signSeed));
667 return ret;
668 }
669
670 // Algorithm 5 HashML-DSA.Verify(pk, M, , ctx, PH)
CRYPT_ML_DSA_Verify(CRYPT_ML_DSA_Ctx * ctx,int32_t hashId,const uint8_t * data,uint32_t dataLen,uint8_t * sign,uint32_t signLen)671 int32_t CRYPT_ML_DSA_Verify(CRYPT_ML_DSA_Ctx *ctx, int32_t hashId, const uint8_t *data, uint32_t dataLen,
672 uint8_t *sign, uint32_t signLen)
673 {
674 int32_t ret = MLDSA_VerifyArgCheck(ctx, data, dataLen, sign, signLen);
675 if (ret != CRYPT_SUCCESS) {
676 BSL_ERR_PUSH_ERROR(ret);
677 return ret;
678 }
679 CRYPT_Data msg = { 0 };
680 RETURN_RET_IF_ERR(MLDSAEncodeInputData(ctx, hashId, data, dataLen, &msg), ret);
681 ret = MLDSA_VerifyInternal(ctx, &msg, sign, signLen);
682 BSL_SAL_Free(msg.data);
683 return ret;
684 }
685
686 #endif