Leancrypto 0.12.0
Post-Quantum Cryptographic Library
Loading...
Searching...
No Matches
lc_cshake.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 - 2024, 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_CSHAKE_H
21#define LC_CSHAKE_H
22
23#include "lc_hash.h"
24#include "lc_sha3.h"
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
60void lc_cshake_init(struct lc_hash_ctx *ctx, const uint8_t *n, size_t nlen,
61 const uint8_t *s, size_t slen);
62
74static inline void lc_cshake_final(struct lc_hash_ctx *ctx, uint8_t *out,
75 size_t outlen)
76{
77 lc_hash_set_digestsize(ctx, outlen);
78 lc_hash_final(ctx, out);
79}
80
81/*
82 * Separate cSHAKE API with re-initialization support
83 *
84 * Re-initialization means that any state created by the init operation can be
85 * re-established during re-init.
86 */
88struct lc_cshake_ctx {
89 uint8_t *shadow_ctx;
90 struct lc_hash_ctx hash_ctx;
91};
92
93#define LC_CSHAKE_STATE_SIZE(x) (LC_HASH_STATE_SIZE(x))
94#define LC_CSHAKE_STATE_SIZE_REINIT(x) (2 * LC_HASH_STATE_SIZE(x))
95#define LC_CSHAKE_CTX_SIZE(x) \
96 (LC_CSHAKE_STATE_SIZE(x) + sizeof(struct lc_cshake_ctx))
97#define LC_CSHAKE_CTX_SIZE_REINIT(x) \
98 (LC_CSHAKE_STATE_SIZE_REINIT(x) + sizeof(struct lc_cshake_ctx))
99
100#define _LC_CSHAKE_SET_CTX(name, hashname, ctx, offset) \
101 _LC_HASH_SET_CTX((&name->hash_ctx), hashname, ctx, offset); \
102 name->shadow_ctx = NULL
103
104#define LC_CSHAKE_SET_CTX(name, hashname) \
105 _LC_CSHAKE_SET_CTX(name, hashname, name, sizeof(struct lc_cshake_ctx))
106
107#define _LC_CSHAKE_SET_CTX_REINIT(name, hashname, ctx, offset) \
108 _LC_HASH_SET_CTX((&name->hash_ctx), hashname, ctx, offset); \
109 name->shadow_ctx = (uint8_t *)((uint8_t *)ctx + offset + \
110 LC_HASH_STATE_SIZE(hashname))
111
112#define LC_CSHAKE_SET_CTX_REINIT(name, hashname) \
113 _LC_CSHAKE_SET_CTX_REINIT(name, hashname, name, \
114 sizeof(struct lc_cshake_ctx))
116
131void lc_cshake_ctx_init(struct lc_cshake_ctx *cshake_ctx, const uint8_t *n,
132 size_t nlen, const uint8_t *s, size_t slen);
133
143void lc_cshake_ctx_reinit(struct lc_cshake_ctx *cshake_ctx);
144
153void lc_cshake_ctx_update(struct lc_cshake_ctx *cshake_ctx, const uint8_t *in,
154 size_t inlen);
155
167void lc_cshake_ctx_final(struct lc_cshake_ctx *cshake_ctx, uint8_t *out,
168 size_t outlen);
169
182int lc_cshake_ctx_alloc(const struct lc_hash *hash,
183 struct lc_cshake_ctx **cshake_ctx, uint32_t flags);
184
185/*
186 * Support re-initialization of state. You set a key during cshake_init,
187 * perform a full CSHAKE operation. After a cshake_final, the re-initialization
188 * support allows you to call cshake_reinit and reuse the state for a new
189 * operation without providing the keys again. If in doubt, initialize
190 * the context with re-init support. The difference is that more memory is
191 * allocated to retain the initialized state.
192 */
193#define LC_CSHAKE_FLAGS_SUPPORT_REINIT (1 << 0)
194
200void lc_cshake_ctx_zero_free(struct lc_cshake_ctx *cshake_ctx);
201
208static inline void lc_cshake_ctx_zero(struct lc_cshake_ctx *cshake_ctx)
209{
210 struct lc_hash_ctx *hash_ctx;
211 const struct lc_hash *hash;
212
213 if (!cshake_ctx)
214 return;
215 hash_ctx = &cshake_ctx->hash_ctx;
216 hash = hash_ctx->hash;
217
218 lc_memset_secure((uint8_t *)cshake_ctx + sizeof(struct lc_cshake_ctx),
219 0,
220 cshake_ctx->shadow_ctx ?
221 LC_CSHAKE_STATE_SIZE_REINIT(hash) :
222 LC_CSHAKE_STATE_SIZE(hash));
223}
224
235#define LC_CSHAKE_CTX_ON_STACK(name, hashname) \
236 _Pragma("GCC diagnostic push") \
237 _Pragma("GCC diagnostic ignored \"-Wvla\"") _Pragma( \
238 "GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
239 LC_ALIGNED_BUFFER(name##_ctx_buf, \
240 LC_CSHAKE_CTX_SIZE(hashname), \
241 LC_HASH_COMMON_ALIGNMENT); \
242 struct lc_cshake_ctx *name = (struct lc_cshake_ctx *)name##_ctx_buf; \
243 LC_CSHAKE_SET_CTX(name, hashname); \
244 lc_cshake_ctx_zero(name); \
245 _Pragma("GCC diagnostic pop")
246
258#define LC_CSHAKE_CTX_ON_STACK_REINIT(name, hashname) \
259 _Pragma("GCC diagnostic push") \
260 _Pragma("GCC diagnostic ignored \"-Wvla\"") _Pragma( \
261 "GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
262 LC_ALIGNED_BUFFER(name##_ctx_buf, \
263 LC_CSHAKE_CTX_SIZE_REINIT(hashname), \
264 LC_HASH_COMMON_ALIGNMENT); \
265 struct lc_cshake_ctx *name = (struct lc_cshake_ctx *)name##_ctx_buf; \
266 LC_CSHAKE_SET_CTX_REINIT(name, hashname); \
267 lc_cshake_ctx_zero(name); \
268 _Pragma("GCC diagnostic pop")
269
270#ifdef __cplusplus
271}
272#endif
273
274#endif /* LC_CSHAKE_H */
static 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.
Definition lc_hash.h:211
void lc_hash(const struct lc_hash *hash, const uint8_t *in, size_t inlen, uint8_t *digest)
Calculate message digest - one-shot.
static void lc_hash_final(struct lc_hash_ctx *hash_ctx, uint8_t *digest)
Calculate message digest.
Definition lc_hash.h:192
void lc_cshake_ctx_update(struct lc_cshake_ctx *cshake_ctx, const uint8_t *in, size_t inlen)
Update CSHAKE.
int lc_cshake_ctx_alloc(const struct lc_hash *hash, struct lc_cshake_ctx **cshake_ctx, uint32_t flags)
Allocate CSHAKE context on heap.
void lc_cshake_ctx_final(struct lc_cshake_ctx *cshake_ctx, uint8_t *out, size_t outlen)
Generate a cSHAKE message digest from a given state.
void lc_cshake_ctx_zero_free(struct lc_cshake_ctx *cshake_ctx)
Zeroize and free CSHAKE context.
static void lc_cshake_ctx_zero(struct lc_cshake_ctx *cshake_ctx)
Zeroize CSHAKE context allocated with either LC_CSHAKE_CTX_ON_STACK or lc_cshake_alloc.
Definition lc_cshake.h:208
void lc_cshake_init(struct lc_hash_ctx *ctx, const uint8_t *n, size_t nlen, const uint8_t *s, size_t slen)
Initialize the hash state following the cSHAKE specification.
void lc_cshake_ctx_reinit(struct lc_cshake_ctx *cshake_ctx)
Re-initialize CSHAKE context after a cshake_final operation.
void lc_cshake_ctx_init(struct lc_cshake_ctx *cshake_ctx, const uint8_t *n, size_t nlen, const uint8_t *s, size_t slen)
Initialize the hash state with re-init support following the cSHAKE specification.
static void lc_cshake_final(struct lc_hash_ctx *ctx, uint8_t *out, size_t outlen)
Generate a cSHAKE message digest from a given state.
Definition lc_cshake.h:74
static void lc_memset_secure(void *s, int c, size_t n)