Commit ce5c66d7 authored by Niels Möller's avatar Niels Möller

Implemented handling of NETTLE_FAT_OVERRIDE.

parent 68aa75e3
2015-01-20 Niels Möller <nisse@lysator.liu.se>
* fat-x86_64.c (get_x86_features): New function. Check
NETTLE_FAT_OVERRIDE environment variable.
(fat_init): Use it.
* fat-setup.h (secure_getenv) [!HAVE_SECURE_GETENV]: Dummy
definition, returning NULL.
(ENV_OVERRIDE): New constant.
* configure.ac: Check for secure_getenv function.
2015-01-19 Niels Möller <nisse@lysator.liu.se>
......
......@@ -70,7 +70,12 @@
# endif
#endif
#if !HAVE_SECURE_GETENV
#define secure_getenv(s) NULL
#endif
#define ENV_VERBOSE "NETTLE_FAT_VERBOSE"
#define ENV_OVERRIDE "NETTLE_FAT_OVERRIDE"
/* DECLARE_FAT_FUNC(name, ftype)
*
......
......@@ -29,6 +29,8 @@
not, see http://www.gnu.org/licenses/.
*/
#define _GNU_SOURCE
#if HAVE_CONFIG_H
# include "config.h"
#endif
......@@ -46,6 +48,61 @@
void _nettle_cpuid (uint32_t input, uint32_t regs[4]);
struct x86_features
{
enum x86_vendor { X86_OTHER, X86_INTEL, X86_AMD } vendor;
int have_aesni;
};
#define SKIP(s, slen, literal, llen) \
(((slen) >= (llen) && memcmp ((s), (literal), llen) == 0) \
? ((slen) -= (llen), (s) += (llen), 1) : 0)
#define MATCH(s, slen, literal, llen) \
((slen) == (llen) && memcmp ((s), (literal), llen) == 0)
static void
get_x86_features (struct x86_features *features)
{
const char *s;
features->vendor = X86_OTHER;
features->have_aesni = 0;
s = secure_getenv (ENV_OVERRIDE);
if (s)
for (;;)
{
const char *sep = strchr (s, ',');
size_t length = sep ? (size_t) (sep - s) : strlen(s);
if (SKIP (s, length, "vendor:", 7))
{
if (MATCH(s, length, "intel", 5))
features->vendor = X86_INTEL;
else if (MATCH(s, length, "amd", 3))
features->vendor = X86_AMD;
}
else if (MATCH (s, length, "aesni", 5))
features->have_aesni = 1;
if (!sep)
break;
s = sep + 1;
}
else
{
uint32_t cpuid_data[4];
_nettle_cpuid (0, cpuid_data);
if (memcmp (cpuid_data + 1, "Genu" "ntel" "ineI", 12) == 0)
features->vendor = X86_INTEL;
else if (memcmp (cpuid_data + 1, "Auth" "cAMD" "enti", 12) == 0)
features->vendor = X86_AMD;
_nettle_cpuid (1, cpuid_data);
if (cpuid_data[2] & 0x02000000)
features->have_aesni = 1;
}
}
DECLARE_FAT_FUNC(_nettle_aes_encrypt, aes_crypt_internal_func)
DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, x86_64)
DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, aesni)
......@@ -66,7 +123,7 @@ static void CONSTRUCTOR
fat_init (void)
{
static volatile int initialized = 0;
uint32_t cpuid_data[4];
struct x86_features features;
int verbose;
if (initialized)
return;
......@@ -76,39 +133,40 @@ fat_init (void)
if (verbose)
fprintf (stderr, "libnettle: fat library initialization.\n");
_nettle_cpuid (1, cpuid_data);
get_x86_features (&features);
if (verbose)
fprintf (stderr, "libnettle: cpuid 1: %08x, %08x, %08x, %08x\n",
cpuid_data[0], cpuid_data[1], cpuid_data[2], cpuid_data[3]);
if (cpuid_data[2] & 0x02000000)
{
const char * const vendor_names[3] =
{ "other", "intel", "amd" };
fprintf (stderr, "libnettle: cpu features: vendor:%s%s\n",
vendor_names[features.vendor],
features.have_aesni ? ",aesni" : "");
}
if (features.have_aesni)
{
if (verbose)
fprintf (stderr, "libnettle: aes instructions available.\n");
fprintf (stderr, "libnettle: using aes instructions.\n");
_nettle_aes_encrypt_vec = _nettle_aes_encrypt_aesni;
_nettle_aes_decrypt_vec = _nettle_aes_decrypt_aesni;
}
else
{
if (verbose)
fprintf (stderr, "libnettle: aes instructions not available.\n");
fprintf (stderr, "libnettle: not using aes instructions.\n");
_nettle_aes_encrypt_vec = _nettle_aes_encrypt_x86_64;
_nettle_aes_decrypt_vec = _nettle_aes_decrypt_x86_64;
}
_nettle_cpuid (0, cpuid_data);
if (memcmp(&cpuid_data[1], "Genu", 4) == 0 &&
memcmp(&cpuid_data[3], "ineI", 4) == 0 &&
memcmp(&cpuid_data[2], "ntel", 4) == 0)
if (features.vendor == X86_INTEL)
{
if (verbose)
fprintf (stderr, "libnettle: intel SSE2 will be used for XOR.\n");
fprintf (stderr, "libnettle: intel SSE2 will be used for memxor.\n");
nettle_memxor_vec = _nettle_memxor_sse2;
}
else
{
if (verbose)
fprintf (stderr, "libnettle: intel SSE2 will not be used for XOR.\n");
fprintf (stderr, "libnettle: intel SSE2 will not be used for memxor.\n");
nettle_memxor_vec = _nettle_memxor_x86_64;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment