Coverage Report

Created: 2026-10-28 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl40/crypto/slh_dsa/slh_hash.c
Line
Count
Source
1
/*
2
 * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include "internal/deprecated.h" /* PKCS1_MGF1() */
11
12
#include <string.h>
13
#include <openssl/evp.h>
14
#include <openssl/core_names.h>
15
#include <openssl/rsa.h> /* PKCS1_MGF1() */
16
#include "slh_dsa_local.h"
17
#include "slh_dsa_key.h"
18
19
#include "openssl/sha.h"
20
#include "internal/sha3.h"
21
#include "crypto/evp.h"
22
#include "crypto/sha.h"
23
24
#define MAX_DIGEST_SIZE 64 /* SHA-512 is used for security category 3 & 5 */
25
588M
#define NIBBLE_MASK 15
26
27
/* Most hash functions in SLH-DSA truncate the output */
28
#define sha256_final(ctx, out, outlen)    \
29
410M
    (ctx)->md_len = (unsigned int)outlen; \
30
410M
    SHA256_Final(out, ctx)
31
32
#define sha512_final(ctx, out, outlen)    \
33
19.9M
    (ctx)->md_len = (unsigned int)outlen; \
34
19.9M
    SHA512_Final(out, ctx)
35
36
static OSSL_SLH_HASHFUNC_PRF slh_prf_sha256;
37
static OSSL_SLH_HASHFUNC_PRF slh_prf_shake;
38
39
static OSSL_SLH_HASHFUNC_F slh_f_sha256;
40
static OSSL_SLH_HASHFUNC_F slh_f_shake;
41
42
static OSSL_SLH_HASHFUNC_PRF_MSG slh_prf_msg_sha2;
43
static OSSL_SLH_HASHFUNC_PRF_MSG slh_prf_msg_shake;
44
45
static OSSL_SLH_HASHFUNC_H_MSG slh_hmsg_sha256;
46
static OSSL_SLH_HASHFUNC_H_MSG slh_hmsg_sha512;
47
static OSSL_SLH_HASHFUNC_H_MSG slh_hmsg_shake;
48
49
static OSSL_SLH_HASHFUNC_H slh_h_sha256;
50
static OSSL_SLH_HASHFUNC_H slh_h_sha512;
51
static OSSL_SLH_HASHFUNC_H slh_h_shake;
52
static OSSL_SLH_HASHFUNC_T slh_t_sha256;
53
static OSSL_SLH_HASHFUNC_T slh_t_sha512;
54
static OSSL_SLH_HASHFUNC_wots_pk_gen slh_wots_pk_gen_sha2;
55
static OSSL_SLH_HASHFUNC_wots_pk_gen slh_wots_pk_gen_shake;
56
57
static const uint8_t zeros[128] = { 0 };
58
59
/* See FIPS 205 Section 11.1 */
60
static int
61
slh_hmsg_shake(SLH_DSA_HASH_CTX *hctx, const uint8_t *r,
62
    const uint8_t *pk_seed, const uint8_t *pk_root,
63
    const uint8_t *msg, size_t msg_len,
64
    uint8_t *out, size_t out_len)
65
690
{
66
690
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->shactx);
67
690
    const SLH_DSA_PARAMS *params = hctx->key->params;
68
690
    size_t m = params->m;
69
690
    size_t n = params->n;
70
71
690
    ossl_sha3_reset(sctx);
72
690
    ossl_sha3_absorb(sctx, r, n);
73
690
    ossl_sha3_absorb(sctx, pk_seed, n);
74
690
    ossl_sha3_absorb(sctx, pk_root, n);
75
690
    ossl_sha3_absorb(sctx, msg, msg_len);
76
690
    ossl_sha3_squeeze(sctx, out, m);
77
690
    return 1;
78
690
}
79
80
static int
81
slh_prf_msg_shake(SLH_DSA_HASH_CTX *hctx, const uint8_t *sk_prf,
82
    const uint8_t *opt_rand, const uint8_t *msg, size_t msg_len,
83
    WPACKET *pkt)
84
121
{
85
121
    int ret;
86
121
    unsigned char out[SLH_MAX_N];
87
121
    const SLH_DSA_PARAMS *params = hctx->key->params;
88
121
    size_t n = params->n;
89
121
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->shactx);
90
91
121
    ossl_sha3_reset(sctx);
92
121
    ossl_sha3_absorb(sctx, sk_prf, n);
93
121
    ossl_sha3_absorb(sctx, opt_rand, n);
94
121
    ossl_sha3_absorb(sctx, msg, msg_len);
95
121
    ossl_sha3_squeeze(sctx, out, n);
96
121
    ret = WPACKET_memcpy(pkt, out, n);
97
121
    OPENSSL_cleanse(out, sizeof(out));
98
121
    return ret;
99
121
}
100
101
static int
102
slh_f_shake(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
103
    const uint8_t *m1, size_t m1_len, uint8_t *out, size_t out_len)
104
305M
{
105
305M
    const SLH_DSA_PARAMS *params = hctx->key->params;
106
305M
    size_t n = params->n;
107
305M
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->scratch);
108
109
305M
    *sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed));
110
305M
    ossl_sha3_absorb(sctx, adrs, SLH_ADRS_SIZE);
111
305M
    ossl_sha3_absorb(sctx, m1, m1_len);
112
305M
    ossl_sha3_squeeze(sctx, out, n);
113
305M
    return 1;
114
305M
}
115
116
static int
117
slh_prf_shake(SLH_DSA_HASH_CTX *hctx,
118
    const uint8_t *pk_seed, const uint8_t *sk_seed,
119
    const uint8_t *adrs, uint8_t *out, size_t out_len)
120
59.8M
{
121
59.8M
    const SLH_DSA_PARAMS *params = hctx->key->params;
122
59.8M
    size_t n = params->n;
123
59.8M
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->scratch);
124
125
59.8M
    *sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed));
126
59.8M
    ossl_sha3_absorb(sctx, adrs, SLH_ADRS_SIZE);
127
59.8M
    ossl_sha3_absorb(sctx, sk_seed, n);
128
59.8M
    ossl_sha3_squeeze(sctx, out, n);
129
59.8M
    return 1;
130
59.8M
}
131
132
static int
133
slh_h_shake(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
134
    const uint8_t *m1, const uint8_t *m2, uint8_t *out, size_t out_len)
135
43.2M
{
136
43.2M
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->scratch);
137
43.2M
    const SLH_DSA_PARAMS *params = hctx->key->params;
138
43.2M
    size_t n = params->n;
139
140
43.2M
    *sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed));
141
43.2M
    ossl_sha3_absorb(sctx, adrs, SLH_ADRS_SIZE);
142
43.2M
    ossl_sha3_absorb(sctx, m1, n);
143
43.2M
    ossl_sha3_absorb(sctx, m2, n);
144
43.2M
    ossl_sha3_squeeze(sctx, out, n);
145
43.2M
    return 1;
146
43.2M
}
147
148
/* FIPS 205 Section 11.2.1 and 11.2.2 */
149
150
static int
151
slh_hmsg_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed,
152
    const uint8_t *pk_root, const uint8_t *msg, size_t msg_len,
153
    uint8_t *out, size_t out_len)
154
287
{
155
287
    int ret;
156
287
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
157
287
    const SLH_DSA_PARAMS *params = hctx->key->params;
158
287
    size_t m = params->m;
159
287
    size_t n = params->n;
160
287
    uint8_t seed[2 * SLH_MAX_N + SHA256_DIGEST_LENGTH];
161
287
    long seed_len = SHA256_DIGEST_LENGTH + (long)(2 * n);
162
163
287
    memcpy(seed, r, n);
164
287
    memcpy(seed + n, pk_seed, n);
165
166
287
    SHA256_Init(sctx);
167
287
    SHA256_Update(sctx, r, n);
168
287
    SHA256_Update(sctx, pk_seed, n);
169
287
    SHA256_Update(sctx, pk_root, n);
170
287
    SHA256_Update(sctx, msg, msg_len);
171
287
    ret = SHA256_Final(seed + 2 * n, sctx)
172
287
        && (PKCS1_MGF1(out, (long)m, seed, seed_len, hctx->key->md) == 0);
173
287
    OPENSSL_cleanse(seed, sizeof(seed));
174
287
    return ret;
175
287
}
176
177
static int
178
slh_hmsg_sha512(SLH_DSA_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed,
179
    const uint8_t *pk_root, const uint8_t *msg, size_t msg_len,
180
    uint8_t *out, size_t out_len)
181
293
{
182
293
    int ret;
183
293
    SHA512_CTX *sctx = (SHA512_CTX *)(hctx->scratch);
184
293
    const SLH_DSA_PARAMS *params = hctx->key->params;
185
293
    size_t m = params->m;
186
293
    size_t n = params->n;
187
293
    uint8_t seed[2 * SLH_MAX_N + SHA512_DIGEST_LENGTH];
188
293
    long seed_len = SHA512_DIGEST_LENGTH + (long)(2 * n);
189
190
293
    memcpy(seed, r, n);
191
293
    memcpy(seed + n, pk_seed, n);
192
193
293
    SHA512_Init(sctx);
194
293
    SHA512_Update(sctx, r, n);
195
293
    SHA512_Update(sctx, pk_seed, n);
196
293
    SHA512_Update(sctx, pk_root, n);
197
293
    SHA512_Update(sctx, msg, msg_len);
198
293
    ret = SHA512_Final(seed + 2 * n, sctx)
199
293
        && (PKCS1_MGF1(out, (long)m, seed, seed_len, hctx->key->md_sha512) == 0);
200
293
    OPENSSL_cleanse(seed, sizeof(seed));
201
293
    return ret;
202
293
}
203
204
static int
205
slh_prf_msg_sha2(SLH_DSA_HASH_CTX *hctx,
206
    const uint8_t *sk_prf, const uint8_t *opt_rand,
207
    const uint8_t *msg, size_t msg_len, WPACKET *pkt)
208
244
{
209
244
    int ret;
210
244
    const SLH_DSA_KEY *key = hctx->key;
211
244
    EVP_MAC_CTX *mctx = hctx->hmac_ctx;
212
244
    const SLH_DSA_PARAMS *prms = key->params;
213
244
    size_t n = prms->n;
214
244
    uint8_t mac[MAX_DIGEST_SIZE] = { 0 };
215
244
    OSSL_PARAM *p = NULL;
216
244
    OSSL_PARAM params[3];
217
218
    /*
219
     * Due to the way HMAC works, it is not possible to do this code early
220
     * in hmac_ctx_new() since it requires a key in order to set the digest.
221
     * So we do a lazy update here on the first call.
222
     */
223
244
    if (hctx->hmac_digest_used == 0) {
224
244
        const char *nm = EVP_MD_get0_name(key->md_sha512 == NULL ? key->md : key->md_sha512);
225
226
244
        p = params;
227
        /* The underlying digest to be used */
228
244
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, (char *)nm, 0);
229
244
        if (key->propq != NULL)
230
0
            *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES,
231
0
                (char *)key->propq, 0);
232
244
        *p = OSSL_PARAM_construct_end();
233
244
        p = params;
234
244
        hctx->hmac_digest_used = 1;
235
244
    }
236
237
244
    ret = EVP_MAC_init(mctx, sk_prf, n, p) == 1
238
244
        && EVP_MAC_update(mctx, opt_rand, n) == 1
239
244
        && EVP_MAC_update(mctx, msg, msg_len) == 1
240
244
        && EVP_MAC_final(mctx, mac, NULL, sizeof(mac)) == 1
241
244
        && WPACKET_memcpy(pkt, mac, n); /* Truncate output to n bytes */
242
244
    OPENSSL_cleanse(mac, sizeof(mac));
243
244
    return ret;
244
244
}
245
246
static int
247
slh_prf_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed,
248
    const uint8_t *sk_seed, const uint8_t *adrs,
249
    uint8_t *out, size_t out_len)
250
22.7M
{
251
22.7M
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
252
22.7M
    size_t n = hctx->key->params->n;
253
254
22.7M
    *sctx = *((SHA256_CTX *)hctx->shactx_pkseed);
255
22.7M
    SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE);
256
22.7M
    SHA256_Update(sctx, sk_seed, n);
257
22.7M
    sha256_final(sctx, out, n);
258
22.7M
    return 1;
259
22.7M
}
260
261
static int
262
slh_wots_pk_gen_sha2(SLH_DSA_HASH_CTX *hctx,
263
    const uint8_t *sk_seed, const uint8_t *pk_seed,
264
    uint8_t *adrs, uint8_t *pk_out, size_t pk_out_len)
265
498k
{
266
498k
    int ret = 0;
267
498k
    size_t n = hctx->key->params->n;
268
498k
    size_t i, j = 0, len = SLH_WOTS_LEN(n);
269
498k
    uint8_t sk[SLH_MAX_N];
270
498k
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->shactx_pkseed);
271
498k
    SHA256_CTX *ctx = (SHA256_CTX *)(hctx->scratch);
272
498k
    const SLH_ADRS_FUNC *adrsf = hctx->key->adrs_func;
273
498k
    SLH_ADRS_DECLARE(sk_adrs);
274
498k
    SLH_ADRS_FN_DECLARE(adrsf, set_chain_address);
275
498k
    SLH_ADRS_FN_DECLARE(adrsf, set_hash_address);
276
277
498k
    adrsf->copy(sk_adrs, adrs);
278
498k
    adrsf->set_type_and_clear(sk_adrs, SLH_ADRS_TYPE_WOTS_PRF);
279
498k
    adrsf->copy_keypair_address(sk_adrs, adrs);
280
281
22.8M
    for (i = 0; i < len; ++i) { /* len = 2n + 3 */
282
22.3M
        set_chain_address(sk_adrs, (uint32_t)i);
283
284
        /* PRF */
285
22.3M
        *ctx = *sctx;
286
22.3M
        SHA256_Update(ctx, sk_adrs, SLH_ADRSC_SIZE);
287
22.3M
        SHA256_Update(ctx, sk_seed, n);
288
22.3M
        sha256_final(ctx, sk, n);
289
290
22.3M
        set_chain_address(adrs, (uint32_t)i);
291
357M
        for (j = 0; j < NIBBLE_MASK; ++j) {
292
335M
            set_hash_address(adrs, (uint32_t)j);
293
            /* F */
294
335M
            *ctx = *sctx;
295
335M
            SHA256_Update(ctx, adrs, SLH_ADRSC_SIZE);
296
335M
            SHA256_Update(ctx, sk, n);
297
335M
            sha256_final(ctx, sk, n);
298
335M
        }
299
22.3M
        memcpy(pk_out, sk, n);
300
22.3M
        pk_out += n;
301
22.3M
    }
302
498k
    ret = 1;
303
498k
    OPENSSL_cleanse(sk, sizeof(sk));
304
498k
    return ret;
305
498k
}
306
307
int slh_wots_pk_gen_shake(SLH_DSA_HASH_CTX *hctx,
308
    const uint8_t *sk_seed, const uint8_t *pk_seed,
309
    uint8_t *adrs, uint8_t *pk_out, size_t pk_out_len)
310
262k
{
311
262k
    int ret = 0;
312
262k
    size_t n = hctx->key->params->n;
313
262k
    size_t i, j = 0, len = SLH_WOTS_LEN(n);
314
262k
    uint8_t sk[SLH_MAX_N];
315
262k
    const SLH_ADRS_FUNC *adrsf = hctx->key->adrs_func;
316
262k
    SLH_ADRS_DECLARE(sk_adrs);
317
262k
    SLH_ADRS_FN_DECLARE(adrsf, set_chain_address);
318
262k
    SLH_ADRS_FN_DECLARE(adrsf, set_hash_address);
319
262k
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->shactx_pkseed);
320
262k
    KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)(hctx->scratch);
321
322
262k
    adrsf->copy(sk_adrs, adrs);
323
262k
    adrsf->set_type_and_clear(sk_adrs, SLH_ADRS_TYPE_WOTS_PRF);
324
262k
    adrsf->copy_keypair_address(sk_adrs, adrs);
325
326
14.6M
    for (i = 0; i < len; ++i) { /* len = 2n + 3 */
327
14.4M
        set_chain_address(sk_adrs, (uint32_t)i);
328
329
        /* PRF */
330
14.4M
        *ctx = *sctx;
331
14.4M
        ossl_sha3_absorb(ctx, sk_adrs, SLH_ADRS_SIZE);
332
14.4M
        ossl_sha3_absorb(ctx, sk_seed, n);
333
14.4M
        ossl_sha3_squeeze(ctx, sk, n);
334
335
14.4M
        set_chain_address(adrs, (uint32_t)i);
336
230M
        for (j = 0; j < NIBBLE_MASK; ++j) {
337
216M
            set_hash_address(adrs, (uint32_t)j);
338
            /* F */
339
216M
            *ctx = *sctx;
340
216M
            ossl_sha3_absorb(ctx, adrs, SLH_ADRS_SIZE);
341
216M
            ossl_sha3_absorb(ctx, sk, n);
342
216M
            ossl_sha3_squeeze(ctx, sk, n);
343
216M
        }
344
14.4M
        memcpy(pk_out, sk, n);
345
14.4M
        pk_out += n;
346
14.4M
    }
347
262k
    ret = 1;
348
262k
    OPENSSL_cleanse(sk, sizeof(sk));
349
262k
    return ret;
350
262k
}
351
352
static int
353
slh_f_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
354
    const uint8_t *m1, size_t m1_len, uint8_t *out, size_t out_len)
355
26.6M
{
356
26.6M
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
357
358
26.6M
    *sctx = *((SHA256_CTX *)hctx->shactx_pkseed);
359
26.6M
    SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE);
360
26.6M
    SHA256_Update(sctx, m1, m1_len);
361
26.6M
    sha256_final(sctx, out, hctx->key->params->n);
362
26.6M
    return 1;
363
26.6M
}
364
365
static int
366
slh_h_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
367
    const uint8_t *m1, const uint8_t *m2, uint8_t *out, size_t out_len)
368
3.42M
{
369
3.42M
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
370
3.42M
    const SLH_DSA_PARAMS *prms = hctx->key->params;
371
3.42M
    size_t n = prms->n;
372
373
3.42M
    *sctx = *((SHA256_CTX *)hctx->shactx_pkseed);
374
3.42M
    SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE);
375
3.42M
    SHA256_Update(sctx, m1, n);
376
3.42M
    SHA256_Update(sctx, m2, n);
377
3.42M
    sha256_final(sctx, out, n);
378
3.42M
    return 1;
379
3.42M
}
380
381
static int
382
slh_h_sha512(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
383
    const uint8_t *m1, const uint8_t *m2, uint8_t *out, size_t out_len)
384
19.7M
{
385
19.7M
    SHA512_CTX *sctx = (SHA512_CTX *)(hctx->scratch);
386
19.7M
    const SLH_DSA_PARAMS *prms = hctx->key->params;
387
19.7M
    size_t n = prms->n;
388
389
19.7M
    SHA512_Init(sctx);
390
19.7M
    SHA512_Update(sctx, pk_seed, n);
391
19.7M
    SHA512_Update(sctx, zeros, 128 - n);
392
19.7M
    SHA512_Update(sctx, adrs, SLH_ADRSC_SIZE);
393
19.7M
    SHA512_Update(sctx, m1, n);
394
19.7M
    SHA512_Update(sctx, m2, n);
395
19.7M
    sha512_final(sctx, out, n);
396
19.7M
    return 1;
397
19.7M
}
398
399
static int
400
slh_t_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
401
    const uint8_t *ml, size_t ml_len, uint8_t *out, size_t out_len)
402
294k
{
403
294k
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
404
405
294k
    *sctx = *((SHA256_CTX *)hctx->shactx_pkseed);
406
294k
    SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE);
407
294k
    SHA256_Update(sctx, ml, ml_len);
408
294k
    sha256_final(sctx, out, hctx->key->params->n);
409
294k
    return 1;
410
294k
}
411
412
static int
413
slh_t_sha512(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs,
414
    const uint8_t *ml, size_t ml_len, uint8_t *out, size_t out_len)
415
212k
{
416
212k
    SHA512_CTX *sctx = (SHA512_CTX *)(hctx->scratch);
417
212k
    const SLH_DSA_PARAMS *prms = hctx->key->params;
418
212k
    size_t n = prms->n;
419
420
212k
    SHA512_Init(sctx);
421
212k
    SHA512_Update(sctx, pk_seed, n);
422
212k
    SHA512_Update(sctx, zeros, 128 - n);
423
212k
    SHA512_Update(sctx, adrs, SLH_ADRSC_SIZE);
424
212k
    SHA512_Update(sctx, ml, ml_len);
425
212k
    sha512_final(sctx, out, hctx->key->params->n);
426
212k
    return 1;
427
212k
}
428
429
static int slh_hash_shake_precache(SLH_DSA_HASH_CTX *hctx, const uint8_t *pkseed, size_t n)
430
617
{
431
617
    KECCAK1600_CTX *ctx = NULL, *seedctx = NULL, *scratch = NULL;
432
433
617
    ctx = ossl_shake256_new();
434
617
    if (ctx == NULL)
435
0
        return 0;
436
617
    seedctx = OPENSSL_memdup(ctx, sizeof(*ctx));
437
617
    scratch = OPENSSL_malloc(sizeof(*scratch));
438
617
    if (seedctx == NULL || scratch == NULL) {
439
0
        OPENSSL_free(ctx);
440
0
        OPENSSL_free(seedctx);
441
0
        OPENSSL_free(scratch);
442
0
        return 0;
443
0
    }
444
617
    ossl_sha3_absorb(seedctx, pkseed, n);
445
617
    hctx->shactx = (void *)ctx;
446
617
    hctx->shactx_pkseed = (void *)seedctx;
447
617
    hctx->shactx_len = sizeof(*ctx);
448
617
    hctx->scratch = (void *)scratch;
449
617
    hctx->scratch_len = sizeof(*scratch);
450
617
    return 1;
451
617
}
452
453
static int slh_hash_shake_dup(SLH_DSA_HASH_CTX *dst, const SLH_DSA_HASH_CTX *src)
454
0
{
455
0
    if (src->shactx != NULL) {
456
0
        dst->shactx = OPENSSL_memdup(src->shactx, sizeof(KECCAK1600_CTX));
457
0
        if (dst->shactx == NULL)
458
0
            return 0;
459
0
    }
460
0
    if (src->shactx_pkseed != NULL) {
461
0
        dst->shactx_pkseed = OPENSSL_memdup(src->shactx_pkseed, sizeof(KECCAK1600_CTX));
462
0
        if (dst->shactx_pkseed == NULL) {
463
0
            OPENSSL_free(dst->shactx);
464
0
            dst->shactx = NULL;
465
0
            return 0;
466
0
        }
467
0
    }
468
0
    dst->shactx_len = src->shactx_len;
469
    /* A prehashed context needs a scratch context, its content is transient */
470
0
    if (dst->shactx_pkseed != NULL) {
471
0
        dst->scratch = OPENSSL_malloc(sizeof(KECCAK1600_CTX));
472
0
        if (dst->scratch == NULL)
473
0
            return 0;
474
0
        dst->scratch_len = sizeof(KECCAK1600_CTX);
475
0
    } else {
476
0
        dst->scratch = NULL;
477
0
        dst->scratch_len = 0;
478
0
    }
479
0
    return 1;
480
0
}
481
482
static int slh_hash_sha256_precache(SLH_DSA_HASH_CTX *hctx, const uint8_t *pkseed, size_t n)
483
1.20k
{
484
1.20k
    SHA256_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
485
    /* The scratch context is also used as a SHA512_CTX by category 3 and 5 */
486
1.20k
    size_t scratch_len = sizeof(SHA512_CTX);
487
488
1.20k
    if (ctx == NULL)
489
0
        return 0;
490
1.20k
    if ((hctx->scratch = OPENSSL_malloc(scratch_len)) == NULL) {
491
0
        OPENSSL_free(ctx);
492
0
        return 0;
493
0
    }
494
1.20k
    hctx->scratch_len = scratch_len;
495
1.20k
    SHA256_Init(ctx);
496
1.20k
    SHA256_Update(ctx, pkseed, n);
497
1.20k
    SHA256_Update(ctx, zeros, 64 - n);
498
1.20k
    hctx->shactx_pkseed = (void *)ctx;
499
1.20k
    hctx->shactx_len = sizeof(*ctx);
500
1.20k
    return 1;
501
1.20k
}
502
503
static int slh_hash_sha256_dup(SLH_DSA_HASH_CTX *dst, const SLH_DSA_HASH_CTX *src)
504
0
{
505
0
    if (src->shactx_pkseed != NULL) {
506
0
        dst->shactx_pkseed = OPENSSL_memdup(src->shactx_pkseed, sizeof(SHA256_CTX));
507
0
        if (dst->shactx_pkseed == NULL)
508
0
            return 0;
509
0
    }
510
    /*
511
     * A prehashed context needs a scratch context, its content is transient.
512
     * As in slh_hash_sha256_precache() the scratch context is sized to also
513
     * serve as a SHA512_CTX for security categories 3 and 5.
514
     */
515
0
    dst->shactx_len = src->shactx_len;
516
0
    if (dst->shactx_pkseed != NULL) {
517
0
        dst->scratch = OPENSSL_malloc(sizeof(SHA512_CTX));
518
0
        if (dst->scratch == NULL)
519
0
            return 0;
520
0
        dst->scratch_len = sizeof(SHA512_CTX);
521
0
    } else {
522
0
        dst->scratch = NULL;
523
0
        dst->scratch_len = 0;
524
0
    }
525
0
    return 1;
526
0
}
527
528
const SLH_HASH_FUNC *ossl_slh_get_hash_fn(int is_shake, int security_category)
529
142k
{
530
142k
    static const SLH_HASH_FUNC methods[] = {
531
142k
        { slh_hash_shake_precache,
532
142k
            slh_hash_shake_dup,
533
142k
            slh_hmsg_shake,
534
142k
            slh_prf_shake,
535
142k
            slh_prf_msg_shake,
536
142k
            slh_f_shake,
537
142k
            slh_h_shake,
538
142k
            slh_f_shake,
539
142k
            slh_wots_pk_gen_shake },
540
142k
        { slh_hash_sha256_precache,
541
142k
            slh_hash_sha256_dup,
542
142k
            slh_hmsg_sha256,
543
142k
            slh_prf_sha256,
544
142k
            slh_prf_msg_sha2,
545
142k
            slh_f_sha256,
546
142k
            slh_h_sha256,
547
142k
            slh_t_sha256,
548
142k
            slh_wots_pk_gen_sha2 },
549
142k
        { slh_hash_sha256_precache,
550
142k
            slh_hash_sha256_dup,
551
142k
            slh_hmsg_sha512,
552
142k
            slh_prf_sha256,
553
142k
            slh_prf_msg_sha2,
554
142k
            slh_f_sha256,
555
142k
            slh_h_sha512,
556
142k
            slh_t_sha512,
557
142k
            slh_wots_pk_gen_sha2 }
558
142k
    };
559
142k
    return &methods[is_shake ? 0 : (security_category == 1 ? 1 : 2)];
560
142k
}