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_SLH_DSA
18
19 #include "securec.h"
20 #include "bsl_err_internal.h"
21 #include "crypt_errno.h"
22 #include "crypt_types.h"
23 #include "crypt_eal_md.h"
24 #include "crypt_eal_mac.h"
25 #include "eal_md_local.h"
26 #include "slh_dsa_local.h"
27 #include "slh_dsa_hash.h"
28
29 #define MAX_MDSIZE 64
30 #define SHA256_PADDING_LEN 64
31 #define SHA512_PADDING_LEN 128
32
CalcMultiMsgHash(CRYPT_MD_AlgId mdId,const CRYPT_ConstData * hashData,uint32_t hashDataLen,uint8_t * out,uint32_t outLen)33 static int32_t CalcMultiMsgHash(CRYPT_MD_AlgId mdId, const CRYPT_ConstData *hashData, uint32_t hashDataLen,
34 uint8_t *out, uint32_t outLen)
35 {
36 uint8_t tmp[MAX_MDSIZE] = {0};
37 uint32_t tmpLen = sizeof(tmp);
38 int32_t ret = CRYPT_CalcHash(EAL_MdFindMethod(mdId), hashData, hashDataLen, tmp, &tmpLen);
39 if (ret != CRYPT_SUCCESS) {
40 BSL_ERR_PUSH_ERROR(ret);
41 return ret;
42 }
43 (void)memcpy_s(out, outLen, tmp, outLen);
44 return CRYPT_SUCCESS;
45 }
46
PrfmsgShake256(const CryptSlhDsaCtx * ctx,const uint8_t * rand,const uint8_t * msg,uint32_t msgLen,uint8_t * out)47 static int32_t PrfmsgShake256(const CryptSlhDsaCtx *ctx, const uint8_t *rand, const uint8_t *msg, uint32_t msgLen,
48 uint8_t *out)
49 {
50 uint32_t n = ctx->para.n;
51 const CRYPT_ConstData hashData[] = {{ctx->prvKey.prf, n}, {rand, n}, {msg, msgLen}};
52 return CalcMultiMsgHash(CRYPT_MD_SHAKE256, hashData, sizeof(hashData) / sizeof(hashData[0]), out, n);
53 }
54
HmsgShake256(const CryptSlhDsaCtx * ctx,const uint8_t * r,const uint8_t * msg,uint32_t msgLen,uint8_t * out)55 static int32_t HmsgShake256(const CryptSlhDsaCtx *ctx, const uint8_t *r, const uint8_t *msg, uint32_t msgLen,
56 uint8_t *out)
57 {
58 uint32_t n = ctx->para.n;
59 uint32_t m = ctx->para.m;
60 const CRYPT_ConstData hashData[] = {{r, n}, {ctx->prvKey.pub.seed, n}, {ctx->prvKey.pub.root, n}, {msg, msgLen}};
61 return CalcMultiMsgHash(CRYPT_MD_SHAKE256, hashData, sizeof(hashData) / sizeof(hashData[0]), out, m);
62 }
63
PrfShake256(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,uint8_t * out)64 static int32_t PrfShake256(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, uint8_t *out)
65 {
66 uint32_t n = ctx->para.n;
67 const CRYPT_ConstData hashData[] = {
68 {ctx->prvKey.pub.seed, n}, {adrs->bytes, ctx->adrsOps.getAdrsLen()}, {ctx->prvKey.seed, n}};
69 return CalcMultiMsgHash(CRYPT_MD_SHAKE256, hashData, sizeof(hashData) / sizeof(hashData[0]), out, n);
70 }
71
HShake256(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,const uint8_t * msg,uint32_t msgLen,uint8_t * out)72 static int32_t HShake256(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, const uint8_t *msg, uint32_t msgLen,
73 uint8_t *out)
74 {
75 uint32_t n = ctx->para.n;
76 const CRYPT_ConstData hashData[] = {
77 {ctx->prvKey.pub.seed, n}, {adrs->bytes, ctx->adrsOps.getAdrsLen()}, {msg, msgLen}};
78 return CalcMultiMsgHash(CRYPT_MD_SHAKE256, hashData, sizeof(hashData) / sizeof(hashData[0]), out, n);
79 }
80
TlShake256(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,const uint8_t * msg,uint32_t msgLen,uint8_t * out)81 static int32_t TlShake256(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, const uint8_t *msg, uint32_t msgLen,
82 uint8_t *out)
83 {
84 return HShake256(ctx, adrs, msg, msgLen, out);
85 }
86
FShake256(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,const uint8_t * msg,uint32_t msgLen,uint8_t * out)87 static int32_t FShake256(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, const uint8_t *msg, uint32_t msgLen,
88 uint8_t *out)
89 {
90 return HShake256(ctx, adrs, msg, msgLen, out);
91 }
92
Prfmsg(const CryptSlhDsaCtx * ctx,const uint8_t * rand,const uint8_t * msg,uint32_t msgLen,uint8_t * out,CRYPT_MAC_AlgId macId)93 static int32_t Prfmsg(const CryptSlhDsaCtx *ctx, const uint8_t *rand, const uint8_t *msg, uint32_t msgLen, uint8_t *out,
94 CRYPT_MAC_AlgId macId)
95 {
96 int32_t ret;
97 uint32_t n = ctx->para.n;
98 uint8_t tmp[MAX_MDSIZE] = {0};
99 uint32_t tmpLen = sizeof(tmp);
100 CRYPT_EAL_MacCtx *mdCtx = CRYPT_EAL_MacNewCtx(macId);
101 if (mdCtx == NULL) {
102 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
103 return CRYPT_MEM_ALLOC_FAIL;
104 }
105 GOTO_ERR_IF_EX(CRYPT_EAL_MacInit(mdCtx, ctx->prvKey.prf, n), ret);
106 GOTO_ERR_IF_EX(CRYPT_EAL_MacUpdate(mdCtx, rand, n), ret);
107 GOTO_ERR_IF_EX(CRYPT_EAL_MacUpdate(mdCtx, msg, msgLen), ret);
108 GOTO_ERR_IF_EX(CRYPT_EAL_MacFinal(mdCtx, tmp, &tmpLen), ret);
109 (void)memcpy_s(out, n, tmp, n);
110 ERR:
111 CRYPT_EAL_MacFreeCtx(mdCtx);
112 return ret;
113 }
114
PrfmsgSha256(const CryptSlhDsaCtx * ctx,const uint8_t * rand,const uint8_t * msg,uint32_t msgLen,uint8_t * out)115 static int32_t PrfmsgSha256(const CryptSlhDsaCtx *ctx, const uint8_t *rand, const uint8_t *msg, uint32_t msgLen,
116 uint8_t *out)
117 {
118 return Prfmsg(ctx, rand, msg, msgLen, out, CRYPT_MAC_HMAC_SHA256);
119 }
PrfmsgSha512(const CryptSlhDsaCtx * ctx,const uint8_t * rand,const uint8_t * msg,uint32_t msgLen,uint8_t * out)120 static int32_t PrfmsgSha512(const CryptSlhDsaCtx *ctx, const uint8_t *rand, const uint8_t *msg, uint32_t msgLen,
121 uint8_t *out)
122 {
123 return Prfmsg(ctx, rand, msg, msgLen, out, CRYPT_MAC_HMAC_SHA512);
124 }
125
HmsgSha(const CryptSlhDsaCtx * ctx,const uint8_t * r,const uint8_t * seed,const uint8_t * root,const uint8_t * msg,uint32_t msgLen,uint8_t * out,CRYPT_MD_AlgId mdId)126 static int32_t HmsgSha(const CryptSlhDsaCtx *ctx, const uint8_t *r, const uint8_t *seed, const uint8_t *root,
127 const uint8_t *msg, uint32_t msgLen, uint8_t *out, CRYPT_MD_AlgId mdId)
128 {
129 int32_t ret;
130 uint32_t m = ctx->para.m;
131 uint32_t n = ctx->para.n;
132 uint32_t tmpLen;
133
134 uint8_t tmpSeed[2 * SLH_DSA_MAX_N + MAX_MDSIZE] = {0}; // 2 is for double
135 uint32_t tmpSeedLen = 0;
136 (void)memcpy_s(tmpSeed, sizeof(tmpSeed), r, n);
137 (void)memcpy_s(tmpSeed + n, sizeof(tmpSeed) - n, seed, n);
138 tmpSeedLen = n + n;
139 tmpLen = CRYPT_EAL_MdGetDigestSize(mdId);
140
141 const CRYPT_ConstData hashData[] = {{tmpSeed, tmpSeedLen}, {root, n}, {msg, msgLen}};
142 ret = CalcMultiMsgHash(mdId, hashData, sizeof(hashData) / sizeof(hashData[0]), tmpSeed + tmpSeedLen, tmpLen);
143 if (ret != CRYPT_SUCCESS) {
144 BSL_ERR_PUSH_ERROR(ret);
145 return ret;
146 }
147 tmpSeedLen += tmpLen;
148 return CRYPT_Mgf1(EAL_MdFindMethod(mdId), tmpSeed, tmpSeedLen, out, m);
149 }
150
HmsgSha256(const CryptSlhDsaCtx * ctx,const uint8_t * r,const uint8_t * msg,uint32_t msgLen,uint8_t * out)151 static int32_t HmsgSha256(const CryptSlhDsaCtx *ctx, const uint8_t *r, const uint8_t *msg, uint32_t msgLen,
152 uint8_t *out)
153 {
154 return HmsgSha(ctx, r, ctx->prvKey.pub.seed, ctx->prvKey.pub.root, msg, msgLen, out, CRYPT_MD_SHA256);
155 }
156
HmsgSha512(const CryptSlhDsaCtx * ctx,const uint8_t * r,const uint8_t * msg,uint32_t msgLen,uint8_t * out)157 static int32_t HmsgSha512(const CryptSlhDsaCtx *ctx, const uint8_t *r, const uint8_t *msg, uint32_t msgLen,
158 uint8_t *out)
159 {
160 return HmsgSha(ctx, r, ctx->prvKey.pub.seed, ctx->prvKey.pub.root, msg, msgLen, out, CRYPT_MD_SHA512);
161 }
162
PrfSha256(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,uint8_t * out)163 static int32_t PrfSha256(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, uint8_t *out)
164 {
165 uint32_t n = ctx->para.n;
166 uint8_t padding[SHA256_PADDING_LEN] = {0};
167 const CRYPT_ConstData hashData[] = {{ctx->prvKey.pub.seed, n},
168 {padding, sizeof(padding) - n},
169 {adrs->bytes, ctx->adrsOps.getAdrsLen()},
170 {ctx->prvKey.seed, n}};
171 return CalcMultiMsgHash(CRYPT_MD_SHA256, hashData, sizeof(hashData) / sizeof(hashData[0]), out, n);
172 }
173
HSha256(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,const uint8_t * msg,uint32_t msgLen,uint8_t * out)174 static int32_t HSha256(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, const uint8_t *msg, uint32_t msgLen,
175 uint8_t *out)
176 {
177 uint32_t n = ctx->para.n;
178 uint8_t padding[SHA256_PADDING_LEN] = {0};
179 const CRYPT_ConstData hashData[] = {{ctx->prvKey.pub.seed, n},
180 {padding, sizeof(padding) - n},
181 {adrs->bytes, ctx->adrsOps.getAdrsLen()},
182 {msg, msgLen}};
183 return CalcMultiMsgHash(CRYPT_MD_SHA256, hashData, sizeof(hashData) / sizeof(hashData[0]), out, n);
184 }
185
FSha256(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,const uint8_t * msg,uint32_t msgLen,uint8_t * out)186 static int32_t FSha256(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, const uint8_t *msg, uint32_t msgLen,
187 uint8_t *out)
188 {
189 return HSha256(ctx, adrs, msg, msgLen, out);
190 }
191
TlSha256(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,const uint8_t * msg,uint32_t msgLen,uint8_t * out)192 static int32_t TlSha256(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, const uint8_t *msg, uint32_t msgLen,
193 uint8_t *out)
194 {
195 return HSha256(ctx, adrs, msg, msgLen, out);
196 }
197
HSha512(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,const uint8_t * msg,uint32_t msgLen,uint8_t * out)198 static int32_t HSha512(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, const uint8_t *msg, uint32_t msgLen,
199 uint8_t *out)
200 {
201 uint32_t n = ctx->para.n;
202 uint8_t padding[SHA512_PADDING_LEN] = {0};
203 const CRYPT_ConstData hashData[] = {{ctx->prvKey.pub.seed, n},
204 {padding, sizeof(padding) - n},
205 {adrs->bytes, ctx->adrsOps.getAdrsLen()},
206 {msg, msgLen}};
207 return CalcMultiMsgHash(CRYPT_MD_SHA512, hashData, sizeof(hashData) / sizeof(hashData[0]), out, n);
208 }
209
TlSha512(const CryptSlhDsaCtx * ctx,const SlhDsaAdrs * adrs,const uint8_t * msg,uint32_t msgLen,uint8_t * out)210 static int32_t TlSha512(const CryptSlhDsaCtx *ctx, const SlhDsaAdrs *adrs, const uint8_t *msg, uint32_t msgLen,
211 uint8_t *out)
212 {
213 return HSha512(ctx, adrs, msg, msgLen, out);
214 }
215
SlhDsaInitHashFuncs(CryptSlhDsaCtx * ctx)216 void SlhDsaInitHashFuncs(CryptSlhDsaCtx *ctx)
217 {
218 CRYPT_SLH_DSA_AlgId algId = ctx->para.algId;
219 SlhDsaHashFuncs *hashFuncs = &ctx->hashFuncs;
220 if (algId == CRYPT_SLH_DSA_SHA2_128S || algId == CRYPT_SLH_DSA_SHA2_128F || algId == CRYPT_SLH_DSA_SHA2_192S ||
221 algId == CRYPT_SLH_DSA_SHA2_192F || algId == CRYPT_SLH_DSA_SHA2_256S || algId == CRYPT_SLH_DSA_SHA2_256F) {
222 ctx->para.isCompressed = true;
223 hashFuncs->prf = PrfSha256;
224 hashFuncs->f = FSha256;
225 if (ctx->para.secCategory == 1) {
226 hashFuncs->prfmsg = PrfmsgSha256;
227 hashFuncs->hmsg = HmsgSha256;
228 hashFuncs->tl = TlSha256;
229 hashFuncs->h = HSha256;
230 } else {
231 hashFuncs->prfmsg = PrfmsgSha512;
232 hashFuncs->hmsg = HmsgSha512;
233 hashFuncs->tl = TlSha512;
234 hashFuncs->h = HSha512;
235 }
236 } else {
237 ctx->para.isCompressed = false;
238 hashFuncs->prfmsg = PrfmsgShake256;
239 hashFuncs->hmsg = HmsgShake256;
240 hashFuncs->prf = PrfShake256;
241 hashFuncs->tl = TlShake256;
242 hashFuncs->f = FShake256;
243 hashFuncs->h = HShake256;
244 }
245 }
246
247 #endif // HITLS_CRYPTO_SLH_DSA