• 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_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