Expand description
Stateful streaming cipher context (init / update / finalize) with padding, on top of the existing block-cipher and mode primitives.
This module provides the Cipher object that wraps the block
ciphers (AES, DES, 3DES) and the unauthenticated modes (ECB, CBC,
CTR) into a single uniform init / update / finalize API. The
design intent is to mirror what OpenSSL’s EVP_CIPHER_CTX and PSA
Crypto’s psa_cipher_operation_t offer, while keeping all buffers
caller-provided so the implementation is suitable for embedded
targets without an allocator.
AEAD modes (GCM, CCM, ChaCha20-Poly1305) are intentionally not routed through this object; they remain function-oriented in their own modules to avoid the trap of releasing unverified plaintext during streaming decryption.
§Cycle of life
new(algo, mode, padding)
│
▼
init(direction, key, iv) ◄──┐ (may be called again to rekey
│ │ or change direction)
▼ │
update(input, output) ──────┘
│ (0..N times)
▼
finalize(output)§Buffer ownership
Both update and finalize write into a caller-provided output
slice and return the number of bytes actually written. Callers can
query a safe upper bound for the output size with
Cipher::update_output_size / Cipher::finalize_output_size
before sizing the buffer. Convenience helpers
Cipher::update_to_vec / Cipher::finalize_to_vec are
provided for callers that prefer allocation.
§Example: AES-256-CBC with PKCS#7 padding
use arcana::cipher::ctx::{Cipher, Algorithm, Mode, Padding, Direction};
let key = [0u8; 32];
let iv = [0u8; 16];
let mut c = Cipher::new(Algorithm::Aes256, Mode::Cbc, Padding::Pkcs7).unwrap();
c.init(Direction::Encrypt, &key, &iv).unwrap();
let mut out = vec![0u8; 64];
let mut written = 0;
written += c.update(b"hello, ", &mut out[written..]).unwrap();
written += c.update(b"world!", &mut out[written..]).unwrap();
written += c.finalize(&mut out[written..]).unwrap();
out.truncate(written);Structs§
- Cipher
- Stateful symmetric cipher context.