Coverage Report

Created: 2023-03-26 07:33

/src/nettle/fat-setup.h
Line
Count
Source (jump to first uncovered line)
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
2
#define ENV_VERBOSE "NETTLE_FAT_VERBOSE"
94
2
#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
0
  {               \
143
0
    return name##_vec args;         \
144
0
  }                \
Unexecuted instantiation: nettle_aes128_encrypt
Unexecuted instantiation: nettle_aes128_decrypt
Unexecuted instantiation: nettle_aes192_encrypt
Unexecuted instantiation: nettle_aes192_decrypt
Unexecuted instantiation: nettle_aes256_encrypt
Unexecuted instantiation: nettle_aes256_decrypt
Unexecuted instantiation: nettle_cbc_aes128_encrypt
Unexecuted instantiation: nettle_cbc_aes192_encrypt
Unexecuted instantiation: nettle_cbc_aes256_encrypt
Unexecuted instantiation: nettle_memxor
Unexecuted instantiation: nettle_sha1_compress
Unexecuted instantiation: _nettle_sha256_compress_n
Unexecuted instantiation: _nettle_ghash_set_key
Unexecuted instantiation: _nettle_ghash_update
145
0
  static rtype name##_init prototype {       \
146
0
    if (getenv (ENV_VERBOSE))          \
147
0
      fprintf (stderr, "libnettle: "#name"_init\n");   \
148
0
    if (name##_vec == name##_init)        \
149
0
      fat_init();           \
150
0
    assert (name##_vec != name##_init);       \
151
0
    return name##_vec args;         \
152
0
  }
Unexecuted instantiation: fat-x86_64.c:nettle_aes128_encrypt_init
Unexecuted instantiation: fat-x86_64.c:nettle_aes128_decrypt_init
Unexecuted instantiation: fat-x86_64.c:nettle_aes192_encrypt_init
Unexecuted instantiation: fat-x86_64.c:nettle_aes192_decrypt_init
Unexecuted instantiation: fat-x86_64.c:nettle_aes256_encrypt_init
Unexecuted instantiation: fat-x86_64.c:nettle_aes256_decrypt_init
Unexecuted instantiation: fat-x86_64.c:nettle_cbc_aes128_encrypt_init
Unexecuted instantiation: fat-x86_64.c:nettle_cbc_aes192_encrypt_init
Unexecuted instantiation: fat-x86_64.c:nettle_cbc_aes256_encrypt_init
Unexecuted instantiation: fat-x86_64.c:nettle_sha1_compress_init
Unexecuted instantiation: fat-x86_64.c:_nettle_sha256_compress_n_init
Unexecuted instantiation: fat-x86_64.c:_nettle_ghash_set_key_init
Unexecuted instantiation: fat-x86_64.c:_nettle_ghash_update_init
Unexecuted instantiation: fat-x86_64.c:nettle_memxor_init
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
166
struct gcm_key;
167
typedef void ghash_set_key_func (struct gcm_key *ctx, const union nettle_block16 *key);
168
typedef const uint8_t *
169
ghash_update_func (const struct gcm_key *ctx, union nettle_block16 *state,
170
       size_t blocks, const uint8_t *data);
171
172
typedef void *(memxor_func)(void *dst, const void *src, size_t n);
173
typedef void *(memxor3_func)(void *dst_in, const void *a_in, const void *b_in, size_t n);
174
175
typedef void salsa20_core_func (uint32_t *dst, const uint32_t *src, unsigned rounds);
176
typedef void salsa20_crypt_func (struct salsa20_ctx *ctx, unsigned rounds,
177
         size_t length, uint8_t *dst,
178
         const uint8_t *src);
179
180
typedef void sha1_compress_func(uint32_t *state, const uint8_t *input);
181
typedef const uint8_t *
182
sha256_compress_n_func(uint32_t *state, const uint32_t *k,
183
           size_t blocks, const uint8_t *input);
184
185
struct sha3_state;
186
typedef void sha3_permute_func (struct sha3_state *state);
187
188
typedef void sha512_compress_func (uint64_t *state, const uint8_t *input, const uint64_t *k);
189
190
typedef uint64_t umac_nh_func (const uint32_t *key, unsigned length, const uint8_t *msg);
191
typedef void umac_nh_n_func (uint64_t *out, unsigned n, const uint32_t *key,
192
           unsigned length, const uint8_t *msg);
193
194
typedef void chacha_core_func(uint32_t *dst, const uint32_t *src, unsigned rounds);
195
196
typedef void chacha_crypt_func(struct chacha_ctx *ctx,
197
             size_t length,
198
             uint8_t *dst,
199
             const uint8_t *src);
200
201
struct poly1305_ctx;
202
typedef void poly1305_set_key_func(struct poly1305_ctx *ctx, const uint8_t *key);
203
typedef void poly1305_digest_func(struct poly1305_ctx *ctx, union nettle_block16 *s);
204
typedef void poly1305_block_func(struct poly1305_ctx *ctx, const uint8_t *m,
205
           unsigned high);
206
typedef const uint8_t * poly1305_blocks_func(struct poly1305_ctx *ctx, size_t blocks,
207
           const uint8_t *m);
208
209
struct aes128_ctx;
210
typedef void aes128_set_key_func (struct aes128_ctx *ctx, const uint8_t *key);
211
typedef void aes128_invert_key_func (struct aes128_ctx *dst, const struct aes128_ctx *src);
212
typedef void aes128_crypt_func (const struct aes128_ctx *ctx, size_t length, uint8_t *dst,
213
         const uint8_t *src);
214
215
struct aes192_ctx;
216
typedef void aes192_set_key_func (struct aes192_ctx *ctx, const uint8_t *key);
217
typedef void aes192_invert_key_func (struct aes192_ctx *dst, const struct aes192_ctx *src);
218
typedef void aes192_crypt_func (const struct aes192_ctx *ctx, size_t length, uint8_t *dst,
219
         const uint8_t *src);
220
221
struct aes256_ctx;
222
typedef void aes256_set_key_func (struct aes256_ctx *ctx, const uint8_t *key);
223
typedef void aes256_invert_key_func (struct aes256_ctx *dst, const struct aes256_ctx *src);
224
typedef void aes256_crypt_func (const struct aes256_ctx *ctx, size_t length, uint8_t *dst,
225
         const uint8_t *src);
226
227
typedef void cbc_aes128_encrypt_func (const struct aes128_ctx *ctx, uint8_t *iv,
228
              size_t length, uint8_t *dst, const uint8_t *src);
229
typedef void cbc_aes192_encrypt_func (const struct aes192_ctx *ctx, uint8_t *iv,
230
              size_t length, uint8_t *dst, const uint8_t *src);
231
typedef void cbc_aes256_encrypt_func (const struct aes256_ctx *ctx, uint8_t *iv,
232
              size_t length, uint8_t *dst, const uint8_t *src);