• 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 #include "hitls_build.h"
16 #ifdef HITLS_CRYPTO_SLH_DSA
17 
18 #include <stdint.h>
19 #include "securec.h"
20 #include "bsl_err_internal.h"
21 #include "bsl_sal.h"
22 #include "crypt_errno.h"
23 #include "slh_dsa_local.h"
24 #include "slh_dsa_xmss.h"
25 #include "slh_dsa_hypertree.h"
26 
HypertreeSign(const uint8_t * msg,uint32_t msgLen,uint64_t treeIdx,uint32_t leafIdx,const CryptSlhDsaCtx * ctx,uint8_t * sig,uint32_t * sigLen)27 int32_t HypertreeSign(const uint8_t *msg, uint32_t msgLen, uint64_t treeIdx, uint32_t leafIdx,
28                       const CryptSlhDsaCtx *ctx, uint8_t *sig, uint32_t *sigLen)
29 {
30     int32_t ret;
31     uint32_t n = ctx->para.n;
32     uint32_t hp = ctx->para.hp;
33     uint32_t d = ctx->para.d;
34     uint32_t len = 2 * n + 3;
35     uint32_t retLen = (len + hp) * n * d;
36     uint32_t leafIdxTmp = leafIdx;
37     uint64_t treeIdxTmp = treeIdx;
38 
39     if (*sigLen < retLen) {
40         return CRYPT_SLHDSA_ERR_SIG_LEN_NOT_ENOUGH;
41     }
42 
43     SlhDsaAdrs adrs = {0};
44 
45     uint32_t offset = 0;
46     uint32_t tmpLen = *sigLen;
47     uint8_t root[SLH_DSA_MAX_N] = {0};
48     // the msgLen is actually n.
49     (void)memcpy_s(root, sizeof(root), msg, msgLen);
50 
51     for (uint32_t j = 0; j < d; j++) {
52         if (j != 0) {
53             leafIdxTmp = (uint32_t)(treeIdxTmp & ((1UL << hp) - 1));
54             treeIdxTmp = treeIdxTmp >> hp;
55             ctx->adrsOps.setLayerAddr(&adrs, j);
56         }
57         ctx->adrsOps.setTreeAddr(&adrs, treeIdxTmp);
58         tmpLen = retLen - offset;
59         ret = XmssSign(root, n, leafIdxTmp, &adrs, ctx, sig + offset, &tmpLen);
60         if (ret != CRYPT_SUCCESS) {
61             return ret;
62         }
63         ret = XmssPkFromSig(leafIdxTmp, sig + offset, tmpLen, root, n, &adrs, ctx, root);
64         if (ret != CRYPT_SUCCESS) {
65             return ret;
66         }
67         offset += tmpLen;
68     }
69     *sigLen = retLen;
70     return CRYPT_SUCCESS;
71 }
72 
HypertreeVerify(const uint8_t * msg,uint32_t msgLen,const uint8_t * sig,uint32_t sigLen,uint64_t treeIdx,uint32_t leafIdx,const CryptSlhDsaCtx * ctx)73 int32_t HypertreeVerify(const uint8_t *msg, uint32_t msgLen, const uint8_t *sig, uint32_t sigLen, uint64_t treeIdx,
74                         uint32_t leafIdx, const CryptSlhDsaCtx *ctx)
75 {
76     int32_t ret;
77     uint32_t n = ctx->para.n;
78     uint32_t hp = ctx->para.hp;
79     uint32_t d = ctx->para.d;
80     uint32_t len = 2 * n + 3;
81     uint32_t retLen = (len + hp) * n * d;
82     uint32_t leafIdxTmp = leafIdx;
83     uint64_t treeIdxTmp = treeIdx;
84 
85     if (sigLen < retLen) {
86         return CRYPT_SLHDSA_ERR_SIG_LEN_NOT_ENOUGH;
87     }
88 
89     SlhDsaAdrs adrs = {0};
90     uint32_t offset = 0;
91 
92     uint8_t node[SLH_DSA_MAX_N] = {0};
93     // the msgLen is actually n.
94     (void)memcpy_s(node, sizeof(node), msg, msgLen);
95     for (uint32_t j = 0; j < d; j++) {
96         if (j != 0) {
97             leafIdxTmp = (uint32_t)(treeIdxTmp & ((1UL << hp) - 1));
98             treeIdxTmp = treeIdxTmp >> hp;
99             ctx->adrsOps.setLayerAddr(&adrs, j);
100         }
101         ctx->adrsOps.setTreeAddr(&adrs, treeIdxTmp);
102         ret = XmssPkFromSig(leafIdxTmp, sig + offset, sigLen - offset, node, n, &adrs, ctx, node);
103         if (ret != CRYPT_SUCCESS) {
104             return ret;
105         }
106         offset += (len + hp) * n;
107     }
108 
109     if (memcmp(node, ctx->prvKey.pub.root, n) != 0) {
110         return CRYPT_SLHDSA_ERR_HYPERTREE_VERIFY_FAIL;
111     }
112     return CRYPT_SUCCESS;
113 }
114 
115 #endif // HITLS_CRYPTO_SLH_DSA
116