[PATCH] Add CFB8 - Cipher Feedback 8-bit block cipher mode

2018-01-12 Thread Dmitry Eremin-Solenikov
Add CFB variant with 8-bit segment size.

Signed-off-by: Dmitry Eremin-Solenikov 
---
 cfb.c |  75 +
 cfb.h |  35 ++
 nettle.texinfo|  96 +--
 testsuite/cfb-test.c  | 103 +
 testsuite/testutils.c | 178 ++
 testsuite/testutils.h |   7 ++
 6 files changed, 487 insertions(+), 7 deletions(-)

---

CFB8 support, contributed by Dmitry Eremin-Solenikov.
* cfb.c (cfb8_encrypt, cfb8_decrypt): New functions.
* cfb.h (CFB8_CTX, CFB8_SET_IV, CFB8_ENCRYPT, CFB8_DECRYPT): New
macros.
* testsuite/cfb-test.c: CFB8 test cases.
* testsuite/testutils.c (test_cipher_cfb8): New function.
* nettle.texinfo (CFB8): Documentation.

diff --git a/cfb.c b/cfb.c
index 805b8c4533a0..8e0ca47130d4 100644
--- a/cfb.c
+++ b/cfb.c
@@ -162,3 +162,78 @@ cfb_decrypt(const void *ctx, nettle_cipher_func *f,
}
 }
 }
+
+/* CFB-8 uses slight optimization: it encrypts or decrypts up to block_size
+ * bytes and does memcpy/memxor afterwards */
+void
+cfb8_encrypt(const void *ctx, nettle_cipher_func *f,
+   size_t block_size, uint8_t *iv,
+   size_t length, uint8_t *dst,
+   const uint8_t *src)
+{
+  TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
+  TMP_DECL(outbuf, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
+  TMP_ALLOC(buffer, block_size * 2);
+  TMP_ALLOC(outbuf, block_size);
+  uint8_t pos;
+
+  memcpy(buffer, iv, block_size);
+  pos = 0;
+  while (length)
+{
+  uint8_t t;
+
+  if (pos == block_size)
+   {
+ memcpy(buffer, buffer + block_size, block_size);
+ pos = 0;
+   }
+
+  f(ctx, block_size, outbuf, buffer + pos);
+  t = *(dst++) = *(src++) ^ outbuf[0];
+  buffer[pos + block_size] = t;
+  length--;
+  pos ++;
+}
+  memcpy(iv, buffer + pos, block_size);
+}
+
+void
+cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
+size_t block_size, uint8_t *iv,
+size_t length, uint8_t *dst,
+const uint8_t *src)
+{
+  TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
+  TMP_DECL(outbuf, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
+  TMP_ALLOC(buffer, block_size * 2);
+  TMP_ALLOC(outbuf, block_size * 2);
+  uint8_t i = 0;
+
+  memcpy(buffer, iv, block_size);
+  memcpy(buffer + block_size, src,
+length < block_size ? length : block_size);
+
+  while (length)
+{
+
+  for (i = 0; i < length && i < block_size; i++)
+   f(ctx, block_size, outbuf + i, buffer + i);
+
+  if (src != dst)
+   memxor3(dst, src, outbuf, i);
+  else
+   memxor(dst, outbuf, i);
+
+  length -= i;
+  src += i;
+  dst += i;
+
+  memcpy(buffer, buffer + block_size, block_size);
+  memcpy(buffer + block_size, src,
+length < block_size ? length : block_size);
+
+}
+
+  memcpy(iv, buffer + i, block_size);
+}
diff --git a/cfb.h b/cfb.h
index 16660df9b8ab..782ac133aa1c 100644
--- a/cfb.h
+++ b/cfb.h
@@ -45,6 +45,9 @@ extern "C" {
 #define cfb_encrypt nettle_cfb_encrypt
 #define cfb_decrypt nettle_cfb_decrypt
 
+#define cfb8_encrypt nettle_cfb8_encrypt
+#define cfb8_decrypt nettle_cfb8_decrypt
+
 void
 cfb_encrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
@@ -57,12 +60,28 @@ cfb_decrypt(const void *ctx, nettle_cipher_func *f,
size_t length, uint8_t *dst,
const uint8_t *src);
 
+void
+cfb8_encrypt(const void *ctx, nettle_cipher_func *f,
+size_t block_size, uint8_t *iv,
+size_t length, uint8_t *dst,
+const uint8_t *src);
+
+void
+cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
+size_t block_size, uint8_t *iv,
+size_t length, uint8_t *dst,
+const uint8_t *src);
+
+
 #define CFB_CTX(type, size) \
 { type ctx; uint8_t iv[size]; }
 
 #define CFB_SET_IV(ctx, data) \
 memcpy((ctx)->iv, (data), sizeof((ctx)->iv))
 
+#define CFB8_CTX CFB_CTX
+#define CFB8_SET_IV CFB_SET_IV
+
 /* NOTE: Avoid using NULL, as we don't include anything defining it. */
 #define CFB_ENCRYPT(self, f, length, dst, src) \
   (0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
@@ -80,6 +99,22 @@ memcpy((ctx)->iv, (data), sizeof((ctx)->iv))
 sizeof((self)->iv), (self)->iv,\
 (length), (dst), (src)))
 
+#define CFB8_ENCRYPT(self, f, length, dst, src)\
+  (0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
+   (uint8_t *) 0, (const uint8_t *) 0))\
+   : cfb8_encrypt((void *) &(self)->ctx,   \
+ (nettle_cipher_func *) (f),   \
+ sizeof((self)->iv), (self)->iv,   \
+ (length), (dst), (src)))
+
+#define CFB8_DECRYPT(self, f, length, dst, src)\
+  (0 ? 

Re: [PATCH 0/8] Implement Curve448 ECDH and Ed448

2018-01-12 Thread Daiki Ueno
ni...@lysator.liu.se (Niels Möller) writes:

> I think there are three main pieces left to integrate.
>
> 1. Curve operations to support Curve448 (i.e., diffie-hellman
>operations). I have made some progress, on my curve448 branch,
>
> 2. SHAKE 128/256. I think I had some question on the interface design.
>
> 3. EdDSA 448.
>
> Optimization of the mod p arithmetic isn't that important yet,

I see.  I thought that the performance of curve operations should at
least be comparable to P-521.  However, even with the generic ecc_mod
for mod p, those are already close.  So let's look at the above items
first.  I have rebased my patch implementing (1) on the curve448 branch:
https://gitlab.com/dueno/nettle/commits/wip/dueno/curve448-2

One thing I noticed is that the point addition formula for untwisted
curves doesn't look correct:
https://gitlab.com/dueno/nettle/commit/4e3a50f4a50d8d03536dc107d7b77c84462e3068#6c80341e16ba39077bf2507d8450393d7e7e677a_261_262

> but I'll nevertheless try to explain how I think about it.

Thank you for the detailed explanation.  I ran the benchmark for those 3
variants: (1) the original version using ecc_mod, (2) the two step
reduction as you suggest, and (3) my formula optimized with single
7-limbs operations:

size   modp reduce   modq modinv mi_gcd mi_pow dup_jj ad_jja ad_hhh  mul_g  
mul_a (us)
 448 0.0727 0.0720 0.0739  44.01  1.451  52.92  1.088  1.456  1.406  299.6  
557.6
 521 0.0139 0.0151 0.1003  77.72  1.703 101.59  0.728  0.995  1.277  255.8  
588.4

 448 0.0496 0.0497 0.0764  34.77  1.500  49.59  0.923  1.158  1.169  273.5  
500.1
 521 0.0147 0.0144 0.1027  77.63  1.816  88.57  0.716  0.934  1.276  237.2  
589.9

 448 0.0641 0.0644 0.0809  52.76  1.570  49.42  1.007  1.340  1.343  288.1  
570.5
 521 0.0139 0.0141 0.0967  78.22  1.697  99.44  0.714  1.012  1.264  235.8  
589.2

on Core i7-6600U CPU @ 2.60GHz.

My code could be wrong or inefficient, but actually (2) is the fastest.
(3) is slower due to the final carry handling; the carry is accumulated
at most 3 and wrapping around it with cnd_add_n seems to be costly.

Regards,
-- 
Daiki Ueno
___
nettle-bugs mailing list
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs


Re: cmac

2018-01-12 Thread Nikos Mavrogiannopoulos
On Fri, 2018-01-12 at 11:51 +0100, Nikos Mavrogiannopoulos wrote:
> On Wed, 2018-01-10 at 11:24 +0100, Niels Möller wrote:
> > Nikos Mavrogiannopoulos  writes:
> > 
> > >  The attached patch brings support for AES-128-CMAC. The code is
> > > based
> > > on the samba code.
> > 
> > Nice. I think I'll have to read up a bit to understand what it's
> > doing.
> > 
> > > The rshift and lshift functions come from the AES
> > > implementation bundled with samba.
> > 
> > These to just a single bit right or left shift of a 16-byte block?
> > To
> > me
> > it seems odd to do that with a table lookup for each byte.
> 
> Indeed, and I don't see any obvious benefit of that code. I've
> replaced
> it with a simpler version.

Re-sending as it seems I forgot to remove cmac-internal from makefile.

regards,
Nikos
From 929f1a4cb927bf7e16df7980e4d9c30586a894fb Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos 
Date: Wed, 10 Jan 2018 09:29:17 +0100
Subject: [PATCH] Added support for CMAC

That adds support for CMAC as a generic framework for
128-bit block and key ciphers, as well as API for AES-128-CMAC.

Signed-off-by: Nikos Mavrogiannopoulos 
---
 Makefile.in |   2 +
 cmac-aes128.c   |  60 ++
 cmac.c  | 150 
 cmac.h  | 117 ++
 examples/nettle-benchmark.c |  24 ++-
 testsuite/.test-rules.make  |   3 +
 testsuite/Makefile.in   |   1 +
 testsuite/cmac-test.c   |  57 +
 8 files changed, 413 insertions(+), 1 deletion(-)
 create mode 100644 cmac-aes128.c
 create mode 100644 cmac.c
 create mode 100644 cmac.h
 create mode 100644 testsuite/cmac-test.c

diff --git a/Makefile.in b/Makefile.in
index 6a0c13ec..a25c0f99 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -103,6 +103,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
 		 gcm-aes256.c gcm-aes256-meta.c \
 		 gcm-camellia128.c gcm-camellia128-meta.c \
 		 gcm-camellia256.c gcm-camellia256-meta.c \
+		 cmac.c cmac-aes128.c \
 		 gosthash94.c gosthash94-meta.c \
 		 hmac.c hmac-md5.c hmac-ripemd160.c hmac-sha1.c \
 		 hmac-sha224.c hmac-sha256.c hmac-sha384.c hmac-sha512.c \
@@ -195,6 +196,7 @@ HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \
 	  gcm.h gosthash94.h hmac.h \
 	  knuth-lfib.h hkdf.h \
 	  macros.h \
+	  cmac.h \
 	  md2.h md4.h \
 	  md5.h md5-compat.h \
 	  memops.h memxor.h \
diff --git a/cmac-aes128.c b/cmac-aes128.c
new file mode 100644
index ..e53e114e
--- /dev/null
+++ b/cmac-aes128.c
@@ -0,0 +1,60 @@
+/* cmac-aes128.c
+
+   CMAC using AES128 as the underlying cipher.
+
+   Copyright (C) 2017 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 
+
+#include "cmac.h"
+
+void
+cmac_aes128_set_key(struct cmac_aes128_ctx *ctx, const uint8_t *key)
+{
+  CMAC128_SET_KEY(ctx, aes128_set_encrypt_key, aes128_encrypt, key);
+}
+
+void
+cmac_aes128_update (struct cmac_aes128_ctx *ctx,
+		   size_t length, const uint8_t *data)
+{
+  CMAC128_UPDATE (ctx, aes128_encrypt, length, data);
+}
+
+void
+cmac_aes128_digest(struct cmac_aes128_ctx *ctx,
+		  size_t length, uint8_t *digest)
+{
+  CMAC128_DIGEST(ctx, aes128_encrypt, length, digest);
+}
diff --git a/cmac.c b/cmac.c
new file mode 100644
index ..b4886808
--- /dev/null
+++ b/cmac.c
@@ -0,0 +1,150 @@
+/*
+   AES-CMAC-128 (rfc 4493)
+   Copyright (C) Stefan Metzmacher 2012
+   Copyright (C) Jeremy Allison 2012
+   Copyright (C) Michael Adam 2012
+   Copyright (C) 2017, Red Hat Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the