Skip to content

arch/arm64: AES using the Armv8 Cryptography Extension - #20193

Draft
royzah wants to merge 1 commit into
apache:masterfrom
royzah:arm64-crypto-aes
Draft

royzah wants to merge 1 commit into
apache:masterfrom
royzah:arm64-crypto-aes

Conversation

@royzah

@royzah royzah commented Sep 19, 2026

Copy link
Copy Markdown

Summary

NuttX emits no AES instruction on any core. arm64 has no runtime feature dispatch, so a part that implements the Cryptography Extension still runs the table version in https://github.com/apache/nuttx/blob/master/crypto/rijndael.c, which indexes eight 256-entry tables with key-dependent values and therefore has cache-dependent timing.

This provides the crypto/aes.h block operations with AESE, AESD and the MixColumns pair, behind CONFIG_ARM64_CRYPTO_AES. ID_AA64ISAR0_EL1.AES is read at key setup, so a core without the extension gets a failed aes_setkey rather than an undefined instruction.

Two points for review:

  • The key schedule stays in C apart from SubWord, which borrows AESE with a zero round key. That only yields the substituted word if ShiftRows has nothing to move, so the word is replicated across all four columns first.
  • Decryption uses the equivalent inverse cipher: InvMixColumns is folded into the middle round keys at setup, so the block path is the same shape as encryption.

Impact

arm64, opt-in, off by default. New file, no existing behaviour changes. crypto/rijndael.c is untouched and remains what xform.c uses.

Testing

Verified against the FIPS-197 appendix C vectors for 128, 192 and 256 bits, both directions, executing the instructions under qemu-aarch64:

ok   AES-128        ok   AES-128 decrypt
ok   AES-192        ok   AES-192 decrypt
ok   AES-256        ok   AES-256 decrypt
all FIPS-197 vectors pass

tools/nxstyle clean.

Owed before ready: throughput against the table version on a real part, and a boot log. Both need hardware this branch does not have.

@github-actions github-actions Bot added Arch: arm64 Issues related to ARM64 (64-bit) architecture Size: M The size of the change in this PR is medium labels Sep 19, 2026
@github-actions

github-actions Bot commented Sep 19, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

Comment thread arch/arm64/src/common/arm64_aes.c Outdated
*
****************************************************************************/

int aes_setkey(FAR AES_CTX *ctx, FAR const uint8_t *key, int len)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we implement as crypto driver?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. And it found a bug: my file and crypto/aes.c define the same five functions, so both on will not link.

aes_cypher() avoids that, like stm32h7 and esp32, but then only /dev/crypto gets it, not xform.c. Prefer that?

NuttX emits no AES instruction on any arm64 core. There is no runtime
feature dispatch in arch/arm64, so every AES goes through crypto/rijndael.c
or crypto/aes.c, and the table-driven one indexes memory with key-dependent
values, so its timing follows the cache.

Provide aes_cypher() for ECB, CBC and CTR built on AESE, AESD and the
MixColumns pair, and register it with /dev/crypto as a hardware driver
alongside the existing stm32h7, sam34 and esp32 modules.

ID_AA64ISAR0_EL1.AES is read on every call, which returns -ENOTSUP rather
than trapping on a core without the extension.

Verified against the NIST SP 800-38A appendix F vectors for ECB-128,
ECB-256, CBC-128, CBC-192 and CTR-128, encrypt and decrypt, in place and
out of place.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm64 Issues related to ARM64 (64-bit) architecture Size: M The size of the change in this PR is medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants