Coverage Report

Created: 2023-03-26 08:33

/src/nettle/fat-x86_64.c
Line
Count
Source (jump to first uncovered line)
1
/* fat-x86_64.c
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
#define _GNU_SOURCE
33
34
#if HAVE_CONFIG_H
35
# include "config.h"
36
#endif
37
38
#include <assert.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <string.h>
42
43
#include "nettle-types.h"
44
45
#include "aes-internal.h"
46
#include "ghash-internal.h"
47
#include "memxor.h"
48
#include "fat-setup.h"
49
50
void _nettle_cpuid (uint32_t input, uint32_t regs[4]);
51
52
struct x86_features
53
{
54
  enum x86_vendor { X86_OTHER, X86_INTEL, X86_AMD } vendor;
55
  int have_aesni;
56
  int have_sha_ni;
57
  int have_pclmul;
58
};
59
60
#define SKIP(s, slen, literal, llen)        \
61
0
  (((slen) >= (llen) && memcmp ((s), (literal), llen) == 0) \
62
0
   ? ((slen) -= (llen), (s) += (llen), 1) : 0)
63
#define MATCH(s, slen, literal, llen)       \
64
0
  ((slen) == (llen) && memcmp ((s), (literal), llen) == 0)
65
66
static void
67
get_x86_features (struct x86_features *features)
68
20
{
69
20
  const char *s;
70
20
  features->vendor = X86_OTHER;
71
20
  features->have_aesni = 0;
72
20
  features->have_sha_ni = 0;
73
20
  features->have_pclmul = 0;
74
75
20
  s = secure_getenv (ENV_OVERRIDE);
76
20
  if (s)
77
0
    for (;;)
78
0
      {
79
0
  const char *sep = strchr (s, ',');
80
0
  size_t length = sep ? (size_t) (sep - s) : strlen(s);
81
82
0
  if (SKIP (s, length, "vendor:", 7))
83
0
    {
84
0
      if (MATCH(s, length, "intel", 5))
85
0
        features->vendor = X86_INTEL;
86
0
      else if (MATCH(s, length, "amd", 3))
87
0
        features->vendor = X86_AMD;
88
      
89
0
    }
90
0
  else if (MATCH (s, length, "aesni", 5))
91
0
    features->have_aesni = 1;
92
0
  else if (MATCH (s, length, "sha_ni", 6))
93
0
    features->have_sha_ni = 1;
94
0
  else if (MATCH (s, length, "pclmul", 6))
95
0
    features->have_pclmul = 1;
96
0
  if (!sep)
97
0
    break;
98
0
  s = sep + 1;
99
0
      }
100
20
  else
101
20
    {
102
20
      uint32_t cpuid_data[4];
103
20
      _nettle_cpuid (0, cpuid_data);
104
20
      if (memcmp (cpuid_data + 1, "Genu" "ntel" "ineI", 12) == 0)
105
0
  features->vendor = X86_INTEL;
106
20
      else if (memcmp (cpuid_data + 1, "Auth" "cAMD" "enti", 12) == 0)
107
20
  features->vendor = X86_AMD;
108
109
20
      _nettle_cpuid (1, cpuid_data);
110
20
      if (cpuid_data[2] & 0x2)
111
20
  features->have_pclmul = 1;
112
20
      if (cpuid_data[2] & 0x02000000)
113
20
  features->have_aesni = 1;
114
115
20
      _nettle_cpuid (7, cpuid_data);
116
20
      if (cpuid_data[1] & 0x20000000)
117
20
  features->have_sha_ni = 1;
118
20
    }
119
20
}
120
121
DECLARE_FAT_FUNC(nettle_aes128_encrypt, aes128_crypt_func)
122
DECLARE_FAT_FUNC(nettle_aes128_decrypt, aes128_crypt_func)
123
DECLARE_FAT_FUNC_VAR(aes128_encrypt, aes128_crypt_func, c)
124
DECLARE_FAT_FUNC_VAR(aes128_encrypt, aes128_crypt_func, aesni)
125
DECLARE_FAT_FUNC_VAR(aes128_decrypt, aes128_crypt_func, c)
126
DECLARE_FAT_FUNC_VAR(aes128_decrypt, aes128_crypt_func, aesni)
127
DECLARE_FAT_FUNC(nettle_aes192_encrypt, aes192_crypt_func)
128
DECLARE_FAT_FUNC(nettle_aes192_decrypt, aes192_crypt_func)
129
DECLARE_FAT_FUNC_VAR(aes192_encrypt, aes192_crypt_func, c)
130
DECLARE_FAT_FUNC_VAR(aes192_encrypt, aes192_crypt_func, aesni)
131
DECLARE_FAT_FUNC_VAR(aes192_decrypt, aes192_crypt_func, c)
132
DECLARE_FAT_FUNC_VAR(aes192_decrypt, aes192_crypt_func, aesni)
133
DECLARE_FAT_FUNC(nettle_aes256_encrypt, aes256_crypt_func)
134
DECLARE_FAT_FUNC(nettle_aes256_decrypt, aes256_crypt_func)
135
DECLARE_FAT_FUNC_VAR(aes256_encrypt, aes256_crypt_func, c)
136
DECLARE_FAT_FUNC_VAR(aes256_encrypt, aes256_crypt_func, aesni)
137
DECLARE_FAT_FUNC_VAR(aes256_decrypt, aes256_crypt_func, c)
138
DECLARE_FAT_FUNC_VAR(aes256_decrypt, aes256_crypt_func, aesni)
139
140
DECLARE_FAT_FUNC(nettle_cbc_aes128_encrypt, cbc_aes128_encrypt_func);
141
DECLARE_FAT_FUNC_VAR(cbc_aes128_encrypt, cbc_aes128_encrypt_func, c);
142
DECLARE_FAT_FUNC_VAR(cbc_aes128_encrypt, cbc_aes128_encrypt_func, aesni);
143
DECLARE_FAT_FUNC(nettle_cbc_aes192_encrypt, cbc_aes192_encrypt_func);
144
DECLARE_FAT_FUNC_VAR(cbc_aes192_encrypt, cbc_aes192_encrypt_func, c);
145
DECLARE_FAT_FUNC_VAR(cbc_aes192_encrypt, cbc_aes192_encrypt_func, aesni);
146
DECLARE_FAT_FUNC(nettle_cbc_aes256_encrypt, cbc_aes256_encrypt_func);
147
DECLARE_FAT_FUNC_VAR(cbc_aes256_encrypt, cbc_aes256_encrypt_func, c);
148
DECLARE_FAT_FUNC_VAR(cbc_aes256_encrypt, cbc_aes256_encrypt_func, aesni);
149
150
DECLARE_FAT_FUNC(nettle_memxor, memxor_func)
151
DECLARE_FAT_FUNC_VAR(memxor, memxor_func, x86_64)
152
DECLARE_FAT_FUNC_VAR(memxor, memxor_func, sse2)
153
154
DECLARE_FAT_FUNC(nettle_sha1_compress, sha1_compress_func)
155
DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, x86_64)
156
DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, sha_ni)
157
158
DECLARE_FAT_FUNC(_nettle_sha256_compress_n, sha256_compress_n_func)
159
DECLARE_FAT_FUNC_VAR(sha256_compress_n, sha256_compress_n_func, x86_64)
160
DECLARE_FAT_FUNC_VAR(sha256_compress_n, sha256_compress_n_func, sha_ni)
161
162
DECLARE_FAT_FUNC(_nettle_ghash_set_key, ghash_set_key_func)
163
DECLARE_FAT_FUNC_VAR(ghash_set_key, ghash_set_key_func, c)
164
DECLARE_FAT_FUNC_VAR(ghash_set_key, ghash_set_key_func, pclmul)
165
166
DECLARE_FAT_FUNC(_nettle_ghash_update, ghash_update_func)
167
DECLARE_FAT_FUNC_VAR(ghash_update, ghash_update_func, table)
168
DECLARE_FAT_FUNC_VAR(ghash_update, ghash_update_func, pclmul)
169
170
171
/* This function should usually be called only once, at startup. But
172
   it is idempotent, and on x86, pointer updates are atomic, so
173
   there's no danger if it is called simultaneously from multiple
174
   threads. */
175
static void CONSTRUCTOR
176
fat_init (void)
177
20
{
178
20
  struct x86_features features;
179
20
  int verbose;
180
181
  /* FIXME: Replace all getenv calls by getenv_secure? */
182
20
  verbose = getenv (ENV_VERBOSE) != NULL;
183
20
  if (verbose)
184
0
    fprintf (stderr, "libnettle: fat library initialization.\n");
185
186
20
  get_x86_features (&features);
187
20
  if (verbose)
188
0
    {
189
0
      const char * const vendor_names[3] =
190
0
  { "other", "intel", "amd" };
191
0
      fprintf (stderr, "libnettle: cpu features: vendor:%s%s%s%s\n",
192
0
         vendor_names[features.vendor],
193
0
         features.have_aesni ? ",aesni" : "",
194
0
         features.have_sha_ni ? ",sha_ni" : "",
195
0
         features.have_pclmul ? ",pclmul" : "");
196
0
    }
197
20
  if (features.have_aesni)
198
20
    {
199
20
      if (verbose)
200
0
  fprintf (stderr, "libnettle: using aes instructions.\n");
201
20
      nettle_aes128_encrypt_vec = _nettle_aes128_encrypt_aesni;
202
20
      nettle_aes128_decrypt_vec = _nettle_aes128_decrypt_aesni;
203
20
      nettle_aes192_encrypt_vec = _nettle_aes192_encrypt_aesni;
204
20
      nettle_aes192_decrypt_vec = _nettle_aes192_decrypt_aesni;
205
20
      nettle_aes256_encrypt_vec = _nettle_aes256_encrypt_aesni;
206
20
      nettle_aes256_decrypt_vec = _nettle_aes256_decrypt_aesni;
207
20
      nettle_cbc_aes128_encrypt_vec = _nettle_cbc_aes128_encrypt_aesni;
208
20
      nettle_cbc_aes192_encrypt_vec = _nettle_cbc_aes192_encrypt_aesni;
209
20
      nettle_cbc_aes256_encrypt_vec = _nettle_cbc_aes256_encrypt_aesni;
210
20
    }
211
0
  else
212
0
    {
213
0
      if (verbose)
214
0
  fprintf (stderr, "libnettle: not using aes instructions.\n");
215
0
      nettle_aes128_encrypt_vec = _nettle_aes128_encrypt_c;
216
0
      nettle_aes128_decrypt_vec = _nettle_aes128_decrypt_c;
217
0
      nettle_aes192_encrypt_vec = _nettle_aes192_encrypt_c;
218
0
      nettle_aes192_decrypt_vec = _nettle_aes192_decrypt_c;
219
0
      nettle_aes256_encrypt_vec = _nettle_aes256_encrypt_c;
220
0
      nettle_aes256_decrypt_vec = _nettle_aes256_decrypt_c;
221
0
      nettle_cbc_aes128_encrypt_vec = _nettle_cbc_aes128_encrypt_c;
222
0
      nettle_cbc_aes192_encrypt_vec = _nettle_cbc_aes192_encrypt_c;
223
0
      nettle_cbc_aes256_encrypt_vec = _nettle_cbc_aes256_encrypt_c;
224
0
    }
225
226
20
  if (features.have_sha_ni)
227
20
    {
228
20
      if (verbose)
229
0
  fprintf (stderr, "libnettle: using sha_ni instructions.\n");
230
20
      nettle_sha1_compress_vec = _nettle_sha1_compress_sha_ni;
231
20
      _nettle_sha256_compress_n_vec = _nettle_sha256_compress_n_sha_ni;
232
20
    }
233
0
  else
234
0
    {
235
0
      if (verbose)
236
0
  fprintf (stderr, "libnettle: not using sha_ni instructions.\n");
237
0
      nettle_sha1_compress_vec = _nettle_sha1_compress_x86_64;
238
0
      _nettle_sha256_compress_n_vec = _nettle_sha256_compress_n_x86_64;
239
0
    }
240
241
20
  if (features.have_pclmul)
242
20
    {
243
20
      if (verbose)
244
0
  fprintf (stderr, "libnettle: using pclmulqdq instructions.\n");
245
20
      _nettle_ghash_set_key_vec = _nettle_ghash_set_key_pclmul;
246
20
      _nettle_ghash_update_vec = _nettle_ghash_update_pclmul;
247
20
    }
248
0
  else
249
0
    {
250
0
      if (verbose)
251
0
  fprintf (stderr, "libnettle: not using pclmulqdq instructions.\n");
252
0
      _nettle_ghash_set_key_vec = _nettle_ghash_set_key_c;
253
0
      _nettle_ghash_update_vec = _nettle_ghash_update_table;
254
0
    }
255
256
20
  if (features.vendor == X86_INTEL)
257
0
    {
258
0
      if (verbose)
259
0
  fprintf (stderr, "libnettle: intel SSE2 will be used for memxor.\n");
260
0
      nettle_memxor_vec = _nettle_memxor_sse2;
261
0
    }
262
20
  else
263
20
    {
264
20
      if (verbose)
265
0
  fprintf (stderr, "libnettle: intel SSE2 will not be used for memxor.\n");
266
20
      nettle_memxor_vec = _nettle_memxor_x86_64;
267
20
    }
268
20
}
269
270
DEFINE_FAT_FUNC(nettle_aes128_encrypt, void,
271
 (const struct aes128_ctx *ctx, size_t length,
272
  uint8_t *dst,const uint8_t *src),
273
 (ctx, length, dst, src))
274
DEFINE_FAT_FUNC(nettle_aes128_decrypt, void,
275
 (const struct aes128_ctx *ctx, size_t length,
276
  uint8_t *dst,const uint8_t *src),
277
 (ctx, length, dst, src))
278
279
DEFINE_FAT_FUNC(nettle_aes192_encrypt, void,
280
 (const struct aes192_ctx *ctx, size_t length,
281
  uint8_t *dst,const uint8_t *src),
282
 (ctx, length, dst, src))
283
DEFINE_FAT_FUNC(nettle_aes192_decrypt, void,
284
 (const struct aes192_ctx *ctx, size_t length,
285
  uint8_t *dst,const uint8_t *src),
286
 (ctx, length, dst, src))
287
288
DEFINE_FAT_FUNC(nettle_aes256_encrypt, void,
289
 (const struct aes256_ctx *ctx, size_t length,
290
  uint8_t *dst,const uint8_t *src),
291
 (ctx, length, dst, src))
292
DEFINE_FAT_FUNC(nettle_aes256_decrypt, void,
293
 (const struct aes256_ctx *ctx, size_t length,
294
  uint8_t *dst,const uint8_t *src),
295
 (ctx, length, dst, src))
296
297
DEFINE_FAT_FUNC(nettle_cbc_aes128_encrypt, void,
298
 (const struct aes128_ctx *ctx, uint8_t *iv,
299
  size_t length, uint8_t *dst, const uint8_t *src),
300
 (ctx, iv, length, dst, src))
301
DEFINE_FAT_FUNC(nettle_cbc_aes192_encrypt, void,
302
 (const struct aes192_ctx *ctx, uint8_t *iv,
303
  size_t length, uint8_t *dst, const uint8_t *src),
304
 (ctx, iv, length, dst, src))
305
DEFINE_FAT_FUNC(nettle_cbc_aes256_encrypt, void,
306
 (const struct aes256_ctx *ctx, uint8_t *iv,
307
  size_t length, uint8_t *dst, const uint8_t *src),
308
 (ctx, iv, length, dst, src))
309
310
DEFINE_FAT_FUNC(nettle_memxor, void *,
311
    (void *dst, const void *src, size_t n),
312
    (dst, src, n))
313
314
DEFINE_FAT_FUNC(nettle_sha1_compress, void,
315
    (uint32_t *state, const uint8_t *input),
316
    (state, input))
317
318
DEFINE_FAT_FUNC(_nettle_sha256_compress_n, const uint8_t *,
319
    (uint32_t *state, const uint32_t *k,
320
     size_t blocks, const uint8_t *input),
321
    (state, k, blocks, input))
322
323
DEFINE_FAT_FUNC(_nettle_ghash_set_key, void,
324
    (struct gcm_key *ctx, const union nettle_block16 *key),
325
    (ctx, key))
326
DEFINE_FAT_FUNC(_nettle_ghash_update, const uint8_t *,
327
    (const struct gcm_key *ctx, union nettle_block16 *state,
328
     size_t blocks, const uint8_t *data),
329
    (ctx, state, blocks, data))