{bp-19403} crypto: add CRYPTO_CHACHA20_DJB variant (64-bit counter/nonce) - #19709
Merged
Conversation
Since already have support for SHA2-224, extend cryptodev/cryptosoft to support HMAC version of SHA2-224. Signed-off-by: Peter Barada <peter.barada@gmail.com>
…once.
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 <makejian@xiaomi.com>
CRYPTO_CHACHA20 implements the RFC 8439/IETF parameterization (32-bit counter + 96-bit nonce). SSH's chacha20-poly1305@openssh.com uses the original DJB construction instead: a 64-bit block counter in state words 12..13 and a 64-bit nonce in words 14..15 (libtomcrypt's chacha_ivctr64). The two layouts produce different keystreams for the same key, so an SSH server cannot interoperate with OpenSSH clients through the IETF variant. Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
jerpelea
requested review from
pkarashchenko,
raiden00pl,
simbit18 and
xiaoxiang781216
as code owners
August 6, 2026 07:40
xiaoxiang781216
approved these changes
Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a new OCF algorithm ID, CRYPTO_CHACHA20_DJB, implementing the
original ChaCha20 construction as designed by Daniel J. Bernstein (DJB),
alongside the already-supported IETF variant.
ChaCha20 exists in two standard parameterizations that differ only in how the
last four words of the cipher state (words 12..15) are split:
Includes
#19294
#19396
Impact
RELEASE
Testing
CI