Skip to content

Commit d2afc69

Browse files
committed
Add AES support for RISC-V: RV64 scalar
1 parent 1f7c695 commit d2afc69

File tree

8 files changed

+1016
-1
lines changed

8 files changed

+1016
-1
lines changed

.github/workflows/aes.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,35 @@ jobs:
310310
- run: cross test --package aes --target ${{ matrix.target }} --features hazmat
311311
- run: cross test --package aes --target ${{ matrix.target }} --all-features
312312

313+
riscv:
314+
strategy:
315+
matrix:
316+
include:
317+
- target: riscv64gc-unknown-linux-gnu
318+
rustflags: ''
319+
rust: stable
320+
- target: riscv64gc-unknown-linux-gnu
321+
rustflags: ''
322+
rust: nightly
323+
- target: riscv64gc-unknown-linux-gnu
324+
rustflags: '-Ctarget-feature=+zkne,+zknd'
325+
rust: nightly
326+
runs-on: ubuntu-latest
327+
defaults:
328+
run:
329+
working-directory: .
330+
steps:
331+
- uses: actions/checkout@v4
332+
- uses: RustCrypto/actions/cargo-cache@master
333+
- uses: dtolnay/rust-toolchain@master
334+
with:
335+
toolchain: ${{ matrix.rust }}
336+
targets: ${{ matrix.target }}
337+
- uses: RustCrypto/actions/cross-install@master
338+
- run: cross test --package aes --target ${{ matrix.target }}
339+
env:
340+
RUSTFLAGS: "-Dwarning ${{ matrix.rustflags }}"
341+
313342
clippy:
314343
env:
315344
RUSTFLAGS: "-Dwarnings --cfg aes_compact"

aes/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ hazmat = [] # Expose cryptographically hazardous APIs
3131

3232
[lints.rust.unexpected_cfgs]
3333
level = "warn"
34-
check-cfg = ["cfg(aes_compact)", "cfg(aes_force_soft)", "cfg(aes_avx256_disable)", "cfg(aes_avx512_disable)"]
34+
check-cfg = [
35+
"cfg(aes_compact)",
36+
"cfg(aes_force_soft)",
37+
"cfg(aes_avx256_disable)",
38+
"cfg(aes_avx512_disable)",
39+
"cfg(riscv_zkned)",
40+
]
3541

3642
[package.metadata.docs.rs]
3743
all-features = true

aes/src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@
3535
//! runtime. On other platforms the `aes` target feature must be enabled via
3636
//! RUSTFLAGS.
3737
//!
38+
//! ## RISC-V rv64 (scalar) {Zkne, ZKnd} extensions
39+
//!
40+
//! Support is available for the RISC-V rv64 scalar crypto extensions for AES. This
41+
//! is not currently autodetected at runtime. In order to enable, you need to
42+
//! enable the appropriate target features at compile time. For example:
43+
//! `RUSTFLAGS=-C target-feature=+zkne,+zknd`.
44+
//!
3845
//! ## `x86`/`x86_64` intrinsics (AES-NI and VAES)
3946
//! By default this crate uses runtime detection on `i686`/`x86_64` targets
4047
//! in order to determine if AES-NI and VAES are available, and if they are
@@ -123,12 +130,26 @@
123130
)]
124131
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
125132
#![warn(missing_docs, rust_2018_idioms)]
133+
#![cfg_attr(
134+
all(any(target_arch = "riscv64"), riscv_zkned),
135+
feature(riscv_ext_intrinsics)
136+
)]
126137

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

130141
#[macro_use]
131142
mod macros;
143+
#[cfg_attr(not(any(
144+
target_arch = "aarch64",
145+
target_arch = "x86",
146+
target_arch = "x86_64",
147+
)),
148+
// Architectures that have hardware-support backends, but that do not use
149+
// `autodetect` -- like RISC-V 64 -- will generate warnings about unused
150+
// definitions in `soft`. We silence them once here in order to avoid cluttering
151+
// `soft` with architecture specific conditionals.
152+
allow(unused))]
132153
mod soft;
133154

134155
use cfg_if::cfg_if;
@@ -138,6 +159,9 @@ cfg_if! {
138159
mod armv8;
139160
mod autodetect;
140161
pub use autodetect::*;
162+
} else if #[cfg(all(target_arch = "riscv64", riscv_zkned))] {
163+
mod riscv;
164+
pub use riscv::rv64::*;
141165
} else if #[cfg(all(
142166
any(target_arch = "x86", target_arch = "x86_64"),
143167
not(aes_force_soft)

aes/src/riscv.rs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
//! AES block cipher implementations for RISC-V using the Cryptography
2+
//! Extensions
3+
//!
4+
//! Supported targets: rv64 (scalar)
5+
//!
6+
//! NOTE: rv32 (scalar) is not currently implemented, primarily due to the
7+
//! difficulty in obtaining a suitable development environment (lack of distro
8+
//! support and lack of precompiled toolchains), the effort required for
9+
//! maintaining a test environment as 32-bit becomes less supported, and the
10+
//! overall scarcity of relevant hardware. If someone has a specific need for
11+
//! such an implementation, please open an issue.
12+
//!
13+
//! NOTE: These implementations are currently not enabled through
14+
//! auto-detection. In order to use this implementation, you must enable the
15+
//! appropriate target-features.
16+
//!
17+
//! Examining the module structure for this implementation should give you an
18+
//! idea of how to specify these features in your own code.
19+
//!
20+
//! NOTE: AES-128, AES-192, and AES-256 are supported.
21+
22+
#[cfg(all(target_arch = "riscv64", riscv_zkned))]
23+
pub(crate) mod rv64;
24+
25+
use crate::Block;
26+
27+
#[cfg(test)]
28+
mod test {
29+
use hex_literal::hex;
30+
31+
pub(crate) const AES128_KEY: [u8; 16] = hex!("2b7e151628aed2a6abf7158809cf4f3c");
32+
pub(crate) const AES128_EXP_KEYS: [[u8; 16]; 11] = [
33+
AES128_KEY,
34+
hex!("a0fafe1788542cb123a339392a6c7605"),
35+
hex!("f2c295f27a96b9435935807a7359f67f"),
36+
hex!("3d80477d4716fe3e1e237e446d7a883b"),
37+
hex!("ef44a541a8525b7fb671253bdb0bad00"),
38+
hex!("d4d1c6f87c839d87caf2b8bc11f915bc"),
39+
hex!("6d88a37a110b3efddbf98641ca0093fd"),
40+
hex!("4e54f70e5f5fc9f384a64fb24ea6dc4f"),
41+
hex!("ead27321b58dbad2312bf5607f8d292f"),
42+
hex!("ac7766f319fadc2128d12941575c006e"),
43+
hex!("d014f9a8c9ee2589e13f0cc8b6630ca6"),
44+
];
45+
pub(crate) const AES128_EXP_INVKEYS: [[u8; 16]; 11] = [
46+
AES128_KEY,
47+
hex!("2b3708a7f262d405bc3ebdbf4b617d62"),
48+
hex!("cc7505eb3e17d1ee82296c51c9481133"),
49+
hex!("7c1f13f74208c219c021ae480969bf7b"),
50+
hex!("90884413d280860a12a128421bc89739"),
51+
hex!("6ea30afcbc238cf6ae82a4b4b54a338d"),
52+
hex!("6efcd876d2df54807c5df034c917c3b9"),
53+
hex!("12c07647c01f22c7bc42d2f37555114a"),
54+
hex!("df7d925a1f62b09da320626ed6757324"),
55+
hex!("0c7b5a631319eafeb0398890664cfbb4"),
56+
hex!("d014f9a8c9ee2589e13f0cc8b6630ca6"),
57+
];
58+
59+
pub(crate) const AES192_KEY: [u8; 24] =
60+
hex!("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b");
61+
pub(crate) const AES192_EXP_KEYS: [[u8; 16]; 13] = [
62+
hex!("8e73b0f7da0e6452c810f32b809079e5"),
63+
hex!("62f8ead2522c6b7bfe0c91f72402f5a5"),
64+
hex!("ec12068e6c827f6b0e7a95b95c56fec2"),
65+
hex!("4db7b4bd69b5411885a74796e92538fd"),
66+
hex!("e75fad44bb095386485af05721efb14f"),
67+
hex!("a448f6d94d6dce24aa326360113b30e6"),
68+
hex!("a25e7ed583b1cf9a27f939436a94f767"),
69+
hex!("c0a69407d19da4e1ec1786eb6fa64971"),
70+
hex!("485f703222cb8755e26d135233f0b7b3"),
71+
hex!("40beeb282f18a2596747d26b458c553e"),
72+
hex!("a7e1466c9411f1df821f750aad07d753"),
73+
hex!("ca4005388fcc5006282d166abc3ce7b5"),
74+
hex!("e98ba06f448c773c8ecc720401002202"),
75+
];
76+
pub(crate) const AES192_EXP_INVKEYS: [[u8; 16]; 13] = [
77+
hex!("8e73b0f7da0e6452c810f32b809079e5"),
78+
hex!("9eb149c479d69c5dfeb4a27ceab6d7fd"),
79+
hex!("659763e78c817087123039436be6a51e"),
80+
hex!("41b34544ab0592b9ce92f15e421381d9"),
81+
hex!("5023b89a3bc51d84d04b19377b4e8b8e"),
82+
hex!("b5dc7ad0f7cffb09a7ec43939c295e17"),
83+
hex!("c5ddb7f8be933c760b4f46a6fc80bdaf"),
84+
hex!("5b6cfe3cc745a02bf8b9a572462a9904"),
85+
hex!("4d65dfa2b1e5620dea899c312dcc3c1a"),
86+
hex!("f3b42258b59ebb5cf8fb64fe491e06f3"),
87+
hex!("a3979ac28e5ba6d8e12cc9e654b272ba"),
88+
hex!("ac491644e55710b746c08a75c89b2cad"),
89+
hex!("e98ba06f448c773c8ecc720401002202"),
90+
];
91+
92+
pub(crate) const AES256_KEY: [u8; 32] =
93+
hex!("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
94+
pub(crate) const AES256_EXP_KEYS: [[u8; 16]; 15] = [
95+
hex!("603deb1015ca71be2b73aef0857d7781"),
96+
hex!("1f352c073b6108d72d9810a30914dff4"),
97+
hex!("9ba354118e6925afa51a8b5f2067fcde"),
98+
hex!("a8b09c1a93d194cdbe49846eb75d5b9a"),
99+
hex!("d59aecb85bf3c917fee94248de8ebe96"),
100+
hex!("b5a9328a2678a647983122292f6c79b3"),
101+
hex!("812c81addadf48ba24360af2fab8b464"),
102+
hex!("98c5bfc9bebd198e268c3ba709e04214"),
103+
hex!("68007bacb2df331696e939e46c518d80"),
104+
hex!("c814e20476a9fb8a5025c02d59c58239"),
105+
hex!("de1369676ccc5a71fa2563959674ee15"),
106+
hex!("5886ca5d2e2f31d77e0af1fa27cf73c3"),
107+
hex!("749c47ab18501ddae2757e4f7401905a"),
108+
hex!("cafaaae3e4d59b349adf6acebd10190d"),
109+
hex!("fe4890d1e6188d0b046df344706c631e"),
110+
];
111+
pub(crate) const AES256_EXP_INVKEYS: [[u8; 16]; 15] = [
112+
hex!("603deb1015ca71be2b73aef0857d7781"),
113+
hex!("8ec6bff6829ca03b9e49af7edba96125"),
114+
hex!("42107758e9ec98f066329ea193f8858b"),
115+
hex!("4a7459f9c8e8f9c256a156bc8d083799"),
116+
hex!("6c3d632985d1fbd9e3e36578701be0f3"),
117+
hex!("54fb808b9c137949cab22ff547ba186c"),
118+
hex!("25ba3c22a06bc7fb4388a28333934270"),
119+
hex!("d669a7334a7ade7a80c8f18fc772e9e3"),
120+
hex!("c440b289642b757227a3d7f114309581"),
121+
hex!("32526c367828b24cf8e043c33f92aa20"),
122+
hex!("34ad1e4450866b367725bcc763152946"),
123+
hex!("b668b621ce40046d36a047ae0932ed8e"),
124+
hex!("57c96cf6074f07c0706abb07137f9241"),
125+
hex!("ada23f4963e23b2455427c8a5c709104"),
126+
hex!("fe4890d1e6188d0b046df344706c631e"),
127+
];
128+
}

0 commit comments

Comments
 (0)