block modes: move Galois shifts to block-internal.h
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Wed, 4 Sep 2019 06:10:30 +0000 (09:10 +0300)
committerNiels Möller <nisse@lysator.liu.se>
Wed, 4 Sep 2019 20:02:14 +0000 (22:02 +0200)
Move Galois polynomial shifts to block-internal.h, simplifying common
code. GCM is left unconverted for now, this will be fixed later.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Makefile.in
block-internal.h
cmac-internal.h [deleted file]
cmac.c
cmac64.c
eax.c
siv-cmac-aes128.c
siv-cmac-aes256.c
siv-cmac.c
xts.c

index f6658c86341c69261d4529d01b9ecc932eb1cf90..ae9c8a7563f97f9eb1453e1f3b29b2615175fc2f 100644 (file)
@@ -231,7 +231,7 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \
        nettle.pc.in hogweed.pc.in \
        $(des_headers) descore.README desdata.stamp \
        aes-internal.h block-internal.h \
-       camellia-internal.h cmac-internal.h serpent-internal.h \
+       camellia-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 \
index ab3a6a79b8cbfc86970c8719d571afd6fd61e704..8972d0ac2b5be04b8170364cbc515fe9325e0ddc 100644 (file)
@@ -90,4 +90,76 @@ block8_xor_bytes (union nettle_block8 *r,
   memxor3 (r->b, x->b, bytes, 8);
 }
 
+/* Do a foreign-endianness shift of data */
+
+#define LSHIFT_ALIEN_UINT64(x) \
+       ((((x) & UINT64_C(0x7f7f7f7f7f7f7f7f)) << 1) | \
+        (((x) & UINT64_C(0x8080808080808080)) >> 15))
+
+/* Two typical defining polynoms */
+
+#define BLOCK16_POLY (UINT64_C(0x87))
+#define BLOCK8_POLY (UINT64_C(0x1b))
+
+/* Galois multiplications by 2:
+ * functions differ in shifting right or left, big- or little- endianness
+ * and by defining polynom.
+ * r == x is allowed. */
+
+#if WORDS_BIGENDIAN
+static inline void
+block16_mulx_be (union nettle_block16 *dst,
+                const union nettle_block16 *src)
+{
+  uint64_t carry = src->u64[0] >> 63;
+  dst->u64[0] = (src->u64[0] << 1) | (src->u64[1] >> 63);
+  dst->u64[1] = (src->u64[1] << 1) ^ (BLOCK16_POLY & -carry);
+}
+
+static inline void
+block16_mulx_le (union nettle_block16 *dst,
+                const union nettle_block16 *src)
+{
+  uint64_t carry = (src->u64[1] & 0x80) >> 7;
+  dst->u64[1] = LSHIFT_ALIEN_UINT64(src->u64[1]) | ((src->u64[0] & 0x80) << 49);
+  dst->u64[0] = LSHIFT_ALIEN_UINT64(src->u64[0]) ^ ((BLOCK16_POLY << 56) & -carry);
+}
+
+static inline void
+block8_mulx_be (union nettle_block8 *dst,
+               const union nettle_block8 *src)
+{
+  uint64_t carry = src->u64 >> 63;
+
+  dst->u64 = (src->u64 << 1) ^ (BLOCK8_POLY & -carry);
+}
+#else /* !WORDS_BIGENDIAN */
+static inline void
+block16_mulx_be (union nettle_block16 *dst,
+                const union nettle_block16 *src)
+{
+  uint64_t carry = (src->u64[0] & 0x80) >> 7;
+  dst->u64[0] = LSHIFT_ALIEN_UINT64(src->u64[0]) | ((src->u64[1] & 0x80) << 49);
+  dst->u64[1] = LSHIFT_ALIEN_UINT64(src->u64[1]) ^ ((BLOCK16_POLY << 56) & -carry);
+}
+
+static inline void
+block16_mulx_le (union nettle_block16 *dst,
+                const union nettle_block16 *src)
+{
+  uint64_t carry = src->u64[1] >> 63;
+  dst->u64[1] = (src->u64[1] << 1) | (src->u64[0] >> 63);
+  dst->u64[0] = (src->u64[0] << 1) ^ (BLOCK16_POLY & -carry);
+}
+
+static inline void
+block8_mulx_be (union nettle_block8 *dst,
+               const union nettle_block8 *src)
+{
+  uint64_t carry = (src->u64 & 0x80) >> 7;
+
+  dst->u64 = LSHIFT_ALIEN_UINT64(src->u64) ^ ((BLOCK8_POLY << 56) & -carry);
+}
+#endif /* !WORDS_BIGENDIAN */
+
 #endif /* NETTLE_BLOCK_INTERNAL_H_INCLUDED */
diff --git a/cmac-internal.h b/cmac-internal.h
deleted file mode 100644 (file)
index 80db7fc..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* cmac-internal.h
-
-   CMAC mode internal functions
-
-   Copyright (C) 2017 Red Hat, Inc.
-
-   Contributed by Nikos Mavrogiannopoulos
-
-   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_CMAC_INTERNAL_H_INCLUDED
-#define NETTLE_CMAC_INTERNAL_H_INCLUDED
-
-#include "cmac.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define _cmac128_block_mulx _nettle_cmac128_block_mulx
-
-void _cmac128_block_mulx(union nettle_block16 *out,
-                        const union nettle_block16 *in);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* CMAC_INTERNAL_H_INCLUDED */
diff --git a/cmac.c b/cmac.c
index 194324421c58a65ce06f84f77bc4d9e610287538..af9b3c2c0cf4946c872fe344578cf5dc449a5e87 100644 (file)
--- a/cmac.c
+++ b/cmac.c
 
 #include "memxor.h"
 #include "nettle-internal.h"
-#include "cmac-internal.h"
 #include "block-internal.h"
 #include "macros.h"
 
-/* shift one and XOR with 0x87. */
-#if WORDS_BIGENDIAN
-void
-_cmac128_block_mulx(union nettle_block16 *dst,
-                   const union nettle_block16 *src)
-{
-  uint64_t carry = src->u64[0] >> 63;
-  dst->u64[0] = (src->u64[0] << 1) | (src->u64[1] >> 63);
-  dst->u64[1] = (src->u64[1] << 1) ^ (0x87 & -carry);
-}
-#else /* !WORDS_BIGENDIAN */
-#define LE_SHIFT(x) ((((x) & 0x7f7f7f7f7f7f7f7f) << 1) | \
-                     (((x) & 0x8080808080808080) >> 15))
-void
-_cmac128_block_mulx(union nettle_block16 *dst,
-                   const union nettle_block16 *src)
-{
-  uint64_t carry = (src->u64[0] & 0x80) >> 7;
-  dst->u64[0] = LE_SHIFT(src->u64[0]) | ((src->u64[1] & 0x80) << 49);
-  dst->u64[1] = LE_SHIFT(src->u64[1]) ^ (0x8700000000000000 & -carry);
-}
-#endif /* !WORDS_BIGENDIAN */
-
 void
 cmac128_set_key(struct cmac128_key *key, const void *cipher,
                nettle_cipher_func *encrypt)
@@ -81,8 +57,8 @@ cmac128_set_key(struct cmac128_key *key, const void *cipher,
   /* step 1 - generate subkeys k1 and k2 */
   encrypt(cipher, 16, L.b, zero_block.b);
 
-  _cmac128_block_mulx(&key->K1, &L);
-  _cmac128_block_mulx(&key->K2, &key->K1);
+  block16_mulx_be(&key->K1, &L);
+  block16_mulx_be(&key->K2, &key->K1);
 }
 
 void
index e7bb438580d6e1d27a61b3ff12e2d48fd93e199c..e4be1b547c50b473d9ed5d2fa6c9f772edd0b3bd 100644 (file)
--- a/cmac64.c
+++ b/cmac64.c
 #include "block-internal.h"
 #include "macros.h"
 
-/* shift one and XOR with 0x87. */
-#if WORDS_BIGENDIAN
-static void
-_cmac64_block_mulx(union nettle_block8 *dst,
-           const union nettle_block8 *src)
-{
-  uint64_t carry = src->u64 >> 63;
-
-  dst->u64 = (src->u64 << 1) ^ (0x1b & -carry);
-}
-#else /* !WORDS_BIGENDIAN */
-#define LE_SHIFT(x) ((((x) & 0x7f7f7f7f7f7f7f7f) << 1) | \
-                     (((x) & 0x8080808080808080) >> 15))
-static void
-_cmac64_block_mulx(union nettle_block8 *dst,
-          const union nettle_block8 *src)
-{
-  uint64_t carry = (src->u64 & 0x80) >> 7;
-
-  dst->u64 = LE_SHIFT(src->u64) ^ (0x1b00000000000000 & -carry);
-}
-#endif /* !WORDS_BIGENDIAN */
-
 void
 cmac64_set_key(struct cmac64_key *key, const void *cipher,
               nettle_cipher_func *encrypt)
@@ -80,8 +57,8 @@ cmac64_set_key(struct cmac64_key *key, const void *cipher,
   /* step 1 - generate subkeys k1 and k2 */
   encrypt(cipher, 8, L.b, zero_block.b);
 
-  _cmac64_block_mulx(&key->K1, &L);
-  _cmac64_block_mulx(&key->K2, &key->K1);
+  block8_mulx_be(&key->K1, &L);
+  block8_mulx_be(&key->K2, &key->K1);
 }
 
 void
diff --git a/eax.c b/eax.c
index 63f3ff82fe651203c66b7475442075f938b371c9..f0b6fac5c5b1e4e7f1ddc566e30c1502868a7689 100644 (file)
--- a/eax.c
+++ b/eax.c
@@ -82,27 +82,13 @@ omac_final (union nettle_block16 *state, const struct eax_key *key,
   f (cipher, EAX_BLOCK_SIZE, state->b, state->b);
 }
 
-/* Allows r == a */
-static void
-gf2_double (uint8_t *r, const uint8_t *a)
-{
-  unsigned high = - (a[0] >> 7);
-  unsigned i;
-  /* Shift left */
-  for (i = 0; i < EAX_BLOCK_SIZE - 1; i++)
-    r[i] = (a[i] << 1) + (a[i+1] >> 7);
-
-  /* Wrap around for x^{128} = x^7 + x^2 + x + 1 */
-  r[EAX_BLOCK_SIZE - 1] = (a[EAX_BLOCK_SIZE - 1] << 1) ^ (high & 0x87);
-}
-
 void
 eax_set_key (struct eax_key *key, const void *cipher, nettle_cipher_func *f)
 {
   static const union nettle_block16 zero_block;
   f (cipher, EAX_BLOCK_SIZE, key->pad_block.b, zero_block.b);
-  gf2_double (key->pad_block.b, key->pad_block.b);
-  gf2_double (key->pad_partial.b, key->pad_block.b);
+  block16_mulx_be (&key->pad_block, &key->pad_block);
+  block16_mulx_be (&key->pad_partial, &key->pad_block);
   block16_xor (&key->pad_partial, &key->pad_block);
 }
 
index 82ac16e91992f2f867ef1c854e894d083a68dba0..fd2e23a4513eb323a5bdfb94216139e286f68e69 100644 (file)
@@ -44,7 +44,6 @@
 #include "ctr.h"
 #include "memxor.h"
 #include "memops.h"
-#include "cmac-internal.h"
 
 void
 siv_cmac_aes128_set_key(struct siv_cmac_aes128_ctx *ctx, const uint8_t *key)
index 9401bbf119c50592169068eeb06afd8040cea4c6..eda7f1c27a55f5e1157d407d341d678a6340de6c 100644 (file)
@@ -44,7 +44,6 @@
 #include "ctr.h"
 #include "memxor.h"
 #include "memops.h"
-#include "cmac-internal.h"
 
 void
 siv_cmac_aes256_set_key(struct siv_cmac_aes256_ctx *ctx, const uint8_t *key)
index 42f740cddf5dbdac86bac0057c41e9e497e5591c..8205c320f544b725246c5078d0b13bd9015bf839 100644 (file)
@@ -44,7 +44,6 @@
 #include "ctr.h"
 #include "memxor.h"
 #include "memops.h"
-#include "cmac-internal.h"
 #include "nettle-internal.h"
 #include "block-internal.h"
 
@@ -67,12 +66,12 @@ _siv_s2v (const struct nettle_cipher *nc,
   cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, 16, const_zero.b);
   cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, D.b);
 
-  _cmac128_block_mulx (&D, &D);
+  block16_mulx_be (&D, &D);
   cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, alength, adata);
   cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
   block16_xor (&D, &S);
 
-  _cmac128_block_mulx (&D, &D);
+  block16_mulx_be (&D, &D);
   cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, nlength, nonce);
   cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
   block16_xor (&D, &S);
@@ -90,7 +89,7 @@ _siv_s2v (const struct nettle_cipher *nc,
     {
       union nettle_block16 pad;
 
-      _cmac128_block_mulx (&T, &D);
+      block16_mulx_be (&T, &D);
       memcpy (pad.b, pdata, plength);
       pad.b[plength] = 0x80;
       if (plength + 1 < 16)
diff --git a/xts.c b/xts.c
index 6730b3ad76ffaff4cd4f28fa06a883cf814c6fb8..7b023748ddd49accfc36d72d9e777ee527dc4b92 100644 (file)
--- a/xts.c
+++ b/xts.c
 #include "macros.h"
 #include "memxor.h"
 #include "nettle-internal.h"
-
-/* shift left one and XOR with 0x87 if there is carry. */
-/* the algorithm reads this as a 128bit Little Endian number */
-/* src and dest can point to the same buffer for in-place operations */
-#if WORDS_BIGENDIAN
-#define BE_SHIFT(x) ((((x) & 0x7f7f7f7f7f7f7f7f) << 1) | \
-                     (((x) & 0x8080808080808080) >> 15))
-static void
-xts_shift(union nettle_block16 *dst,
-          const union nettle_block16 *src)
-{
-  uint64_t carry = (src->u64[1] & 0x80) >> 7;
-  dst->u64[1] = BE_SHIFT(src->u64[1]) | ((src->u64[0] & 0x80) << 49);
-  dst->u64[0] = BE_SHIFT(src->u64[0]) ^ (0x8700000000000000 & -carry);
-}
-#else /* !WORDS_BIGENDIAN */
-static void
-xts_shift(union nettle_block16 *dst,
-          const union nettle_block16 *src)
-{
-  uint64_t carry = src->u64[1] >> 63;
-  dst->u64[1] = (src->u64[1] << 1) | (src->u64[0] >> 63);
-  dst->u64[0] = (src->u64[0] << 1) ^ (0x87 & -carry);
-}
-#endif /* !WORDS_BIGNDIAN */
+#include "block-internal.h"
 
 static void
 check_length(size_t length, uint8_t *dst)
@@ -107,7 +83,7 @@ xts_encrypt_message(const void *enc_ctx, const void *twk_ctx,
 
       /* shift T for next block if any */
       if (length > XTS_BLOCK_SIZE)
-          xts_shift(&T, &T);
+          block16_mulx_le(&T, &T);
     }
 
   /* if the last block is partial, handle via stealing */
@@ -121,7 +97,7 @@ xts_encrypt_message(const void *enc_ctx, const void *twk_ctx,
       memxor(S.b, T.b, XTS_BLOCK_SIZE);                /* CC -> S */
 
       /* shift T for next block */
-      xts_shift(&T, &T);
+      block16_mulx_le(&T, &T);
 
       length -= XTS_BLOCK_SIZE;
       src += XTS_BLOCK_SIZE;
@@ -162,7 +138,7 @@ xts_decrypt_message(const void *dec_ctx, const void *twk_ctx,
 
       /* shift T for next block if any */
       if (length > XTS_BLOCK_SIZE)
-          xts_shift(&T, &T);
+          block16_mulx_le(&T, &T);
     }
 
   /* if the last block is partial, handle via stealing */
@@ -173,7 +149,7 @@ xts_decrypt_message(const void *dec_ctx, const void *twk_ctx,
       union nettle_block16 S;
 
       /* we need the last T(n) and save the T(n-1) for later */
-      xts_shift(&T1, &T);
+      block16_mulx_le(&T1, &T);
 
       memxor3(C.b, src, T1.b, XTS_BLOCK_SIZE); /* C -> CC */
       decf(dec_ctx, XTS_BLOCK_SIZE, S.b, C.b);  /* PP */