Coverage Report

Created: 2026-02-26 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libsodium/src/libsodium/crypto_pwhash/argon2/blake2b-long.c
Line
Count
Source
1
#include <limits.h>
2
#include <stdint.h>
3
#include <stdlib.h>
4
#include <string.h>
5
6
#include "crypto_generichash_blake2b.h"
7
#include "private/common.h"
8
#include "utils.h"
9
10
#include "blake2b-long.h"
11
12
int
13
blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen)
14
0
{
15
0
    uint8_t *out = (uint8_t *) pout;
16
0
    crypto_generichash_blake2b_state blake_state;
17
0
    uint8_t outlen_bytes[4 /* sizeof(uint32_t) */] = { 0 };
18
0
    int     ret = -1;
19
20
0
    if (outlen > UINT32_MAX) {
21
0
        goto fail; /* LCOV_EXCL_LINE */
22
0
    }
23
24
    /* Ensure little-endian byte order! */
25
0
    STORE32_LE(outlen_bytes, (uint32_t) outlen);
26
27
0
#define TRY(statement)   \
28
0
    do {                 \
29
0
        ret = statement; \
30
0
        if (ret < 0) {   \
31
0
            goto fail;   \
32
0
        }                \
33
0
    } while ((void) 0, 0)
34
35
0
    if (outlen <= crypto_generichash_blake2b_BYTES_MAX) {
36
0
        TRY(crypto_generichash_blake2b_init(&blake_state, NULL, 0U, outlen));
37
0
        TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes,
38
0
                                              sizeof(outlen_bytes)));
39
0
        TRY(crypto_generichash_blake2b_update(
40
0
            &blake_state, (const unsigned char *) in, inlen));
41
0
        TRY(crypto_generichash_blake2b_final(&blake_state, out, outlen));
42
0
    } else {
43
0
        uint32_t toproduce;
44
0
        uint8_t  out_buffer[crypto_generichash_blake2b_BYTES_MAX];
45
0
        uint8_t  in_buffer[crypto_generichash_blake2b_BYTES_MAX];
46
0
        TRY(crypto_generichash_blake2b_init(
47
0
            &blake_state, NULL, 0U, crypto_generichash_blake2b_BYTES_MAX));
48
0
        TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes,
49
0
                                              sizeof(outlen_bytes)));
50
0
        TRY(crypto_generichash_blake2b_update(
51
0
            &blake_state, (const unsigned char *) in, inlen));
52
0
        TRY(crypto_generichash_blake2b_final(
53
0
            &blake_state, out_buffer, crypto_generichash_blake2b_BYTES_MAX));
54
0
        memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2);
55
0
        out += crypto_generichash_blake2b_BYTES_MAX / 2;
56
0
        toproduce =
57
0
            (uint32_t) outlen - crypto_generichash_blake2b_BYTES_MAX / 2;
58
59
0
        while (toproduce > crypto_generichash_blake2b_BYTES_MAX) {
60
0
            memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX);
61
0
            TRY(crypto_generichash_blake2b(
62
0
                out_buffer, crypto_generichash_blake2b_BYTES_MAX, in_buffer,
63
0
                crypto_generichash_blake2b_BYTES_MAX, NULL, 0U));
64
0
            memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2);
65
0
            out += crypto_generichash_blake2b_BYTES_MAX / 2;
66
0
            toproduce -= crypto_generichash_blake2b_BYTES_MAX / 2;
67
0
        }
68
69
0
        memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX);
70
0
        TRY(crypto_generichash_blake2b(out_buffer, toproduce, in_buffer,
71
0
                                       crypto_generichash_blake2b_BYTES_MAX,
72
0
                                       NULL, 0U));
73
0
        memcpy(out, out_buffer, toproduce);
74
0
    }
75
0
fail:
76
0
    sodium_memzero(&blake_state, sizeof(blake_state));
77
0
    return ret;
78
0
#undef TRY
79
0
}