• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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