3 Copyright (C) 2015 Niels Möller
5 This file is part of GNU Nettle.
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
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.
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.
20 or both in parallel, as here.
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.
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/.
43 #include "nettle-types.h"
45 #include "aes-internal.h"
47 #include "fat-setup.h"
49 void _nettle_cpuid (uint32_t input, uint32_t regs[4]);
53 enum x86_vendor { X86_OTHER, X86_INTEL, X86_AMD } vendor;
58 #define SKIP(s, slen, literal, llen) \
59 (((slen) >= (llen) && memcmp ((s), (literal), llen) == 0) \
60 ? ((slen) -= (llen), (s) += (llen), 1) : 0)
61 #define MATCH(s, slen, literal, llen) \
62 ((slen) == (llen) && memcmp ((s), (literal), llen) == 0)
65 get_x86_features (struct x86_features *features)
68 features->vendor = X86_OTHER;
69 features->have_aesni = 0;
70 features->have_sha_ni = 0;
72 s = secure_getenv (ENV_OVERRIDE);
76 const char *sep = strchr (s, ',');
77 size_t length = sep ? (size_t) (sep - s) : strlen(s);
79 if (SKIP (s, length, "vendor:", 7))
81 if (MATCH(s, length, "intel", 5))
82 features->vendor = X86_INTEL;
83 else if (MATCH(s, length, "amd", 3))
84 features->vendor = X86_AMD;
87 else if (MATCH (s, length, "aesni", 5))
88 features->have_aesni = 1;
89 else if (MATCH (s, length, "sha_ni", 6))
90 features->have_sha_ni = 1;
97 uint32_t cpuid_data[4];
98 _nettle_cpuid (0, cpuid_data);
99 if (memcmp (cpuid_data + 1, "Genu" "ntel" "ineI", 12) == 0)
100 features->vendor = X86_INTEL;
101 else if (memcmp (cpuid_data + 1, "Auth" "cAMD" "enti", 12) == 0)
102 features->vendor = X86_AMD;
104 _nettle_cpuid (1, cpuid_data);
105 if (cpuid_data[2] & 0x02000000)
106 features->have_aesni = 1;
108 _nettle_cpuid (7, cpuid_data);
109 if (cpuid_data[1] & 0x20000000)
110 features->have_sha_ni = 1;
114 DECLARE_FAT_FUNC(_nettle_aes_encrypt, aes_crypt_internal_func)
115 DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, x86_64)
116 DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, aesni)
118 DECLARE_FAT_FUNC(_nettle_aes_decrypt, aes_crypt_internal_func)
119 DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, x86_64)
120 DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, aesni)
122 DECLARE_FAT_FUNC(nettle_memxor, memxor_func)
123 DECLARE_FAT_FUNC_VAR(memxor, memxor_func, x86_64)
124 DECLARE_FAT_FUNC_VAR(memxor, memxor_func, sse2)
126 DECLARE_FAT_FUNC(nettle_sha1_compress, sha1_compress_func)
127 DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, x86_64)
128 DECLARE_FAT_FUNC_VAR(sha1_compress, sha1_compress_func, sha_ni)
130 DECLARE_FAT_FUNC(_nettle_sha256_compress, sha256_compress_func)
131 DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, x86_64)
132 DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, sha_ni)
134 /* This function should usually be called only once, at startup. But
135 it is idempotent, and on x86, pointer updates are atomic, so
136 there's no danger if it is called simultaneously from multiple
138 static void CONSTRUCTOR
141 struct x86_features features;
144 /* FIXME: Replace all getenv calls by getenv_secure? */
145 verbose = getenv (ENV_VERBOSE) != NULL;
147 fprintf (stderr, "libnettle: fat library initialization.\n");
149 get_x86_features (&features);
152 const char * const vendor_names[3] =
153 { "other", "intel", "amd" };
154 fprintf (stderr, "libnettle: cpu features: vendor:%s%s%s\n",
155 vendor_names[features.vendor],
156 features.have_aesni ? ",aesni" : "",
157 features.have_sha_ni ? ",sha_ni" : "");
159 if (features.have_aesni)
162 fprintf (stderr, "libnettle: using aes instructions.\n");
163 _nettle_aes_encrypt_vec = _nettle_aes_encrypt_aesni;
164 _nettle_aes_decrypt_vec = _nettle_aes_decrypt_aesni;
169 fprintf (stderr, "libnettle: not using aes instructions.\n");
170 _nettle_aes_encrypt_vec = _nettle_aes_encrypt_x86_64;
171 _nettle_aes_decrypt_vec = _nettle_aes_decrypt_x86_64;
174 if (features.have_sha_ni)
177 fprintf (stderr, "libnettle: using sha_ni instructions.\n");
178 nettle_sha1_compress_vec = _nettle_sha1_compress_sha_ni;
179 _nettle_sha256_compress_vec = _nettle_sha256_compress_sha_ni;
184 fprintf (stderr, "libnettle: not using sha_ni instructions.\n");
185 nettle_sha1_compress_vec = _nettle_sha1_compress_x86_64;
186 _nettle_sha256_compress_vec = _nettle_sha256_compress_x86_64;
188 if (features.vendor == X86_INTEL)
191 fprintf (stderr, "libnettle: intel SSE2 will be used for memxor.\n");
192 nettle_memxor_vec = _nettle_memxor_sse2;
197 fprintf (stderr, "libnettle: intel SSE2 will not be used for memxor.\n");
198 nettle_memxor_vec = _nettle_memxor_x86_64;
202 DEFINE_FAT_FUNC(_nettle_aes_encrypt, void,
203 (unsigned rounds, const uint32_t *keys,
204 const struct aes_table *T,
205 size_t length, uint8_t *dst,
207 (rounds, keys, T, length, dst, src))
209 DEFINE_FAT_FUNC(_nettle_aes_decrypt, void,
210 (unsigned rounds, const uint32_t *keys,
211 const struct aes_table *T,
212 size_t length, uint8_t *dst,
214 (rounds, keys, T, length, dst, src))
216 DEFINE_FAT_FUNC(nettle_memxor, void *,
217 (void *dst, const void *src, size_t n),
220 DEFINE_FAT_FUNC(nettle_sha1_compress, void,
221 (uint32_t *state, const uint8_t *input),
224 DEFINE_FAT_FUNC(_nettle_sha256_compress, void,
225 (uint32_t *state, const uint8_t *input, const uint32_t *k),