Merge branch 'mdw/rsvr'
authorMark Wooding <mdw@distorted.org.uk>
Sun, 8 Sep 2019 17:36:28 +0000 (18:36 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 8 Sep 2019 17:36:28 +0000 (18:36 +0100)
* mdw/rsvr: (49 commits)
  progs/cc-kem.c: Reimplement the `naclbox' bulk cipher in terms of AEAD.
  progs/cc-kem.c: Split `aead_init' into two pieces.
  symm/latinpoly-def.h: Implement Bernstein's `crypto_secretbox'.
  symm/latinpoly-def.h, etc.: Refactor in preparation for a related scheme.
  symm/gaead.h: Specify a flag for `AEAD' schemes which don't do AAD.
  symm/t/chacha: Add IETF test vector for XChacha20-Poly1305.
  symm/gcm-*.S: GCM acceleration using hardware polynomial multiplication.
  symm/gcm.c: Make `gcm_mktable' and `gcm_mulk_...' be CPU-dependent.
  symm/gcm.c: Add low-level multiplication tests.
  base/regdump.[ch], etc.: Fancy register dumping infrastructure.
  base/asm-common.h: Add some macros for shifting entire NEON vectors.
  base/asm-common.h: Use `push' and `pop', for Thumb compatibility.
  base/asm-common.h: Provide default frame pointer registers.
  base/asm-common.h: Prefer `nil' as the unspecified-argument sentinel.
  base/asm-common.h: Fix bogus indentation.
  base/asm-common.h: Settle on no spaces around keyword-argument `='.
  base/asm-common.h: Add an `IMM' macro for immediate operands.
  base/asm-common.h: Implement the `r' decorator for `MEM' accesses.
  base/asm-common.h: Hoist the `_DECOR_mem_...' definitions.
  base/asm-common.h: Put `l' suffix on `si', `di', etc. under `CPUFAM_AMD'.
  ...

1  2 
symm/chacha.c
symm/salsa20.c
symm/t/chacha

diff --combined symm/chacha.c
@@@ -41,6 -41,7 +41,7 @@@
  #include "grand.h"
  #include "keysz.h"
  #include "paranoia.h"
+ #include "rsvr.h"
  
  /*----- Global variables --------------------------------------------------*/
  
@@@ -152,8 -153,6 +153,8 @@@ static void populate(chacha_matrix a, c
  
  /*----- ChaCha implementation ---------------------------------------------*/
  
 +static const octet zerononce[XCHACHA_NONCESZ];
 +
  /* --- @chacha_init@ --- *
   *
   * Arguments: @chacha_ctx *ctx@ = context to fill in
  void chacha_init(chacha_ctx *ctx, const void *key, size_t ksz,
                  const void *nonce)
  {
 -  static const octet zerononce[CHACHA_NONCESZ];
 -
    populate(ctx->a, key, ksz);
    chacha_setnonce(ctx, nonce ? nonce : zerononce);
  }
@@@ -224,7 -225,7 +225,7 @@@ void chacha_seek(chacha_ctx *ctx, unsig
  void chacha_seeku64(chacha_ctx *ctx, kludge64 i)
  {
    ctx->a[12] = LO64(i); ctx->a[13] = HI64(i);
-   ctx->bufi = CHACHA_OUTSZ;
+   ctx->off = CHACHA_OUTSZ;
  }
  
  void chacha_seek_ietf(chacha_ctx *ctx, uint32 i)
@@@ -264,6 -265,8 +265,8 @@@ uint32 chacha_tell_ietf(chacha_ctx *ctx
   *            to @dest@.
   */
  
+ static const rsvr_policy policy = { 0, CHACHA_OUTSZ, CHACHA_OUTSZ };
  #define CHACHA_ENCRYPT(r, ctx, src, dest, sz)                         \
    chacha##r##_encrypt(ctx, src, dest, sz)
  #define DEFENCRYPT(r)                                                 \
      chacha_matrix b;                                                  \
      const octet *s = src;                                             \
      octet *d = dest;                                                  \
-     size_t n;                                                         \
+     rsvr_plan plan;                                                   \
      kludge64 pos, delta;                                              \
                                                                        \
-     SALSA20_OUTBUF(ctx, d, s, sz);                                    \
-     if (!sz) return;                                                  \
+     rsvr_mkplan(&plan, &policy, ctx->off, sz);                                \
                                                                        \
-     if (!dest) {                                                      \
-       n = sz/CHACHA_OUTSZ;                                            \
-       pos = chacha_tellu64(ctx);                                      \
-       ASSIGN64(delta, n);                                             \
-       ADD64(pos, pos, delta);                                         \
-       chacha_seeku64(ctx, pos);                                               \
-       sz = sz%CHACHA_OUTSZ;                                           \
-     } else if (!src) {                                                        \
-       while (sz >= CHACHA_OUTSZ) {                                    \
-       core(r, ctx->a, b);                                             \
-       CHACHA_STEP(ctx->a);                                            \
-       SALSA20_GENFULL(b, d);                                          \
-       sz -= CHACHA_OUTSZ;                                             \
+     if (plan.head) {                                                  \
+       if (!ctx->off) {                                                        \
+       core(r, ctx->a, b); CHACHA_STEP(ctx->a);                        \
+       SALSA20_PREPBUF(ctx, b);                                        \
        }                                                                       \
-     } else {                                                          \
-       while (sz >= CHACHA_OUTSZ) {                                    \
-       core(r, ctx->a, b);                                             \
-       CHACHA_STEP(ctx->a);                                            \
-       SALSA20_MIXFULL(b, d, s);                                       \
-       sz -= CHACHA_OUTSZ;                                             \
+       SALSA20_OUTBUF(ctx, d, s, plan.head);                           \
+     }                                                                 \
+                                                                       \
+     ctx->off -= plan.from_rsvr;                                               \
+                                                                       \
+     if (!d) {                                                         \
+       if (plan.from_input) {                                          \
+       pos = chacha_tellu64(ctx);                                      \
+       ASSIGN64(delta, plan.from_input/SALSA20_OUTSZ);                 \
+       ADD64(pos, pos, delta);                                         \
+       chacha_seeku64(ctx, pos);                                       \
        }                                                                       \
+     } else if (!s) while (plan.from_input) {                          \
+       core(r, ctx->a, b); CHACHA_STEP(ctx->a);                                \
+       SALSA20_GENFULL(b, d); plan.from_input -= CHACHA_OUTSZ;         \
+     } else while (plan.from_input) {                                  \
+       core(r, ctx->a, b); CHACHA_STEP(ctx->a);                                \
+       SALSA20_MIXFULL(b, d, s); plan.from_input -= CHACHA_OUTSZ;      \
      }                                                                 \
                                                                        \
-     if (sz) {                                                         \
-       core(r, ctx->a, b);                                             \
-       CHACHA_STEP(ctx->a);                                            \
+     if (plan.tail) {                                                  \
+       core(r, ctx->a, b); CHACHA_STEP(ctx->a);                                \
        SALSA20_PREPBUF(ctx, b);                                                \
-       SALSA20_OUTBUF(ctx, d, s, sz);                                  \
-       assert(!sz);                                                    \
+       SALSA20_OUTBUF(ctx, d, s, plan.tail);                           \
      }                                                                 \
    }
  CHACHA_VARS(DEFENCRYPT)
@@@ -403,6 -405,8 +405,6 @@@ CHACHA_VARS(DEFHCHACHA
    void XCHACHA_INIT(r, XCHACHA_CTX(r) *ctx,                           \
                    const void *key, size_t ksz, const void *nonce)     \
    {                                                                   \
 -    static const octet zerononce[XCHACHA_NONCESZ];                    \
 -                                                                      \
      populate(ctx->k, key, ksz);                                               \
      ctx->s.a[ 0] = CHACHA_A256;                                               \
      ctx->s.a[ 1] = CHACHA_B256;                                               \
@@@ -591,7 -595,7 +593,7 @@@ CHACHA_VARS(DEFGCIPHER
                                                                        \
    const gccipher xchacha##r = {                                               \
      "xchacha" #r, chacha_keysz,                                               \
 -    CHACHA_NONCESZ, gxinit_##r                                                \
 +    XCHACHA_NONCESZ, gxinit_##r                                               \
    };
  
  CHACHA_VARS(DEFGXCIPHER)
diff --combined symm/salsa20.c
@@@ -39,6 -39,7 +39,7 @@@
  #include "grand.h"
  #include "keysz.h"
  #include "paranoia.h"
+ #include "rsvr.h"
  #include "salsa20.h"
  #include "salsa20-core.h"
  
@@@ -161,8 -162,6 +162,8 @@@ static void populate(salsa20_matrix a, 
  
  /*----- Salsa20 implementation --------------------------------------------*/
  
 +static const octet zerononce[XSALSA20_NONCESZ];
 +
  /* --- @salsa20_init@ --- *
   *
   * Arguments: @salsa20_ctx *ctx@ = context to fill in
  void salsa20_init(salsa20_ctx *ctx, const void *key, size_t ksz,
                  const void *nonce)
  {
 -  static const octet zerononce[SALSA20_NONCESZ];
 -
    populate(ctx->a, key, ksz);
    salsa20_setnonce(ctx, nonce ? nonce : zerononce);
  }
@@@ -233,7 -234,7 +234,7 @@@ void salsa20_seek(salsa20_ctx *ctx, uns
  void salsa20_seeku64(salsa20_ctx *ctx, kludge64 i)
  {
    ctx->a[8] = LO64(i); ctx->a[5] = HI64(i);
-   ctx->bufi = SALSA20_OUTSZ;
+   ctx->off = 0;
  }
  
  void salsa20_seek_ietf(salsa20_ctx *ctx, uint32 i)
@@@ -273,6 -274,8 +274,8 @@@ uint32 salsa20_tell_ietf(salsa20_ctx *c
   *            to @dest@.
   */
  
+ static const rsvr_policy policy = { 0, SALSA20_OUTSZ, SALSA20_OUTSZ };
  #define SALSA20_ENCRYPT(r, ctx, src, dest, sz)                                \
    SALSA20_DECOR(salsa20, r, _encrypt)(ctx, src, dest, sz)
  #define DEFENCRYPT(r)                                                 \
      salsa20_matrix b;                                                 \
      const octet *s = src;                                             \
      octet *d = dest;                                                  \
-     size_t n;                                                         \
+     rsvr_plan plan;                                                   \
      kludge64 pos, delta;                                              \
                                                                        \
-     SALSA20_OUTBUF(ctx, d, s, sz);                                    \
-     if (!sz) return;                                                  \
+     rsvr_mkplan(&plan, &policy, ctx->off, sz);                                \
                                                                        \
-     if (!dest) {                                                      \
-       n = sz/SALSA20_OUTSZ;                                           \
-       pos = salsa20_tellu64(ctx);                                     \
-       ASSIGN64(delta, n);                                             \
-       ADD64(pos, pos, delta);                                         \
-       salsa20_seeku64(ctx, pos);                                      \
-       sz = sz%SALSA20_OUTSZ;                                          \
-     } else if (!src) {                                                        \
-       while (sz >= SALSA20_OUTSZ) {                                   \
-       core(r, ctx->a, b);                                             \
-       SALSA20_STEP(ctx->a);                                           \
-       SALSA20_GENFULL(b, d);                                          \
-       sz -= SALSA20_OUTSZ;                                            \
+     if (plan.head) {                                                  \
+       if (!ctx->off) {                                                        \
+       core(r, ctx->a, b); SALSA20_STEP(ctx->a);                       \
+       SALSA20_PREPBUF(ctx, b);                                        \
        }                                                                       \
-     } else {                                                          \
-       while (sz >= SALSA20_OUTSZ) {                                   \
-       core(r, ctx->a, b);                                             \
-       SALSA20_STEP(ctx->a);                                           \
-       SALSA20_MIXFULL(b, d, s);                                       \
-       sz -= SALSA20_OUTSZ;                                            \
+       SALSA20_OUTBUF(ctx, d, s, plan.head);                           \
+     }                                                                 \
+                                                                       \
+     ctx->off -= plan.from_rsvr;                                               \
+                                                                       \
+     if (!d) {                                                         \
+       if (plan.from_input) {                                          \
+       pos = salsa20_tellu64(ctx);                                     \
+       ASSIGN64(delta, plan.from_input/SALSA20_OUTSZ);                 \
+       ADD64(pos, pos, delta);                                         \
+       salsa20_seeku64(ctx, pos);                                      \
        }                                                                       \
+     } else if (!s) while (plan.from_input) {                          \
+       core(r, ctx->a, b); SALSA20_STEP(ctx->a);                               \
+       SALSA20_GENFULL(b, d); plan.from_input -= SALSA20_OUTSZ;                \
+     } else while (plan.from_input) {                                  \
+       core(r, ctx->a, b); SALSA20_STEP(ctx->a);                               \
+       SALSA20_MIXFULL(b, d, s); plan.from_input -= SALSA20_OUTSZ;     \
      }                                                                 \
                                                                        \
-     if (sz) {                                                         \
-       core(r, ctx->a, b);                                             \
-       SALSA20_STEP(ctx->a);                                           \
+     if (plan.tail) {                                                  \
+       core(r, ctx->a, b); SALSA20_STEP(ctx->a);                               \
        SALSA20_PREPBUF(ctx, b);                                                \
-       SALSA20_OUTBUF(ctx, d, s, sz);                                  \
-       assert(!sz);                                                    \
+       SALSA20_OUTBUF(ctx, d, s, plan.tail);                           \
      }                                                                 \
    }
  SALSA20_VARS(DEFENCRYPT)
@@@ -421,6 -423,8 +423,6 @@@ SALSA20_VARS(DEFHSALSA20
    void XSALSA20_INIT(r, XSALSA20_CTX(r) *ctx,                         \
                        const void *key, size_t ksz, const void *nonce) \
    {                                                                   \
 -    static const octet zerononce[XSALSA20_NONCESZ];                   \
 -                                                                      \
      populate(ctx->k, key, ksz);                                               \
      ctx->s.a[ 0] = SALSA20_A256;                                      \
      ctx->s.a[ 1] = SALSA20_B256;                                      \
diff --combined symm/t/chacha
@@@ -31,19 -31,12 +31,19 @@@ chacha8-core 
  
  xchacha20 {
    ## Unfortunately, XChaCha isn't actually defined anywhere, even though it's
 -  ## obvious how to do it.  These test vectors are from
 -  ##   https://github.com/DaGenix/rust-crypto/blob/master/src/chacha20.rs
 +  ## obvious how to do it.
  
 +  ## These test vectors are from
 +  ##   https://github.com/DaGenix/rust-crypto/blob/master/src/chacha20.rs
    1b27556473e985d462cd51197a9a46c76009549eac6474f206c4ee0844f68389
    69696ee955b62b73cd62bda875fc73d68219e0036b7a0b37 "" 0 ""
    4febf2fe4b359c508dc5e8b5980c88e38946d8f18f313465c862a08782648248018dacdcb904178853a46dca3a0eaaee747cba97434eaffad58fea8222047e0de6c3a6775106e0331ad714d2f27a55641340a1f1dd9f94532e68cb241cbdd150970d14e05c5b173193fb14f51c41f393835bf7f416a7e0bba81ffb8b13af0e21691d7ecec93b75e6e4183a;
 +
 +  ## This one's from draft-irtf-cfrg-xchacha-03.
 +  808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
 +  404142434445464748494a4b4c4d4e4f5051525354555658 "" 64
 +  5468652064686f6c65202870726f6e6f756e6365642022646f6c65222920697320616c736f206b6e6f776e2061732074686520417369617469632077696c6420646f672c2072656420646f672c20616e642077686973746c696e6720646f672e2049742069732061626f7574207468652073697a65206f662061204765726d616e20736865706865726420627574206c6f6f6b73206d6f7265206c696b652061206c6f6e672d6c656767656420666f782e205468697320686967686c7920656c757369766520616e6420736b696c6c6564206a756d70657220697320636c6173736966696564207769746820776f6c7665732c20636f796f7465732c206a61636b616c732c20616e6420666f78657320696e20746865207461786f6e6f6d69632066616d696c792043616e696461652e
 +  7d0a2e6b7f7c65a236542630294e063b7ab9b555a5d5149aa21e4ae1e4fbce87ecc8e08a8b5e350abe622b2ffa617b202cfad72032a3037e76ffdcdc4376ee053a190d7e46ca1de04144850381b9cb29f051915386b8a710b8ac4d027b8b050f7cba5854e028d564e453b8a968824173fc16488b8970cac828f11ae53cabd20112f87107df24ee6183d2274fe4c8b1485534ef2c5fbc1ec24bfc3663efaa08bc047d29d25043532db8391a8a3d776bf4372a6955827ccb0cdd4af403a7ce4c63d595c75a43e045f0cce1f29c8b93bd65afc5974922f214a40b7c402cdb91ae73c0b63615cdad0480680f16515a7ace9d39236464328a37743ffc28f4ddb324f4d0f5bbdc270c65b1749a6efff1fbaa09536175ccd29fb9e6057b307320d316838a9c71f70b5b5907a66f7ea49aadc409;
  }
  
  chacha8 {
@@@ -233,3 -226,21 +233,21 @@@ chacha20 
    000000000000000000000002 "" 0 ""
    965e3bc6f9ec7ed9560808f4d229f94b137ff275ca9b3fcbdd59deaad23310ae;
  }
+ chacha20-poly1305 {
+   ## Test from RFC7539.
+   808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+     070000004041424344454647
+     50515253c0c1c2c3c4c5c6c7
+     4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e
+     d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116
+     1ae10b594f09e26a7e902ecbd0600691;
+   ## Test from draft-irtf-cfrg-xchacha-03.
+   808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+     404142434445464748494a4b4c4d4e4f5051525354555657
+     50515253c0c1c2c3c4c5c6c7
+     4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e
+     bd6d179d3e83d43b9576579493c0e939572a1700252bfaccbed2902c21396cbb731c7f1b0b4aa6440bf3a82f4eda7e39ae64c6708c54c216cb96b72e1213b4522f8c9ba40db5d945b11b69b982c1bb9e3f3fac2bc369488f76b2383565d3fff921f9664c97637da9768812f615c68b13b52e
+     c0875924c1c7987947deafd8780acf49;
+ }