diff --git a/ChangeLog b/ChangeLog index 3150310d9bbcfb532381c4ee1176c06b83cb0e39..79540d5b570548bb016dc9f5ae835c922f5c3b57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2015-01-17 Niels Möller <nisse@lysator.liu.se> + + * fat-x86_64.c: Set up for sse2 vs non-sse2 memxor. Patch by Nikos + Mavrogiannopoulos. + * configure.ac (asm_nettle_optional_list): Added memxor-2.asm. + * x86_64/fat/memxor-2.asm: New file. + * x86_64/fat/memxor.asm: New file. + + * x86_64/memxor.asm: Use ifdef, not ifelse, for testing USE_SSE2. + 2015-01-16 Niels Möller <nisse@lysator.liu.se> * configure.ac (OPT_NETTLE_SOURCES): New substituted variable. diff --git a/configure.ac b/configure.ac index 7b8dc775f46960af6cb34c9f14958b6e12041e56..2ebdb0b0aa44711dcfe82b571bd08db012512fc2 100644 --- a/configure.ac +++ b/configure.ac @@ -299,7 +299,7 @@ asm_replace_list="aes-encrypt-internal.asm aes-decrypt-internal.asm \ # Assembler files which generate additional object files if they are used. asm_nettle_optional_list="gcm-hash8.asm cpuid.asm \ - aes-encrypt-internal-2.asm aes-decrypt-internal-2.asm" + aes-encrypt-internal-2.asm aes-decrypt-internal-2.asm memxor-2.asm" asm_hogweed_optional_list="" if test "x$enable_public_key" = "xyes" ; then asm_hogweed_optional_list="ecc-192-modp.asm ecc-224-modp.asm \ diff --git a/fat-x86_64.c b/fat-x86_64.c index 30d1c249bc56a2d77b638334eabfc53c5606648e..b6c1f44278dba4d6e4956e0f86c6dd92ae8d10c3 100644 --- a/fat-x86_64.c +++ b/fat-x86_64.c @@ -36,6 +36,7 @@ #include <assert.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include "nettle-types.h" @@ -102,6 +103,13 @@ aes_crypt_internal_func _aes_decrypt IFUNC ("_aes_decrypt_resolve"); aes_crypt_internal_func _nettle_aes_decrypt_x86_64; aes_crypt_internal_func _nettle_aes_decrypt_aesni; +typedef void *(memxor_func)(void *dst_in, const void *src_in, size_t n); + +/* FIXME: Fix fat name-mangling to get _nettle prefix. */ +memxor_func nettle_memxor IFUNC ("_memxor_resolve"); +memxor_func nettle_memxor_x86_64; +memxor_func nettle_memxor_sse2; + #if HAVE_LINK_IFUNC #define _aes_encrypt_init NULL #define _aes_decrypt_init NULL @@ -112,6 +120,7 @@ static aes_crypt_internal_func _aes_decrypt_init; static aes_crypt_internal_func *_aes_encrypt_vec = _aes_encrypt_init; static aes_crypt_internal_func *_aes_decrypt_vec = _aes_decrypt_init; +static memxor_func *_memxor_vec = nettle_memxor_x86_64; /* This function should usually be called only once, at startup. But it is idempotent, and on x86, pointer updates are atomic, so @@ -151,6 +160,22 @@ fat_init (void) _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 (verbose) + fprintf (stderr, "libnettle: intel SSE2 will be used for XOR.\n"); + _memxor_vec = nettle_memxor_sse2; + } + else + { + if (verbose) + fprintf (stderr, "libnettle: intel SSE2 will not be used for XOR.\n"); + _memxor_vec = nettle_memxor_x86_64; + } + /* The x86_64 architecture should always make stores visible in the right order to other processors (except for non-temporal stores and the like). So we don't need any memory barrier. */ @@ -177,6 +202,15 @@ _aes_decrypt_resolve (void) return (void_func *) _aes_decrypt_vec; } +static void_func * +_memxor_resolve (void) +{ + if (getenv ("NETTLE_FAT_VERBOSE")) + fprintf (stderr, "libnettle: _memxor_resolve\n"); + fat_init (); + return (void_func *) _memxor_vec; +} + #else /* !HAVE_LINK_IFUNC */ /* We need wrapper functions jumping via the function pointer. */ @@ -224,4 +258,11 @@ _aes_decrypt_init (unsigned rounds, const uint32_t *keys, _aes_decrypt (rounds, keys, T, length, dst, src); } +/* FIXME: Missing _memxor_init. */ +void * +memxor(void *dst_in, const void *src_in, size_t n) +{ + return _memxor_vec (dst_in, src_in, n); +} + #endif /* !HAVE_LINK_IFUNC */ diff --git a/x86_64/fat/memxor-2.asm b/x86_64/fat/memxor-2.asm new file mode 100644 index 0000000000000000000000000000000000000000..ffc844401cb4b3cb1bd9ff93ba4e21d83696f873 --- /dev/null +++ b/x86_64/fat/memxor-2.asm @@ -0,0 +1,36 @@ +C x86_64/fat/memxor-2.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +define(<fat_suffix>, <_sse2>) +define(<USE_SSE2>, <yes>) +include_src(<x86_64/memxor.asm>) diff --git a/x86_64/fat/memxor.asm b/x86_64/fat/memxor.asm new file mode 100644 index 0000000000000000000000000000000000000000..a040bb3958275b035de630e34bd1c767bf9f8d9e --- /dev/null +++ b/x86_64/fat/memxor.asm @@ -0,0 +1,35 @@ +C x86_64/fat/memxor.asm + + +ifelse(< + Copyright (C) 2015 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +>) + +define(<fat_suffix>, <_x86_64>) +include_src(<x86_64/memxor.asm>) diff --git a/x86_64/memxor.asm b/x86_64/memxor.asm index 69d6cfe382a12e8a0d2ace1d1019a9db44d23f24..f07f00177c4ebef18cc75ef457cd5ba96ad83db3 100644 --- a/x86_64/memxor.asm +++ b/x86_64/memxor.asm @@ -79,7 +79,7 @@ PROLOGUE(nettle_memxor) jnz .Lalign_loop .Laligned: -ifelse(USE_SSE2, yes, < +ifdef(<USE_SSE2>, < cmp $16, N jnc .Lsse2_case >) @@ -135,7 +135,7 @@ ifelse(USE_SSE2, yes, < W64_EXIT(3, 0) ret -ifelse(USE_SSE2, yes, < +ifdef(<USE_SSE2>, < .Lsse2_case: lea (DST, N), TMP