git: 7063329b2fc1 - stable/12 - Fortuna: push CTR-mode loop down into randomdev hash.h interface

From: David E. O'Brien <obrien_at_FreeBSD.org>
Date: Fri, 11 Feb 2022 05:54:52 UTC
The branch stable/12 has been updated by obrien:

URL: https://cgit.FreeBSD.org/src/commit/?id=7063329b2fc132f3eebe2680ddf41e85c0fe59c5

commit 7063329b2fc132f3eebe2680ddf41e85c0fe59c5
Author:     Conrad Meyer <cem@FreeBSD.org>
AuthorDate: 2019-03-01 19:21:45 +0000
Commit:     David E. O'Brien <obrien@FreeBSD.org>
CommitDate: 2022-02-11 05:47:36 +0000

    Fortuna: push CTR-mode loop down into randomdev hash.h interface
    
    As a step towards adding other potential streaming ciphers.  As well as just
    pushing the loop down into the rijndael APIs (basically 128-bit wide AES-ICM
    mode) to eliminate some excess explicit_bzero().
    
    No functional change intended.
    
    (cherry picked from commit 51c68d18e2580e5a3949b8c1b331125b71325e0b)
---
 sys/dev/random/fortuna.c | 16 ++++++----------
 sys/dev/random/hash.c    | 23 ++++++++++++++++++-----
 sys/dev/random/hash.h    |  4 +++-
 3 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/sys/dev/random/fortuna.c b/sys/dev/random/fortuna.c
index 11879831dbbd..31fcab9e89ff 100644
--- a/sys/dev/random/fortuna.c
+++ b/sys/dev/random/fortuna.c
@@ -301,20 +301,16 @@ random_fortuna_reseed_internal(uint32_t *entropy_data, u_int blockcount)
 static __inline void
 random_fortuna_genblocks(uint8_t *buf, u_int blockcount)
 {
-	u_int i;
 
 	RANDOM_RESEED_ASSERT_LOCK_OWNED();
 	KASSERT(!uint128_is_zero(fortuna_state.fs_counter), ("FS&K: C != 0"));
 
-	for (i = 0; i < blockcount; i++) {
-		/*-
-		 * FS&K - r = r|E(K,C)
-		 *      - C = C + 1
-		 */
-		randomdev_encrypt(&fortuna_state.fs_key, &fortuna_state.fs_counter, buf, RANDOM_BLOCKSIZE);
-		buf += RANDOM_BLOCKSIZE;
-		uint128_increment(&fortuna_state.fs_counter);
-	}
+	/*
+	 * Fills buf with RANDOM_BLOCKSIZE * blockcount bytes of keystream.
+	 * Increments fs_counter as it goes.
+	 */
+	randomdev_keystream(&fortuna_state.fs_key, &fortuna_state.fs_counter,
+	    buf, blockcount);
 }
 
 /*-
diff --git a/sys/dev/random/hash.c b/sys/dev/random/hash.c
index fe52cd68b848..0bad46519f50 100644
--- a/sys/dev/random/hash.c
+++ b/sys/dev/random/hash.c
@@ -88,13 +88,26 @@ randomdev_encrypt_init(struct randomdev_key *context, const void *data)
 	rijndael_makeKey(&context->key, DIR_ENCRYPT, RANDOM_KEYSIZE*8, data);
 }
 
-/* Encrypt the supplied data using the key schedule preset in the context.
- * <length> bytes are encrypted from <*d_in> to <*d_out>. <length> must be
- * a multiple of RANDOM_BLOCKSIZE.
+/*
+ * Create a psuedorandom output stream of 'blockcount' blocks using a CTR-mode
+ * cipher or similar.  The 128-bit counter is supplied in the in-out parmeter
+ * 'ctr.'  The output stream goes to 'd_out.'  'blockcount' RANDOM_BLOCKSIZE
+ * bytes are generated.
  */
 void
-randomdev_encrypt(struct randomdev_key *context, const void *d_in, void *d_out, u_int length)
+randomdev_keystream(struct randomdev_key *context, uint128_t *ctr,
+    void *d_out, u_int blockcount)
 {
+	u_int i;
 
-	rijndael_blockEncrypt(&context->cipher, &context->key, d_in, length*8, d_out);
+	for (i = 0; i < blockcount; i++) {
+		/*-
+		 * FS&K - r = r|E(K,C)
+		 *      - C = C + 1
+		 */
+		rijndael_blockEncrypt(&context->cipher, &context->key,
+		    (void *)ctr, RANDOM_BLOCKSIZE * 8, d_out);
+		d_out = (char *)d_out + RANDOM_BLOCKSIZE;
+		uint128_increment(ctr);
+	}
 }
diff --git a/sys/dev/random/hash.h b/sys/dev/random/hash.h
index 41dcf9089f0e..ff24d3fb802d 100644
--- a/sys/dev/random/hash.h
+++ b/sys/dev/random/hash.h
@@ -29,6 +29,8 @@
 #ifndef SYS_DEV_RANDOM_HASH_H_INCLUDED
 #define	SYS_DEV_RANDOM_HASH_H_INCLUDED
 
+#include <dev/random/uint128.h>
+
 /* Keys are formed from cipher blocks */
 #define	RANDOM_KEYSIZE		32	/* (in bytes) == 256 bits */
 #define	RANDOM_KEYSIZE_WORDS	(RANDOM_KEYSIZE/sizeof(uint32_t))
@@ -52,6 +54,6 @@ void randomdev_hash_init(struct randomdev_hash *);
 void randomdev_hash_iterate(struct randomdev_hash *, const void *, size_t);
 void randomdev_hash_finish(struct randomdev_hash *, void *);
 void randomdev_encrypt_init(struct randomdev_key *, const void *);
-void randomdev_encrypt(struct randomdev_key *context, const void *, void *, u_int);
+void randomdev_keystream(struct randomdev_key *context, uint128_t *, void *, u_int);
 
 #endif /* SYS_DEV_RANDOM_HASH_H_INCLUDED */