--- aes-decrypt-internal.c | 10 ++ aes-encrypt-internal.c | 10 ++ fat-ppc.c | 173 +++++++++++++++++++++++++++++++ fat-setup.h | 9 ++ powerpc64/fat/aes-decrypt-internal-2.asm | 37 +++++++ powerpc64/fat/aes-encrypt-internal-2.asm | 37 +++++++ powerpc64/fat/gcm-hash.asm | 40 +++++++ 7 files changed, 316 insertions(+) create mode 100644 fat-ppc.c create mode 100644 powerpc64/fat/aes-decrypt-internal-2.asm create mode 100644 powerpc64/fat/aes-encrypt-internal-2.asm create mode 100644 powerpc64/fat/gcm-hash.asm
diff --git a/aes-decrypt-internal.c b/aes-decrypt-internal.c index 709c52f9..6326befb 100644 --- a/aes-decrypt-internal.c +++ b/aes-decrypt-internal.c @@ -40,6 +40,16 @@ #include "aes-internal.h" #include "macros.h"
+/* For fat builds */ +#if HAVE_NATIVE_aes_decrypt +void +_nettle_aes_decrypt_c(unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src); +#define _nettle_aes_decrypt _nettle_aes_decrypt_c +#endif + void _nettle_aes_decrypt(unsigned rounds, const uint32_t *keys, const struct aes_table *T, diff --git a/aes-encrypt-internal.c b/aes-encrypt-internal.c index 9f61386d..7ff4ca40 100644 --- a/aes-encrypt-internal.c +++ b/aes-encrypt-internal.c @@ -40,6 +40,16 @@ #include "aes-internal.h" #include "macros.h"
+/* For fat builds */ +#if HAVE_NATIVE_aes_encrypt +void +_nettle_aes_encrypt_c(unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src); +#define _nettle_aes_encrypt _nettle_aes_encrypt_c +#endif + void _nettle_aes_encrypt(unsigned rounds, const uint32_t *keys, const struct aes_table *T, diff --git a/fat-ppc.c b/fat-ppc.c new file mode 100644 index 00000000..e09b2097 --- /dev/null +++ b/fat-ppc.c @@ -0,0 +1,173 @@ +/* fat-ppc.c + + Copyright (C) 2020 Mamone Tarsha + + 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 _GNU_SOURCE + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if defined(__FreeBSD__) && __FreeBSD__ < 12 +#include <sys/sysctl.h> +#else +#include <sys/auxv.h> +#endif + +#include "nettle-types.h" + +#include "aes-internal.h" +#include "gcm.h" +#include "fat-setup.h" + +/* Define from arch/powerpc/include/uapi/asm/cputable.h in Linux kernel */ +#ifndef PPC_FEATURE2_VEC_CRYPTO +#define PPC_FEATURE2_VEC_CRYPTO 0x02000000 +#endif + +struct ppc_features +{ + int have_crypto_ext; +}; + +static void +get_ppc_features (struct ppc_features *features) +{ + unsigned long hwcap2 = 0; +#if defined(__FreeBSD__) +#if __FreeBSD__ < 12 + size_t len = sizeof(hwcap2); + sysctlbyname("hw.cpu_features2", &hwcap2, &len, NULL, 0); +#else + elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)); +#endif +#else + hwcap2 = getauxval(AT_HWCAP2); +#endif + features->have_crypto_ext = + (hwcap2 & PPC_FEATURE2_VEC_CRYPTO) == PPC_FEATURE2_VEC_CRYPTO ? 1 : 0; +} + +DECLARE_FAT_FUNC(_nettle_aes_encrypt, aes_crypt_internal_func) +DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, c) +DECLARE_FAT_FUNC_VAR(aes_encrypt, aes_crypt_internal_func, ppc64) + +DECLARE_FAT_FUNC(_nettle_aes_decrypt, aes_crypt_internal_func) +DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, c) +DECLARE_FAT_FUNC_VAR(aes_decrypt, aes_crypt_internal_func, ppc64) + +#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, ppc64) + +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, ppc64) +#endif /* GCM_TABLE_BITS == 8 */ + +DECLARE_FAT_FUNC(_nettle_gcm_fill, gcm_fill_func) +DECLARE_FAT_FUNC_VAR(gcm_fill, gcm_fill_func, c) +DECLARE_FAT_FUNC_VAR(gcm_fill, gcm_fill_func, ppc64) + +static void CONSTRUCTOR +fat_init (void) +{ + struct ppc_features features; + int verbose; + + get_ppc_features (&features); + + verbose = getenv (ENV_VERBOSE) != NULL; + if (verbose) + fprintf (stderr, "libnettle: cpu features: %s\n", + features.have_crypto_ext ? "crypto extensions" : ""); + + if (features.have_crypto_ext) + { + if (verbose) + fprintf (stderr, "libnettle: enabling arch 2.07 code.\n"); + _nettle_aes_encrypt_vec = _nettle_aes_encrypt_ppc64; + _nettle_aes_decrypt_vec = _nettle_aes_decrypt_ppc64; +#if GCM_TABLE_BITS == 8 + /* Make sure _nettle_gcm_init_key_vec function is compatible + with _nettle_gcm_hash_vec function e.g. _nettle_gcm_init_key_c() + fills gcm_key table with values that are incompatible with + _nettle_gcm_hash_ppc64() */ + _nettle_gcm_init_key_vec = _nettle_gcm_init_key_ppc64; + _nettle_gcm_hash_vec = _nettle_gcm_hash_ppc64; +#endif /* GCM_TABLE_BITS == 8 */ + _nettle_gcm_fill_vec = _nettle_gcm_fill_ppc64; + } + else + { + _nettle_aes_encrypt_vec = _nettle_aes_encrypt_c; + _nettle_aes_decrypt_vec = _nettle_aes_decrypt_c; +#if GCM_TABLE_BITS == 8 + _nettle_gcm_init_key_vec = _nettle_gcm_init_key_c; + _nettle_gcm_hash_vec = _nettle_gcm_hash_c; +#endif /* GCM_TABLE_BITS == 8 */ + _nettle_gcm_fill_vec = _nettle_gcm_fill_c; + } +} + +DEFINE_FAT_FUNC(_nettle_aes_encrypt, void, + (unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src), + (rounds, keys, T, length, dst, src)) + +DEFINE_FAT_FUNC(_nettle_aes_decrypt, void, + (unsigned rounds, const uint32_t *keys, + const struct aes_table *T, + size_t length, uint8_t *dst, + const uint8_t *src), + (rounds, keys, T, length, dst, src)) + +#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 */ + +DEFINE_FAT_FUNC(_nettle_gcm_fill, void, + (uint8_t *ctr, size_t blocks, + union nettle_block16 *buffer), + (ctr, blocks, buffer)) diff --git a/fat-setup.h b/fat-setup.h index 58b687fd..9793eebb 100644 --- a/fat-setup.h +++ b/fat-setup.h @@ -161,6 +161,15 @@ typedef void aes_crypt_internal_func (unsigned rounds, const uint32_t *keys, size_t length, uint8_t *dst, const uint8_t *src);
+#if GCM_TABLE_BITS == 8 +typedef void gcm_init_key_func (union nettle_block16 *table); + +typedef void gcm_hash_func (const struct gcm_key *key, union nettle_block16 *x, + size_t length, const uint8_t *data); + +typedef void gcm_fill_func (uint8_t *ctr, size_t blocks, union nettle_block16 *buffer); +#endif /* GCM_TABLE_BITS == 8 */ + typedef void *(memxor_func)(void *dst, const void *src, size_t n);
typedef void salsa20_core_func (uint32_t *dst, const uint32_t *src, unsigned rounds); diff --git a/powerpc64/fat/aes-decrypt-internal-2.asm b/powerpc64/fat/aes-decrypt-internal-2.asm new file mode 100644 index 00000000..593bf6cf --- /dev/null +++ b/powerpc64/fat/aes-decrypt-internal-2.asm @@ -0,0 +1,37 @@ +C powerpc64/fat/aes-decrypt-internal-2.asm + + +ifelse(< + Copyright (C) 2020 Mamone Tarsha + + 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 PROLOGUE(_nettle_aes_decrypt) picked up by configure + +define(<fat_transform>, <$1_ppc64>) +include_src(<powerpc64/P8/aes-decrypt-internal.asm>) diff --git a/powerpc64/fat/aes-encrypt-internal-2.asm b/powerpc64/fat/aes-encrypt-internal-2.asm new file mode 100644 index 00000000..73a4d543 --- /dev/null +++ b/powerpc64/fat/aes-encrypt-internal-2.asm @@ -0,0 +1,37 @@ +C powerpc64/fat/aes-encrypt-internal-2.asm + + +ifelse(< + Copyright (C) 2020 Mamone Tarsha + + 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 PROLOGUE(_nettle_aes_encrypt) picked up by configure + +define(<fat_transform>, <$1_ppc64>) +include_src(<powerpc64/P8/aes-encrypt-internal.asm>) diff --git a/powerpc64/fat/gcm-hash.asm b/powerpc64/fat/gcm-hash.asm new file mode 100644 index 00000000..dbb827db --- /dev/null +++ b/powerpc64/fat/gcm-hash.asm @@ -0,0 +1,40 @@ +C powerpc64/fat/gcm-hash.asm + + +ifelse(< + Copyright (C) 2020 Mamone Tarsha + + 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_gcm_init_key) +dnl PROLOGUE(_nettle_gcm_hash) +dnl PROLOGUE(_nettle_gcm_fill) + +define(<fat_transform>, <$1_ppc64>) +include_src(<powerpc64/P8/gcm-hash.asm>)
Hi, I've been busy and silent for a while.
I was thinking, that I don't want to merge to master with --enable-power-crypto-ext enabled by default. And then we really need fat builds to have easy ci testing.
So I'm applying the AES-parts of this patch, to try to get fat builds working as soon as possible.
Another question: When looking at the powerpc64 things in configure.ac, I wonder if powerpc64 supports 32-bit binaries, which would be built with something like CC='gcc -m32' ?
If 32-bit builds are possible, and are incompatible with the assembly files, we need to add an ABI check similar to the one for x86_64 and sparc, and add powerpc64 to asm_path only for ABI=64.
Regards, /Niels
On Wed, Aug 19, 2020 at 10:46 PM Niels Möller nisse@lysator.liu.se wrote:
Hi, I've been busy and silent for a while.
I was thinking, that I don't want to merge to master with --enable-power-crypto-ext enabled by default. And then we really need fat builds to have easy ci testing.
So I'm applying the AES-parts of this patch, to try to get fat builds working as soon as possible.
Great. Thank you for your work.
Another question: When looking at the powerpc64 things in configure.ac, I wonder if powerpc64 supports 32-bit binaries, which would be built with something like CC='gcc -m32' ?
If 32-bit builds are possible, and are incompatible with the assembly files, we need to add an ABI check similar to the one for x86_64 and sparc, and add powerpc64 to asm_path only for ABI=64.
Right, I missed the '-m32' thing. I will add the ABI check to configure.ac
regards, Mamone
On Wed, Aug 19, 2020 at 5:42 PM Maamoun TK maamoun.tk@googlemail.com wrote:
...
Another question: When looking at the powerpc64 things in configure.ac, I wonder if powerpc64 supports 32-bit binaries, which would be built with something like CC='gcc -m32' ?
If 32-bit builds are possible, and are incompatible with the assembly files, we need to add an ABI check similar to the one for x86_64 and sparc, and add powerpc64 to asm_path only for ABI=64.
Right, I missed the '-m32' thing. I will add the ABI check to configure.ac
You might want to check this. In practice I don't believe 32-bit ABIs are supported on the 64-bit iron.
I don't recall if the Linux ABI supports 32-bit on these machines. I thought Steven Monroe said something about this (i.e., not supported), but I cannot find it in my inbox.
If the ABI does specify a 32-bit interface, then GCC does not support it. Here's from GCC112 on the compile farm. GCC112 offers GCC 4.8 and GCC 8.3.
# GCC 4.8 $ gcc -m32 test.c -o test In file included from /usr/include/features.h:399:0, from /usr/include/stdint.h:25, from /usr/lib/gcc/ppc64le-redhat-linux/4.8.5/include/stdint.h:9, from test.c:1: /usr/include/gnu/stubs.h:8:27: fatal error: gnu/stubs-32.h: No such file or directory # include <gnu/stubs-32.h>
# GCC 8.3 gcc112:~$ /opt/at12.0/bin/gcc -m32 test.c -o test cc1: error: ‘-m32’ not supported in this configuration
I don't know what Clang offers.
Jeff
Jeffrey Walton noloader@gmail.com writes:
If the ABI does specify a 32-bit interface, then GCC does not support it. Here's from GCC112 on the compile farm. GCC112 offers GCC 4.8 and GCC 8.3.
# GCC 4.8 $ gcc -m32 test.c -o test In file included from /usr/include/features.h:399:0, from /usr/include/stdint.h:25, from /usr/lib/gcc/ppc64le-redhat-linux/4.8.5/include/stdint.h:9, from test.c:1: /usr/include/gnu/stubs.h:8:27: fatal error: gnu/stubs-32.h: No such file or directory # include <gnu/stubs-32.h>
# GCC 8.3 gcc112:~$ /opt/at12.0/bin/gcc -m32 test.c -o test cc1: error: ‘-m32’ not supported in this configuration
I'm not familiar with how redhat packages gcc, but on debian, the plain gcc package supports only the default (64-bit abi), and one has to install a separate gcc-multilib package to get headers and libraries needed for building 32-bit (and x32, on x86_64) binaries.
Regards, /Niels
On Thu, Aug 20, 2020 at 1:07 AM Jeffrey Walton noloader@gmail.com wrote:
You might want to check this. In practice I don't believe 32-bit ABIs are supported on the 64-bit iron.
I don't recall if the Linux ABI supports 32-bit on these machines. I thought Steven Monroe said something about this (i.e., not supported), but I cannot find it in my inbox.
If the ABI does specify a 32-bit interface, then GCC does not support it. Here's from GCC112 on the compile farm. GCC112 offers GCC 4.8 and GCC 8.3.
# GCC 4.8 $ gcc -m32 test.c -o test In file included from /usr/include/features.h:399:0, from /usr/include/stdint.h:25, from /usr/lib/gcc/ppc64le-redhat-linux/4.8.5/include/stdint.h:9, from test.c:1: /usr/include/gnu/stubs.h:8:27: fatal error: gnu/stubs-32.h: No such file or directory # include <gnu/stubs-32.h>
# GCC 8.3 gcc112:~$ /opt/at12.0/bin/gcc -m32 test.c -o test cc1: error: ‘-m32’ not supported in this configuration
I don't know what Clang offers.
Jeff
Hi,
As Niels said, maybe a missing package is what stops the compilation process. I tested it on GCC119 which has AIX 7.2, gcc builds 32 bit binary by default when -maix64 is enabled it builds 64 bit binary and both are executed successfully.
I posted a patch that adds ABI check, thank you both.
regards, Mamone
nettle-bugs@lists.lysator.liu.se