From 8834cd412be07641808be222959b0582d1c3508e Mon Sep 17 00:00:00 2001 From: Simon Josefsson <simon@josefsson.org> Date: Wed, 10 May 2023 10:28:29 +0200 Subject: [PATCH] Add DRBG-CTR-AES256. --- Makefile.in | 6 +- NEWS | 6 ++ drbg-ctr-aes256.c | 100 +++++++++++++++++++++++++++++++ drbg-ctr.h | 69 +++++++++++++++++++++ nettle.texinfo | 39 ++++++++++++ testsuite/.gitignore | 1 + testsuite/Makefile.in | 2 +- testsuite/drbg-ctr-aes256-test.c | 74 +++++++++++++++++++++++ 8 files changed, 294 insertions(+), 3 deletions(-) create mode 100644 drbg-ctr-aes256.c create mode 100644 drbg-ctr.h create mode 100644 testsuite/drbg-ctr-aes256-test.c diff --git a/Makefile.in b/Makefile.in index 779b8922..905ebd6b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -164,7 +164,8 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c aes-decrypt-table.c \ version.c \ write-be32.c write-le32.c write-le64.c \ yarrow256.c yarrow_key_event.c \ - xts.c xts-aes128.c xts-aes256.c + xts.c xts-aes128.c xts-aes256.c \ + drbg-ctr-aes256.c hogweed_SOURCES = sexp.c sexp-format.c \ sexp-transport.c sexp-transport-format.c \ @@ -243,7 +244,8 @@ HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h balloon.h \ pgp.h pkcs1.h pss.h pss-mgf1.h realloc.h ripemd160.h rsa.h \ salsa20.h sexp.h serpent.h \ sha.h sha1.h sha2.h sha3.h sm3.h sm4.h streebog.h twofish.h \ - umac.h yarrow.h xts.h poly1305.h nist-keywrap.h + umac.h yarrow.h xts.h poly1305.h nist-keywrap.h \ + drbg-ctr.h INSTALL_HEADERS = $(HEADERS) version.h @IF_MINI_GMP@ mini-gmp.h diff --git a/NEWS b/NEWS index 413538c6..cf51326b 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +NEWS for the Nettle 3.10 release + + New features: + + * Added DRBG-CTR with AES256, contributed by Simon Josefsson. + NEWS for the Nettle 3.9.1 release This is a bugfix release, fixing a few bugs reported for diff --git a/drbg-ctr-aes256.c b/drbg-ctr-aes256.c new file mode 100644 index 00000000..b3e8e194 --- /dev/null +++ b/drbg-ctr-aes256.c @@ -0,0 +1,100 @@ +/* drbg-ctr-aes256.c + + Copyright (C) 2023 Simon Josefsson + + 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 "drbg-ctr.h" + +#include <string.h> +#include "macros.h" +#include "memxor.h" + +static void +drbg_ctr_aes256_update (struct aes256_ctx *Key, + uint8_t *V, uint8_t *provided_data) +{ + uint8_t tmp[DRBG_CTR_AES256_SEED_SIZE]; + + INCREMENT (AES_BLOCK_SIZE, V); + aes256_encrypt (Key, AES_BLOCK_SIZE, tmp, V); + + INCREMENT (AES_BLOCK_SIZE, V); + aes256_encrypt (Key, AES_BLOCK_SIZE, tmp + AES_BLOCK_SIZE, V); + + INCREMENT (AES_BLOCK_SIZE, V); + aes256_encrypt (Key, AES_BLOCK_SIZE, tmp + 2 * AES_BLOCK_SIZE, V); + + if (provided_data) + memxor (tmp, provided_data, 48); + + aes256_set_encrypt_key (Key, tmp); + + memcpy (V, tmp + AES256_KEY_SIZE, AES_BLOCK_SIZE); +} + +void +drbg_ctr_aes256_init (struct drbg_ctr_aes256_ctx *ctx, uint8_t *seed_material) +{ + uint8_t Key[AES256_KEY_SIZE]; + + memset (Key, 0, AES256_KEY_SIZE); + aes256_set_encrypt_key (&ctx->Key, Key); + + memset (ctx->V, 0, AES_BLOCK_SIZE); + + drbg_ctr_aes256_update (&ctx->Key, ctx->V, seed_material); +} + +void +drbg_ctr_aes256_random (struct drbg_ctr_aes256_ctx *ctx, + size_t n, uint8_t *dst) +{ + while (n >= AES_BLOCK_SIZE) + { + INCREMENT (AES_BLOCK_SIZE, ctx->V); + aes256_encrypt (&ctx->Key, AES_BLOCK_SIZE, dst, ctx->V); + dst += AES_BLOCK_SIZE; + n -= AES_BLOCK_SIZE; + } + + if (n > 0) + { + uint8_t block[AES_BLOCK_SIZE]; + + INCREMENT (AES_BLOCK_SIZE, ctx->V); + aes256_encrypt (&ctx->Key, AES_BLOCK_SIZE, block, ctx->V); + memcpy (dst, block, n); + } + + drbg_ctr_aes256_update (&ctx->Key, ctx->V, NULL); +} diff --git a/drbg-ctr.h b/drbg-ctr.h new file mode 100644 index 00000000..63ac3680 --- /dev/null +++ b/drbg-ctr.h @@ -0,0 +1,69 @@ +/* drbg-ctr.h + + 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_DRBG_CTR_H_INCLUDED +#define NETTLE_DRBG_CTR_H_INCLUDED + +#include "nettle-types.h" + +#include "aes.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Namespace mangling */ +#define drbg_ctr_aes256_init nettle_drbg_ctr_aes256_init +#define drbg_ctr_aes256_random nettle_drbg_ctr_aes256_random + +#define DRBG_CTR_AES256_SEED_SIZE (AES_BLOCK_SIZE + AES256_KEY_SIZE) + +struct drbg_ctr_aes256_ctx +{ + struct aes256_ctx Key; + uint8_t V[AES_BLOCK_SIZE]; +}; + +/* Initialize using DRBG_CTR_AES256_SEED_SIZE bytes of + SEED_MATERIAL. */ +void +drbg_ctr_aes256_init (struct drbg_ctr_aes256_ctx *ctx, + uint8_t *seed_material); + +/* Output N bytes of random data into DST. */ +void +drbg_ctr_aes256_random (struct drbg_ctr_aes256_ctx *ctx, + size_t n, uint8_t *dst); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_DRBG_CTR_H_INCLUDED */ diff --git a/nettle.texinfo b/nettle.texinfo index 736150d9..2da63453 100644 --- a/nettle.texinfo +++ b/nettle.texinfo @@ -6298,6 +6298,45 @@ Returns an entropy estimate, in bits, suitable for calling @code{yarrow256_update}. Usually, 0, 1 or 2 bits. @end deftypefun +@subsection DRBG-CTR + +The Deterministic Random Bit Generator (DRBG) family is a complex family +of deterministic randomness generators published by NIST in SP 800-90A. + +We support what we believe is the reasonable parts of the CTR_DRBG +algorithm for AES256. Re-seeding, personalization strings, derivation +functions and support for non-AES256 is not implemented. +Personalization strings can be implemented by the caller, if desired, +with xor. If you need re-seeding or entropy derivation, we suggest that +you use Yarrow instead. + +The security bounds of DRBG-CTR are not intuitive, see ``Security Bounds +for the NIST Codebook-based Deterministic Random Bit Generator'' by +Matthew J. Campagna, from @url{https://eprint.iacr.org/2006/379.pdf}. + +Our suggested use-case for DRBG-CTR is to deterministically generate +known values from a seed when comparing against expected values for some +other algorithm. + +Nettle defines DRBG-CTR in @file{<nettle/drbg-ctr.h>}. + +@deftp {Context struct} {struct drbg_ctr_aes256_ctx} +@end deftp + +@defvr Constant DRBG_CTR_AES256_SEED_SIZE +The size of the seeding material. +@end defvr + +@deftypefun void drbg_ctr_aes256_init (struct drbg_ctr_aes256_ctx *@var{ctx}, uint8_t *@var{seed_material}) +Initialize the DRBG-CTR-AES256 context using +@code{DRBG_CTR_AES256_SEED_SIZE} bytes of @var{seed_material}. +@end deftypefun + +@deftypefun void drbg_ctr_aes256_random (struct drbg_ctr_aes256_ctx *@var{ctx}, size_t n, uint8_t *@var{dst}); +Generates @var{n} octets of output into @var{dst}. The generator must +be initialized before you call this function. +@end deftypefun + @node ASCII encoding @section ASCII encoding diff --git a/testsuite/.gitignore b/testsuite/.gitignore index 8c91d1af..f2378152 100644 --- a/testsuite/.gitignore +++ b/testsuite/.gitignore @@ -113,6 +113,7 @@ /ed448-test /shake256-test /x86-ibt-test +/drbg-ctr-aes256-test /test.in /test1.out diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index c11023a3..eb68fe89 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -34,7 +34,7 @@ TS_NETTLE_SOURCES = aes-test.c aes-keywrap-test.c arcfour-test.c arctwo-test.c \ meta-hash-test.c meta-cipher-test.c\ meta-aead-test.c meta-armor-test.c meta-mac-test.c \ buffer-test.c yarrow-test.c xts-test.c pbkdf2-test.c \ - x86-ibt-test.c + x86-ibt-test.c drbg-ctr-aes256.c TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \ rsa2sexp-test.c sexp2rsa-test.c \ diff --git a/testsuite/drbg-ctr-aes256-test.c b/testsuite/drbg-ctr-aes256-test.c new file mode 100644 index 00000000..4f09d805 --- /dev/null +++ b/testsuite/drbg-ctr-aes256-test.c @@ -0,0 +1,74 @@ +/* drbg-ctr-aes256-test.c + + Copyright (C) 2023 Simon Josefsson + + 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/. +*/ + +#include "testutils.h" + +#include "drbg-ctr.h" + +void +test_main (void) +{ + struct drbg_ctr_aes256_ctx rng; + uint8_t seed_material[DRBG_CTR_AES256_SEED_SIZE]; + uint8_t tmp[DRBG_CTR_AES256_SEED_SIZE]; + size_t i; + + /* https://ntruprime.cr.yp.to/nist/ntruprime-20201007/Reference_Implementation/kem/sntrup761/nist/kat_kem.c.html + https://ntruprime.cr.yp.to/nist/ntruprime-20201007/KAT/kem/sntrup761/kat_kem.req.html + */ + + for (i = 0; i < DRBG_CTR_AES256_SEED_SIZE; i++) + seed_material[i] = i; + + drbg_ctr_aes256_init (&rng, seed_material); + + drbg_ctr_aes256_random (&rng, DRBG_CTR_AES256_SEED_SIZE, tmp); + if (!MEMEQ (DRBG_CTR_AES256_SEED_SIZE, + tmp, + H ("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479" + "D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"))) + { + printf ("drbg_ctr_aes256 = "); + print_hex (DRBG_CTR_AES256_SEED_SIZE, tmp); + abort (); + } + + drbg_ctr_aes256_random (&rng, DRBG_CTR_AES256_SEED_SIZE, tmp); + if (!MEMEQ (DRBG_CTR_AES256_SEED_SIZE, + tmp, + H ("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55" + "B22E75BF57BB556AC81ADDE6AEEB4A5A875C3BFCADFA958F"))) + { + printf ("drbg_ctr_aes256 = "); + print_hex (DRBG_CTR_AES256_SEED_SIZE, tmp); + abort (); + } +} -- GitLab