From: Niels Möller Date: Thu, 26 Nov 2020 19:07:07 +0000 (+0100) Subject: ppc: Enable gcm code in fat builds. Based on patch by Mamone Tarsha. X-Git-Tag: nettle_3.7rc1~29^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90c34ebe3ee812ecaee46980597e37b6136ba9e2;p=thirdparty%2Fnettle.git ppc: Enable gcm code in fat builds. Based on patch by Mamone Tarsha. --- diff --git a/ChangeLog b/ChangeLog index fb4b6ab5..d63f8198 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2020-11-26 Niels Möller + + Enable powerpc64 gcm code in fat builds. Based on patch + contributed by Mamone Tarsha: + * powerpc64/fat/gcm-hash.asm: New file. + * configure.ac: Add HAVE_NATIVE_fat_gcm_init_key and + HAVE_NATIVE_fat_gcm_hash. + * gcm.c (gcm_init_key): Renamed, to ... + (_nettle_gcm_init_key_c): ... new name. Add fat setup conditionals. + (gcm_hash): Renamed, to... + (_nettle_gcm_hash_c): ... new name. Add fat setup conditionals. + * fat-setup.h (gcm_init_key_func, gcm_hash_func): New typedefs. + * fat-ppc.c: Select implementations of _nettle_gcm_init_key and _nettle_gcm_hash. + * gcm-internal.h: New file. + * Makefile.in (DISTFILES): Add gcm-internal.h. + 2020-10-21 Niels Möller * ecc-secp384r1.c (ecc_secp384r1_inv): New function, modular diff --git a/Makefile.in b/Makefile.in index d955774d..c4df14e1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -259,8 +259,8 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \ nettle.pc.in hogweed.pc.in \ desdata.stamp $(des_headers) descore.README \ aes-internal.h block-internal.h blowfish-internal.h camellia-internal.h \ - gost28147-internal.h poly1305-internal.h serpent-internal.h \ - cast128_sboxes.h desinfo.h desCode.h \ + gcm-internal.h gost28147-internal.h poly1305-internal.h \ + serpent-internal.h cast128_sboxes.h desinfo.h desCode.h \ ripemd160-internal.h sha2-internal.h \ memxor-internal.h nettle-internal.h nettle-write.h \ ctr-internal.h chacha-internal.h sha3-internal.h \ diff --git a/configure.ac b/configure.ac index 20f7cf74..9908c61a 100644 --- a/configure.ac +++ b/configure.ac @@ -622,7 +622,9 @@ AH_VERBATIM([HAVE_NATIVE], #undef HAVE_NATIVE_ecc_secp521r1_modp #undef HAVE_NATIVE_ecc_secp521r1_redc #undef HAVE_NATIVE_gcm_init_key +#undef HAVE_NATIVE_fat_gcm_init_key #undef HAVE_NATIVE_gcm_hash +#undef HAVE_NATIVE_fat_gcm_hash #undef HAVE_NATIVE_gcm_hash8 #undef HAVE_NATIVE_salsa20_core #undef HAVE_NATIVE_salsa20_2core diff --git a/fat-ppc.c b/fat-ppc.c index 7b12e54a..1a52261a 100644 --- a/fat-ppc.c +++ b/fat-ppc.c @@ -61,6 +61,7 @@ #include "aes-internal.h" #include "gcm.h" +#include "gcm-internal.h" #include "fat-setup.h" /* Defines from arch/powerpc/include/uapi/asm/cputable.h in Linux kernel */ @@ -109,7 +110,7 @@ get_ppc_features (struct ppc_features *features) { #if defined(_AIX) features->have_crypto_ext - = _system_configuration.implementation >= 0x10000u; + = _system_configuration.implementation >= 0x10000u; features->have_altivec = _system_configuration.vmx_version > 1; #else unsigned long hwcap = 0; @@ -148,6 +149,16 @@ 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_chacha_core, chacha_core_func) DECLARE_FAT_FUNC_VAR(chacha_core, chacha_core_func, c); DECLARE_FAT_FUNC_VAR(chacha_core, chacha_core_func, altivec); @@ -171,11 +182,23 @@ fat_init (void) 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 */ } 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 */ } if (features.have_altivec) { @@ -203,6 +226,17 @@ DEFINE_FAT_FUNC(_nettle_aes_decrypt, void, 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_chacha_core, void, (uint32_t *dst, const uint32_t *src, unsigned rounds), (dst, src, rounds)) diff --git a/fat-setup.h b/fat-setup.h index 99f1ea67..10177390 100644 --- a/fat-setup.h +++ b/fat-setup.h @@ -162,6 +162,11 @@ typedef void aes_crypt_internal_func (unsigned rounds, const uint32_t *keys, size_t length, uint8_t *dst, const uint8_t *src); +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 *(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/gcm-internal.h b/gcm-internal.h new file mode 100644 index 00000000..6e858b20 --- /dev/null +++ b/gcm-internal.h @@ -0,0 +1,53 @@ +/* gcm-internal.h + + Copyright (C) 2020 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/. +*/ + +#ifndef NETTLE_GCM_INTERNAL_H_INCLUDED +#define NETTLE_GCM_INTERNAL_H_INCLUDED + +/* Functions available only in some configurations */ +#if HAVE_NATIVE_fat_gcm_init_key +void +_nettle_gcm_init_key (union nettle_block16 *table); + +void +_nettle_gcm_init_key_c (union nettle_block16 *table); +#endif + +#if HAVE_NATIVE_fat_gcm_hash +void +_nettle_gcm_hash(const struct gcm_key *key, union nettle_block16 *x, + size_t length, const uint8_t *data); +void +_nettle_gcm_hash_c (const struct gcm_key *key, union nettle_block16 *x, + size_t length, const uint8_t *data); +#endif + +#endif /* NETTLE_GCM_INTERNAL_H_INCLUDED */ diff --git a/gcm.c b/gcm.c index f0290b70..4770e414 100644 --- a/gcm.c +++ b/gcm.c @@ -49,13 +49,24 @@ #include "gcm.h" +#include "gcm-internal.h" #include "memxor.h" #include "nettle-internal.h" #include "macros.h" #include "ctr-internal.h" #include "block-internal.h" -#if GCM_TABLE_BITS == 0 +#if GCM_TABLE_BITS != 8 +/* The native implementations (currently ppc64 only) depend on the + GCM_TABLE_BITS == 8 layout */ +#undef HAVE_NATIVE_gcm_hash +#undef HAVE_NATIVE_gcm_init_key +#undef HAVE_NATIVE_fat_gcm_hash +#undef HAVE_NATIVE_fat_gcm_init_key +#endif + +#if !HAVE_NATIVE_gcm_hash +# if GCM_TABLE_BITS == 0 /* Sets x <- x * y mod r, using the plain bitwise algorithm from the specification. y may be shorter than a full block, missing bytes are assumed zero. */ @@ -83,15 +94,15 @@ gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *y) } memcpy (x->b, Z.b, sizeof(Z)); } -#else /* GCM_TABLE_BITS != 0 */ +# else /* GCM_TABLE_BITS != 0 */ -# if WORDS_BIGENDIAN -# define W(left,right) (0x##left##right) -# else -# define W(left,right) (0x##right##left) -# endif +# if WORDS_BIGENDIAN +# define W(left,right) (0x##left##right) +# else +# define W(left,right) (0x##right##left) +# endif -# if GCM_TABLE_BITS == 4 +# if GCM_TABLE_BITS == 4 static const uint16_t shift_table[0x10] = { W(00,00),W(1c,20),W(38,40),W(24,60),W(70,80),W(6c,a0),W(48,c0),W(54,e0), @@ -110,7 +121,7 @@ gcm_gf_shift_4(union nettle_block16 *x) u64[1] = (u64[1] >> 4) | ((u64[0] & 0xf) << 60); u64[0] = (u64[0] >> 4) ^ (reduce << 48); #else /* ! WORDS_BIGENDIAN */ -#define RSHIFT_WORD_4(x) \ +# define RSHIFT_WORD_4(x) \ ((((x) & UINT64_C(0xf0f0f0f0f0f0f0f0)) >> 4) \ | (((x) & UINT64_C(0x000f0f0f0f0f0f0f)) << 12)) reduce = shift_table[(u64[1] >> 56) & 0xf]; @@ -139,20 +150,7 @@ gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *table) } memcpy (x->b, Z.b, sizeof(Z)); } -# elif GCM_TABLE_BITS == 8 -# if HAVE_NATIVE_gcm_init_key -# define gcm_init_key _nettle_gcm_init_key -void -_nettle_gcm_init_key (union nettle_block16 *table); -# endif /* HAVE_NATIVE_gcm_init_key */ - -# if HAVE_NATIVE_gcm_hash -# define gcm_hash _nettle_gcm_hash -void -_nettle_gcm_hash (const struct gcm_key *key, union nettle_block16 *x, - size_t length, const uint8_t *data); -# else /* !HAVE_NATIVE_gcm_hash */ - +# elif GCM_TABLE_BITS == 8 # if HAVE_NATIVE_gcm_hash8 #define gcm_hash _nettle_gcm_hash8 @@ -230,21 +228,25 @@ gcm_gf_mul (union nettle_block16 *x, const union nettle_block16 *table) block16_xor3(x, &Z, &table[x->b[0]]); } # endif /* ! HAVE_NATIVE_gcm_hash8 */ -# endif /* !HAVE_NATIVE_gcm_hash */ -# else /* GCM_TABLE_BITS != 8 */ -# error Unsupported table size. -# endif /* GCM_TABLE_BITS != 8 */ +# else /* GCM_TABLE_BITS != 8 */ +# error Unsupported table size. +# endif /* GCM_TABLE_BITS != 8 */ -#undef W +# undef W +# endif /* GCM_TABLE_BITS != 0 */ +#endif /* !HAVE_NATIVE_gcm_hash */ -#endif /* GCM_TABLE_BITS */ /* Increment the rightmost 32 bits. */ #define INC32(block) INCREMENT(4, (block.b) + GCM_BLOCK_SIZE - 4) -#ifndef gcm_init_key -static void -gcm_init_key(union nettle_block16 *table) +#if !HAVE_NATIVE_gcm_init_key +# if !HAVE_NATIVE_fat_gcm_hash +# define _nettle_gcm_init_key _nettle_gcm_init_key_c +static +# endif +void +_nettle_gcm_init_key_c(union nettle_block16 *table) { #if GCM_TABLE_BITS /* Middle element if GCM_TABLE_BITS > 0, otherwise the first @@ -263,7 +265,7 @@ gcm_init_key(union nettle_block16 *table) } #endif } -#endif /* !gcm_init_key */ +#endif /* !HAVE_NATIVE_gcm_init_key */ /* Initialization of GCM. * @ctx: The context of GCM @@ -281,14 +283,18 @@ gcm_set_key(struct gcm_key *key, /* H */ memset(key->h[0].b, 0, GCM_BLOCK_SIZE); f (cipher, GCM_BLOCK_SIZE, key->h[i].b, key->h[0].b); - - gcm_init_key(key->h); + + _nettle_gcm_init_key(key->h); } -#ifndef gcm_hash -static void -gcm_hash(const struct gcm_key *key, union nettle_block16 *x, - size_t length, const uint8_t *data) +#if !(HAVE_NATIVE_gcm_hash || HAVE_NATIVE_gcm_hash8) +# if !HAVE_NATIVE_fat_gcm_hash +# define _nettle_gcm_hash _nettle_gcm_hash_c +static +# endif +void +_nettle_gcm_hash_c(const struct gcm_key *key, union nettle_block16 *x, + size_t length, const uint8_t *data) { for (; length >= GCM_BLOCK_SIZE; length -= GCM_BLOCK_SIZE, data += GCM_BLOCK_SIZE) @@ -302,7 +308,7 @@ gcm_hash(const struct gcm_key *key, union nettle_block16 *x, gcm_gf_mul (x, key->h); } } -#endif /* !gcm_hash */ +#endif /* !(HAVE_NATIVE_gcm_hash || HAVE_NATIVE_gcm_hash8) */ static void gcm_hash_sizes(const struct gcm_key *key, union nettle_block16 *x, @@ -316,7 +322,7 @@ gcm_hash_sizes(const struct gcm_key *key, union nettle_block16 *x, WRITE_UINT64 (buffer, auth_size); WRITE_UINT64 (buffer + 8, data_size); - gcm_hash(key, x, GCM_BLOCK_SIZE, buffer); + _nettle_gcm_hash(key, x, GCM_BLOCK_SIZE, buffer); } /* NOTE: The key is needed only if length != GCM_IV_SIZE */ @@ -335,7 +341,7 @@ gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key, else { memset(ctx->iv.b, 0, GCM_BLOCK_SIZE); - gcm_hash(key, &ctx->iv, length, iv); + _nettle_gcm_hash(key, &ctx->iv, length, iv); gcm_hash_sizes(key, &ctx->iv, 0, length); } @@ -354,7 +360,7 @@ gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key, assert(ctx->auth_size % GCM_BLOCK_SIZE == 0); assert(ctx->data_size == 0); - gcm_hash(key, &ctx->x, length, data); + _nettle_gcm_hash(key, &ctx->x, length, data); ctx->auth_size += length; } @@ -425,7 +431,7 @@ gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key, assert(ctx->data_size % GCM_BLOCK_SIZE == 0); _ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src); - gcm_hash(key, &ctx->x, length, dst); + _nettle_gcm_hash(key, &ctx->x, length, dst); ctx->data_size += length; } @@ -437,7 +443,7 @@ gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key, { assert(ctx->data_size % GCM_BLOCK_SIZE == 0); - gcm_hash(key, &ctx->x, length, src); + _nettle_gcm_hash(key, &ctx->x, length, src); _ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src); ctx->data_size += length; diff --git a/powerpc64/fat/gcm-hash.asm b/powerpc64/fat/gcm-hash.asm new file mode 100644 index 00000000..57c343d7 --- /dev/null +++ b/powerpc64/fat/gcm-hash.asm @@ -0,0 +1,39 @@ +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_fat_gcm_init_key) +dnl PROLOGUE(_nettle_fat_gcm_hash) + +define(`fat_transform', `$1_ppc64') +include_src(`powerpc64/p8/gcm-hash.asm')