Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
4db4fb8
aria: add bouncycastle-aria, a constant-time, table-free ARIA ported …
dghgit Sep 5, 2026
2e8a0dc
aria: every CBC and ECB alias takes <Dir, Pad> over the shared Padded…
dghgit Sep 8, 2026
e2bfc73
aria: add Wycheproof CBC-PKCS5 vectors, 216 cases of which 144 are in…
dghgit Sep 8, 2026
e0192f5
aria: the ElectronicCodeBook trait is the only public route to the pe…
dghgit Sep 7, 2026
fbedd0b
aria: consolidate the bc-java attribution
dghgit Sep 19, 2026
3cba0b0
mem_usage_benches: fence bench_aria_mem_usage's shell recipes as ```text
dghgit Sep 19, 2026
3022284
aria: add the ARIA_CFB_*, ARIA_CFB8_* and ARIA_CTR_* aliases and thei…
dghgit Sep 20, 2026
cd6d0fb
aria: make the new CLI stream-mode test harnesses tolerate a broken p…
dghgit Sep 20, 2026
f6c3af8
aria: give aria_cbc_cli_tests.rs the same broken-pipe tolerance the s…
dghgit Sep 20, 2026
9efd6f3
aria: drop references to ElectronicCodeBook's batch-method defaults, …
dghgit Sep 25, 2026
a1db9da
aria: adapt to feature/simple-ciphers -- the API changes this branch …
dghgit Sep 28, 2026
33d9203
aria: adapt to feature/simple-ciphers 0fb4e79 -- the stream-mode alia…
dghgit Sep 29, 2026
ebd1087
aria: adopt the hazmat layout (#156 step 5)
dghgit Oct 1, 2026
93e1544
aria: project the ARIA_CBC_* aliases through core's sealed Direction:…
dghgit Oct 1, 2026
0035d54
aria: what the linear replay dropped -- the merge-carried adaptations…
dghgit Oct 24, 2026
318f03b
aria: onto the key objects -- ARIAKey<P, M> hands out the mode worker…
dghgit Oct 24, 2026
4f39822
aria: the keys carry only the roles the aliases use -- the AEAD, ECB …
dghgit Oct 25, 2026
e18f813
aria: the engine and the keys compare in constant time
dghgit Oct 25, 2026
7ee0710
aria: key expansion keeps every intermediate in a Secret
dghgit Nov 3, 2026
f555f1b
aria: the diffusion layer broadcasts the parity byte with shifts, not…
dghgit Nov 3, 2026
cb1d00a
aria: review fixes -- the keys' leftover MAC-key path goes, the mode …
dghgit Nov 3, 2026
06cda6d
cli: the aria commands take the aes contract -- PKCS7, --iv/--iv-file…
dghgit Nov 3, 2026
6713417
aria: the Wycheproof suites through the shared loaders -- CBC-PKCS5 w…
dghgit Nov 3, 2026
08e15bd
aria: the mode and key modules stay private, and their docs move onto…
dghgit Nov 3, 2026
d70fe5b
aria: the merge-time adaptations to feature/key-rework-memory, carrie…
dghgit Nov 3, 2026
42b5da3
aria: the diffusion layer's byte-parity broadcast is three rotations,…
dghgit Nov 3, 2026
015f69e
aria: the decryption-order test runs the engine: it transcribes Sec 2…
dghgit Nov 3, 2026
ab948d3
aria, cli: the second review round's doc corrections: the aria*-cbc c…
dghgit Nov 3, 2026
e64d01e
aria: the AEAD, ECB and MAC role pairs return to the key, as AESKey c…
dghgit Nov 4, 2026
b5f786e
cli: aria{128,192,256}-gcm and aria{128,192,256}-ccm, the aes*-gcm an…
dghgit Nov 4, 2026
f16cb1f
Merge release/0.1.3alpha (029a17b0, the squash merge of PR #190) into…
dghgit Nov 4, 2026
2f7fba2
aria: the Wycheproof CCM suite runs through ARIA*Key<CCM<N, T>> and i…
dghgit Nov 4, 2026
60c4b94
cli: the ARIA commands' help takes the AES wording for the input rule…
dghgit Nov 4, 2026
43eeccc
aria: add bouncycastle-aria, a constant-time, table-free ARIA ported …
dghgit Sep 5, 2026
dd2f66f
aria: every CBC and ECB alias takes <Dir, Pad> over the shared Padded…
dghgit Sep 8, 2026
8e0830d
aria: add Wycheproof CBC-PKCS5 vectors, 216 cases of which 144 are in…
dghgit Sep 8, 2026
7b7d271
aria: the ElectronicCodeBook trait is the only public route to the pe…
dghgit Sep 7, 2026
cd2bf73
aria: consolidate the bc-java attribution
dghgit Sep 19, 2026
3409a82
mem_usage_benches: fence bench_aria_mem_usage's shell recipes as ```text
dghgit Sep 19, 2026
a1714d4
aria: add the ARIA_CFB_*, ARIA_CFB8_* and ARIA_CTR_* aliases and thei…
dghgit Sep 20, 2026
5dd1fa6
aria: make the new CLI stream-mode test harnesses tolerate a broken p…
dghgit Sep 20, 2026
3c0848b
aria: give aria_cbc_cli_tests.rs the same broken-pipe tolerance the s…
dghgit Sep 20, 2026
92b2306
aria: drop references to ElectronicCodeBook's batch-method defaults, …
dghgit Sep 25, 2026
773f9b4
aria: adapt to feature/simple-ciphers -- the API changes this branch …
dghgit Sep 28, 2026
5c18bf4
aria: adapt to feature/simple-ciphers 0fb4e79 -- the stream-mode alia…
dghgit Sep 29, 2026
76984d0
aria: adopt the hazmat layout (#156 step 5)
dghgit Oct 1, 2026
7db0632
aria: project the ARIA_CBC_* aliases through core's sealed Direction:…
dghgit Oct 1, 2026
25eb280
aria: what the linear replay dropped -- the merge-carried adaptations…
dghgit Oct 24, 2026
801ce09
aria: onto the key objects -- ARIAKey<P, M> hands out the mode worker…
dghgit Oct 24, 2026
cd9a115
aria: the keys carry only the roles the aliases use -- the AEAD, ECB …
dghgit Oct 25, 2026
bba3dbb
aria: the engine and the keys compare in constant time
dghgit Oct 25, 2026
d6ebd93
aria: key expansion keeps every intermediate in a Secret
dghgit Nov 3, 2026
d8f342a
aria: the diffusion layer broadcasts the parity byte with shifts, not…
dghgit Nov 3, 2026
a4d8725
aria: review fixes -- the keys' leftover MAC-key path goes, the mode …
dghgit Nov 3, 2026
530c511
cli: the aria commands take the aes contract -- PKCS7, --iv/--iv-file…
dghgit Nov 3, 2026
9152d84
aria: the Wycheproof suites through the shared loaders -- CBC-PKCS5 w…
dghgit Nov 3, 2026
2f32bd4
aria: the mode and key modules stay private, and their docs move onto…
dghgit Nov 3, 2026
709835e
aria: the merge-time adaptations to feature/key-rework-memory, carrie…
dghgit Nov 3, 2026
f58d906
aria: the diffusion layer's byte-parity broadcast is three rotations,…
dghgit Nov 3, 2026
c7f1be1
aria: the decryption-order test runs the engine: it transcribes Sec 2…
dghgit Nov 3, 2026
1b4afad
aria, cli: the second review round's doc corrections: the aria*-cbc c…
dghgit Nov 3, 2026
d33e792
aria: the AEAD, ECB and MAC role pairs return to the key, as AESKey c…
dghgit Nov 4, 2026
79ff4ae
cli: aria{128,192,256}-gcm and aria{128,192,256}-ccm, the aes*-gcm an…
dghgit Nov 4, 2026
3d2b504
aria: the Wycheproof CCM suite runs through ARIA*Key<CCM<N, T>> and i…
dghgit Nov 4, 2026
475bd6c
cli: the ARIA commands' help takes the AES wording for the input rule…
dghgit Nov 4, 2026
95a55fc
aria: the merge-time adaptations to release/0.1.3alpha, carried over …
dghgit Nov 4, 2026
780cfc1
Merge branch 'feature/aria' of git.bouncycastle.org:bc-rust into feat…
Nov 4, 2026
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
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ version = "0.1.4"
# *** Internal Dependencies ***
bouncycastle = { path = "./" }
bouncycastle-aes = { path = "./crypto/aes" }
bouncycastle-aria = { path = "./crypto/aria" }
bouncycastle-ascon = { path = "./crypto/ascon" }
bouncycastle-base64 = { path = "./crypto/base64" }
bouncycastle-cipher = { path = "./crypto/cipher" }
Expand Down Expand Up @@ -59,6 +60,7 @@ edition.workspace = true

[dependencies]
bouncycastle-aes.workspace = true
bouncycastle-aria.workspace = true
bouncycastle-ascon.workspace = true
bouncycastle-base64.workspace = true
bouncycastle-cipher.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions cli/src/aes_ccm_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ use crate::helpers::block_mode_helpers::{CipherDirection, load_key};
/// The one-shots this command uses are on the key's role traits, and the key type carries the
/// nonce and tag lengths as const parameters, so a generic `run` over the key length needs a way
/// to name the key type for an `(N, T)` it chooses at run time: this generic associated type.
trait CcmKeys<const KEY_LEN: usize> {
pub(crate) trait CcmKeys<const KEY_LEN: usize> {
/// The key type at nonce length `N` and tag length `T`.
type Key<const N: usize, const T: usize>: FromKeyMaterial<KEY_LEN>
+ AeadDeclaredEncryptionKey<KEY_LEN, N, T, T>
Expand Down Expand Up @@ -227,7 +227,7 @@ fn load_aad(aad: &Option<String>, aad_file: &Option<String>) -> Vec<u8> {
/// be matched into one of the permitted instantiations. The two nested matches are the price of
/// that, and they are exhaustive over A.1's sets: 7 nonce lengths x 7 tag lengths.
#[allow(clippy::too_many_arguments)] // the three key lengths' inputs, already parsed
fn run<F: CcmKeys<KEY_LEN>, const KEY_LEN: usize>(
pub(crate) fn run<F: CcmKeys<KEY_LEN>, const KEY_LEN: usize>(
action: &CipherDirection,
key: &KeyMaterial<KEY_LEN>,
nonce: &Option<String>,
Expand Down
91 changes: 91 additions & 0 deletions cli/src/aria_cbc_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//! ARIA-CBC encryption and decryption, streaming stdin to stdout.
//!
//! Only the cipher wiring lives here: the IV convention, key loading and stdin framing are all
//! in [`crate::helpers::block_mode_helpers`], shared with the `aes*-cbc` and `aes*-ecb`
//! commands. See that module for the command-line contract. Input is padded with PKCS7, so it
//! may be any length.
//!
//! `aria128-cbc` / `aria192-cbc` / `aria256-cbc` are the same command as `aes*-cbc` over the ARIA
//! permutation (RFC 5794; 16-, 24- or 32-byte key, 16-byte block), so every remark there applies
//! unchanged. They are not the `id-aria*-cbc` objects of RFC 5794 Appendix B: those default to
//! padding method 2 of ISO/IEC 9797-1 (`AriaCbcParameters`' `padAlgo DEFAULT id-pad-1`), and
//! PKCS#7 is not among the padding algorithms the RFC specifies. CBC (NIST SP 800-38A Sec 6.2)
//! provides confidentiality only: neither the ciphertext nor the IV is authenticated. Do not
//! decrypt data you have not authenticated separately.

use crate::helpers::block_mode_helpers::{
CipherDirection, decrypt_stream, encrypt_stream, load_iv, load_key_object, start_encryptor,
};
use bouncycastle::aria::{ARIA128Key, ARIA192Key, ARIA256Key, BLOCK_LEN};
use bouncycastle::cipher::modes::CBC;
use bouncycastle::cipher::padding::PKCS7;
use bouncycastle::core::symmetric_key::{SymmetricDecryptionKey, SymmetricEncryptionKey};

pub(crate) fn aria128_cbc_cmd(
action: &CipherDirection,
key: &Option<String>,
key_file: &Option<String>,
iv: &Option<String>,
iv_file: &Option<String>,
output_hex: bool,
) {
run::<_, 16>(
action,
&load_key_object::<ARIA128Key<CBC<PKCS7>>, 16>(key, key_file, "ARIA-128"),
load_iv::<BLOCK_LEN>(iv, iv_file),
output_hex,
);
}

pub(crate) fn aria192_cbc_cmd(
action: &CipherDirection,
key: &Option<String>,
key_file: &Option<String>,
iv: &Option<String>,
iv_file: &Option<String>,
output_hex: bool,
) {
run::<_, 24>(
action,
&load_key_object::<ARIA192Key<CBC<PKCS7>>, 24>(key, key_file, "ARIA-192"),
load_iv::<BLOCK_LEN>(iv, iv_file),
output_hex,
);
}

pub(crate) fn aria256_cbc_cmd(
action: &CipherDirection,
key: &Option<String>,
key_file: &Option<String>,
iv: &Option<String>,
iv_file: &Option<String>,
output_hex: bool,
) {
run::<_, 32>(
action,
&load_key_object::<ARIA256Key<CBC<PKCS7>>, 32>(key, key_file, "ARIA-256"),
load_iv::<BLOCK_LEN>(iv, iv_file),
output_hex,
);
}

/// Dispatches to the shared streaming loops under the key's padded CBC mode.
fn run<K, const KEY_LEN: usize>(
action: &CipherDirection,
key: &K,
iv: Option<[u8; BLOCK_LEN]>,
output_hex: bool,
) where
K: SymmetricEncryptionKey<KEY_LEN, BLOCK_LEN, BLOCK_LEN>
+ SymmetricDecryptionKey<KEY_LEN, BLOCK_LEN, BLOCK_LEN>,
{
match action {
CipherDirection::Encrypt => {
let (enc, generated_iv) = start_encryptor(iv, |rng| key.create_encryptor(rng));
encrypt_stream::<_, BLOCK_LEN>(enc, generated_iv.as_ref(), output_hex, None)
}
CipherDirection::Decrypt => {
decrypt_stream::<_, BLOCK_LEN>(iv, |iv| key.create_decryptor(iv), output_hex, None)
}
}
}
101 changes: 101 additions & 0 deletions cli/src/aria_ccm_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//! ARIA-CCM authenticated encryption and decryption: the `aes*-ccm` commands over the ARIA
//! permutation (RFC 5794; Appendix B's `id-aria*-ccm`), with the same contract -- the whole
//! input read first, the nonce supplied rather than generated, `ciphertext || tag` out. See
//! [`crate::aes_ccm_cmd`] for why CCM cannot stream and for the nonce and length rules; this
//! file only names the ARIA key types for that module's runner.

use crate::aes_ccm_cmd::{CcmKeys, run};
use crate::helpers::block_mode_helpers::{CipherDirection, load_key};
use bouncycastle::aria::{ARIA128Key, ARIA192Key, ARIA256Key};
use bouncycastle::cipher::modes::CCM;

struct Aria128;
struct Aria192;
struct Aria256;

impl CcmKeys<16> for Aria128 {
type Key<const N: usize, const T: usize> = ARIA128Key<CCM<N, T>>;
}

impl CcmKeys<24> for Aria192 {
type Key<const N: usize, const T: usize> = ARIA192Key<CCM<N, T>>;
}

impl CcmKeys<32> for Aria256 {
type Key<const N: usize, const T: usize> = ARIA256Key<CCM<N, T>>;
}

/// ARIA-128 CCM. See the module docs and the subcommand help.
#[allow(clippy::too_many_arguments)]
pub(crate) fn aria128_ccm_cmd(
action: &CipherDirection,
key: &Option<String>,
key_file: &Option<String>,
nonce: &Option<String>,
nonce_file: &Option<String>,
aad: &Option<String>,
aad_file: &Option<String>,
tag_len: usize,
output_hex: bool,
) {
run::<Aria128, 16>(
action,
&load_key::<16>(key, key_file, "ARIA-128"),
nonce,
nonce_file,
aad,
aad_file,
tag_len,
output_hex,
);
}

/// ARIA-192 CCM. See [`aria128_ccm_cmd`].
#[allow(clippy::too_many_arguments)]
pub(crate) fn aria192_ccm_cmd(
action: &CipherDirection,
key: &Option<String>,
key_file: &Option<String>,
nonce: &Option<String>,
nonce_file: &Option<String>,
aad: &Option<String>,
aad_file: &Option<String>,
tag_len: usize,
output_hex: bool,
) {
run::<Aria192, 24>(
action,
&load_key::<24>(key, key_file, "ARIA-192"),
nonce,
nonce_file,
aad,
aad_file,
tag_len,
output_hex,
);
}

/// ARIA-256 CCM. See [`aria128_ccm_cmd`].
#[allow(clippy::too_many_arguments)]
pub(crate) fn aria256_ccm_cmd(
action: &CipherDirection,
key: &Option<String>,
key_file: &Option<String>,
nonce: &Option<String>,
nonce_file: &Option<String>,
aad: &Option<String>,
aad_file: &Option<String>,
tag_len: usize,
output_hex: bool,
) {
run::<Aria256, 32>(
action,
&load_key::<32>(key, key_file, "ARIA-256"),
nonce,
nonce_file,
aad,
aad_file,
tag_len,
output_hex,
);
}
88 changes: 88 additions & 0 deletions cli/src/aria_cfb8_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//! ARIA-CFB8 encryption and decryption, streaming stdin to stdout.
//!
//! Only the cipher wiring lives here: the IV convention, key loading and stdin framing are in
//! [`crate::helpers::stream_mode_helpers`] (and [`crate::helpers::block_mode_helpers`] for the
//! key and IV loaders), shared with the `aes*-cfb8` commands. See those modules for the
//! command-line contract.
//!
//! `aria128-cfb8` / `aria192-cfb8` / `aria256-cfb8` are the same command as `aes*-cfb8`
//! over the ARIA permutation (RFC 5794; 16-, 24- or 32-byte key, 16-byte block), so every
//! remark there applies unchanged. The segment size is one byte (NIST SP 800-38A Sec 6.3 with
//! `s = 8`): a DIFFERENT, NON-INTEROPERABLE mode from the CFB128 of `aria*-cfb`, costing a full
//! ARIA call per byte, sixteen times the work. Prefer `aria*-cfb` unless a byte-granular
//! self-synchronising stream is required or the format demands CFB8.
//!
//! # Warning
//!
//! CFB8 provides confidentiality only. It does not detect tampering, and neither the ciphertext nor
//! the IV is authenticated. Do not decrypt data you have not authenticated separately.

use crate::helpers::block_mode_helpers::{CipherDirection, load_iv, load_key_object};
use crate::helpers::stream_mode_helpers::run_stream_mode;
use bouncycastle::aria::{ARIA128Key, ARIA192Key, ARIA256Key, BLOCK_LEN};
use bouncycastle::cipher::modes::CFB8;
use bouncycastle::core::symmetric_key::{SymmetricDecryptionKey, SymmetricEncryptionKey};
use bouncycastle::core::traits::{StreamCipherDecryptor, StreamCipherEncryptor};

pub(crate) fn aria128_cfb8_cmd(
action: &CipherDirection,
key: &Option<String>,
key_file: &Option<String>,
iv: &Option<String>,
iv_file: &Option<String>,
output_hex: bool,
) {
run::<_, 16>(
action,
&load_key_object::<ARIA128Key<CFB8>, 16>(key, key_file, "ARIA-128"),
load_iv::<BLOCK_LEN>(iv, iv_file),
output_hex,
);
}

pub(crate) fn aria192_cfb8_cmd(
action: &CipherDirection,
key: &Option<String>,
key_file: &Option<String>,
iv: &Option<String>,
iv_file: &Option<String>,
output_hex: bool,
) {
run::<_, 24>(
action,
&load_key_object::<ARIA192Key<CFB8>, 24>(key, key_file, "ARIA-192"),
load_iv::<BLOCK_LEN>(iv, iv_file),
output_hex,
);
}

pub(crate) fn aria256_cfb8_cmd(
action: &CipherDirection,
key: &Option<String>,
key_file: &Option<String>,
iv: &Option<String>,
iv_file: &Option<String>,
output_hex: bool,
) {
run::<_, 32>(
action,
&load_key_object::<ARIA256Key<CFB8>, 32>(key, key_file, "ARIA-256"),
load_iv::<BLOCK_LEN>(iv, iv_file),
output_hex,
);
}

/// Dispatches to the shared streaming loops with `Cfb8` filled in as the mode.
fn run<'k, K, const KEY_LEN: usize>(
action: &CipherDirection,
key: &'k K,
iv: Option<[u8; BLOCK_LEN]>,
output_hex: bool,
) where
K: SymmetricEncryptionKey<KEY_LEN, BLOCK_LEN, 0>
+ SymmetricDecryptionKey<KEY_LEN, BLOCK_LEN, 0>,
K::Encryptor<'k>: StreamCipherEncryptor<BLOCK_LEN>,
K::Decryptor<'k>: StreamCipherDecryptor<BLOCK_LEN>,
{
run_stream_mode::<K, KEY_LEN, BLOCK_LEN>(action, key, iv, output_hex)
}
Loading
Loading