diff --git a/Makefile.in b/Makefile.in index 919f273c90d69b3e3d836d4ffe2c61986fd09d0f..19f5e4299cb922819dbd5310f34540b01c212f81 100644 --- a/Makefile.in +++ b/Makefile.in @@ -217,7 +217,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ ed448-shake256.c ed448-shake256-pubkey.c \ ed448-shake256-sign.c ed448-shake256-verify.c -OPT_SOURCES = fat-x86_64.c fat-arm.c mini-gmp.c +OPT_SOURCES = fat-arm.c fat-ppc.c fat-x86_64.c mini-gmp.c HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \ base16.h base64.h bignum.h buffer.h camellia.h cast128.h \ diff --git a/aes-decrypt-internal.c b/aes-decrypt-internal.c index 709c52f9ea155caf5d3212c8a13cf74a94c59fbb..9e8cf34a100f773e94c4c4e35062feb3c4f00a55 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 9f61386db94a932edbbeabb650c3503d9d34113b..ad17e6c10a130e2399b3c061072de79ab15d0718 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/configure.ac b/configure.ac index c4e9b3043e3ee21f559a55aab49f03b6c74ddf29..0e4b41f35caa4f074cbb2437fd9bb918db315fa6 100644 --- a/configure.ac +++ b/configure.ac @@ -446,8 +446,12 @@ if test "x$enable_assembler" = xyes ; then fi ;; *powerpc64*) - if test "x$enable_power_crypto_ext" = xyes ; then - asm_path="powerpc64/p8 powerpc64" + asm_path="powerpc64" + if test "x$enable_fat" = xyes ; then + asm_path="powerpc64/fat $asm_path" + OPT_NETTLE_SOURCES="fat-ppc.c $OPT_NETTLE_SOURCES" + elif test "x$enable_power_crypto_ext" = xyes ; then + asm_path="powerpc64/p8 $asm_path" fi ;; diff --git a/fat-ppc.c b/fat-ppc.c new file mode 100644 index 0000000000000000000000000000000000000000..7198e2dd39c6f90a56801996f8d952dc45b1ac9c --- /dev/null +++ b/fat-ppc.c @@ -0,0 +1,129 @@ +/* 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) + +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; + } + else + { + _nettle_aes_encrypt_vec = _nettle_aes_encrypt_c; + _nettle_aes_decrypt_vec = _nettle_aes_decrypt_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)) diff --git a/powerpc64/fat/aes-decrypt-internal-2.asm b/powerpc64/fat/aes-decrypt-internal-2.asm new file mode 100644 index 0000000000000000000000000000000000000000..3a4e08c2f7414c15cb6ca8072d73deed86a2523f --- /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 0000000000000000000000000000000000000000..42126e4f92e1b0d02fc819fd5c8a785465dbfecc --- /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>)