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;
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)
64 get_x86_features (struct x86_features *features)
67 features->vendor = X86_OTHER;
68 features->have_aesni = 0;
70 s = secure_getenv (ENV_OVERRIDE);
74 const char *sep = strchr (s, ',');
75 size_t length = sep ? (size_t) (sep - s) : strlen(s);
77 if (SKIP (s, length, "vendor:", 7))
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;
85 else if (MATCH (s, length, "aesni", 5))
86 features->have_aesni = 1;
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;
100 _nettle_cpuid (1, cpuid_data);
101 if (cpuid_data[2] & 0x02000000)
102 features->have_aesni = 1;
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)
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)
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)
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
122 static void CONSTRUCTOR
125 struct x86_features features;
128 /* FIXME: Replace all getenv calls by getenv_secure? */
129 verbose = getenv (ENV_VERBOSE) != NULL;
131 fprintf (stderr, "libnettle: fat library initialization.\n");
133 get_x86_features (&features);
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" : "");
142 if (features.have_aesni)
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;
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;
157 if (features.vendor == X86_INTEL)
160 fprintf (stderr, "libnettle: intel SSE2 will be used for memxor.\n");
161 nettle_memxor_vec = _nettle_memxor_sse2;
166 fprintf (stderr, "libnettle: intel SSE2 will not be used for memxor.\n");
167 nettle_memxor_vec = _nettle_memxor_x86_64;
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,
176 (rounds, keys, T, length, dst, src))
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,
183 (rounds, keys, T, length, dst, src))
185 DEFINE_FAT_FUNC(nettle_memxor, void *,
186 (void *dst, const void *src, size_t n),