Coverage Report

Created: 2026-09-12 06:55

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
472M
#define NIBBLE_MASK 15
26
27
/* Most hash functions in SLH-DSA truncate the output */
28
#define sha256_final(ctx, out, outlen)    \
29
331M
    (ctx)->md_len = (unsigned int)outlen; \
30
331M
    SHA256_Final(out, ctx)
31
32
#define sha512_final(ctx, out, outlen)    \
33
14.9M
    (ctx)->md_len = (unsigned int)outlen; \
34
14.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
652
{
66
652
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->shactx);
67
652
    const SLH_DSA_PARAMS *params = hctx->key->params;
68
652
    size_t m = params->m;
69
652
    size_t n = params->n;
70
71
652
    ossl_sha3_reset(sctx);
72
652
    ossl_sha3_absorb(sctx, r, n);
73
652
    ossl_sha3_absorb(sctx, pk_seed, n);
74
652
    ossl_sha3_absorb(sctx, pk_root, n);
75
652
    ossl_sha3_absorb(sctx, msg, msg_len);
76
652
    ossl_sha3_squeeze(sctx, out, m);
77
652
    return 1;
78
652
}
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
117
{
85
117
    int ret;
86
117
    unsigned char out[SLH_MAX_N];
87
117
    const SLH_DSA_PARAMS *params = hctx->key->params;
88
117
    size_t n = params->n;
89
117
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->shactx);
90
91
117
    ossl_sha3_reset(sctx);
92
117
    ossl_sha3_absorb(sctx, sk_prf, n);
93
117
    ossl_sha3_absorb(sctx, opt_rand, n);
94
117
    ossl_sha3_absorb(sctx, msg, msg_len);
95
117
    ossl_sha3_squeeze(sctx, out, n);
96
117
    ret = WPACKET_memcpy(pkt, out, n);
97
117
    OPENSSL_cleanse(out, sizeof(out));
98
117
    return ret;
99
117
}
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
248M
{
105
248M
    const SLH_DSA_PARAMS *params = hctx->key->params;
106
248M
    size_t n = params->n;
107
248M
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->scratch);
108
109
248M
    *sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed));
110
248M
    ossl_sha3_absorb(sctx, adrs, SLH_ADRS_SIZE);
111
248M
    ossl_sha3_absorb(sctx, m1, m1_len);
112
248M
    ossl_sha3_squeeze(sctx, out, n);
113
248M
    return 1;
114
248M
}
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
48.2M
{
121
48.2M
    const SLH_DSA_PARAMS *params = hctx->key->params;
122
48.2M
    size_t n = params->n;
123
48.2M
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->scratch);
124
125
48.2M
    *sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed));
126
48.2M
    ossl_sha3_absorb(sctx, adrs, SLH_ADRS_SIZE);
127
48.2M
    ossl_sha3_absorb(sctx, sk_seed, n);
128
48.2M
    ossl_sha3_squeeze(sctx, out, n);
129
48.2M
    return 1;
130
48.2M
}
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
34.6M
{
136
34.6M
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->scratch);
137
34.6M
    const SLH_DSA_PARAMS *params = hctx->key->params;
138
34.6M
    size_t n = params->n;
139
140
34.6M
    *sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed));
141
34.6M
    ossl_sha3_absorb(sctx, adrs, SLH_ADRS_SIZE);
142
34.6M
    ossl_sha3_absorb(sctx, m1, n);
143
34.6M
    ossl_sha3_absorb(sctx, m2, n);
144
34.6M
    ossl_sha3_squeeze(sctx, out, n);
145
34.6M
    return 1;
146
34.6M
}
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
212
{
155
212
    int ret;
156
212
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
157
212
    const SLH_DSA_PARAMS *params = hctx->key->params;
158
212
    size_t m = params->m;
159
212
    size_t n = params->n;
160
212
    uint8_t seed[2 * SLH_MAX_N + SHA256_DIGEST_LENGTH];
161
212
    long seed_len = SHA256_DIGEST_LENGTH + (long)(2 * n);
162
163
212
    memcpy(seed, r, n);
164
212
    memcpy(seed + n, pk_seed, n);
165
166
212
    SHA256_Init(sctx);
167
212
    SHA256_Update(sctx, r, n);
168
212
    SHA256_Update(sctx, pk_seed, n);
169
212
    SHA256_Update(sctx, pk_root, n);
170
212
    SHA256_Update(sctx, msg, msg_len);
171
212
    ret = SHA256_Final(seed + 2 * n, sctx)
172
212
        && (PKCS1_MGF1(out, (long)m, seed, seed_len, hctx->key->md) == 0);
173
212
    OPENSSL_cleanse(seed, sizeof(seed));
174
212
    return ret;
175
212
}
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
236
{
182
236
    int ret;
183
236
    SHA512_CTX *sctx = (SHA512_CTX *)(hctx->scratch);
184
236
    const SLH_DSA_PARAMS *params = hctx->key->params;
185
236
    size_t m = params->m;
186
236
    size_t n = params->n;
187
236
    uint8_t seed[2 * SLH_MAX_N + SHA512_DIGEST_LENGTH];
188
236
    long seed_len = SHA512_DIGEST_LENGTH + (long)(2 * n);
189
190
236
    memcpy(seed, r, n);
191
236
    memcpy(seed + n, pk_seed, n);
192
193
236
    SHA512_Init(sctx);
194
236
    SHA512_Update(sctx, r, n);
195
236
    SHA512_Update(sctx, pk_seed, n);
196
236
    SHA512_Update(sctx, pk_root, n);
197
236
    SHA512_Update(sctx, msg, msg_len);
198
236
    ret = SHA512_Final(seed + 2 * n, sctx)
199
236
        && (PKCS1_MGF1(out, (long)m, seed, seed_len, hctx->key->md_sha512) == 0);
200
236
    OPENSSL_cleanse(seed, sizeof(seed));
201
236
    return ret;
202
236
}
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
224
{
209
224
    int ret;
210
224
    const SLH_DSA_KEY *key = hctx->key;
211
224
    EVP_MAC_CTX *mctx = hctx->hmac_ctx;
212
224
    const SLH_DSA_PARAMS *prms = key->params;
213
224
    size_t n = prms->n;
214
224
    uint8_t mac[MAX_DIGEST_SIZE] = { 0 };
215
224
    OSSL_PARAM *p = NULL;
216
224
    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
224
    if (hctx->hmac_digest_used == 0) {
224
224
        const char *nm = EVP_MD_get0_name(key->md_sha512 == NULL ? key->md : key->md_sha512);
225
226
224
        p = params;
227
        /* The underlying digest to be used */
228
224
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, (char *)nm, 0);
229
224
        if (key->propq != NULL)
230
0
            *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES,
231
0
                (char *)key->propq, 0);
232
224
        *p = OSSL_PARAM_construct_end();
233
224
        p = params;
234
224
        hctx->hmac_digest_used = 1;
235
224
    }
236
237
224
    ret = EVP_MAC_init(mctx, sk_prf, n, p) == 1
238
224
        && EVP_MAC_update(mctx, opt_rand, n) == 1
239
224
        && EVP_MAC_update(mctx, msg, msg_len) == 1
240
224
        && EVP_MAC_final(mctx, mac, NULL, sizeof(mac)) == 1
241
224
        && WPACKET_memcpy(pkt, mac, n); /* Truncate output to n bytes */
242
224
    OPENSSL_cleanse(mac, sizeof(mac));
243
224
    return ret;
244
224
}
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
17.5M
{
251
17.5M
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
252
17.5M
    size_t n = hctx->key->params->n;
253
254
17.5M
    *sctx = *((SHA256_CTX *)hctx->shactx_pkseed);
255
17.5M
    SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE);
256
17.5M
    SHA256_Update(sctx, sk_seed, n);
257
17.5M
    sha256_final(sctx, out, n);
258
17.5M
    return 1;
259
17.5M
}
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
409k
{
266
409k
    int ret = 0;
267
409k
    size_t n = hctx->key->params->n;
268
409k
    size_t i, j = 0, len = SLH_WOTS_LEN(n);
269
409k
    uint8_t sk[SLH_MAX_N];
270
409k
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->shactx_pkseed);
271
409k
    SHA256_CTX *ctx = (SHA256_CTX *)(hctx->scratch);
272
409k
    const SLH_ADRS_FUNC *adrsf = hctx->key->adrs_func;
273
409k
    SLH_ADRS_DECLARE(sk_adrs);
274
409k
    SLH_ADRS_FN_DECLARE(adrsf, set_chain_address);
275
409k
    SLH_ADRS_FN_DECLARE(adrsf, set_hash_address);
276
277
409k
    adrsf->copy(sk_adrs, adrs);
278
409k
    adrsf->set_type_and_clear(sk_adrs, SLH_ADRS_TYPE_WOTS_PRF);
279
409k
    adrsf->copy_keypair_address(sk_adrs, adrs);
280
281
18.4M
    for (i = 0; i < len; ++i) { /* len = 2n + 3 */
282
18.0M
        set_chain_address(sk_adrs, (uint32_t)i);
283
284
        /* PRF */
285
18.0M
        *ctx = *sctx;
286
18.0M
        SHA256_Update(ctx, sk_adrs, SLH_ADRSC_SIZE);
287
18.0M
        SHA256_Update(ctx, sk_seed, n);
288
18.0M
        sha256_final(ctx, sk, n);
289
290
18.0M
        set_chain_address(adrs, (uint32_t)i);
291
289M
        for (j = 0; j < NIBBLE_MASK; ++j) {
292
271M
            set_hash_address(adrs, (uint32_t)j);
293
            /* F */
294
271M
            *ctx = *sctx;
295
271M
            SHA256_Update(ctx, adrs, SLH_ADRSC_SIZE);
296
271M
            SHA256_Update(ctx, sk, n);
297
271M
            sha256_final(ctx, sk, n);
298
271M
        }
299
18.0M
        memcpy(pk_out, sk, n);
300
18.0M
        pk_out += n;
301
18.0M
    }
302
409k
    ret = 1;
303
409k
    OPENSSL_cleanse(sk, sizeof(sk));
304
409k
    return ret;
305
409k
}
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
219k
{
311
219k
    int ret = 0;
312
219k
    size_t n = hctx->key->params->n;
313
219k
    size_t i, j = 0, len = SLH_WOTS_LEN(n);
314
219k
    uint8_t sk[SLH_MAX_N];
315
219k
    const SLH_ADRS_FUNC *adrsf = hctx->key->adrs_func;
316
219k
    SLH_ADRS_DECLARE(sk_adrs);
317
219k
    SLH_ADRS_FN_DECLARE(adrsf, set_chain_address);
318
219k
    SLH_ADRS_FN_DECLARE(adrsf, set_hash_address);
319
219k
    KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->shactx_pkseed);
320
219k
    KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)(hctx->scratch);
321
322
219k
    adrsf->copy(sk_adrs, adrs);
323
219k
    adrsf->set_type_and_clear(sk_adrs, SLH_ADRS_TYPE_WOTS_PRF);
324
219k
    adrsf->copy_keypair_address(sk_adrs, adrs);
325
326
11.6M
    for (i = 0; i < len; ++i) { /* len = 2n + 3 */
327
11.4M
        set_chain_address(sk_adrs, (uint32_t)i);
328
329
        /* PRF */
330
11.4M
        *ctx = *sctx;
331
11.4M
        ossl_sha3_absorb(ctx, sk_adrs, SLH_ADRS_SIZE);
332
11.4M
        ossl_sha3_absorb(ctx, sk_seed, n);
333
11.4M
        ossl_sha3_squeeze(ctx, sk, n);
334
335
11.4M
        set_chain_address(adrs, (uint32_t)i);
336
182M
        for (j = 0; j < NIBBLE_MASK; ++j) {
337
171M
            set_hash_address(adrs, (uint32_t)j);
338
            /* F */
339
171M
            *ctx = *sctx;
340
171M
            ossl_sha3_absorb(ctx, adrs, SLH_ADRS_SIZE);
341
171M
            ossl_sha3_absorb(ctx, sk, n);
342
171M
            ossl_sha3_squeeze(ctx, sk, n);
343
171M
        }
344
11.4M
        memcpy(pk_out, sk, n);
345
11.4M
        pk_out += n;
346
11.4M
    }
347
219k
    ret = 1;
348
219k
    OPENSSL_cleanse(sk, sizeof(sk));
349
219k
    return ret;
350
219k
}
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
21.0M
{
356
21.0M
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
357
358
21.0M
    *sctx = *((SHA256_CTX *)hctx->shactx_pkseed);
359
21.0M
    SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE);
360
21.0M
    SHA256_Update(sctx, m1, m1_len);
361
21.0M
    sha256_final(sctx, out, hctx->key->params->n);
362
21.0M
    return 1;
363
21.0M
}
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.08M
{
369
3.08M
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
370
3.08M
    const SLH_DSA_PARAMS *prms = hctx->key->params;
371
3.08M
    size_t n = prms->n;
372
373
3.08M
    *sctx = *((SHA256_CTX *)hctx->shactx_pkseed);
374
3.08M
    SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE);
375
3.08M
    SHA256_Update(sctx, m1, n);
376
3.08M
    SHA256_Update(sctx, m2, n);
377
3.08M
    sha256_final(sctx, out, n);
378
3.08M
    return 1;
379
3.08M
}
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
14.8M
{
385
14.8M
    SHA512_CTX *sctx = (SHA512_CTX *)(hctx->scratch);
386
14.8M
    const SLH_DSA_PARAMS *prms = hctx->key->params;
387
14.8M
    size_t n = prms->n;
388
389
14.8M
    SHA512_Init(sctx);
390
14.8M
    SHA512_Update(sctx, pk_seed, n);
391
14.8M
    SHA512_Update(sctx, zeros, 128 - n);
392
14.8M
    SHA512_Update(sctx, adrs, SLH_ADRSC_SIZE);
393
14.8M
    SHA512_Update(sctx, m1, n);
394
14.8M
    SHA512_Update(sctx, m2, n);
395
14.8M
    sha512_final(sctx, out, n);
396
14.8M
    return 1;
397
14.8M
}
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
249k
{
403
249k
    SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch);
404
405
249k
    *sctx = *((SHA256_CTX *)hctx->shactx_pkseed);
406
249k
    SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE);
407
249k
    SHA256_Update(sctx, ml, ml_len);
408
249k
    sha256_final(sctx, out, hctx->key->params->n);
409
249k
    return 1;
410
249k
}
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
167k
{
416
167k
    SHA512_CTX *sctx = (SHA512_CTX *)(hctx->scratch);
417
167k
    const SLH_DSA_PARAMS *prms = hctx->key->params;
418
167k
    size_t n = prms->n;
419
420
167k
    SHA512_Init(sctx);
421
167k
    SHA512_Update(sctx, pk_seed, n);
422
167k
    SHA512_Update(sctx, zeros, 128 - n);
423
167k
    SHA512_Update(sctx, adrs, SLH_ADRSC_SIZE);
424
167k
    SHA512_Update(sctx, ml, ml_len);
425
167k
    sha512_final(sctx, out, hctx->key->params->n);
426
167k
    return 1;
427
167k
}
428
429
static int slh_hash_shake_precache(SLH_DSA_HASH_CTX *hctx, const uint8_t *pkseed, size_t n)
430
499
{
431
499
    KECCAK1600_CTX *ctx = NULL, *seedctx = NULL, *scratch = NULL;
432
433
499
    ctx = ossl_shake256_new();
434
499
    if (ctx == NULL)
435
0
        return 0;
436
499
    seedctx = OPENSSL_memdup(ctx, sizeof(*ctx));
437
499
    scratch = OPENSSL_malloc(sizeof(*scratch));
438
499
    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
499
    ossl_sha3_absorb(seedctx, pkseed, n);
445
499
    hctx->shactx = (void *)ctx;
446
499
    hctx->shactx_pkseed = (void *)seedctx;
447
499
    hctx->shactx_len = sizeof(*ctx);
448
499
    hctx->scratch = (void *)scratch;
449
499
    hctx->scratch_len = sizeof(*scratch);
450
499
    return 1;
451
499
}
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
943
{
484
943
    SHA256_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
485
    /* The scratch context is also used as a SHA512_CTX by category 3 and 5 */
486
943
    size_t scratch_len = sizeof(SHA512_CTX);
487
488
943
    if (ctx == NULL)
489
0
        return 0;
490
943
    if ((hctx->scratch = OPENSSL_malloc(scratch_len)) == NULL) {
491
0
        OPENSSL_free(ctx);
492
0
        return 0;
493
0
    }
494
943
    hctx->scratch_len = scratch_len;
495
943
    SHA256_Init(ctx);
496
943
    SHA256_Update(ctx, pkseed, n);
497
943
    SHA256_Update(ctx, zeros, 64 - n);
498
943
    hctx->shactx_pkseed = (void *)ctx;
499
943
    hctx->shactx_len = sizeof(*ctx);
500
943
    return 1;
501
943
}
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
50.9k
{
530
50.9k
    static const SLH_HASH_FUNC methods[] = {
531
50.9k
        { slh_hash_shake_precache,
532
50.9k
            slh_hash_shake_dup,
533
50.9k
            slh_hmsg_shake,
534
50.9k
            slh_prf_shake,
535
50.9k
            slh_prf_msg_shake,
536
50.9k
            slh_f_shake,
537
50.9k
            slh_h_shake,
538
50.9k
            slh_f_shake,
539
50.9k
            slh_wots_pk_gen_shake },
540
50.9k
        { slh_hash_sha256_precache,
541
50.9k
            slh_hash_sha256_dup,
542
50.9k
            slh_hmsg_sha256,
543
50.9k
            slh_prf_sha256,
544
50.9k
            slh_prf_msg_sha2,
545
50.9k
            slh_f_sha256,
546
50.9k
            slh_h_sha256,
547
50.9k
            slh_t_sha256,
548
50.9k
            slh_wots_pk_gen_sha2 },
549
50.9k
        { slh_hash_sha256_precache,
550
50.9k
            slh_hash_sha256_dup,
551
50.9k
            slh_hmsg_sha512,
552
50.9k
            slh_prf_sha256,
553
50.9k
            slh_prf_msg_sha2,
554
50.9k
            slh_f_sha256,
555
50.9k
            slh_h_sha512,
556
50.9k
            slh_t_sha512,
557
50.9k
            slh_wots_pk_gen_sha2 }
558
50.9k
    };
559
50.9k
    return &methods[is_shake ? 0 : (security_category == 1 ? 1 : 2)];
560
50.9k
}