This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new bdd68ed1e50 crypto: Add ChaCha20/ChaCha20-Poly1305 to /dev/crypto, fix 
RFC 8439 nonce.
bdd68ed1e50 is described below

commit bdd68ed1e5076d4bb16565399a6d918f51025ae8
Author: makejian <[email protected]>
AuthorDate: Fri Jul 10 14:13:58 2026 +0800

    crypto: Add ChaCha20/ChaCha20-Poly1305 to /dev/crypto, fix RFC 8439 nonce.
    
    Expose the ChaCha20 stream cipher and the ChaCha20-Poly1305 AEAD through
    the OCF crypto framework (/dev/crypto) so applications such as an SSH
    server (chacha20-poly1305) can use them directly, and fix the underlying
    ChaCha nonce/counter layout so both match RFC 8439.
    
    RFC 8439 nonce layout fix
    -------------------------
    chacha_ivsetup() previously used the original DJB layout: a 64-bit block
    counter (input[12..13]) followed by a 64-bit nonce (input[14..15]). RFC
    8439 defines a 32-bit block counter (input[12]) and a 96-bit / 12-byte
    nonce (input[13..15]). With the old layout the existing ChaCha20-Poly1305
    AEAD could not reproduce the RFC 8439 test vectors (the last 4 bytes of a
    12-byte nonce were consumed as the high half of the counter). This
    commit switches chacha_ivsetup() to the RFC 8439 layout and updates the
    ChaCha20-Poly1305 one-shot helpers to pass a 12-byte nonce accordingly.
    
    Standalone ChaCha20 on the unified enc path
    -------------------------------------------
    Instead of introducing a separate multi-buffer stream path (parallel
    encrypt_multi/decrypt_multi callbacks), extend the existing enc_xform
    encrypt/decrypt callback signature with a length argument:
    
      void (*encrypt)(caddr_t, FAR uint8_t *, size_t len);
      void (*decrypt)(caddr_t, FAR uint8_t *, size_t len);
    
    With that single change every cipher, block or stream, flows through the
    same swcr_encdec path. swcr_encdec already handles a short final block
    via buflen = MIN(i, blocksize), so arbitrary-length data works without a
    second code path. This is exactly how the existing stream ciphers
    (AES-CTR/OFB/CFB) already behave: the cipher keeps its own counter in the
    context and swcr_encdec feeds it whole blocks (only the last one may be
    shorter). chacha20_crypt likewise relies on the underlying chacha state
    block counter (input[12]) to continue the keystream across calls, so no
    per-call keystream caching is needed.
    
      * chacha_private.h: chacha_ivsetup uses a 4-byte counter and a 12-byte
        nonce (RFC 8439).
      * chachapoly.c / chachapoly.h: split reinit into chacha20_reinit (raw,
        counter 0) and chachapoly_reinit (AEAD, counter 1); chacha20_crypt
        takes a length and encrypts it in one pass, mirroring aes_ctr_crypt;
        12-byte nonce for the one-shot AEAD helpers.
      * xform.h / xform.c: add size_t len to encrypt/decrypt; add
        enc_xform_chacha20 (blocksize 64, 12-byte IV).
      * cryptodev.c / cryptosoft.c: register CRYPTO_CHACHA20 as a txform
        cipher, route new sessions to enc_xform_chacha20, feed the AEAD AAD
        through crp_aad/crp_aadlen, and handle the short final block in
        swcr_encdec.
      * cryptodev.h: add CRYPTO_CHACHA20; bump EALG_MAX_BLOCK_LEN to 64.
    
    This keeps all ciphers on one uniform path instead of maintaining two,
    and any future stream cipher drops in with just an xform table entry.
    
    Impact: extends an internal kernel callback signature (enc_xform
    encrypt/decrypt). All in-tree implementations are updated in the same
    commit and the user-facing /dev/crypto ABI is unchanged, so this is
    self-contained and not a breaking change for existing configurations.
    
    Testing:
      Build host: Ubuntu Linux x86_64, GCC (host sim toolchain)
      Target: sim:crypto (CONFIG_ARCH=sim)
      Ran the crypto test apps. ChaCha20 uses RFC 8439 2.4.2 vectors
      (including a 375-byte multi-block vector exercising cross-block counter
      continuity); ChaCha20-Poly1305 uses the RFC 8439 2.8.2 AEAD vector.
      A full regression of the other ciphers was run to confirm the extended
      encrypt/decrypt signature does not change their behaviour:
    
        nsh> chacha20
        chacha20: 2/2 vectors passed
        nsh> chachapoly
        OK test vector 0
        chachapoly: 1/1 vectors passed
        nsh> des3cbc          -> all vectors OK
        nsh> aescbc           -> all vectors OK
        nsh> aesctr           -> all vectors OK
        nsh> aesxts           -> 14 vectors OK (encrypt + decrypt)
        nsh> hmac             -> md5 / sha1 / sha256 all success
    
    Signed-off-by: makejian <[email protected]>
---
 crypto/chacha_private.h     |  6 +--
 crypto/chachapoly.c         | 36 +++++++++++++-----
 crypto/cryptodev.c          |  9 +++++
 crypto/cryptosoft.c         | 67 +++++++++++++++++++++++----------
 crypto/xform.c              | 91 +++++++++++++++++++++++++--------------------
 include/crypto/chachapoly.h |  7 ++--
 include/crypto/cryptodev.h  |  5 ++-
 include/crypto/xform.h      |  5 ++-
 8 files changed, 147 insertions(+), 79 deletions(-)

diff --git a/crypto/chacha_private.h b/crypto/chacha_private.h
index 516b9a115ac..5829cfbee66 100644
--- a/crypto/chacha_private.h
+++ b/crypto/chacha_private.h
@@ -141,9 +141,9 @@ static void chacha_ivsetup(FAR chacha_ctx *x,
                            FAR const uint8_t *counter)
 {
   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);
+  x->input[13] = U8TO32_LITTLE(iv + 0);
+  x->input[14] = U8TO32_LITTLE(iv + 4);
+  x->input[15] = U8TO32_LITTLE(iv + 8);
 }
 
 static void chacha_encrypt_bytes(FAR chacha_ctx *x,
diff --git a/crypto/chachapoly.c b/crypto/chachapoly.c
index c03bf8fac18..885b066ff6e 100644
--- a/crypto/chachapoly.c
+++ b/crypto/chachapoly.c
@@ -48,10 +48,7 @@ int chacha20_setkey(FAR void *sched, FAR uint8_t *key, int 
len)
       return -1;
     }
 
-  /* initial counter is 1 */
-
-  ctx->nonce[0] = 1;
-  memcpy(ctx->nonce + CHACHA20_CTR, key + CHACHA20_KEYSIZE,
+  memcpy(ctx->nonce, key + CHACHA20_KEYSIZE,
          CHACHA20_SALT);
   chacha_keysetup((FAR chacha_ctx *)&ctx->block, key, CHACHA20_KEYSIZE * 8);
   return 0;
@@ -64,12 +61,27 @@ void chacha20_reinit(caddr_t key, FAR uint8_t *iv)
   chacha_ivsetup((FAR chacha_ctx *)ctx->block, iv, ctx->nonce);
 }
 
-void chacha20_crypt(caddr_t key, FAR uint8_t *data)
+void chacha20_crypt(caddr_t key, FAR uint8_t *data, size_t len)
+{
+  FAR struct chacha20_ctx *ctx = (FAR struct chacha20_ctx *)key;
+
+  /* The underlying chacha state keeps its own block counter (input[12]),
+   * so successive calls continue the keystream seamlessly.  This mirrors
+   * how aes_ctr_crypt relies on swcr_encdec feeding whole blocks (only the
+   * final block may be shorter), keeping every stream cipher on one path.
+   */
+
+  chacha_encrypt_bytes((FAR chacha_ctx *)ctx, data, data, len);
+}
+
+void chachapoly_reinit(caddr_t key, FAR uint8_t *iv)
 {
   FAR struct chacha20_ctx *ctx = (FAR struct chacha20_ctx *)key;
 
-  chacha_encrypt_bytes((FAR chacha_ctx *)ctx->block, data, data,
-                       CHACHA20_BLOCK_LEN);
+  /* initial counter is 1 */
+
+  ctx->nonce[0] = 1;
+  chacha_ivsetup((FAR chacha_ctx *)ctx->block, iv, ctx->nonce);
 }
 
 void chacha20_poly1305_init(FAR void *xctx)
@@ -156,9 +168,12 @@ void chacha20poly1305_encrypt(
   };
 
   uint64_t le_nonce = htole64(nonce);
+  uint8_t le_nonce_array[12];
+  explicit_bzero(le_nonce_array, sizeof(le_nonce_array));
+  memcpy(le_nonce_array, &le_nonce, sizeof(uint64_t));
 
   chacha_keysetup(&ctx, key, CHACHA20POLY1305_KEY_SIZE * 8);
-  chacha_ivsetup(&ctx, (FAR uint8_t *) &le_nonce, NULL);
+  chacha_ivsetup(&ctx, le_nonce_array, NULL);
   chacha_encrypt_bytes(&ctx, b.b0, b.b0, sizeof(b.b0));
   poly1305_begin(&poly1305_ctx, b.b0);
 
@@ -205,6 +220,9 @@ int chacha20poly1305_decrypt(
   };
 
   uint64_t le_nonce = htole64(nonce);
+  uint8_t le_nonce_array[12];
+  explicit_bzero(le_nonce_array, sizeof(le_nonce_array));
+  memcpy(le_nonce_array, &le_nonce, sizeof(uint64_t));
 
   if (src_len < CHACHA20POLY1305_AUTHTAG_SIZE)
     {
@@ -212,7 +230,7 @@ int chacha20poly1305_decrypt(
     }
 
   chacha_keysetup(&ctx, key, CHACHA20POLY1305_KEY_SIZE * 8);
-  chacha_ivsetup(&ctx, (FAR uint8_t *) &le_nonce, NULL);
+  chacha_ivsetup(&ctx, le_nonce_array, NULL);
   chacha_encrypt_bytes(&ctx, b.b0, b.b0, sizeof(b.b0));
   poly1305_begin(&poly1305_ctx, b.b0);
 
diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c
index fa165165f4c..e36716443d1 100644
--- a/crypto/cryptodev.c
+++ b/crypto/cryptodev.c
@@ -236,6 +236,8 @@ static int cryptof_ioctl(FAR struct file *filep,
             case CRYPTO_AES_OFB:
             case CRYPTO_AES_CFB_8:
             case CRYPTO_AES_CFB_128:
+            case CRYPTO_CHACHA20:
+            case CRYPTO_CHACHA20_POLY1305:
             case CRYPTO_NULL:
               txform = true;
               break;
@@ -256,6 +258,7 @@ static int cryptof_ioctl(FAR struct file *filep,
             case CRYPTO_SHA2_512_HMAC:
             case CRYPTO_AES_128_GMAC:
             case CRYPTO_AES_128_CMAC:
+            case CRYPTO_CHACHA20_POLY1305_MAC:
             case CRYPTO_MD5:
             case CRYPTO_POLY1305:
             case CRYPTO_RIPEMD160:
@@ -463,6 +466,12 @@ static int cryptodev_op(FAR struct csession *cse,
       crp.crp_ivlen = cop->ivlen;
     }
 
+  if (cop->aad)
+    {
+      crp.crp_aad = cop->aad;
+      crp.crp_aadlen = cop->aadlen;
+    }
+
   if (cop->dst)
     {
       crp.crp_dst = cop->dst;
diff --git a/crypto/cryptosoft.c b/crypto/cryptosoft.c
index 9dcbce8b503..de1d87b4e9d 100644
--- a/crypto/cryptosoft.c
+++ b/crypto/cryptosoft.c
@@ -998,6 +998,7 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct 
cryptodesc *crd,
   int j;
   int blks;
   int ivlen;
+  int buflen;
 
   exf = sw->sw_exf;
   blks = exf->blocksize;
@@ -1036,7 +1037,7 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct 
cryptodesc *crd,
    * handling themselves.
    */
 
-  if (exf->reinit)
+  if (!(crd->crd_flags & CRD_F_UPDATE) && exf->reinit)
     {
       exf->reinit((caddr_t)sw->sw_kschedule, iv);
     }
@@ -1047,19 +1048,20 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct 
cryptodesc *crd,
   output = crp->crp_dst;
   while (i > 0)
     {
-      bcopy(buf, blk, exf->blocksize);
-      buf += exf->blocksize;
+      buflen = MIN(i, exf->blocksize);
+      bcopy(buf, blk, buflen);
+      buf += buflen;
       if (exf->reinit)
         {
           if (crd->crd_flags & CRD_F_ENCRYPT)
             {
               exf->encrypt((caddr_t)sw->sw_kschedule,
-                  blk);
+                  blk, buflen);
             }
           else
             {
               exf->decrypt((caddr_t)sw->sw_kschedule,
-                  blk);
+                  blk, buflen);
             }
         }
       else if (crd->crd_flags & CRD_F_ENCRYPT)
@@ -1069,7 +1071,7 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct 
cryptodesc *crd,
           for (j = 0; j < blks; j++)
             blk[j] ^= ivp[j];
 
-          exf->encrypt((caddr_t)sw->sw_kschedule, blk);
+          exf->encrypt((caddr_t)sw->sw_kschedule, blk, buflen);
 
           /* Keep encrypted block for XOR'ng
            * with next block
@@ -1089,7 +1091,7 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct 
cryptodesc *crd,
           nivp = (ivp == iv) ? iv2 : iv;
           bcopy(blk, nivp, blks);
 
-          exf->decrypt((caddr_t)sw->sw_kschedule, blk);
+          exf->decrypt((caddr_t)sw->sw_kschedule, blk, buflen);
 
           /* XOR with previous block */
 
@@ -1101,10 +1103,10 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct 
cryptodesc *crd,
           ivp = nivp;
         }
 
-      bcopy(blk, output, exf->blocksize);
-      output += exf->blocksize;
+      bcopy(blk, output, buflen);
+      output += buflen;
 
-      i -= blks;
+      i -= buflen;
 
       /* Could be done... */
 
@@ -1114,7 +1116,10 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct 
cryptodesc *crd,
         }
     }
 
-  bcopy(ivp, crp->crp_iv, ivlen);
+  if (crp->crp_iv)
+    {
+      bcopy(ivp, crp->crp_iv, ivlen);
+    }
 
   return 0; /* Done with encryption/decryption */
 }
@@ -1279,6 +1284,22 @@ int swcr_authenc(FAR struct cryptop *crp)
 
   /* Initialize the IV */
 
+  if (crp->crp_iv)
+    {
+      if (!(crde->crd_flags & CRD_F_IV_EXPLICIT))
+        {
+          bcopy(crp->crp_iv, crde->crd_iv, exf->ivsize);
+          crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
+          crde->crd_skip = 0;
+        }
+    }
+  else
+    {
+      crde->crd_flags |= CRD_F_IV_PRESENT;
+      crde->crd_skip = exf->blocksize;
+      crde->crd_len -= exf->blocksize;
+    }
+
   if (crde->crd_flags & CRD_F_ENCRYPT)
     {
       /* IV explicitly provided ? */
@@ -1317,7 +1338,7 @@ int swcr_authenc(FAR struct cryptop *crp)
 
   /* Supply MAC with IV */
 
-  if (axf->reinit)
+  if (!(crda->crd_flags & CRD_F_UPDATE_AAD) && axf->reinit)
     {
       axf->reinit(&ctx, iv, ivlen);
     }
@@ -1326,7 +1347,7 @@ int swcr_authenc(FAR struct cryptop *crp)
 
   if (aad)
     {
-      aadlen = crda->crd_len;
+      aadlen = crp->crp_aadlen;
       /* Section 5 of RFC 4106 specifies that AAD construction consists of
       * {SPI, ESN, SN} whereas the real packet contains only {SPI, SN}.
       * Unfortunately it doesn't follow a good example set in the Section
@@ -1342,7 +1363,7 @@ int swcr_authenc(FAR struct cryptop *crp)
 
           /* SPI */
 
-          bcopy(buf + crda->crd_skip, blk, 4);
+          bcopy(aad + crda->crd_skip, blk, 4);
           iskip = 4; /* loop below will start with an offset of 4 */
 
           /* ESN */
@@ -1351,10 +1372,10 @@ int swcr_authenc(FAR struct cryptop *crp)
           oskip = iskip + 4; /* offset output buffer blk by 8 */
         }
 
-      for (i = iskip; i < crda->crd_len; i += axf->hashsize)
+      for (i = iskip; i < aadlen; i += axf->hashsize)
         {
-          len = MIN(crda->crd_len - i, axf->hashsize - oskip);
-          bcopy(buf + crda->crd_skip + i, blk + oskip, len);
+          len = MIN(aadlen - i, axf->hashsize - oskip);
+          bcopy(aad + i, blk + oskip, len);
           bzero(blk + len + oskip, axf->hashsize - len - oskip);
           axf->update(&ctx, blk, axf->hashsize);
           oskip = 0; /* reset initial output offset */
@@ -1381,13 +1402,13 @@ int swcr_authenc(FAR struct cryptop *crp)
           bcopy(buf + i, blk, len);
           if (crde->crd_flags & CRD_F_ENCRYPT)
             {
-              exf->encrypt((caddr_t)swe->sw_kschedule, blk);
+              exf->encrypt((caddr_t)swe->sw_kschedule, blk, len);
               axf->update(&ctx, blk, len);
             }
           else
             {
               axf->update(&ctx, blk, len);
-              exf->decrypt((caddr_t)swe->sw_kschedule, blk);
+              exf->decrypt((caddr_t)swe->sw_kschedule, blk, len);
             }
 
           if (crp->crp_dst)
@@ -1621,6 +1642,9 @@ int swcr_newsession(FAR uint32_t *sid, FAR struct 
cryptoini *cri)
           case CRYPTO_AES_CFB_128:
             txf = &enc_xform_aes_cfb_128;
             goto enccommon;
+          case CRYPTO_CHACHA20:
+            txf = &enc_xform_chacha20;
+            goto enccommon;
           case CRYPTO_CHACHA20_POLY1305:
             txf = &enc_xform_chacha20_poly1305;
             goto enccommon;
@@ -1883,6 +1907,7 @@ int swcr_freesession(uint64_t tid)
           case CRYPTO_AES_OFB:
           case CRYPTO_AES_CFB_8:
           case CRYPTO_AES_CFB_128:
+          case CRYPTO_CHACHA20:
           case CRYPTO_CHACHA20_POLY1305:
           case CRYPTO_NULL:
             txf = swd->sw_exf;
@@ -1967,7 +1992,7 @@ int swcr_process(struct cryptop *crp)
       return -EINVAL;
     }
 
-  if (crp->crp_desc == NULL || crp->crp_buf == NULL)
+  if (crp->crp_desc == NULL)
     {
       crp->crp_etype = -EINVAL;
       goto done;
@@ -2021,6 +2046,7 @@ int swcr_process(struct cryptop *crp)
           case CRYPTO_AES_OFB:
           case CRYPTO_AES_CFB_8:
           case CRYPTO_AES_CFB_128:
+          case CRYPTO_CHACHA20:
             txf = sw->sw_exf;
 
             if (crp->crp_iv)
@@ -2425,6 +2451,7 @@ void swcr_init(void)
   algs[CRYPTO_AES_OFB] = CRYPTO_ALG_FLAG_SUPPORTED;
   algs[CRYPTO_AES_CFB_8] = CRYPTO_ALG_FLAG_SUPPORTED;
   algs[CRYPTO_AES_CFB_128] = CRYPTO_ALG_FLAG_SUPPORTED;
+  algs[CRYPTO_CHACHA20] = CRYPTO_ALG_FLAG_SUPPORTED;
   algs[CRYPTO_CHACHA20_POLY1305] = CRYPTO_ALG_FLAG_SUPPORTED;
   algs[CRYPTO_CHACHA20_POLY1305_MAC] = CRYPTO_ALG_FLAG_SUPPORTED;
   algs[CRYPTO_MD5] = CRYPTO_ALG_FLAG_SUPPORTED;
diff --git a/crypto/xform.c b/crypto/xform.c
index cc63cd0562b..ff9729c2295 100644
--- a/crypto/xform.c
+++ b/crypto/xform.c
@@ -112,26 +112,26 @@ int aes_xts_setkey(FAR void *, FAR uint8_t *, int);
 int aes_ofb_setkey(FAR void *, FAR uint8_t *, int);
 int null_setkey(FAR void *, FAR uint8_t *, int);
 
-void des3_encrypt(caddr_t, FAR uint8_t *);
-void blf_encrypt(caddr_t, FAR uint8_t *);
-void cast5_encrypt(caddr_t, FAR uint8_t *);
-void aes_encrypt_xform(caddr_t, FAR uint8_t *);
-void null_encrypt(caddr_t, FAR uint8_t *);
-void aes_xts_encrypt(caddr_t, FAR uint8_t *);
-void aes_ofb_encrypt(caddr_t, FAR uint8_t *);
-void aes_cfb8_encrypt(caddr_t, FAR uint8_t *);
-void aes_cfb128_encrypt(caddr_t, FAR uint8_t *);
-
-void des3_decrypt(caddr_t, FAR uint8_t *);
-void blf_decrypt(caddr_t, FAR uint8_t *);
-void cast5_decrypt(caddr_t, FAR uint8_t *);
-void aes_decrypt_xform(caddr_t, FAR uint8_t *);
-void null_decrypt(caddr_t, FAR uint8_t *);
-void aes_xts_decrypt(caddr_t, FAR uint8_t *);
-void aes_cfb8_decrypt(caddr_t, FAR uint8_t *);
-void aes_cfb128_decrypt(caddr_t, FAR uint8_t *);
-
-void aes_ctr_crypt(caddr_t, FAR uint8_t *);
+void des3_encrypt(caddr_t, FAR uint8_t *, size_t);
+void blf_encrypt(caddr_t, FAR uint8_t *, size_t);
+void cast5_encrypt(caddr_t, FAR uint8_t *, size_t);
+void aes_encrypt_xform(caddr_t, FAR uint8_t *, size_t);
+void null_encrypt(caddr_t, FAR uint8_t *, size_t);
+void aes_xts_encrypt(caddr_t, FAR uint8_t *, size_t);
+void aes_ofb_encrypt(caddr_t, FAR uint8_t *, size_t);
+void aes_cfb8_encrypt(caddr_t, FAR uint8_t *, size_t);
+void aes_cfb128_encrypt(caddr_t, FAR uint8_t *, size_t);
+
+void des3_decrypt(caddr_t, FAR uint8_t *, size_t);
+void blf_decrypt(caddr_t, FAR uint8_t *, size_t);
+void cast5_decrypt(caddr_t, FAR uint8_t *, size_t);
+void aes_decrypt_xform(caddr_t, FAR uint8_t *, size_t);
+void null_decrypt(caddr_t, FAR uint8_t *, size_t);
+void aes_xts_decrypt(caddr_t, FAR uint8_t *, size_t);
+void aes_cfb8_decrypt(caddr_t, FAR uint8_t *, size_t);
+void aes_cfb128_decrypt(caddr_t, FAR uint8_t *, size_t);
+
+void aes_ctr_crypt(caddr_t, FAR uint8_t *, size_t);
 
 void aes_ctr_reinit(caddr_t, FAR uint8_t *);
 void aes_xts_reinit(caddr_t, FAR uint8_t *);
@@ -307,15 +307,26 @@ const struct enc_xform enc_xform_aes_cfb_128 =
   aes_ofb_reinit
 };
 
+const struct enc_xform enc_xform_chacha20 =
+{
+  CRYPTO_CHACHA20, "CHACHA20",
+  64, 12, 32 + 4, 32 + 4,
+  sizeof(struct chacha20_ctx),
+  chacha20_crypt,
+  chacha20_crypt,
+  chacha20_setkey,
+  chacha20_reinit
+};
+
 const struct enc_xform enc_xform_chacha20_poly1305 =
 {
   CRYPTO_CHACHA20_POLY1305, "CHACHA20-POLY1305",
-  1, 8, 32 + 4, 32 + 4,
+  64, 12, 32 + 4, 32 + 4,
   sizeof(struct chacha20_ctx),
   chacha20_crypt,
   chacha20_crypt,
   chacha20_setkey,
-  chacha20_reinit
+  chachapoly_reinit
 };
 
 const struct enc_xform enc_xform_null =
@@ -518,12 +529,12 @@ const struct auth_hash auth_hash_crc32 =
 
 /* Encryption wrapper routines. */
 
-void des3_encrypt(caddr_t key, FAR uint8_t *blk)
+void des3_encrypt(caddr_t key, FAR uint8_t *blk, size_t len)
 {
   des_ecb3_encrypt((caddr_t)blk, (caddr_t)blk, key, key + 128, key + 256, 1);
 }
 
-void des3_decrypt(caddr_t key, FAR uint8_t *blk)
+void des3_decrypt(caddr_t key, FAR uint8_t *blk, size_t len)
 {
   des_ecb3_encrypt((caddr_t)blk, (caddr_t)blk, key + 256, key + 128, key, 0);
 }
@@ -539,12 +550,12 @@ int des3_setkey(FAR void *sched, FAR uint8_t *key, int 
len)
   return 0;
 }
 
-void blf_encrypt(caddr_t key, FAR uint8_t *blk)
+void blf_encrypt(caddr_t key, FAR uint8_t *blk, size_t len)
 {
   blf_ecb_encrypt((FAR blf_ctx *) key, blk, 8);
 }
 
-void blf_decrypt(caddr_t key, FAR uint8_t *blk)
+void blf_decrypt(caddr_t key, FAR uint8_t *blk, size_t len)
 {
   blf_ecb_decrypt((FAR blf_ctx *) key, blk, 8);
 }
@@ -561,20 +572,20 @@ int null_setkey(FAR void *sched, FAR uint8_t *key, int 
len)
   return 0;
 }
 
-void null_encrypt(caddr_t key, FAR uint8_t *blk)
+void null_encrypt(caddr_t key, FAR uint8_t *blk, size_t len)
 {
 }
 
-void null_decrypt(caddr_t key, FAR uint8_t *blk)
+void null_decrypt(caddr_t key, FAR uint8_t *blk, size_t len)
 {
 }
 
-void cast5_encrypt(caddr_t key, FAR uint8_t *blk)
+void cast5_encrypt(caddr_t key, FAR uint8_t *blk, size_t len)
 {
   cast_encrypt((FAR cast_key *) key, blk, blk);
 }
 
-void cast5_decrypt(caddr_t key, FAR uint8_t *blk)
+void cast5_decrypt(caddr_t key, FAR uint8_t *blk, size_t len)
 {
   cast_decrypt((FAR cast_key *) key, blk, blk);
 }
@@ -586,12 +597,12 @@ int cast5_setkey(FAR void *sched, FAR uint8_t *key, int 
len)
   return 0;
 }
 
-void aes_encrypt_xform(caddr_t key, FAR uint8_t *blk)
+void aes_encrypt_xform(caddr_t key, FAR uint8_t *blk, size_t len)
 {
   aes_encrypt((FAR AES_CTX *)key, blk, blk);
 }
 
-void aes_decrypt_xform(caddr_t key, FAR uint8_t *blk)
+void aes_decrypt_xform(caddr_t key, FAR uint8_t *blk, size_t len)
 {
   aes_decrypt((FAR AES_CTX *)key, blk, blk);
 }
@@ -626,7 +637,7 @@ void aes_gcm_reinit(caddr_t key, FAR uint8_t *iv)
   ctx->ac_block[AESCTR_BLOCKSIZE - 1] = 1; /* GCM starts with 1 */
 }
 
-void aes_ctr_crypt(caddr_t key, FAR uint8_t *data)
+void aes_ctr_crypt(caddr_t key, FAR uint8_t *data, size_t len)
 {
   FAR struct aes_ctr_ctx *ctx;
   uint8_t keystream[AESCTR_BLOCKSIZE];
@@ -741,12 +752,12 @@ void aes_xts_crypt(FAR struct aes_xts_ctx *ctx,
   explicit_bzero(block, sizeof(block));
 }
 
-void aes_xts_encrypt(caddr_t key, FAR uint8_t *data)
+void aes_xts_encrypt(caddr_t key, FAR uint8_t *data, size_t len)
 {
   aes_xts_crypt((FAR struct aes_xts_ctx *)key, data, 1);
 }
 
-void aes_xts_decrypt(caddr_t key, FAR uint8_t *data)
+void aes_xts_decrypt(caddr_t key, FAR uint8_t *data, size_t len)
 {
   aes_xts_crypt((FAR struct aes_xts_ctx *)key, data, 0);
 }
@@ -768,7 +779,7 @@ int aes_xts_setkey(FAR void *sched, FAR uint8_t *key, int 
len)
   return 0;
 }
 
-void aes_ofb_encrypt(caddr_t key, FAR uint8_t *data)
+void aes_ofb_encrypt(caddr_t key, FAR uint8_t *data, size_t len)
 {
   FAR struct aes_ofb_ctx *ctx;
   int i;
@@ -803,7 +814,7 @@ void aes_ofb_reinit(caddr_t key, FAR uint8_t *iv)
   ctx->iv = iv;
 }
 
-void aes_cfb8_encrypt(caddr_t key, FAR uint8_t *data)
+void aes_cfb8_encrypt(caddr_t key, FAR uint8_t *data, size_t len)
 {
   FAR struct aes_ofb_ctx *ctx;
   uint8_t ov[AESOFB_IVSIZE + 1];
@@ -821,7 +832,7 @@ void aes_cfb8_encrypt(caddr_t key, FAR uint8_t *data)
     }
 }
 
-void aes_cfb8_decrypt(caddr_t key, FAR uint8_t *data)
+void aes_cfb8_decrypt(caddr_t key, FAR uint8_t *data, size_t len)
 {
   FAR struct aes_ofb_ctx *ctx;
   uint8_t ov[AESOFB_IVSIZE + 1];
@@ -839,7 +850,7 @@ void aes_cfb8_decrypt(caddr_t key, FAR uint8_t *data)
     }
 }
 
-void aes_cfb128_encrypt(caddr_t key, FAR uint8_t *data)
+void aes_cfb128_encrypt(caddr_t key, FAR uint8_t *data, size_t len)
 {
   FAR struct aes_ofb_ctx *ctx;
   int i;
@@ -854,7 +865,7 @@ void aes_cfb128_encrypt(caddr_t key, FAR uint8_t *data)
     }
 }
 
-void aes_cfb128_decrypt(caddr_t key, FAR uint8_t *data)
+void aes_cfb128_decrypt(caddr_t key, FAR uint8_t *data, size_t len)
 {
   FAR struct aes_ofb_ctx *ctx;
   uint8_t c;
diff --git a/include/crypto/chachapoly.h b/include/crypto/chachapoly.h
index 49221058daf..ee5a4607842 100644
--- a/include/crypto/chachapoly.h
+++ b/include/crypto/chachapoly.h
@@ -23,7 +23,7 @@
 #define CHACHA20_KEYSIZE   32
 #define CHACHA20_CTR       4
 #define CHACHA20_SALT      4
-#define CHACHA20_NONCE     8
+#define CHACHA20_NONCE     4
 #define CHACHA20_BLOCK_LEN 64
 
 struct chacha20_ctx
@@ -34,9 +34,10 @@ struct chacha20_ctx
 
 int chacha20_setkey(FAR void *, FAR uint8_t *, int);
 void chacha20_reinit(caddr_t, FAR uint8_t *);
-void chacha20_crypt(caddr_t, FAR uint8_t *);
+void chacha20_crypt(caddr_t, FAR uint8_t *, size_t);
+void chachapoly_reinit(caddr_t, FAR uint8_t *);
 
-#define POLY1305_KEYLEN 32
+#define POLY1305_KEYLEN 64
 #define POLY1305_TAGLEN 16
 #define POLY1305_BLOCK_LEN 16
 
diff --git a/include/crypto/cryptodev.h b/include/crypto/cryptodev.h
index ad5f62afb53..3ee6c4f16cf 100644
--- a/include/crypto/cryptodev.h
+++ b/include/crypto/cryptodev.h
@@ -91,7 +91,7 @@
 #define BLOWFISH_BLOCK_LEN    8
 #define CAST128_BLOCK_LEN     8
 #define RIJNDAEL128_BLOCK_LEN 16
-#define EALG_MAX_BLOCK_LEN    16
+#define EALG_MAX_BLOCK_LEN    64
 
 /* Keep this updated */
 
@@ -140,7 +140,8 @@
 #define CRYPTO_PBKDF2_HMAC_SHA256 39
 #define CRYPTO_ESN              40 /* Support for Extended Sequence Numbers */
 #define CRYPTO_SHA2_224_HMAC    41
-#define CRYPTO_ALGORITHM_MAX    41 /* Keep updated */
+#define CRYPTO_CHACHA20         42
+#define CRYPTO_ALGORITHM_MAX    42 /* Keep updated */
 
 /* Algorithm flags */
 
diff --git a/include/crypto/xform.h b/include/crypto/xform.h
index 6f3bc42ec64..2e14495c29f 100644
--- a/include/crypto/xform.h
+++ b/include/crypto/xform.h
@@ -76,8 +76,8 @@ struct enc_xform
   uint16_t minkey;
   uint16_t maxkey;
   uint16_t ctxsize;
-  CODE void (*encrypt)(caddr_t, FAR uint8_t *);
-  CODE void (*decrypt)(caddr_t, FAR uint8_t *);
+  CODE void (*encrypt)(caddr_t, FAR uint8_t *, size_t);
+  CODE void (*decrypt)(caddr_t, FAR uint8_t *, size_t);
   CODE int  (*setkey)(FAR void *, FAR uint8_t *, int len);
   CODE void (*reinit)(caddr_t, FAR uint8_t *);
 };
@@ -112,6 +112,7 @@ extern const struct enc_xform enc_xform_aes_xts;
 extern const struct enc_xform enc_xform_aes_ofb;
 extern const struct enc_xform enc_xform_aes_cfb_8;
 extern const struct enc_xform enc_xform_aes_cfb_128;
+extern const struct enc_xform enc_xform_chacha20;
 extern const struct enc_xform enc_xform_chacha20_poly1305;
 extern const struct enc_xform enc_xform_null;
 

Reply via email to