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;