Update mini-gmp version for _rsa_sec_compute_root_tr rename.
[gd/nettle] / fat-x86_64.c
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 "memxor.h"
47 #include "fat-setup.h"
48
49 void _nettle_cpuid (uint32_t input, uint32_t regs[4]);
50
51 struct x86_features
52 {
53   enum x86_vendor { X86_OTHER, X86_INTEL, X86_AMD } vendor;
54   int have_aesni;
55 };
56
57 #define SKIP(s, slen, literal, llen)                            \
58   (((slen) >= (llen) && memcmp ((s), (literal), llen) == 0)     \
59    ? ((slen) -= (llen), (s) += (llen), 1) : 0)
60 #define MATCH(s, slen, literal, llen)                           \
61   ((slen) == (llen) && memcmp ((s), (literal), llen) == 0)
62
63 static void
64 get_x86_features (struct x86_features *features)
65 {
66   const char *s;
67   features->vendor = X86_OTHER;
68   features->have_aesni = 0;
69
70   s = secure_getenv (ENV_OVERRIDE);
71   if (s)
72     for (;;)
73       {
74         const char *sep = strchr (s, ',');
75         size_t length = sep ? (size_t) (sep - s) : strlen(s);
76
77         if (SKIP (s, length, "vendor:", 7))
78           {
79             if (MATCH(s, length, "intel", 5))
80               features->vendor = X86_INTEL;
81             else if (MATCH(s, length, "amd", 3))
82               features->vendor = X86_AMD;
83             
84           }
85         else if (MATCH (s, length, "aesni", 5))
86           features->have_aesni = 1;
87         if (!sep)
88           break;
89         s = sep + 1;    
90       }
91   else
92     {
93       uint32_t cpuid_data[4];
94       _nettle_cpuid (0, cpuid_data);
95       if (memcmp (cpuid_data + 1, "Genu" "ntel" "ineI", 12) == 0)
96         features->vendor = X86_INTEL;
97       else if (memcmp (cpuid_data + 1, "Auth" "cAMD" "enti", 12) == 0)
98         features->vendor = X86_AMD;
99
100       _nettle_cpuid (1, cpuid_data);
101       if (cpuid_data[2] & 0x02000000)
102         features->have_aesni = 1;      
103     }
104 }
105
106 DECLARE_FAT_FUNC(_nettle_aes_encrypt, aes_crypt_internal_func)
107 DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, x86_64)
108 DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, aesni)
109
110 DECLARE_FAT_FUNC(_nettle_aes_decrypt, aes_crypt_internal_func)
111 DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, x86_64)
112 DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, aesni)
113
114 DECLARE_FAT_FUNC(nettle_memxor, memxor_func)
115 DECLARE_FAT_FUNC_VAR(memxor, memxor_func, x86_64)
116 DECLARE_FAT_FUNC_VAR(memxor, memxor_func, sse2)
117
118 /* This function should usually be called only once, at startup. But
119    it is idempotent, and on x86, pointer updates are atomic, so
120    there's no danger if it is called simultaneously from multiple
121    threads. */
122 static void CONSTRUCTOR
123 fat_init (void)
124 {
125   struct x86_features features;
126   int verbose;
127
128   /* FIXME: Replace all getenv calls by getenv_secure? */
129   verbose = getenv (ENV_VERBOSE) != NULL;
130   if (verbose)
131     fprintf (stderr, "libnettle: fat library initialization.\n");
132
133   get_x86_features (&features);
134   if (verbose)
135     {
136       const char * const vendor_names[3] =
137         { "other", "intel", "amd" };
138       fprintf (stderr, "libnettle: cpu features: vendor:%s%s\n",
139                vendor_names[features.vendor],
140                features.have_aesni ? ",aesni" : "");
141     }
142   if (features.have_aesni)
143     {
144       if (verbose)
145         fprintf (stderr, "libnettle: using aes instructions.\n");
146       _nettle_aes_encrypt_vec = _nettle_aes_encrypt_aesni;
147       _nettle_aes_decrypt_vec = _nettle_aes_decrypt_aesni;
148     }
149   else
150     {
151       if (verbose)
152         fprintf (stderr, "libnettle: not using aes instructions.\n");
153       _nettle_aes_encrypt_vec = _nettle_aes_encrypt_x86_64;
154       _nettle_aes_decrypt_vec = _nettle_aes_decrypt_x86_64;
155     }
156
157   if (features.vendor == X86_INTEL)
158     {
159       if (verbose)
160         fprintf (stderr, "libnettle: intel SSE2 will be used for memxor.\n");
161       nettle_memxor_vec = _nettle_memxor_sse2;
162     }
163   else
164     {
165       if (verbose)
166         fprintf (stderr, "libnettle: intel SSE2 will not be used for memxor.\n");
167       nettle_memxor_vec = _nettle_memxor_x86_64;
168     }
169 }
170
171 DEFINE_FAT_FUNC(_nettle_aes_encrypt, void,
172                 (unsigned rounds, const uint32_t *keys,
173                  const struct aes_table *T,
174                  size_t length, uint8_t *dst,
175                  const uint8_t *src),
176                 (rounds, keys, T, length, dst, src))
177
178 DEFINE_FAT_FUNC(_nettle_aes_decrypt, void,
179                 (unsigned rounds, const uint32_t *keys,
180                  const struct aes_table *T,
181                  size_t length, uint8_t *dst,
182                  const uint8_t *src),
183                 (rounds, keys, T, length, dst, src))
184
185 DEFINE_FAT_FUNC(nettle_memxor, void *,
186                 (void *dst, const void *src, size_t n),
187                 (dst, src, n))