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 \
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
+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
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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 */
@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
/ed448-test
/shake256-test
/x86-ibt-test
+/drbg-ctr-aes256-test
/test.in
/test1.out
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 \
--- /dev/null
+/* 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 ();
+ }
+}