]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Generalize _ctr_crypt16, so it can be used also for gcm.
authorNiels Möller <nisse@lysator.liu.se>
Thu, 1 Feb 2018 19:27:33 +0000 (20:27 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Thu, 1 Feb 2018 19:45:51 +0000 (20:45 +0100)
ChangeLog
Makefile.in
ctr-internal.h [new file with mode: 0644]
ctr.c
ctr16.c [new file with mode: 0644]

index 547fb590274246fb73f1adbdac2a086998899724..4697be51da1d9b8b047e307f9d5662630f2de63c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2018-02-01  Niels Möller  <nisse@lysator.liu.se>
+
+       Based on a patch contributed by Nikos Mavrogiannopoulos.
+       * ctr16.c (_ctr_crypt16): New file, renamed and generalized
+       function. New function pointer argument, used to fill a block with
+       counter values. Use nettle_block16 * as the type for the buffer to
+       be filled. Always process any final and partial block, and return
+       no value.
+       * ctr.c (ctr_crypt): ... previous, replaced, function.
+       (ctr_fill16): Updated to new argument type.
+       (ctr_crypt): Return immediately after using _ctr_crypt16.
+
+       * ctr-internal.h: New file, declaring _ctr_crypt16.
+       (nettle_fill16_func): New function typedef.
+
+       * Makefile.in (nettle_SOURCES): Added ctr16.c.
+       (DISTFILES): Added ctr-internal.h.
+
 2018-01-30  Niels Möller  <nisse@lysator.liu.se>
 
        * Makefile.in (clean-here): Don't delete desdata.stamp.
index 08d2208ef345d9ea56e4f67e0aa9a0e26a992285..4444e8bdb402f52d35c9612002e1fd7e74ebf453 100644 (file)
@@ -92,7 +92,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
                 chacha-crypt.c chacha-core-internal.c \
                 chacha-poly1305.c chacha-poly1305-meta.c \
                 chacha-set-key.c chacha-set-nonce.c \
-                ctr.c des.c des3.c des-compat.c \
+                ctr.c ctr16.c des.c des3.c des-compat.c \
                 eax.c eax-aes128.c eax-aes128-meta.c \
                 gcm.c gcm-aes.c \
                 gcm-aes128.c gcm-aes128-meta.c \
@@ -225,6 +225,7 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \
        aes-internal.h camellia-internal.h serpent-internal.h \
        cast128_sboxes.h desinfo.h desCode.h \
        memxor-internal.h nettle-internal.h nettle-write.h \
+       ctr-internal.h \
        gmp-glue.h ecc-internal.h fat-setup.h \
        mini-gmp.h asm.m4 \
        nettle.texinfo nettle.info nettle.html nettle.pdf sha-example.c
diff --git a/ctr-internal.h b/ctr-internal.h
new file mode 100644 (file)
index 0000000..d8bc136
--- /dev/null
@@ -0,0 +1,56 @@
+/* ctr-internal.h
+
+   Copyright (C) 2018 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_CTR_INTERNAL_H_INCLUDED
+#define NETTLE_CTR_INTERNAL_H_INCLUDED
+
+#include "nettle-types.h"
+
+/* Name mangling */
+#define _ctr_crypt16 _nettle_ctr_crypt16
+
+/* Size limit for temporary stack buffers. */
+#define CTR_BUFFER_LIMIT 512
+
+/* Fill BUFFER (n blocks) with incrementing CTR values. It would be
+   nice if CTR was always 64-bit aligned, but it isn't when called
+   from ctr_crypt. */
+typedef void
+nettle_fill16_func(uint8_t *ctr, size_t n, union nettle_block16 *buffer);
+
+void
+_ctr_crypt16(const void *ctx, nettle_cipher_func *f,
+            nettle_fill16_func *fill, uint8_t *ctr,
+            size_t length, uint8_t *dst,
+            const uint8_t *src);
+
+
+#endif /* NETTLE_CTR_INTERNAL_H_INCLUDED */
diff --git a/ctr.c b/ctr.c
index ee5b28887b747ab11b903338ec5a7bfd79acacce..c6601547fd55094cb9fb338ab420df2a6dee9de7 100644 (file)
--- a/ctr.c
+++ b/ctr.c
 
 #include "ctr.h"
 
+#include "ctr-internal.h"
 #include "macros.h"
 #include "memxor.h"
 #include "nettle-internal.h"
 
-/* Don't allocate any more space than this on the stack */
-#define CTR_BUFFER_LIMIT 512
-
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 
 static size_t
@@ -64,17 +62,19 @@ ctr_fill (size_t block_size, uint8_t *ctr, size_t length, uint8_t *buffer)
 
 #if WORDS_BIGENDIAN
 # define USE_CTR_CRYPT16 1
+static nettle_fill16_func ctr_fill16;
 static void
-ctr_fill16(uint8_t *ctr, size_t blocks, uint64_t *buffer)
+ctr_fill16(uint8_t *ctr, size_t blocks, union nettle_block16 *buffer)
 {
   uint64_t hi, lo;
+  size_t i;
   hi = READ_UINT64(ctr);
   lo = READ_UINT64(ctr + 8);
 
-  while (blocks-- > 0)
+  for (i = 0; i < blocks; i++)
     {
-      *buffer++ = hi;
-      *buffer++ = lo;
+      buffer[i].u64[0] = hi;
+      buffer[i].u64[1] = lo;
       hi += !(++lo);
     }
   WRITE_UINT64(ctr, hi);
@@ -83,18 +83,20 @@ ctr_fill16(uint8_t *ctr, size_t blocks, uint64_t *buffer)
 #else /* !WORDS_BIGENDIAN */
 # if HAVE_BUILTIN_BSWAP64
 #  define USE_CTR_CRYPT16 1
+static nettle_fill16_func ctr_fill16;
 static void
-ctr_fill16(uint8_t *ctr, size_t blocks, uint64_t *buffer)
+ctr_fill16(uint8_t *ctr, size_t blocks, union nettle_block16 *buffer)
 {
   uint64_t hi, lo;
+  size_t i;
   /* Read hi in native endianness */
   hi = LE_READ_UINT64(ctr);
   lo = READ_UINT64(ctr + 8);
 
-  while (blocks-- > 0)
+  for (i = 0; i < blocks; i++)
     {
-      *buffer++ = hi;
-      *buffer++ = __builtin_bswap64(lo);
+      buffer[i].u64[0] = hi;
+      buffer[i].u64[1] = __builtin_bswap64(lo);
       if (!++lo)
        hi = __builtin_bswap64(__builtin_bswap64(hi) + 1);
     }
@@ -106,53 +108,6 @@ ctr_fill16(uint8_t *ctr, size_t blocks, uint64_t *buffer)
 # endif
 #endif /* !WORDS_BIGENDIAN */
 
-#if USE_CTR_CRYPT16
-static size_t
-ctr_crypt16(const void *ctx, nettle_cipher_func *f,
-           uint8_t *ctr,
-           size_t length, uint8_t *dst,
-           const uint8_t *src)
-{
-  if (dst != src && !((uintptr_t) dst % sizeof(uint64_t)))
-    {
-      size_t blocks = length / 16u;
-      ctr_fill16 (ctr, blocks, (uint64_t *) dst);
-      f(ctx, blocks * 16, dst, dst);
-      memxor (dst, src, blocks * 16);
-      return blocks * 16;
-    }
-  else
-    {
-      /* Construct an aligned buffer of consecutive counter values, of
-        size at most CTR_BUFFER_LIMIT. */
-      TMP_DECL(buffer, union nettle_block16, CTR_BUFFER_LIMIT / 16);
-      size_t blocks = (length + 15) / 16u;
-      size_t i;
-      TMP_ALLOC(buffer, MIN(blocks, CTR_BUFFER_LIMIT / 16));
-
-      for (i = 0; blocks >= CTR_BUFFER_LIMIT / 16;
-          i += CTR_BUFFER_LIMIT, blocks -= CTR_BUFFER_LIMIT / 16)
-       {
-         ctr_fill16 (ctr, CTR_BUFFER_LIMIT / 16, buffer->u64);
-         f(ctx, CTR_BUFFER_LIMIT, buffer->b, buffer->b);
-         if (length - i < CTR_BUFFER_LIMIT)
-           goto done;
-         memxor3 (dst, src, buffer->b, CTR_BUFFER_LIMIT);
-       }
-
-      if (blocks > 0)
-       {
-         assert (length - i < CTR_BUFFER_LIMIT);
-         ctr_fill16 (ctr, blocks, buffer->u64);
-         f(ctx, blocks * 16, buffer->b, buffer->b);
-       done:
-         memxor3 (dst + i, src + i, buffer->b, length - i);
-      }
-      return length;
-    }
-}
-#endif /* USE_CTR_CRYPT16 */
-
 void
 ctr_crypt(const void *ctx, nettle_cipher_func *f,
          size_t block_size, uint8_t *ctr,
@@ -162,10 +117,8 @@ ctr_crypt(const void *ctx, nettle_cipher_func *f,
 #if USE_CTR_CRYPT16
   if (block_size == 16)
     {
-      size_t done = ctr_crypt16(ctx, f, ctr, length, dst, src);
-      length -= done;
-      src += done;
-      dst += done;
+      _ctr_crypt16(ctx, f, ctr_fill16, ctr, length, dst, src);
+      return;
     }
 #endif
 
diff --git a/ctr16.c b/ctr16.c
new file mode 100644 (file)
index 0000000..60418e8
--- /dev/null
+++ b/ctr16.c
@@ -0,0 +1,106 @@
+/* ctr16.c
+
+   Cipher counter mode, optimized for 16-byte blocks.
+
+   Copyright (C) 2005-2018 Niels Möller
+   Copyright (C) 2018 Red Hat, Inc.
+
+   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/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "ctr.h"
+
+#include "ctr-internal.h"
+#include "memxor.h"
+#include "nettle-internal.h"
+
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+
+void
+_ctr_crypt16(const void *ctx, nettle_cipher_func *f,
+            nettle_fill16_func *fill, uint8_t *ctr,
+            size_t length, uint8_t *dst,
+            const uint8_t *src)
+{
+  if (dst != src && !((uintptr_t) dst % sizeof(uint64_t)))
+    {
+      size_t blocks = length / 16u;
+      size_t done;
+      fill (ctr, blocks, (union nettle_block16 *) dst);
+
+      done = blocks * 16;
+      f(ctx, done, dst, dst);
+      memxor (dst, src, done);
+
+      length -= done;
+      if (length > 0)
+       { /* Left-over partial block */
+         union nettle_block16 block;
+         dst += done;
+         src += done;
+         assert (length < 16);
+         /* Use fill, to update ctr value in the same way in all cases. */
+         fill (ctr, 1, &block);
+         f (ctx, 16, block.b, block.b);
+         memxor3 (dst, src, block.b, length);
+       }
+    }
+  else
+    {
+      /* Construct an aligned buffer of consecutive counter values, of
+        size at most CTR_BUFFER_LIMIT. */
+      TMP_DECL(buffer, union nettle_block16, CTR_BUFFER_LIMIT / 16);
+      size_t blocks = (length + 15) / 16u;
+      size_t i;
+      TMP_ALLOC(buffer, MIN(blocks, CTR_BUFFER_LIMIT / 16));
+
+      for (i = 0; blocks >= CTR_BUFFER_LIMIT / 16;
+          i += CTR_BUFFER_LIMIT, blocks -= CTR_BUFFER_LIMIT / 16)
+       {
+         fill (ctr, CTR_BUFFER_LIMIT / 16, buffer);
+         f(ctx, CTR_BUFFER_LIMIT, buffer->b, buffer->b);
+         if (length - i < CTR_BUFFER_LIMIT)
+           goto done;
+         memxor3 (dst, src, buffer->b, CTR_BUFFER_LIMIT);
+       }
+
+      if (blocks > 0)
+       {
+         assert (length - i < CTR_BUFFER_LIMIT);
+         fill (ctr, blocks, buffer);
+         f(ctx, blocks * 16, buffer->b, buffer->b);
+       done:
+         memxor3 (dst + i, src + i, buffer->b, length - i);
+       }
+    }
+}