diff options
author | Niels Möller <nisse@lysator.liu.se> | 2022-02-15 21:21:21 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2022-02-15 21:21:21 +0100 |
commit | 60edc2905d4af10a372f83d2a51d688a1646ad43 (patch) | |
tree | 5559cd0c3d60e0abbe31d92a8410a302bc8e23ed | |
parent | be24531355bc8d2b2ce5982e5a059ef382629831 (diff) | |
download | nettle-x86_64-gcm.tar.gz |
x86_64: Fat setup for GCM.x86_64-gcm
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | fat-x86_64.c | 56 | ||||
-rw-r--r-- | x86_64/fat/gcm-hash.asm | 39 |
3 files changed, 94 insertions, 4 deletions
@@ -1,5 +1,8 @@ 2022-02-15 Niels Möller <nisse@lysator.liu.se> + * fat-x86_64.c: Add fat setup for gcm. + * x86_64/fat/gcm-hash.asm: New file. + * Makefile.in (distdir): Add x86_64/pclmul directory. * configure.ac: New configure option --enable-x86-pclmul. (asm_path): Add x86_64/pclmul, if above option is set. diff --git a/fat-x86_64.c b/fat-x86_64.c index 30551cb2..21dab62f 100644 --- a/fat-x86_64.c +++ b/fat-x86_64.c @@ -43,6 +43,8 @@ #include "nettle-types.h" #include "aes-internal.h" +#include "gcm.h" +#include "gcm-internal.h" #include "memxor.h" #include "fat-setup.h" @@ -53,6 +55,7 @@ struct x86_features enum x86_vendor { X86_OTHER, X86_INTEL, X86_AMD } vendor; int have_aesni; int have_sha_ni; + int have_pclmul; }; #define SKIP(s, slen, literal, llen) \ @@ -68,6 +71,7 @@ get_x86_features (struct x86_features *features) features->vendor = X86_OTHER; features->have_aesni = 0; features->have_sha_ni = 0; + features->have_pclmul = 0; s = secure_getenv (ENV_OVERRIDE); if (s) @@ -88,6 +92,8 @@ get_x86_features (struct x86_features *features) features->have_aesni = 1; else if (MATCH (s, length, "sha_ni", 6)) features->have_sha_ni = 1; + else if (MATCH (s, length, "pclmul", 6)) + features->have_pclmul = 1; if (!sep) break; s = sep + 1; @@ -102,12 +108,14 @@ get_x86_features (struct x86_features *features) features->vendor = X86_AMD; _nettle_cpuid (1, cpuid_data); + if (cpuid_data[2] & 0x2) + features->have_pclmul = 1; if (cpuid_data[2] & 0x02000000) - features->have_aesni = 1; + features->have_aesni = 1; _nettle_cpuid (7, cpuid_data); if (cpuid_data[1] & 0x20000000) - features->have_sha_ni = 1; + features->have_sha_ni = 1; } } @@ -152,6 +160,17 @@ DECLARE_FAT_FUNC(_nettle_sha256_compress, sha256_compress_func) DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, x86_64) DECLARE_FAT_FUNC_VAR(sha256_compress, sha256_compress_func, sha_ni) +#if GCM_TABLE_BITS == 8 +DECLARE_FAT_FUNC(_nettle_gcm_init_key, gcm_init_key_func) +DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, c) +DECLARE_FAT_FUNC_VAR(gcm_init_key, gcm_init_key_func, pclmul) + +DECLARE_FAT_FUNC(_nettle_gcm_hash, gcm_hash_func) +DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, c) +DECLARE_FAT_FUNC_VAR(gcm_hash, gcm_hash_func, pclmul) +#endif /* GCM_TABLE_BITS == 8 */ + + /* This function should usually be called only once, at startup. But it is idempotent, and on x86, pointer updates are atomic, so there's no danger if it is called simultaneously from multiple @@ -172,10 +191,11 @@ fat_init (void) { const char * const vendor_names[3] = { "other", "intel", "amd" }; - fprintf (stderr, "libnettle: cpu features: vendor:%s%s%s\n", + fprintf (stderr, "libnettle: cpu features: vendor:%s%s%s%s\n", vendor_names[features.vendor], features.have_aesni ? ",aesni" : "", - features.have_sha_ni ? ",sha_ni" : ""); + features.have_sha_ni ? ",sha_ni" : "", + features.have_pclmul ? ",pclmul" : ""); } if (features.have_aesni) { @@ -220,6 +240,23 @@ fat_init (void) nettle_sha1_compress_vec = _nettle_sha1_compress_x86_64; _nettle_sha256_compress_vec = _nettle_sha256_compress_x86_64; } + +#if GCM_TABLE_BITS == 8 + if (features.have_pclmul) + { + if (verbose) + fprintf (stderr, "libnettle: using pclmulqdq instructions.\n"); + _nettle_gcm_init_key_vec = _nettle_gcm_init_key_pclmul; + _nettle_gcm_hash_vec = _nettle_gcm_hash_pclmul; + } + else + { + if (verbose) + fprintf (stderr, "libnettle: not using pclmulqdq instructions.\n"); + _nettle_gcm_init_key_vec = _nettle_gcm_init_key_c; + _nettle_gcm_hash_vec = _nettle_gcm_hash8; + } +#endif if (features.vendor == X86_INTEL) { if (verbose) @@ -285,3 +322,14 @@ DEFINE_FAT_FUNC(nettle_sha1_compress, void, DEFINE_FAT_FUNC(_nettle_sha256_compress, void, (uint32_t *state, const uint8_t *input, const uint32_t *k), (state, input, k)) + +#if GCM_TABLE_BITS == 8 +DEFINE_FAT_FUNC(_nettle_gcm_init_key, void, + (union nettle_block16 *table), + (table)) + +DEFINE_FAT_FUNC(_nettle_gcm_hash, void, + (const struct gcm_key *key, union nettle_block16 *x, + size_t length, const uint8_t *data), + (key, x, length, data)) +#endif /* GCM_TABLE_BITS == 8 */ diff --git a/x86_64/fat/gcm-hash.asm b/x86_64/fat/gcm-hash.asm new file mode 100644 index 00000000..18abc365 --- /dev/null +++ b/x86_64/fat/gcm-hash.asm @@ -0,0 +1,39 @@ +C powerpc64/fat/gcm-hash.asm + + +ifelse(` + Copyright (C) 2022 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/. +') + +dnl picked up by configure +dnl PROLOGUE(_nettle_fat_gcm_init_key) +dnl PROLOGUE(_nettle_fat_gcm_hash) + +define(`fat_transform', `$1_pclmul') +include_src(`x86_64/pclmul/gcm-hash.asm') |