Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/aes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,43 @@ jobs:
- run: cross test --package aes --target ${{ matrix.target }} --features hazmat
- run: cross test --package aes --target ${{ matrix.target }} --all-features

riscv:
strategy:
matrix:
include:
- target: riscv64gc-unknown-linux-gnu
rustflags: ''
rust: stable
- target: riscv64gc-unknown-linux-gnu
rustflags: ''
rust: nightly
- target: riscv64gc-unknown-linux-gnu
rustflags: '-Ctarget-feature=+zkne,+zknd'
rust: nightly
- target: riscv64gc-unknown-linux-gnu
rustflags: '-Ctarget-feature=+v,+zvkned --cfg=aes_zvkned'
rust: nightly
- target: riscv64gc-unknown-linux-gnu
rustflags: '-Ctarget-feature=+zkne,+zknd,+v,+zvkned --cfg=aes_zvkned'
rust: nightly
runs-on: ubuntu-latest
defaults:
run:
working-directory: .
steps:
- uses: actions/checkout@v4
- uses: RustCrypto/actions/cargo-cache@master
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
targets: ${{ matrix.target }}
- run: cargo install cross --git https://github.com/cross-rs/cross --rev e281947ca900da425e4ecea7483cfde646c8a1ea
env:
RUSTFLAGS: "-Dwarning -Astatic-mut-refs"
- run: cross test --package aes --target ${{ matrix.target }}
env:
RUSTFLAGS: "-Dwarning ${{ matrix.rustflags }}"

clippy:
env:
RUSTFLAGS: "-Dwarnings --cfg aes_compact"
Expand Down
9 changes: 8 additions & 1 deletion aes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ hazmat = [] # Expose cryptographically hazardous APIs

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = ["cfg(aes_compact)", "cfg(aes_force_soft)", "cfg(aes_avx256_disable)", "cfg(aes_avx512_disable)"]
check-cfg = [
"cfg(aes_compact)",
"cfg(aes_force_soft)",
"cfg(aes_avx256_disable)",
"cfg(aes_avx512_disable)",
"cfg(riscv_zkned)",
"cfg(riscv_zvkned)"
]

[package.metadata.docs.rs]
all-features = true
Expand Down
40 changes: 40 additions & 0 deletions aes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,26 @@
//! runtime. On other platforms the `aes` target feature must be enabled via
//! RUSTFLAGS.
//!
//! ## RISC-V rv64 (scalar) {Zkne, ZKnd} extensions
//!
//! Support is available for the RISC-V rv64 scalar crypto extensions for AES. This
//! is not currently autodetected at runtime. In order to enable, you need to
//! enable the appropriate target features at compile time. For example:
//! `RUSTFLAGS=-C target-feature=+zkne,+zknd`.
//!
//! ## RISC-V rvv (vector) {Zvkned} extensions
//!
//! Support is available for the RISC-V vector crypto extensions for AES. This is
//! not currently autodetected at runtime. In order to enable, you need to enable
//! the appropriate target features at compile time. For example:
//! `RUSTFLAGS=-C target-feature=+v,+zvkned`.
//!
//! NOTE: Hardware accelerated vector key-schedule routines for AES-192 are not
//! available for the RISC-V vector crypto extensions. It is still possible to
//! fall back to using the scalar key-schedule routines for AES-192 in this case
//! if the appropriate target features are enabled. For example:
//! `RUSTFLAGS=-C target-feature=+zkne,+zknd,+v,+zvkned`.
//!
//! ## `x86`/`x86_64` intrinsics (AES-NI and VAES)
//! By default this crate uses runtime detection on `i686`/`x86_64` targets
//! in order to determine if AES-NI and VAES are available, and if they are
Expand Down Expand Up @@ -123,12 +143,26 @@
)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![warn(missing_docs, rust_2018_idioms)]
#![cfg_attr(
all(any(target_arch = "riscv64"), riscv_zkned),
feature(riscv_ext_intrinsics)
)]

#[cfg(feature = "hazmat")]
pub mod hazmat;

#[macro_use]
mod macros;
#[cfg_attr(not(any(
target_arch = "aarch64",
target_arch = "x86",
target_arch = "x86_64",
)),
// Architectures that have hardware-support backends, but that do not use
// `autodetect` -- like RISC-V 64 -- will generate warnings about unused
// definitions in `soft`. We silence them once here in order to avoid cluttering
// `soft` with architecture specific conditionals.
allow(unused))]
mod soft;

use cfg_if::cfg_if;
Expand All @@ -138,6 +172,12 @@ cfg_if! {
mod armv8;
mod autodetect;
pub use autodetect::*;
} else if #[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "v", riscv_zvkned))] {
mod riscv;
pub use riscv::rvv::*;
} else if #[cfg(all(target_arch = "riscv64", riscv_zkned))] {
mod riscv;
pub use riscv::rv64::*;
} else if #[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(aes_force_soft)
Expand Down
145 changes: 145 additions & 0 deletions aes/src/riscv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
//! AES block cipher implementations for RISC-V using the Cryptography
//! Extensions
//!
//! Supported targets: rv64 (scalar), rvv
//!
//! NOTE: rv32 (scalar) is not currently implemented, primarily due to the
//! difficulty in obtaining a suitable development environment (lack of distro
//! support and lack of precompiled toolchains), the effort required for
//! maintaining a test environment as 32-bit becomes less supported, and the
//! overall scarcity of relevant hardware. If someone has a specific need for
//! such an implementation, please open an issue. Theoretically, the rvv
//! implementation should work for riscv32, for a hypothetical rv32
//! implementation satisfying the vector feature requirements.
//!
//! NOTE: These implementations are currently not enabled through
//! auto-detection. In order to use this implementation, you must enable the
//! appropriate target-features.
//!
//! Additionally, for the vector implementation, since the `zvkned`
//! target-feature is not yet defined in Rust, you must pass
//! `--cfg=riscv_zvkned` to the compiler (through `RUSTFLAGS` or some other
//! means). However, you still must enable the `v` target-feature.
//!
//! Examining the module structure for this implementation should give you an
//! idea of how to specify these features in your own code.
//!
//! NOTE: AES-128, AES-192, and AES-256 are supported for both the scalar and
//! vector implementations.
//!
//! However, key expansion is not vector-accelerated for the AES-192 case
//! (because RISC-V does not provide vector instructions for this case). Users
//! concerned with vector performance are advised to select AES-129 or AES-256
//! instead. Nevertheless, the AES-192 vector implementation will still fall
//! back to the scalar AES-192 key-schedule implementation, if the appropriate
//! scalar target-features are enabled.

#[cfg(all(target_arch = "riscv64", riscv_zkned))]
pub(crate) mod rv64;
#[cfg(all(target_arch = "riscv64", riscv_zvkned,))]
pub(crate) mod rvv;

use crate::Block;

#[cfg(test)]
mod test {
use hex_literal::hex;

pub(crate) const AES128_KEY: [u8; 16] = hex!("2b7e151628aed2a6abf7158809cf4f3c");
pub(crate) const AES128_EXP_KEYS: [[u8; 16]; 11] = [
AES128_KEY,
hex!("a0fafe1788542cb123a339392a6c7605"),
hex!("f2c295f27a96b9435935807a7359f67f"),
hex!("3d80477d4716fe3e1e237e446d7a883b"),
hex!("ef44a541a8525b7fb671253bdb0bad00"),
hex!("d4d1c6f87c839d87caf2b8bc11f915bc"),
hex!("6d88a37a110b3efddbf98641ca0093fd"),
hex!("4e54f70e5f5fc9f384a64fb24ea6dc4f"),
hex!("ead27321b58dbad2312bf5607f8d292f"),
hex!("ac7766f319fadc2128d12941575c006e"),
hex!("d014f9a8c9ee2589e13f0cc8b6630ca6"),
];
pub(crate) const AES128_EXP_INVKEYS: [[u8; 16]; 11] = [
AES128_KEY,
hex!("2b3708a7f262d405bc3ebdbf4b617d62"),
hex!("cc7505eb3e17d1ee82296c51c9481133"),
hex!("7c1f13f74208c219c021ae480969bf7b"),
hex!("90884413d280860a12a128421bc89739"),
hex!("6ea30afcbc238cf6ae82a4b4b54a338d"),
hex!("6efcd876d2df54807c5df034c917c3b9"),
hex!("12c07647c01f22c7bc42d2f37555114a"),
hex!("df7d925a1f62b09da320626ed6757324"),
hex!("0c7b5a631319eafeb0398890664cfbb4"),
hex!("d014f9a8c9ee2589e13f0cc8b6630ca6"),
];

pub(crate) const AES192_KEY: [u8; 24] =
hex!("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b");
pub(crate) const AES192_EXP_KEYS: [[u8; 16]; 13] = [
hex!("8e73b0f7da0e6452c810f32b809079e5"),
hex!("62f8ead2522c6b7bfe0c91f72402f5a5"),
hex!("ec12068e6c827f6b0e7a95b95c56fec2"),
hex!("4db7b4bd69b5411885a74796e92538fd"),
hex!("e75fad44bb095386485af05721efb14f"),
hex!("a448f6d94d6dce24aa326360113b30e6"),
hex!("a25e7ed583b1cf9a27f939436a94f767"),
hex!("c0a69407d19da4e1ec1786eb6fa64971"),
hex!("485f703222cb8755e26d135233f0b7b3"),
hex!("40beeb282f18a2596747d26b458c553e"),
hex!("a7e1466c9411f1df821f750aad07d753"),
hex!("ca4005388fcc5006282d166abc3ce7b5"),
hex!("e98ba06f448c773c8ecc720401002202"),
];
pub(crate) const AES192_EXP_INVKEYS: [[u8; 16]; 13] = [
hex!("8e73b0f7da0e6452c810f32b809079e5"),
hex!("9eb149c479d69c5dfeb4a27ceab6d7fd"),
hex!("659763e78c817087123039436be6a51e"),
hex!("41b34544ab0592b9ce92f15e421381d9"),
hex!("5023b89a3bc51d84d04b19377b4e8b8e"),
hex!("b5dc7ad0f7cffb09a7ec43939c295e17"),
hex!("c5ddb7f8be933c760b4f46a6fc80bdaf"),
hex!("5b6cfe3cc745a02bf8b9a572462a9904"),
hex!("4d65dfa2b1e5620dea899c312dcc3c1a"),
hex!("f3b42258b59ebb5cf8fb64fe491e06f3"),
hex!("a3979ac28e5ba6d8e12cc9e654b272ba"),
hex!("ac491644e55710b746c08a75c89b2cad"),
hex!("e98ba06f448c773c8ecc720401002202"),
];

pub(crate) const AES256_KEY: [u8; 32] =
hex!("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
pub(crate) const AES256_EXP_KEYS: [[u8; 16]; 15] = [
hex!("603deb1015ca71be2b73aef0857d7781"),
hex!("1f352c073b6108d72d9810a30914dff4"),
hex!("9ba354118e6925afa51a8b5f2067fcde"),
hex!("a8b09c1a93d194cdbe49846eb75d5b9a"),
hex!("d59aecb85bf3c917fee94248de8ebe96"),
hex!("b5a9328a2678a647983122292f6c79b3"),
hex!("812c81addadf48ba24360af2fab8b464"),
hex!("98c5bfc9bebd198e268c3ba709e04214"),
hex!("68007bacb2df331696e939e46c518d80"),
hex!("c814e20476a9fb8a5025c02d59c58239"),
hex!("de1369676ccc5a71fa2563959674ee15"),
hex!("5886ca5d2e2f31d77e0af1fa27cf73c3"),
hex!("749c47ab18501ddae2757e4f7401905a"),
hex!("cafaaae3e4d59b349adf6acebd10190d"),
hex!("fe4890d1e6188d0b046df344706c631e"),
];
pub(crate) const AES256_EXP_INVKEYS: [[u8; 16]; 15] = [
hex!("603deb1015ca71be2b73aef0857d7781"),
hex!("8ec6bff6829ca03b9e49af7edba96125"),
hex!("42107758e9ec98f066329ea193f8858b"),
hex!("4a7459f9c8e8f9c256a156bc8d083799"),
hex!("6c3d632985d1fbd9e3e36578701be0f3"),
hex!("54fb808b9c137949cab22ff547ba186c"),
hex!("25ba3c22a06bc7fb4388a28333934270"),
hex!("d669a7334a7ade7a80c8f18fc772e9e3"),
hex!("c440b289642b757227a3d7f114309581"),
hex!("32526c367828b24cf8e043c33f92aa20"),
hex!("34ad1e4450866b367725bcc763152946"),
hex!("b668b621ce40046d36a047ae0932ed8e"),
hex!("57c96cf6074f07c0706abb07137f9241"),
hex!("ada23f4963e23b2455427c8a5c709104"),
hex!("fe4890d1e6188d0b046df344706c631e"),
];
}
Loading