]> git.ipfire.org Git - thirdparty/nettle.git/blob - fat-setup.h
Avoid warnings for assert_maybe.
[thirdparty/nettle.git] / fat-setup.h
1 /* fat-setup.h
2
3 Copyright (C) 2015 Niels Möller
4
5 This file is part of GNU Nettle.
6
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
9
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 or
15
16 * the GNU General Public License as published by the Free
17 Software Foundation; either version 2 of the License, or (at your
18 option) any later version.
19
20 or both in parallel, as here.
21
22 GNU Nettle is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
26
27 You should have received copies of the GNU General Public License and
28 the GNU Lesser General Public License along with this program. If
29 not, see http://www.gnu.org/licenses/.
30 */
31
32 /* Fat library initialization works as follows. The main function is
33 fat_init. We try to do initialization only once, but since it is
34 idempotent, there's no harm if it is in some cases called multiple
35 times from several threads. For correctness, we rely on atomic
36 writes, but not on memory barriers or any other synchronization
37 mechanism.
38
39 The fat_init function checks the cpuid flags, and sets function
40 pointers, e.g, _nettle_aes_encrypt_vec, to point to the appropriate
41 implementation.
42
43 To get everything hooked in, we use a belt-and-suspenders approach.
44
45 We try to register fat_init as a constructor function to be called
46 at load time. If this is unavailable or non-working, we instead
47 arrange fat_init to be called lazily.
48
49 For the actual indirection, there are two cases.
50
51 * If ifunc support is available, function pointers are statically
52 initialized to NULL, and we register resolver functions, e.g.,
53 _nettle_aes_encrypt_resolve, which call fat_init, and then return
54 the function pointer, e.g., the value of _nettle_aes_encrypt_vec.
55
56 * If ifunc is not available, we have to define a wrapper function
57 to jump via the function pointer. (FIXME: For internal calls, we
58 could do this as a macro).
59
60 We statically initialize each function pointer to point to a
61 special initialization function, e.g., _nettle_aes_encrypt_init,
62 which calls fat_init, and then invokes the right function. This
63 way, all pointers are setup correctly at the first call to any
64 fat function.
65
66 And atomic writes are required for correctness in the case that
67 several threads do "first call to any fat function" at the same
68 time.
69 */
70
71 #if HAVE_GCC_ATTRIBUTE
72 # define CONSTRUCTOR __attribute__ ((constructor))
73 #else
74 # define CONSTRUCTOR
75 # if defined (__sun)
76 # pragma init(fat_init)
77 # endif
78 #endif
79
80 /* Disable use of ifunc for now. Problem is, there's no guarantee that
81 one can call any libc functions from the ifunc resolver. On x86 and
82 x86_64, the corresponding IRELATIVE relocs are supposed to be
83 processed last, but that doesn't seem to happen, and its a
84 platform-specific feature. To trigger problems, simply try dlopen
85 ("libnettle.so", RTLD_NOW), which crashes in an uninitialized plt
86 entry. */
87 #undef HAVE_LINK_IFUNC
88
89 #if !HAVE_SECURE_GETENV
90 #define secure_getenv(s) NULL
91 #endif
92
93 #define ENV_VERBOSE "NETTLE_FAT_VERBOSE"
94 #define ENV_OVERRIDE "NETTLE_FAT_OVERRIDE"
95
96 struct chacha_ctx;
97 struct salsa20_ctx;
98
99 /* DECLARE_FAT_FUNC(name, ftype)
100 *
101 * name is the public function, e.g., _nettle_aes_encrypt.
102 * ftype is its type, e.g., aes_crypt_internal_func.
103 *
104 * DECLARE_FAT_VAR(name, type, var)
105 *
106 * name is name without _nettle prefix.
107 * type is its type.
108 * var is the variant, used as a suffix on the symbol name.
109 *
110 * DEFINE_FAT_FUNC(name, rtype, prototype, args)
111 *
112 * name is the public function.
113 * rtype its return type.
114 * prototype is the list of formal arguments, with types.
115 * args contain the argument list without any types.
116 */
117
118 #if HAVE_LINK_IFUNC
119 #define IFUNC(resolve) __attribute__ ((ifunc (resolve)))
120 #define DECLARE_FAT_FUNC(name, ftype) \
121 ftype name IFUNC(#name"_resolve"); \
122 static ftype *name##_vec = NULL;
123
124 #define DEFINE_FAT_FUNC(name, rtype, prototype, args) \
125 static void_func * name##_resolve(void) \
126 { \
127 if (getenv (ENV_VERBOSE)) \
128 fprintf (stderr, "libnettle: "#name"_resolve\n"); \
129 if (!name##_vec) \
130 fat_init(); \
131 return (void_func *) name##_vec; \
132 }
133
134 #else /* !HAVE_LINK_IFUNC */
135 #define DECLARE_FAT_FUNC(name, ftype) \
136 ftype name; \
137 static ftype name##_init; \
138 static ftype *name##_vec = name##_init;
139
140 #define DEFINE_FAT_FUNC(name, rtype, prototype, args) \
141 rtype name prototype \
142 { \
143 return name##_vec args; \
144 } \
145 static rtype name##_init prototype { \
146 if (getenv (ENV_VERBOSE)) \
147 fprintf (stderr, "libnettle: "#name"_init\n"); \
148 if (name##_vec == name##_init) \
149 fat_init(); \
150 assert (name##_vec != name##_init); \
151 return name##_vec args; \
152 }
153 #endif /* !HAVE_LINK_IFUNC */
154
155 #define DECLARE_FAT_FUNC_VAR(name, type, var) \
156 type _nettle_##name##_##var;
157
158 typedef void void_func (void);
159
160 struct aes_table;
161 typedef void aes_crypt_internal_func (unsigned rounds, const uint32_t *keys,
162 const struct aes_table *T,
163 size_t length, uint8_t *dst,
164 const uint8_t *src);
165 typedef void aes_invert_internal_func (unsigned rounds, uint32_t *dst, const uint32_t *src);
166
167 struct gcm_key;
168 typedef void ghash_set_key_func (struct gcm_key *ctx, const union nettle_block16 *key);
169 typedef const uint8_t *
170 ghash_update_func (const struct gcm_key *ctx, union nettle_block16 *state,
171 size_t blocks, const uint8_t *data);
172
173 typedef size_t
174 gcm_aes_crypt_func (struct gcm_key *key, unsigned rounds,
175 size_t len, uint8_t *dst, const uint8_t *src);
176
177 typedef void *(memxor_func)(void *dst, const void *src, size_t n);
178 typedef void *(memxor3_func)(void *dst_in, const void *a_in, const void *b_in, size_t n);
179
180 typedef void salsa20_core_func (uint32_t *dst, const uint32_t *src, unsigned rounds);
181 typedef void salsa20_crypt_func (struct salsa20_ctx *ctx, unsigned rounds,
182 size_t length, uint8_t *dst,
183 const uint8_t *src);
184
185 typedef void sha1_compress_func(uint32_t *state, const uint8_t *input);
186 typedef const uint8_t *
187 sha256_compress_n_func(uint32_t *state, const uint32_t *k,
188 size_t blocks, const uint8_t *input);
189
190 struct sha3_state;
191 typedef void sha3_permute_func (struct sha3_state *state);
192
193 typedef void sha512_compress_func (uint64_t *state, const uint8_t *input, const uint64_t *k);
194
195 typedef uint64_t umac_nh_func (const uint32_t *key, unsigned length, const uint8_t *msg);
196 typedef void umac_nh_n_func (uint64_t *out, unsigned n, const uint32_t *key,
197 unsigned length, const uint8_t *msg);
198
199 typedef void chacha_core_func(uint32_t *dst, const uint32_t *src, unsigned rounds);
200
201 typedef void chacha_crypt_func(struct chacha_ctx *ctx,
202 size_t length,
203 uint8_t *dst,
204 const uint8_t *src);
205
206 struct poly1305_ctx;
207 typedef void poly1305_set_key_func(struct poly1305_ctx *ctx, const uint8_t *key);
208 typedef void poly1305_digest_func(struct poly1305_ctx *ctx, union nettle_block16 *s);
209 typedef void poly1305_block_func(struct poly1305_ctx *ctx, const uint8_t *m,
210 unsigned high);
211 typedef const uint8_t * poly1305_blocks_func(struct poly1305_ctx *ctx, size_t blocks,
212 const uint8_t *m);
213
214 struct aes128_ctx;
215 typedef void aes128_set_key_func (struct aes128_ctx *ctx, const uint8_t *key);
216 typedef void aes128_invert_key_func (struct aes128_ctx *dst, const struct aes128_ctx *src);
217 typedef void aes128_crypt_func (const struct aes128_ctx *ctx, size_t length, uint8_t *dst,
218 const uint8_t *src);
219
220 struct aes192_ctx;
221 typedef void aes192_set_key_func (struct aes192_ctx *ctx, const uint8_t *key);
222 typedef void aes192_invert_key_func (struct aes192_ctx *dst, const struct aes192_ctx *src);
223 typedef void aes192_crypt_func (const struct aes192_ctx *ctx, size_t length, uint8_t *dst,
224 const uint8_t *src);
225
226 struct aes256_ctx;
227 typedef void aes256_set_key_func (struct aes256_ctx *ctx, const uint8_t *key);
228 typedef void aes256_invert_key_func (struct aes256_ctx *dst, const struct aes256_ctx *src);
229 typedef void aes256_crypt_func (const struct aes256_ctx *ctx, size_t length, uint8_t *dst,
230 const uint8_t *src);
231
232 typedef void cbc_aes128_encrypt_func (const struct aes128_ctx *ctx, uint8_t *iv,
233 size_t length, uint8_t *dst, const uint8_t *src);
234 typedef void cbc_aes192_encrypt_func (const struct aes192_ctx *ctx, uint8_t *iv,
235 size_t length, uint8_t *dst, const uint8_t *src);
236 typedef void cbc_aes256_encrypt_func (const struct aes256_ctx *ctx, uint8_t *iv,
237 size_t length, uint8_t *dst, const uint8_t *src);