Leancrypto 1.6.0
Post-Quantum Cryptographic Library
Loading...
Searching...
No Matches
lc_hash.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020 - 2025, Stephan Mueller <smueller@chronox.de>
3 *
4 * License: see LICENSE file in root directory
5 *
6 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
7 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
9 * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
10 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
11 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
12 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
13 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
14 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
16 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
17 * DAMAGE.
18 */
19
20#ifndef LC_HASH_H
21#define LC_HASH_H
22
23#include "ext_headers.h"
24#include "lc_memset_secure.h"
25#include "lc_memory_support.h"
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
32struct lc_hash {
33 /* SHA3 / SHAKE interface */
34 int (*init)(void *state);
35 int (*init_nocheck)(void *state);
36 void (*update)(void *state, const uint8_t *in, size_t inlen);
37 void (*final)(void *state, uint8_t *digest);
38 void (*set_digestsize)(void *state, size_t digestsize);
39 size_t (*get_digestsize)(void *state);
40
41 /* Sponge interface */
42 void (*sponge_permutation)(void *state, unsigned int rounds);
43 void (*sponge_add_bytes)(void *state, const uint8_t *data,
44 size_t offset, size_t length);
45 void (*sponge_extract_bytes)(const void *state, uint8_t *data,
46 size_t offset, size_t length);
47 void (*sponge_newstate)(void *state, const uint8_t *newstate,
48 size_t offset, size_t length);
49 uint64_t algorithm_type;
50
51 uint8_t sponge_rate;
52 unsigned short statesize;
53};
54
55struct lc_hash_ctx {
56 const struct lc_hash *hash;
57 void *hash_state;
58};
59
60/*
61 * Align the hash_state pointer to 8 bytes boundary irrespective where
62 * it is embedded into. This is achieved by adding 7 more bytes than necessary
63 * to LC_ALIGNED_BUFFER and then adjusting the pointer offset in that range
64 * accordingly.
65 *
66 * It is permissible to set the alignment requirement with compile-time
67 * arguments.
68 */
69#ifndef LC_HASH_COMMON_ALIGNMENT
70/* Macro set during leancrypto compile time for target platform */
71#define LC_HASH_COMMON_ALIGNMENT 8
72#endif
73
74#define LC_ALIGN_HASH_MASK(p) \
75 LC_ALIGN_PTR_64(p, LC_ALIGNMENT_MASK(LC_HASH_COMMON_ALIGNMENT))
76
77#define LC_SHA_MAX_SIZE_DIGEST 64
78
79/*
80 * This is the source of the compiler warning of using Variable-Length-Arrays
81 * (VLA). It is considered to be harmless to have this VLA here. If you do not
82 * want it, you have the following options:
83 *
84 * 1. Define a hard-coded value here, e.g. sizeof(struct lc_sha3_224_state)
85 * as the SHA3-224 has the largest structure.
86 * 2. Only use the SHA-specific stack allocation functions
87 * (e.g. LC_SHA3_256_CTX_ON_STACK) instead of the generic
88 * LC_HASH_CTX_ON_STACK call.
89 * 3. Do not use stack-allocation function.
90 * 4. Ignore the warning by using
91 * #pragma GCC diagnostic push
92 * #pragma GCC diagnostic ignored "-Wvla"
93 * LC_HASH_CTX_ON_STACK()
94 * #pragma GCC diagnostic pop
95 */
96#define LC_HASH_STATE_SIZE_NONALIGNED(x) ((unsigned long)(x->statesize))
97#define LC_HASH_STATE_SIZE(x) \
98 (LC_HASH_STATE_SIZE_NONALIGNED(x) + LC_HASH_COMMON_ALIGNMENT)
99#define LC_HASH_CTX_SIZE(x) (sizeof(struct lc_hash_ctx) + LC_HASH_STATE_SIZE(x))
100
101#define _LC_HASH_SET_CTX(name, hashname, ctx, offset) \
102 name->hash_state = LC_ALIGN_HASH_MASK(((uint8_t *)(ctx)) + (offset)); \
103 name->hash = hashname
104
105#define LC_HASH_SET_CTX(name, hashname) \
106 _LC_HASH_SET_CTX(name, hashname, name, sizeof(struct lc_hash_ctx))
108
121
134int lc_hash_init(struct lc_hash_ctx *hash_ctx);
135
145void lc_hash_update(struct lc_hash_ctx *hash_ctx, const uint8_t *in,
146 size_t inlen);
147
178void lc_hash_final(struct lc_hash_ctx *hash_ctx, uint8_t *digest);
179
188void lc_hash_set_digestsize(struct lc_hash_ctx *hash_ctx, size_t digestsize);
189
197size_t lc_hash_digestsize(struct lc_hash_ctx *hash_ctx);
198
207unsigned int lc_hash_blocksize(struct lc_hash_ctx *hash_ctx);
208
216unsigned int lc_hash_ctxsize(struct lc_hash_ctx *hash_ctx);
217
225void lc_hash_zero(struct lc_hash_ctx *hash_ctx);
226
236#define LC_HASH_CTX_ON_STACK(name, hashname) \
237 _Pragma("GCC diagnostic push") \
238 _Pragma("GCC diagnostic ignored \"-Wvla\"") _Pragma( \
239 "GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
240 LC_ALIGNED_BUFFER(name##_ctx_buf, \
241 LC_HASH_CTX_SIZE(hashname), \
242 LC_HASH_COMMON_ALIGNMENT); \
243 struct lc_hash_ctx *name = (struct lc_hash_ctx *)name##_ctx_buf; \
244 LC_HASH_SET_CTX(name, hashname); \
245 _Pragma("GCC diagnostic pop")
246
258int lc_hash_alloc(const struct lc_hash *hash, struct lc_hash_ctx **hash_ctx);
259
266void lc_hash_zero_free(struct lc_hash_ctx *hash_ctx);
267
283int lc_hash(const struct lc_hash *hash, const uint8_t *in, size_t inlen,
284 uint8_t *digest);
285
301int lc_xof(const struct lc_hash *xof, const uint8_t *in, size_t inlen,
302 uint8_t *digest, size_t digestlen);
303
322int lc_sponge(const struct lc_hash *hash, void *state, unsigned int rounds);
323
348int lc_sponge_add_bytes(const struct lc_hash *hash, void *state,
349 const uint8_t *data, size_t offset, size_t length);
350
373int lc_sponge_extract_bytes(const struct lc_hash *hash, const void *state,
374 uint8_t *data, size_t offset, size_t length);
375
393int lc_sponge_newstate(const struct lc_hash *hash, void *state,
394 const uint8_t *data, size_t offset, size_t length);
395
404uint64_t lc_hash_algorithm_type(const struct lc_hash *hash);
405
414uint64_t lc_hash_ctx_algorithm_type(const struct lc_hash_ctx *ctx);
415
416
417#ifdef __cplusplus
418}
419#endif
420
421#endif /* LC_HASH_H */
void lc_hash_update(struct lc_hash_ctx *hash_ctx, const uint8_t *in, size_t inlen)
Update hash.
int lc_sponge(const struct lc_hash *hash, void *state, unsigned int rounds)
Perform Sponge permutation on buffer.
unsigned int lc_hash_blocksize(struct lc_hash_ctx *hash_ctx)
Get the block size of the message digest (or the "rate" in terms of Sponge-based algorithms).
void lc_hash_zero(struct lc_hash_ctx *hash_ctx)
Zeroize Hash context allocated with either LC_HASH_CTX_ON_STACK or lc_hmac_alloc.
int lc_hash_alloc(const struct lc_hash *hash, struct lc_hash_ctx **hash_ctx)
Allocate Hash context on heap.
int lc_xof(const struct lc_hash *xof, const uint8_t *in, size_t inlen, uint8_t *digest, size_t digestlen)
Calculate message digest for an XOF - one-shot.
void lc_hash_set_digestsize(struct lc_hash_ctx *hash_ctx, size_t digestsize)
Set the size of the message digest - this call is intended for SHAKE.
int lc_hash(const struct lc_hash *hash, const uint8_t *in, size_t inlen, uint8_t *digest)
Calculate message digest - one-shot.
uint64_t lc_hash_algorithm_type(const struct lc_hash *hash)
Obtain algorithm type usable with lc_alg_status.
unsigned int lc_hash_ctxsize(struct lc_hash_ctx *hash_ctx)
Get the context size of the message digest implementation.
int lc_hash_init(struct lc_hash_ctx *hash_ctx)
Initialize hash context.
void lc_hash_final(struct lc_hash_ctx *hash_ctx, uint8_t *digest)
Calculate message digest.
int lc_sponge_extract_bytes(const struct lc_hash *hash, const void *state, uint8_t *data, size_t offset, size_t length)
Function to retrieve data from the state. The bit positions that are retrieved by this function are f...
int lc_sponge_add_bytes(const struct lc_hash *hash, void *state, const uint8_t *data, size_t offset, size_t length)
Function to add (in GF(2), using bitwise exclusive-or) data given as bytes into the sponge state.
uint64_t lc_hash_ctx_algorithm_type(const struct lc_hash_ctx *ctx)
Obtain algorithm type usable with lc_alg_status.
int lc_sponge_newstate(const struct lc_hash *hash, void *state, const uint8_t *data, size_t offset, size_t length)
Function to insert a complete new sponge state.
void lc_hash_zero_free(struct lc_hash_ctx *hash_ctx)
Zeroize and free hash context.
size_t lc_hash_digestsize(struct lc_hash_ctx *hash_ctx)
Get the size of the message digest.