Add GOST R 34.11-94 to nettle_hashes
[gd/nettle] / 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 /* DECLARE_FAT_FUNC(name, ftype)
97  *
98  *   name is the public function, e.g., _nettle_aes_encrypt.
99  *   ftype is its type, e.g., aes_crypt_internal_func.
100  *
101  * DECLARE_FAT_VAR(name, type, var)
102  *
103  *   name is name without _nettle prefix.
104  *   type is its type.
105  *   var is the variant, used as a suffix on the symbol name.
106  *
107  * DEFINE_FAT_FUNC(name, rtype, prototype, args)
108  *
109  *   name is the public function.
110  *   rtype its return type.
111  *   prototype is the list of formal arguments, with types.
112  *   args contain the argument list without any types.
113  */
114
115 #if HAVE_LINK_IFUNC
116 #define IFUNC(resolve) __attribute__ ((ifunc (resolve)))
117 #define DECLARE_FAT_FUNC(name, ftype)   \
118   ftype name IFUNC(#name"_resolve");    \
119   static ftype *name##_vec = NULL;
120
121 #define DEFINE_FAT_FUNC(name, rtype, prototype, args)             \
122   static void_func * name##_resolve(void)                         \
123   {                                                               \
124     if (getenv (ENV_VERBOSE))                                     \
125       fprintf (stderr, "libnettle: "#name"_resolve\n");           \
126     if (!name##_vec)                                              \
127       fat_init();                                                 \
128     return (void_func *) name##_vec;                              \
129   }
130
131 #else /* !HAVE_LINK_IFUNC */
132 #define DECLARE_FAT_FUNC(name, ftype)           \
133   ftype name;                                   \
134   static ftype name##_init;                     \
135   static ftype *name##_vec = name##_init;                               
136
137 #define DEFINE_FAT_FUNC(name, rtype, prototype, args)           \
138   rtype name prototype                                          \
139   {                                                             \
140     return name##_vec args;                                     \
141   }                                                             \
142   static rtype name##_init prototype {                          \
143     if (getenv (ENV_VERBOSE))                                   \
144       fprintf (stderr, "libnettle: "#name"_init\n");            \
145     if (name##_vec == name##_init)                              \
146       fat_init();                                               \
147     assert (name##_vec != name##_init);                         \
148     return name##_vec args;                                     \
149   }
150 #endif /* !HAVE_LINK_IFUNC */
151
152 #define DECLARE_FAT_FUNC_VAR(name, type, var)   \
153        type _nettle_##name##_##var;
154
155 typedef void void_func (void);
156
157 typedef void aes_crypt_internal_func (unsigned rounds, const uint32_t *keys,
158                                       const struct aes_table *T,
159                                       size_t length, uint8_t *dst,
160                                       const uint8_t *src);
161
162 typedef void *(memxor_func)(void *dst, const void *src, size_t n);
163
164 typedef void salsa20_core_func (uint32_t *dst, const uint32_t *src, unsigned rounds);
165
166 typedef void sha1_compress_func(uint32_t *state, const uint8_t *input);
167 typedef void sha256_compress_func(uint32_t *state, const uint8_t *input, const uint32_t *k);
168
169 struct sha3_state;
170 typedef void sha3_permute_func (struct sha3_state *state);
171
172 typedef void sha512_compress_func (uint64_t *state, const uint8_t *input, const uint64_t *k);
173
174 typedef uint64_t umac_nh_func (const uint32_t *key, unsigned length, const uint8_t *msg);
175 typedef void umac_nh_n_func (uint64_t *out, unsigned n, const uint32_t *key,
176                              unsigned length, const uint8_t *msg);
177
178 typedef void chacha_core_func(uint32_t *dst, const uint32_t *src, unsigned rounds);