Leancrypto 0.12.0
Post-Quantum Cryptographic Library
Loading...
Searching...
No Matches
lc_sym.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 - 2024, Stephan Mueller <smueller@chronox.de>
3 *
4 * License: see COPYING 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_SYM_H
21#define _LC_SYM_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_sym_state;
33struct lc_sym {
34 void (*init)(struct lc_sym_state *ctx);
35 int (*setkey)(struct lc_sym_state *ctx, const uint8_t *key,
36 size_t keylen);
37 int (*setiv)(struct lc_sym_state *ctx, const uint8_t *iv, size_t ivlen);
38 void (*encrypt)(struct lc_sym_state *ctx, const uint8_t *in,
39 uint8_t *out, size_t len);
40 void (*decrypt)(struct lc_sym_state *ctx, const uint8_t *in,
41 uint8_t *out, size_t len);
42 unsigned int statesize;
43 unsigned int blocksize;
44};
45
46struct lc_sym_ctx {
47 const struct lc_sym *sym;
48 struct lc_sym_state *sym_state;
49};
50
51/*
52 * Align the lc_sym_state structure to 8 bytes boundary irrespective where
53 * it is embedded into. This is achieved by adding 7 more bytes than necessary
54 * to LC_ALIGNED_SYM_BUFFER and then adjusting the pointer offset in that range
55 * accordingly.
56 *
57 * TODO: make this adjustable with a lc_sym->alignment setting - but the
58 * question is which pre-processor macro to use to select the proper
59 * LC_ALIGN_PTR_XX macro depending on lc_sym->alignment during compile time.
60 */
61#ifndef LC_SYM_ALIGNMENT_COMMON
62#define LC_SYM_ALIGNMENT_COMMON (8)
63#endif
64#define LC_SYM_ALIGNMENT(symname) LC_SYM_ALIGNMENT_COMMON
65#define LC_SYM_ALIGNMASK(symname) (LC_SYM_ALIGNMENT(symname) - 1)
66
67#define LC_ALIGN_SYM_MASK(p, symname) \
68 LC_ALIGN_PTR_64(p, LC_SYM_ALIGNMASK(symname))
69
70#define LC_SYM_STATE_SIZE_NONALIGNED(x) ((unsigned long)(x->statesize))
71#define LC_SYM_STATE_SIZE(x) \
72 (LC_SYM_STATE_SIZE_NONALIGNED(x) + LC_SYM_ALIGNMENT_COMMON)
73#define LC_SYM_CTX_SIZE_NONALIGNED(x) \
74 (sizeof(struct lc_sym_ctx) + LC_SYM_STATE_SIZE_NONALIGNED(x))
75#define LC_SYM_CTX_SIZE(x) (sizeof(struct lc_sym_ctx) + LC_SYM_STATE_SIZE(x))
76
82#define LC_ALIGNED_SYM_BUFFER(name, symname, size) \
83 uint64_t name[(size + sizeof(uint64_t) - 1) / sizeof(uint64_t)] \
84 __attribute__((aligned(LC_SYM_ALIGNMENT(symname))))
85
86#define _LC_SYM_SET_CTX(name, symname, ctx, offset) \
87 name->sym_state = (struct lc_sym_state *)LC_ALIGN_SYM_MASK( \
88 ((uint8_t *)(ctx)) + (offset), symname); \
89 name->sym = symname
90
91#define LC_SYM_SET_CTX(name, symname) \
92 _LC_SYM_SET_CTX(name, symname, name, sizeof(struct lc_sym_ctx))
94
118static inline void lc_sym_init(struct lc_sym_ctx *ctx)
119{
120 const struct lc_sym *sym = ctx->sym;
121
122 sym->init(ctx->sym_state);
123}
124
136static inline int lc_sym_setkey(struct lc_sym_ctx *ctx, const uint8_t *key,
137 size_t keylen)
138{
139 const struct lc_sym *sym = ctx->sym;
140
141 return sym->setkey(ctx->sym_state, key, keylen);
142}
143
155static inline int lc_sym_setiv(struct lc_sym_ctx *ctx, const uint8_t *iv,
156 size_t ivlen)
157{
158 const struct lc_sym *sym = ctx->sym;
159
160 return sym->setiv(ctx->sym_state, iv, ivlen);
161}
162
176static inline void lc_sym_encrypt(struct lc_sym_ctx *ctx, const uint8_t *in,
177 uint8_t *out, size_t len)
178{
179 const struct lc_sym *sym = ctx->sym;
180
181 sym->encrypt(ctx->sym_state, in, out, len);
182}
183
197static inline void lc_sym_decrypt(struct lc_sym_ctx *ctx, const uint8_t *in,
198 uint8_t *out, size_t len)
199{
200 const struct lc_sym *sym = ctx->sym;
201
202 sym->decrypt(ctx->sym_state, in, out, len);
203}
204
212static inline void lc_sym_zero(struct lc_sym_ctx *ctx)
213{
214 const struct lc_sym *sym = ctx->sym;
215
216 lc_memset_secure((uint8_t *)ctx + sizeof(struct lc_sym_ctx), 0,
217 LC_SYM_STATE_SIZE_NONALIGNED(sym));
218}
219
229int lc_sym_alloc(const struct lc_sym *sym, struct lc_sym_ctx **ctx);
230
238void lc_sym_zero_free(struct lc_sym_ctx *ctx);
239
248#define LC_SYM_CTX_ON_STACK(name, symname) \
249 _Pragma("GCC diagnostic push") \
250 _Pragma("GCC diagnostic ignored \"-Wvla\"") _Pragma( \
251 "GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \
252 LC_ALIGNED_SYM_BUFFER( \
253 name##_ctx_buf, symname, \
254 LC_SYM_CTX_SIZE_NONALIGNED(symname)); \
255 struct lc_sym_ctx *name = (struct lc_sym_ctx *)name##_ctx_buf; \
256 LC_SYM_SET_CTX(name, symname); \
257 lc_sym_zero(name); \
258 _Pragma("GCC diagnostic pop")
259
260#ifdef __cplusplus
261}
262#endif
263
264#endif /* _LC_SYM_H */
static void lc_sym_decrypt(struct lc_sym_ctx *ctx, const uint8_t *in, uint8_t *out, size_t len)
Symmetric decryption.
Definition lc_sym.h:197
static void lc_sym_init(struct lc_sym_ctx *ctx)
Initialize symmetric context.
Definition lc_sym.h:118
static void lc_sym_encrypt(struct lc_sym_ctx *ctx, const uint8_t *in, uint8_t *out, size_t len)
Symmetric encryption.
Definition lc_sym.h:176
void lc_sym_zero_free(struct lc_sym_ctx *ctx)
Symmetric algorithm deallocation and properly zeroization function to frees all buffers and the ciphe...
static int lc_sym_setiv(struct lc_sym_ctx *ctx, const uint8_t *iv, size_t ivlen)
Set IV.
Definition lc_sym.h:155
static int lc_sym_setkey(struct lc_sym_ctx *ctx, const uint8_t *key, size_t keylen)
Set key.
Definition lc_sym.h:136
int lc_sym_alloc(const struct lc_sym *sym, struct lc_sym_ctx **ctx)
Allocate symmetric algorithm context on heap.
static void lc_sym_zero(struct lc_sym_ctx *ctx)
Zeroize symmetric context allocated with either LC_SYM_CTX_ON_STACK or lc_sym_alloc.
Definition lc_sym.h:212
static void lc_memset_secure(void *s, int c, size_t n)