diff options
author | Niels Möller <nisse@lysator.liu.se> | 2018-02-01 20:27:33 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2018-02-01 20:45:51 +0100 |
commit | 3919ca296ed152801514ac18663b0aff27a3a9db (patch) | |
tree | c154c2b78292159831c5636ea1452de4e8e36866 | |
parent | 1af2ce835bad82f0f5df4bcde2b83abbf6f16352 (diff) | |
download | nettle-3919ca296ed152801514ac18663b0aff27a3a9db.tar.gz |
Generalize _ctr_crypt16, so it can be used also for gcm.
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | Makefile.in | 3 | ||||
-rw-r--r-- | ctr-internal.h | 56 | ||||
-rw-r--r-- | ctr.c | 77 | ||||
-rw-r--r-- | ctr16.c | 106 |
5 files changed, 197 insertions, 63 deletions
@@ -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. diff --git a/Makefile.in b/Makefile.in index 08d2208e..4444e8bd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 index 00000000..d8bc1365 --- /dev/null +++ b/ctr-internal.h @@ -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 */ @@ -41,13 +41,11 @@ #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 index 00000000..60418e8b --- /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); + } + } +} |