git: 7e4be228aa36 - stable/12 - Embedded chacha: Add 0-bit iv + 128-bit counter mode

From: David E. O'Brien <obrien_at_FreeBSD.org>
Date: Sat, 12 Feb 2022 22:58:34 UTC
The branch stable/12 has been updated by obrien:

URL: https://cgit.FreeBSD.org/src/commit/?id=7e4be228aa36fb6be214c166971c33fb2f24dcb3

commit 7e4be228aa36fb6be214c166971c33fb2f24dcb3
Author:     Conrad Meyer <cem@FreeBSD.org>
AuthorDate: 2019-03-01 23:30:23 +0000
Commit:     David E. O'Brien <obrien@FreeBSD.org>
CommitDate: 2022-02-12 22:27:58 +0000

    Embedded chacha: Add 0-bit iv + 128-bit counter mode
    
    This mode might be suitable for a Fortuna keystream primitive.
    
    (cherry picked from commit 7d93ab5e35d97eb23cb4772be4d431a782a65395)
---
 sys/crypto/chacha20/chacha.c | 33 +++++++++++++++++++++++++++++++++
 sys/crypto/chacha20/chacha.h | 11 ++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/sys/crypto/chacha20/chacha.c b/sys/crypto/chacha20/chacha.c
index ac4eef222115..d696307d1a7f 100644
--- a/sys/crypto/chacha20/chacha.c
+++ b/sys/crypto/chacha20/chacha.c
@@ -84,12 +84,32 @@ chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
 LOCAL void
 chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
 {
+#ifndef CHACHA_NONCE0_CTR128
   x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
   x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
   x->input[14] = U8TO32_LITTLE(iv + 0);
   x->input[15] = U8TO32_LITTLE(iv + 4);
+#else
+  // CHACHA_STATELEN
+  (void)iv;
+  x->input[12] = U8TO32_LITTLE(counter + 0);
+  x->input[13] = U8TO32_LITTLE(counter + 4);
+  x->input[14] = U8TO32_LITTLE(counter + 8);
+  x->input[15] = U8TO32_LITTLE(counter + 12);
+#endif
 }
 
+#ifdef CHACHA_NONCE0_CTR128
+LOCAL void
+chacha_ctrsave(const chacha_ctx *x, u8 *counter)
+{
+    U32TO8_LITTLE(counter + 0, x->input[12]);
+    U32TO8_LITTLE(counter + 4, x->input[13]);
+    U32TO8_LITTLE(counter + 8, x->input[14]);
+    U32TO8_LITTLE(counter + 12, x->input[15]);
+}
+#endif
+
 LOCAL void
 chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
 {
@@ -190,7 +210,16 @@ chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
     j12 = PLUSONE(j12);
     if (!j12) {
       j13 = PLUSONE(j13);
+#ifndef CHACHA_NONCE0_CTR128
       /* stopping at 2^70 bytes per nonce is user's responsibility */
+#else
+      if (!j13) {
+        j14 = PLUSONE(j14);
+        if (!j14) {
+          j15 = PLUSONE(j15);
+        }
+      }
+#endif
     }
 
     U32TO8_LITTLE(c + 0,x0);
@@ -216,6 +245,10 @@ chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
       }
       x->input[12] = j12;
       x->input[13] = j13;
+#ifdef CHACHA_NONCE0_CTR128
+      x->input[14] = j14;
+      x->input[15] = j15;
+#endif
       return;
     }
     bytes -= 64;
diff --git a/sys/crypto/chacha20/chacha.h b/sys/crypto/chacha20/chacha.h
index 73548331cc85..32262b04d568 100644
--- a/sys/crypto/chacha20/chacha.h
+++ b/sys/crypto/chacha20/chacha.h
@@ -26,10 +26,19 @@ Public domain.
 #define LOCAL
 #endif
 
+#ifdef CHACHA_NONCE0_CTR128
+#define CHACHA_UNUSED __unused
+#else
+#define CHACHA_UNUSED
+#endif
+
 LOCAL void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits);
-LOCAL void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr);
+LOCAL void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv CHACHA_UNUSED,
+    const u_char *ctr);
 LOCAL void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
     u_char *c, u_int bytes);
 
+#undef CHACHA_UNUSED
+
 #endif	/* CHACHA_H */