On Tue, 2018-01-30 at 20:57 +0100, Niels Möller wrote: > Nikos Mavrogiannopoulos <[email protected]> writes: > > > To follow up on this, gcm would get an 8% (on my system) speedup by > > switching gcm_crypt() with ctr_crypt(). With that change as is > > however, > > the 32-bit counter is replaced with an "unlimited" counter. > > Wouldn't > > introducing an assert on decrypt and encrypt length be sufficient > > to > > share that code? > > I think it's valid to use gcm with an IV which makes the 32-bit > counter > start close to 2^32 - 1, and then propagating carry further then 32 > bits > would produce incorrect results. Right? (I'm afraid there's no test > case > for that, though). > > I agree it would be very nice to reuse ctr_crypt and not duplicate > most > of the logic. But I think we need a gcm-specific variant of ctr_fill. > To > do that, it would make sense to add a field > > uint32_t u32[4]; > > to the nettle_block16 union. > > To reduce code duplication, we could add a fill function pointer as > argument to ctr_crypt16, and use that for gcm. Not sure if that's a > good > idea, but it might be nice and clean and indirect call to the fill > function should be negligible.
It seems that ctr_crypt16() would not handle the whole input and that was complicating things. I've modified it towards that, and added the parameter. I did a gcm_fill(), but I didn't see the need for the nettle_block16 update, as the version I did (quite simplistic), didn't seem to differ in performance comparing to ctr_fill16. regards, Nikos
From 10ce4feedec9df53636aa64e41e43e01d260f42c Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos <[email protected]> Date: Wed, 31 Jan 2018 13:22:20 +0100 Subject: [PATCH] gcm: use ctr_crypt16() for improved performance That also enhances ctr_crypt16() to be complete and handle the full input. --- Makefile.in | 1 + ctr-internal.h | 39 +++++++++++++++++++++++++++++++++++++++ ctr.c | 44 ++++++++++++++++++++++++++++++-------------- gcm.c | 50 ++++++++++++++++++-------------------------------- 4 files changed, 88 insertions(+), 46 deletions(-) create mode 100644 ctr-internal.h diff --git a/Makefile.in b/Makefile.in index 6a0c13ec..58980341 100644 --- a/Makefile.in +++ b/Makefile.in @@ -228,6 +228,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 index 00000000..246afaba --- /dev/null +++ b/ctr-internal.h @@ -0,0 +1,39 @@ +/* ctr.c + + Cipher counter mode. + + Copyright (C) 2005-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/. +*/ + +void +ctr_crypt16(const void *ctx, nettle_cipher_func *f, + void (*fillfunc)(uint8_t *ctr, size_t blocks, uint64_t *buffer), + uint8_t *ctr, + size_t length, uint8_t *dst, + const uint8_t *src); diff --git a/ctr.c b/ctr.c index 8295e1af..2c7ddf3d 100644 --- a/ctr.c +++ b/ctr.c @@ -40,6 +40,7 @@ #include <string.h> #include "ctr.h" +#include "ctr-internal.h" #include "macros.h" #include "memxor.h" @@ -106,20 +107,37 @@ ctr_fill16(uint8_t *ctr, size_t blocks, uint64_t *buffer) # endif #endif /* !WORDS_BIGENDIAN */ -#if USE_CTR_CRYPT16 -static size_t +void ctr_crypt16(const void *ctx, nettle_cipher_func *f, + void (*fill)(uint8_t *ctr, size_t blocks, uint64_t *buffer), uint8_t *ctr, size_t length, uint8_t *dst, const uint8_t *src) { if (dst != src && !((uintptr_t) dst % sizeof(uint64_t))) { + size_t done; 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; + fill (ctr, blocks, (uint64_t *) dst); + + done = blocks * 16; + f(ctx, done, dst, dst); + memxor (dst, src, done); + + dst += done; + src += done; + length -= done; + + /* remainder < 1 block */ + if (length > 0) + { + uint8_t block[16]; + + f(ctx, 16, block, ctr); + fill (ctr, 1, (uint64_t *) ctr); + memxor3(dst, src, block, length); + } + return; } else { @@ -133,7 +151,7 @@ ctr_crypt16(const void *ctx, nettle_cipher_func *f, 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); + fill (ctr, CTR_BUFFER_LIMIT / 16, buffer->u64); f(ctx, CTR_BUFFER_LIMIT, buffer->b, buffer->b); if (length - i < CTR_BUFFER_LIMIT) goto done; @@ -143,15 +161,14 @@ ctr_crypt16(const void *ctx, nettle_cipher_func *f, if (blocks > 0) { assert (length - i < CTR_BUFFER_LIMIT); - ctr_fill16 (ctr, blocks, buffer->u64); + fill (ctr, blocks, buffer->u64); f(ctx, blocks * 16, buffer->b, buffer->b); done: memxor3 (dst + i, src + i, buffer->b, length - i); } - return length; + return; } } -#endif /* USE_CTR_CRYPT16 */ void ctr_crypt(const void *ctx, nettle_cipher_func *f, @@ -162,10 +179,9 @@ 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/gcm.c b/gcm.c index 0a2102f1..062410e9 100644 --- a/gcm.c +++ b/gcm.c @@ -51,6 +51,7 @@ #include "memxor.h" #include "nettle-internal.h" #include "macros.h" +#include "ctr.h" #define GHASH_POLYNOMIAL 0xE1UL @@ -435,40 +436,25 @@ gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key, } static void -gcm_crypt(struct gcm_ctx *ctx, const void *cipher, nettle_cipher_func *f, - size_t length, uint8_t *dst, const uint8_t *src) +gcm_fill(uint8_t *ctr, size_t blocks, uint64_t *_buffer) { - uint8_t buffer[GCM_BLOCK_SIZE]; + uint8_t *buffer = _buffer; + uint32_t c; - if (src != dst) - { - for (; length >= GCM_BLOCK_SIZE; - (length -= GCM_BLOCK_SIZE, - src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE)) - { - f (cipher, GCM_BLOCK_SIZE, dst, ctx->ctr.b); - memxor (dst, src, GCM_BLOCK_SIZE); - INC32 (ctx->ctr); - } - } - else - { - for (; length >= GCM_BLOCK_SIZE; - (length -= GCM_BLOCK_SIZE, - src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE)) - { - f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b); - memxor (dst, buffer, GCM_BLOCK_SIZE); - INC32 (ctx->ctr); - } - } - if (length > 0) + c = READ_UINT32(ctr + GCM_BLOCK_SIZE - 4); + + while (blocks-- > 0) { - /* A final partial block */ - f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b); - memxor3 (dst, src, buffer, length); - INC32 (ctx->ctr); + memcpy(buffer, ctr, GCM_BLOCK_SIZE - 4); + buffer += GCM_BLOCK_SIZE - 4; + + WRITE_UINT32(buffer, c); + buffer += 4; + + c++; } + + WRITE_UINT32(ctr + GCM_BLOCK_SIZE - 4, c); } void @@ -478,7 +464,7 @@ gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key, { assert(ctx->data_size % GCM_BLOCK_SIZE == 0); - gcm_crypt(ctx, cipher, f, length, dst, src); + ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src); gcm_hash(key, &ctx->x, length, dst); ctx->data_size += length; @@ -492,7 +478,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); - gcm_crypt(ctx, cipher, f, length, dst, src); + ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src); ctx->data_size += length; } -- 2.14.3
_______________________________________________ nettle-bugs mailing list [email protected] http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs
