]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
ppc: Enable gcm code in fat builds. Based on patch by Mamone Tarsha.
authorNiels Möller <nisse@lysator.liu.se>
Thu, 26 Nov 2020 19:07:07 +0000 (20:07 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Thu, 26 Nov 2020 19:07:07 +0000 (20:07 +0100)
ChangeLog
Makefile.in
configure.ac
fat-ppc.c
fat-setup.h
gcm-internal.h [new file with mode: 0644]
gcm.c
powerpc64/fat/gcm-hash.asm [new file with mode: 0644]

index fb4b6ab5e6df7e088fc55d37e7dec4490c85398f..d63f8198439be5179fcfd9c5b63f98c7991dbd3c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2020-11-26  Niels Möller  <nisse@lysator.liu.se>
+
+       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  <nisse@lysator.liu.se>
 
        * ecc-secp384r1.c (ecc_secp384r1_inv): New function, modular
index d955774d76ebebb09191f1239d630793bbfb928f..c4df14e158b7581dfb7cf0434069c10588fc33d8 100644 (file)
@@ -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 \
index 20f7cf74353ef78f4bc300a474f55a697f278023..9908c61a921d6c302c693b4276fd694673b3d81d 100644 (file)
@@ -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
index 7b12e54a28de0495b4ede3ebc7279e4fe23a1ae1..1a52261af4f9295378ee42c3031f935aedf87116 100644 (file)
--- 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))
index 99f1ea678abdcd092096648d713d51cf4b7edda7..10177390cf02aae85decd82da56cf1faeb261b99 100644 (file)
@@ -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 (file)
index 0000000..6e858b2
--- /dev/null
@@ -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 f0290b70a5be84cae4e2ddd62e979b509c184711..4770e414ad7687aed831727becb0ac03b273a6b5 100644 (file)
--- a/gcm.c
+++ b/gcm.c
 
 #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 (file)
index 0000000..57c343d
--- /dev/null
@@ -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')