diff --git a/src/hace_controller.rs b/src/hace_controller.rs index 27956df..782806f 100644 --- a/src/hace_controller.rs +++ b/src/hace_controller.rs @@ -1,9 +1,55 @@ // Licensed under the Apache-2.0 license use ast1060_pac::Hace; +use core::any::TypeId; use core::convert::Infallible; +use core::ptr::write_volatile; use proposed_traits::digest::ErrorType as DigestErrorType; use proposed_traits::mac::ErrorType as MacErrorType; +use proposed_traits::symm_cipher::BlockCipherMode; +use proposed_traits::symm_cipher::CipherMode; +use proposed_traits::symm_cipher::ErrorType as SymmCipherErrorType; + +fn dsync_fence_full() { + cortex_m::asm::dsb(); + cortex_m::asm::isb(); + core::sync::atomic::compiler_fence(core::sync::atomic::Ordering::SeqCst); +} + +fn write_reg(addr: u32, val: u32) { + unsafe { write_volatile(addr as *mut u32, val) } +} + +pub fn cache_data_invd_all() { + const CACHE_AREA_OFFSET: u32 = 0x7E6E_2A50; + const CACHE_INVAL_OFFSET: u32 = 0x7E6E_2A54; + const CACHE_CTRL_OFFSET: u32 = 0x7E6E_2A58; + + const CACHE_AREA_VAL: u32 = 0x000F_FFFF; + const CACHE_INVAL_VAL: u32 = 0x8660_0000; + + cortex_m::interrupt::free(|_| { + write_reg(CACHE_CTRL_OFFSET, 0); + dsync_fence_full(); + + write_reg(CACHE_AREA_OFFSET, CACHE_AREA_VAL); + write_reg(CACHE_INVAL_OFFSET, CACHE_INVAL_VAL); + dsync_fence_full(); + + write_reg(CACHE_CTRL_OFFSET, 1); + dsync_fence_full(); + }); + + write_reg(CACHE_CTRL_OFFSET, 0); + dsync_fence_full(); + + write_reg(CACHE_AREA_OFFSET, CACHE_AREA_VAL); + write_reg(CACHE_INVAL_OFFSET, CACHE_INVAL_VAL); + dsync_fence_full(); + + write_reg(CACHE_CTRL_OFFSET, 1); + dsync_fence_full(); +} const SHA1_IV: [u32; 8] = [ 0x0123_4567, @@ -127,9 +173,75 @@ const HACE_ALGO_SHA384: u32 = (1 << 5) | (1 << 6) | (1 << 10); const HACE_ALGO_SHA512_224: u32 = (1 << 5) | (1 << 6) | (1 << 10) | (1 << 11); const HACE_ALGO_SHA512_256: u32 = (1 << 5) | (1 << 6) | (1 << 11); +// Crypto control registers +pub const ASPEED_HACE_SRC: u32 = 0x00; +pub const ASPEED_HACE_DEST: u32 = 0x04; +pub const ASPEED_HACE_CONTEXT: u32 = 0x08; // 8 byte aligned +pub const ASPEED_HACE_DATA_LEN: u32 = 0x0C; +pub const ASPEED_HACE_CMD: u32 = 0x10; + +// HACE_CMD bit definitions +pub const HACE_CMD_AES_KEY_FROM_OTP: u32 = 1 << 24; +pub const HACE_CMD_MBUS_REQ_SYNC_EN: u32 = 1 << 20; +pub const HACE_CMD_DES_SG_CTRL: u32 = 1 << 19; +pub const HACE_CMD_SRC_SG_CTRL: u32 = 1 << 18; + +pub const HACE_CMD_SINGLE_DES: u32 = 0; +pub const HACE_CMD_TRIPLE_DES: u32 = 1 << 17; + +pub const HACE_CMD_AES_SELECT: u32 = 0; +pub const HACE_CMD_DES_SELECT: u32 = 1 << 16; + +pub const HACE_CMD_CTR_IV_AES_128: u32 = 0; + +pub const HACE_CMD_AES_KEY_HW_EXP: u32 = 1 << 13; +pub const HACE_CMD_ISR_EN: u32 = 1 << 12; + +pub const HACE_CMD_DECRYPT: u32 = 0; +pub const HACE_CMD_ENCRYPT: u32 = 1 << 7; + +// AES Modes +pub const HACE_CMD_MODE_MASK: u32 = 0x7 << 4; +pub const HACE_CMD_ECB: u32 = 0; +pub const HACE_CMD_CBC: u32 = 0x1 << 4; +pub const HACE_CMD_CFB: u32 = 0x2 << 4; +pub const HACE_CMD_OFB: u32 = 0x3 << 4; +pub const HACE_CMD_CTR: u32 = 0x4 << 4; + +// AES Key sizes +pub const HACE_CMD_AES128: u32 = 0; +pub const HACE_CMD_AES192: u32 = 0x1 << 2; +pub const HACE_CMD_AES256: u32 = 0x2 << 2; + +#[derive(Debug, Clone, Copy)] +pub struct Ecb; +impl CipherMode for Ecb {} +impl BlockCipherMode for Ecb {} + +#[derive(Debug, Clone, Copy)] +pub struct Cbc; +impl CipherMode for Cbc {} +impl BlockCipherMode for Cbc {} + +#[derive(Debug, Clone, Copy)] +pub struct Cfb; +impl CipherMode for Cfb {} +impl BlockCipherMode for Cfb {} + +#[derive(Debug, Clone, Copy)] +pub struct Ofb; +impl CipherMode for Ofb {} +impl BlockCipherMode for Ofb {} + +#[derive(Debug, Clone, Copy)] +pub struct Ctr; +impl CipherMode for Ctr {} +impl BlockCipherMode for Ctr {} + /// Common context cleanup functionality pub trait ContextCleanup { fn cleanup_context(&mut self); + fn cleanup_crypto_context(&mut self); } impl ContextCleanup for crate::hace_controller::HaceController<'_> { @@ -144,6 +256,12 @@ impl ContextCleanup for crate::hace_controller::HaceController<'_> { self.hace.hace30().write(|w| w.bits(0)); } } + + fn cleanup_crypto_context(&mut self) { + let ctx = self.crypto_ctx_mut(); + ctx.ctx.fill(0); + ctx.cmd = 0; + } } #[derive(Default, Copy, Clone)] @@ -157,6 +275,43 @@ impl AspeedSg { pub const fn new() -> Self { Self { len: 0, addr: 0 } } + + #[must_use] + pub fn phys_addr(&self) -> u32 { + core::ptr::from_ref::(self) as u32 + } +} + +#[repr(C)] +#[repr(align(64))] +pub struct AspeedCryptoContext { + pub ctx: [u8; 64], + pub src_sg: AspeedSg, + pub dst_sg: AspeedSg, + pub cmd: u32, +} + +impl Default for AspeedCryptoContext { + fn default() -> Self { + Self { + ctx: [0; 64], + src_sg: AspeedSg::default(), + dst_sg: AspeedSg::default(), + cmd: 0, + } + } +} + +impl AspeedCryptoContext { + #[must_use] + pub const fn new() -> Self { + Self { + ctx: [0; 64], + src_sg: AspeedSg::new(), + dst_sg: AspeedSg::new(), + cmd: 0, + } + } } #[repr(C)] @@ -236,6 +391,23 @@ impl SectionPlacedContext { #[link_section = ".ram_nc"] static SHARED_HASH_CTX: SectionPlacedContext = SectionPlacedContext::new(); +struct SectionPlacedCryptoContext(UnsafeCell); + +unsafe impl Sync for SectionPlacedCryptoContext {} + +impl SectionPlacedCryptoContext { + const fn new() -> Self { + Self(UnsafeCell::new(AspeedCryptoContext::new())) + } + + fn get(&self) -> *mut AspeedCryptoContext { + self.0.get() + } +} + +#[link_section = ".ram_nc"] +static SHARED_CRYPTO_CTX: SectionPlacedCryptoContext = SectionPlacedCryptoContext::new(); + #[derive(Copy, Clone)] pub enum HashAlgo { SHA1, @@ -319,6 +491,7 @@ pub struct HaceController<'ctrl> { pub hace: &'ctrl Hace, pub algo: HashAlgo, pub aspeed_hash_ctx: AspeedHashContext, // Own the context instead of using a pointer + pub aspeed_crypto_ctx: AspeedCryptoContext, } impl<'ctrl> HaceController<'ctrl> { @@ -328,6 +501,7 @@ impl<'ctrl> HaceController<'ctrl> { hace, algo: HashAlgo::SHA256, aspeed_hash_ctx: AspeedHashContext::new(), // Create a new context instance + aspeed_crypto_ctx: AspeedCryptoContext::new(), } } @@ -336,6 +510,10 @@ impl<'ctrl> HaceController<'ctrl> { pub fn shared_ctx() -> *mut AspeedHashContext { SHARED_HASH_CTX.get() } + + pub fn shared_crypto_ctx() -> *mut AspeedCryptoContext { + SHARED_CRYPTO_CTX.get() + } } impl DigestErrorType for HaceController<'_> { @@ -346,11 +524,45 @@ impl MacErrorType for HaceController<'_> { type Error = Infallible; } +#[derive(Debug)] +pub enum HaceCipherError { + InvalidKeyLength, + InvalidIvLength, + InvalidDataLength, + HardwareFailure, + Busy, + UnsupportedMode, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CryptoAlgo { + Aes, + Des, + Tdes, +} + +pub trait HasCryptoAlgo { + fn algo() -> CryptoAlgo; +} + +pub trait KeyMaterial { + fn key_len(&self) -> usize; + fn as_bytes(&self) -> &[u8]; +} + +impl SymmCipherErrorType for HaceController<'_> { + type Error = HaceCipherError; +} + impl HaceController<'_> { pub fn ctx_mut(&mut self) -> &mut AspeedHashContext { unsafe { &mut *Self::shared_ctx() } } + pub fn crypto_ctx_mut(&mut self) -> &mut AspeedCryptoContext { + unsafe { &mut *Self::shared_crypto_ctx() } + } + pub fn start_hash_operation(&mut self, len: u32) { let ctx = self.ctx_mut(); @@ -445,4 +657,138 @@ impl HaceController<'_> { ctx.bufcnt += u32::try_from(padlen + 16).expect("padlen + 16 too large to fit in u32"); } } + + fn crypto_mode_to_cmd() -> Result { + if TypeId::of::() == TypeId::of::() { + Ok(HACE_CMD_ECB) + } else if TypeId::of::() == TypeId::of::() { + Ok(HACE_CMD_CBC) + } else if TypeId::of::() == TypeId::of::() { + Ok(HACE_CMD_CFB) + } else if TypeId::of::() == TypeId::of::() { + Ok(HACE_CMD_OFB) + } else if TypeId::of::() == TypeId::of::() { + Ok(HACE_CMD_CTR) + } else { + Err(HaceCipherError::UnsupportedMode) + } + } + + pub fn assemble_cmd_from_key_mode( + key: &K, + ) -> Result<(u32, bool, usize, usize), HaceCipherError> + where + M: CipherMode + 'static, + K: HasCryptoAlgo + KeyMaterial, + { + let mut cmd = HACE_CMD_DES_SG_CTRL | HACE_CMD_SRC_SG_CTRL | HACE_CMD_MBUS_REQ_SYNC_EN; + + cmd |= Self::crypto_mode_to_cmd::()?; + + let (is_aes, iv_len, key_len) = match K::algo() { + CryptoAlgo::Aes => { + cmd |= HACE_CMD_AES_SELECT | HACE_CMD_AES_KEY_HW_EXP; + + let kl = key.key_len(); + match kl { + 16 => cmd |= HACE_CMD_AES128, + 24 => cmd |= HACE_CMD_AES192, + 32 => cmd |= HACE_CMD_AES256, + _ => return Err(HaceCipherError::InvalidKeyLength), + } + (true, 16usize, kl) + } + CryptoAlgo::Des => { + if key.key_len() != 8 { + return Err(HaceCipherError::InvalidKeyLength); + } + cmd |= HACE_CMD_DES_SELECT; + (false, 8usize, 8usize) + } + CryptoAlgo::Tdes => { + if key.key_len() != 24 { + return Err(HaceCipherError::InvalidKeyLength); + } + cmd |= HACE_CMD_DES_SELECT | HACE_CMD_TRIPLE_DES; + (false, 8usize, 24usize) + } + }; + + Ok((cmd, is_aes, iv_len, key_len)) + } + + pub fn start_crypto_operation(&mut self, data_len: u32) { + let (src_sg_ptr, dst_sg_ptr, ctx_ptr, cmd) = { + let hw = self.crypto_ctx_mut(); + + hw.src_sg.len = data_len | HACE_SG_LAST; + hw.dst_sg.len = data_len | HACE_SG_LAST; + + let src = hw.src_sg.phys_addr(); + let dst = hw.dst_sg.phys_addr(); + let ctx = hw.ctx.as_ptr() as u32; + let cmd = hw.cmd; + + (src, dst, ctx, cmd) + }; + + unsafe { + self.hace.hace1c().write(|w| w.crypto_intflag().set_bit()); + + self.hace.hace00().write(|w| w.bits(src_sg_ptr)); + self.hace.hace04().write(|w| w.bits(dst_sg_ptr)); + self.hace.hace08().write(|w| w.bits(ctx_ptr)); + self.hace.hace0c().write(|w| w.bits(data_len)); + self.hace.hace10().write(|w| w.bits(cmd)); + + while self.hace.hace1c().read().crypto_intflag().bit_is_clear() { + cortex_m::asm::nop(); + } + } + + cache_data_invd_all(); + } + + #[must_use] + pub fn needs_iv(cmd: u32) -> bool { + (cmd & HACE_CMD_MODE_MASK) != HACE_CMD_ECB + } + + #[must_use] + pub fn mode_block_size(is_aes: bool) -> usize { + if is_aes { + 16 + } else { + 8 + } + } + + pub fn iv_slice_mut(ctx: &mut [u8; 64], is_aes: bool, n: usize) -> &mut [u8] { + if is_aes { + &mut ctx[0..n] + } else { + &mut ctx[8..8 + n] + } + } + + #[must_use] + pub fn iv_slice(ctx: &[u8; 64], is_aes: bool, n: usize) -> &[u8] { + if is_aes { + &ctx[0..n] + } else { + &ctx[8..8 + n] + } + } + pub fn key_slice_mut(ctx: &mut [u8; 64], key_len: usize) -> &mut [u8] { + &mut ctx[16..16 + key_len] + } + + #[must_use] + pub fn iv_out_offset(is_aes: bool) -> usize { + if is_aes { + 0 + } else { + 8 + } + } } diff --git a/src/lib.rs b/src/lib.rs index 5a5bd51..7bdd4b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ pub mod pinctrl; pub mod rsa; pub mod spi; pub mod spimonitor; +pub mod symmetric_cipher; pub mod syscon; pub mod tests; pub mod timer; diff --git a/src/main.rs b/src/main.rs index 0587686..c4290fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,6 +23,7 @@ use aspeed_ddk::tests::functional::hash_test::run_hash_tests; use aspeed_ddk::tests::functional::hmac_test::run_hmac_tests; use aspeed_ddk::tests::functional::i2c_test; use aspeed_ddk::tests::functional::rsa_test::run_rsa_tests; +use aspeed_ddk::tests::functional::symm_cipher_test::run_symm_cipher_tests; use aspeed_ddk::tests::functional::timer_test::run_timer_tests; use panic_halt as _; @@ -156,6 +157,8 @@ fn main() -> ! { run_hmac_tests(&mut uart_controller, &mut hace_controller); + run_symm_cipher_tests(&mut uart_controller, &mut hace_controller); + // Enable RSA and ECC let _ = syscon.enable_clock(ClockId::ClkRSACLK as u8); diff --git a/src/symmetric_cipher.rs b/src/symmetric_cipher.rs new file mode 100644 index 0000000..995c63a --- /dev/null +++ b/src/symmetric_cipher.rs @@ -0,0 +1,432 @@ +// Licensed under the Apache-2.0 license + +use crate::hace_controller::{ + CryptoAlgo, HaceCipherError, HaceController, HasCryptoAlgo, KeyMaterial, HACE_CMD_ENCRYPT, +}; +use core::fmt::Debug; +use proposed_traits::common::{ + Endian, ErrorKind as CommonErrorKind, ErrorType as CommonErrorType, FromBytes, + SerdeError as CommonSerdeError, ToBytes, +}; + +use proposed_traits::symm_cipher::{ + BlockCipherMode, CipherInit, CipherMode, CipherOp, Error, ErrorKind, ErrorType, SymmetricCipher, +}; + +impl Error for HaceCipherError { + fn kind(&self) -> ErrorKind { + match self { + Self::InvalidKeyLength => ErrorKind::KeyError, + Self::InvalidIvLength | Self::InvalidDataLength => ErrorKind::InvalidInput, + Self::HardwareFailure => ErrorKind::HardwareFailure, + Self::Busy => ErrorKind::InvalidState, + Self::UnsupportedMode => ErrorKind::UnsupportedAlgorithm, + } + } +} + +#[derive(Debug)] +pub enum SerdeError { + BufferTooSmall, + Unsupported, +} + +impl CommonSerdeError for SerdeError { + fn kind(&self) -> CommonErrorKind { + match self { + SerdeError::BufferTooSmall => CommonErrorKind::SourceBufferTooSmall, + SerdeError::Unsupported => CommonErrorKind::NotSupported, + } + } +} + +impl CommonErrorType for HaceCipherError { + type Error = SerdeError; +} + +/// ECB/CBC key +#[derive(Clone)] +pub struct AesKey { + pub data: [u8; 32], + pub len: usize, +} + +impl CommonErrorType for AesKey { + type Error = SerdeError; +} + +impl HasCryptoAlgo for AesKey { + fn algo() -> CryptoAlgo { + CryptoAlgo::Aes + } +} + +impl KeyMaterial for AesKey { + fn key_len(&self) -> usize { + self.len + } + + fn as_bytes(&self) -> &[u8] { + &self.data[..self.len] + } +} + +impl FromBytes for AesKey { + fn from_bytes(bytes: &[u8], _endian: Endian) -> Result { + if bytes.len() > 32 { + return Err(SerdeError::BufferTooSmall); + } + let mut data = [0u8; 32]; + data[..bytes.len()].copy_from_slice(bytes); + Ok(Self { + data, + len: bytes.len(), + }) + } +} +impl ToBytes for AesKey { + fn to_bytes(&self, dest: &mut [u8], _endian: Endian) -> Result<(), Self::Error> { + if dest.len() < self.len { + return Err(SerdeError::BufferTooSmall); + } + dest[..self.len].copy_from_slice(&self.data[..self.len]); + Ok(()) + } +} + +#[derive(Clone)] +pub struct DesKey { + pub data: [u8; 8], +} +impl CommonErrorType for DesKey { + type Error = SerdeError; +} +impl HasCryptoAlgo for DesKey { + fn algo() -> CryptoAlgo { + CryptoAlgo::Des + } +} +impl KeyMaterial for DesKey { + fn key_len(&self) -> usize { + 8 + } + fn as_bytes(&self) -> &[u8] { + &self.data + } +} + +impl FromBytes for DesKey { + fn from_bytes(bytes: &[u8], _endian: Endian) -> Result { + if bytes.len() != 8 { + return Err(SerdeError::BufferTooSmall); + } + let mut data = [0u8; 8]; + data.copy_from_slice(bytes); + Ok(Self { data }) + } +} +impl ToBytes for DesKey { + fn to_bytes(&self, dest: &mut [u8], _endian: Endian) -> Result<(), Self::Error> { + if dest.len() < 8 { + return Err(SerdeError::BufferTooSmall); + } + dest[..8].copy_from_slice(&self.data); + Ok(()) + } +} + +#[derive(Clone)] +pub struct TdesKey { + pub data: [u8; 24], +} +impl CommonErrorType for TdesKey { + type Error = SerdeError; +} +impl HasCryptoAlgo for TdesKey { + fn algo() -> CryptoAlgo { + CryptoAlgo::Tdes + } +} +impl KeyMaterial for TdesKey { + fn key_len(&self) -> usize { + 24 + } + fn as_bytes(&self) -> &[u8] { + &self.data + } +} + +impl FromBytes for TdesKey { + fn from_bytes(bytes: &[u8], _endian: Endian) -> Result { + if bytes.len() != 24 { + return Err(SerdeError::BufferTooSmall); + } + let mut data = [0u8; 24]; + data.copy_from_slice(bytes); + Ok(Self { data }) + } +} +impl ToBytes for TdesKey { + fn to_bytes(&self, dest: &mut [u8], _endian: Endian) -> Result<(), Self::Error> { + if dest.len() < 24 { + return Err(SerdeError::BufferTooSmall); + } + dest[..24].copy_from_slice(&self.data); + Ok(()) + } +} + +#[derive(Clone)] +pub struct Iv { + pub data: [u8; 16], + pub len: usize, // 16 typical +} +impl CommonErrorType for Iv { + type Error = SerdeError; +} +impl FromBytes for Iv { + fn from_bytes(bytes: &[u8], _endian: Endian) -> Result { + if bytes.len() > 16 { + return Err(SerdeError::BufferTooSmall); + } + let mut data = [0u8; 16]; + data[..bytes.len()].copy_from_slice(bytes); + Ok(Self { + data, + len: bytes.len(), + }) + } +} +impl ToBytes for Iv { + fn to_bytes(&self, dest: &mut [u8], _endian: Endian) -> Result<(), Self::Error> { + if dest.len() < self.len { + return Err(SerdeError::BufferTooSmall); + } + dest[..self.len].copy_from_slice(&self.data[..self.len]); + Ok(()) + } +} + +impl Iv { + pub const NONE: Self = Self { + data: [0u8; 16], + len: 0, + }; + + #[inline] + #[must_use] + pub const fn none() -> Self { + Self::NONE + } +} + +#[derive(Clone)] +pub struct PlainText { + pub data: [u8; 64], + pub len: usize, +} +impl CommonErrorType for PlainText { + type Error = SerdeError; +} +impl FromBytes for PlainText { + fn from_bytes(bytes: &[u8], _endian: Endian) -> Result { + if bytes.len() > 64 { + return Err(SerdeError::BufferTooSmall); + } + let mut data = [0u8; 64]; + data[..bytes.len()].copy_from_slice(bytes); + Ok(Self { + data, + len: bytes.len(), + }) + } +} +impl ToBytes for PlainText { + fn to_bytes(&self, dest: &mut [u8], _endian: Endian) -> Result<(), Self::Error> { + if dest.len() < self.len { + return Err(SerdeError::BufferTooSmall); + } + dest[..self.len].copy_from_slice(&self.data[..self.len]); + Ok(()) + } +} + +#[derive(Clone)] +pub struct CipherText { + pub data: [u8; 80], + pub len: usize, +} +impl CommonErrorType for CipherText { + type Error = SerdeError; +} +impl FromBytes for CipherText { + fn from_bytes(bytes: &[u8], _endian: Endian) -> Result { + if bytes.len() > 80 { + return Err(SerdeError::BufferTooSmall); + } + let mut data = [0u8; 80]; + data[..bytes.len()].copy_from_slice(bytes); + Ok(Self { + data, + len: bytes.len(), + }) + } +} +impl ToBytes for CipherText { + fn to_bytes(&self, dest: &mut [u8], _endian: Endian) -> Result<(), Self::Error> { + if dest.len() < self.len { + return Err(SerdeError::BufferTooSmall); + } + dest[..self.len].copy_from_slice(&self.data[..self.len]); + Ok(()) + } +} + +pub struct HaceSymmetric<'ctrl, 'h, K> +where + 'h: 'ctrl, +{ + pub controller: &'ctrl mut HaceController<'h>, + pub _key: core::marker::PhantomData, +} + +impl ErrorType for HaceSymmetric<'_, '_, K> { + type Error = HaceCipherError; +} + +impl SymmetricCipher for HaceSymmetric<'_, '_, K> +where + K: FromBytes + ToBytes, +{ + type Key = K; + type Nonce = Iv; + type PlainText = PlainText; + type CipherText = CipherText; +} + +pub struct OpContextImpl<'a, 'ctrl, M: CipherMode, K> { + pub controller: &'a mut HaceController<'ctrl>, + + cmd_base: u32, + is_aes: bool, + iv_len: u8, + used: bool, + + _phantom: core::marker::PhantomData<(M, K)>, +} + +impl<'a, 'ctrl, M: CipherMode, K> ErrorType for OpContextImpl<'a, 'ctrl, M, K> { + type Error = HaceCipherError; +} + +impl<'a, 'ctrl, M: CipherMode, K> SymmetricCipher for OpContextImpl<'a, 'ctrl, M, K> +where + K: KeyMaterial + FromBytes + ToBytes + HasCryptoAlgo, +{ + type Key = K; + type Nonce = Iv; + type PlainText = PlainText; + type CipherText = CipherText; +} + +impl<'ctrl, 'h, M: BlockCipherMode + 'static, K> CipherInit for HaceSymmetric<'ctrl, 'h, K> +where + 'h: 'ctrl, + M: CipherMode, + K: KeyMaterial + FromBytes + ToBytes + HasCryptoAlgo, +{ + type CipherContext<'a> = OpContextImpl<'a, 'h, M, K> + where + Self: 'a; + + fn init<'a>( + &'a mut self, + key: &Self::Key, + nonce: &Self::Nonce, + _mode: M, + ) -> Result, Self::Error> { + let (cmd_base, is_aes, iv_len, key_len) = + HaceController::assemble_cmd_from_key_mode::(key)?; + let hw = self.controller.crypto_ctx_mut(); + hw.cmd = cmd_base; + + if HaceController::needs_iv(hw.cmd) { + let n = core::cmp::min(nonce.len, iv_len); + HaceController::iv_slice_mut(&mut hw.ctx, is_aes, n).copy_from_slice(&nonce.data[..n]); + } + + HaceController::key_slice_mut(&mut hw.ctx, key_len) + .copy_from_slice(&key.as_bytes()[..key_len]); + + Ok(OpContextImpl { + controller: self.controller, + cmd_base, + is_aes, + iv_len: u8::try_from(iv_len).map_err(|_| HaceCipherError::InvalidIvLength)?, + used: false, + + _phantom: core::marker::PhantomData, + }) + } +} + +impl<'a, 'ctrl, M, K> CipherOp for OpContextImpl<'a, 'ctrl, M, K> +where + M: BlockCipherMode, + K: KeyMaterial + FromBytes + ToBytes + HasCryptoAlgo, +{ + fn encrypt(&mut self, pt: Self::PlainText) -> Result { + if core::mem::take(&mut self.used) { + return Err(HaceCipherError::Busy); + } + + let hw = self.controller.crypto_ctx_mut(); + + let mut out = CipherText { + data: [0; 80], + len: pt.len + self.iv_len as usize, + }; + + if HaceController::needs_iv(hw.cmd) { + let iv_off = HaceController::iv_out_offset(self.is_aes); + let n = self.iv_len as usize; + let dst = &mut out.data[iv_off..][..n]; + dst.copy_from_slice(HaceController::iv_slice(&hw.ctx, self.is_aes, n)); + } + + hw.src_sg.addr = pt.data.as_ptr() as u32; + hw.dst_sg.addr = out.data.as_mut_ptr() as u32; + hw.cmd = self.cmd_base | HACE_CMD_ENCRYPT; + + self.controller.start_crypto_operation( + u32::try_from(pt.len).map_err(|_| HaceCipherError::InvalidDataLength)?, + ); + self.used = true; + + Ok(out) + } + + fn decrypt(&mut self, ct: Self::CipherText) -> Result { + if core::mem::take(&mut self.used) { + return Err(HaceCipherError::Busy); + } + + let hw = self.controller.crypto_ctx_mut(); + + let mut out = PlainText { + data: [0; 64], + len: ct.len, + }; + + hw.src_sg.addr = ct.data.as_ptr() as u32; + hw.dst_sg.addr = out.data.as_mut_ptr() as u32; + hw.cmd = self.cmd_base; + + self.controller.start_crypto_operation( + u32::try_from(ct.len).map_err(|_| HaceCipherError::InvalidDataLength)?, + ); + self.used = true; + + Ok(out) + } +} diff --git a/src/tests/functional/cbc_test_vec.rs b/src/tests/functional/cbc_test_vec.rs new file mode 100644 index 0000000..acb199f --- /dev/null +++ b/src/tests/functional/cbc_test_vec.rs @@ -0,0 +1,245 @@ +// Licensed under the Apache-2.0 license + +use crate::symmetric_cipher::{AesKey, CipherText, DesKey, Iv, PlainText, TdesKey}; +use proposed_traits::common::{Endian, FromBytes}; + +pub struct Aes256CbcTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes256CbcTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes256CbcTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 32] = [ + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, + 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, + 0x09, 0x14, 0xdf, 0xf4, + ]; + + let iv_bytes: [u8; 16] = [ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, + ]; + + let ptext_bytes: [u8; 64] = [ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, + 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, + 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, + 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, + ]; + + let ctext_bytes: [u8; 64] = [ + 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, + 0xfb, 0xd6, 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, 0x67, 0x9f, 0x77, 0x7b, + 0xc6, 0x70, 0x2c, 0x7d, 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, 0xa5, 0x30, + 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61, 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, + 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes192CbcTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes192CbcTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes192CbcTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0xd1, 0x2d, 0x58, 0x7a, 0xd8, 0x83, 0xf0, 0xac, 0x46, 0x99, 0x98, 0x6a, 0x63, 0x50, + 0x6f, 0xd1, 0x23, 0x9c, 0x43, 0x33, 0x4d, 0x61, 0xd2, 0x1e, + ]; + + let iv_bytes: [u8; 16] = [ + 0x06, 0x67, 0xd9, 0xf0, 0x7a, 0x00, 0x57, 0xe6, 0x48, 0x59, 0x2f, 0x81, 0xdf, 0x96, + 0x87, 0x31, + ]; + + let ptext_bytes: [u8; 64] = [ + 0xc9, 0xd5, 0xe3, 0x82, 0xf0, 0x84, 0xcb, 0x68, 0xb1, 0x8a, 0x24, 0x20, 0xd4, 0xd7, + 0x24, 0xeb, 0x72, 0xcc, 0x19, 0x0a, 0x5d, 0xb4, 0x78, 0x03, 0x76, 0xcc, 0x10, 0xb2, + 0x33, 0xf7, 0x5d, 0xf6, 0x6e, 0x50, 0x7e, 0xef, 0x31, 0xcb, 0xb0, 0x61, 0x66, 0x88, + 0x74, 0x8a, 0xd4, 0x61, 0xc4, 0xad, 0xfb, 0x68, 0x4a, 0x21, 0xec, 0x33, 0x61, 0xba, + 0x6a, 0x3e, 0x54, 0x92, 0x48, 0x04, 0x0c, 0xdb, + ]; + + let ctext_bytes: [u8; 64] = [ + 0xae, 0x2f, 0x83, 0x77, 0x65, 0x01, 0x79, 0x20, 0xde, 0x66, 0x1d, 0xf0, 0xb6, 0x78, + 0x05, 0xf2, 0x59, 0x0d, 0x1f, 0x94, 0x38, 0x17, 0x44, 0xe3, 0xa5, 0xe0, 0x33, 0xfc, + 0x6e, 0xdb, 0xa1, 0x99, 0x33, 0x39, 0x3d, 0x8f, 0x8c, 0xb5, 0xae, 0xbd, 0x0f, 0xe3, + 0x53, 0x6f, 0xfc, 0xf3, 0x8e, 0x80, 0xeb, 0xf2, 0x24, 0x16, 0x23, 0x2e, 0xb9, 0xf8, + 0x1e, 0xd7, 0x6c, 0x35, 0xd6, 0xdc, 0xb4, 0x09, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes128CbcTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes128CbcTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes128CbcTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 16] = [ + 0x5b, 0x9a, 0x20, 0xff, 0x50, 0xb6, 0x31, 0xc7, 0x49, 0xae, 0x0e, 0x51, 0x70, 0xdc, + 0x61, 0xaa, + ]; + + let iv_bytes: [u8; 16] = [ + 0xe8, 0x0c, 0xd1, 0x4f, 0x9f, 0xef, 0xd9, 0x73, 0x38, 0x2d, 0xb6, 0xc6, 0x5a, 0xb9, + 0x78, 0xa5, + ]; + + let ptext_bytes: [u8; 64] = [ + 0x63, 0x5d, 0x38, 0xc6, 0x47, 0xb9, 0x2e, 0xf5, 0x60, 0xaa, 0x6b, 0x4e, 0x01, 0xe7, + 0x6f, 0x5b, 0xf7, 0x17, 0x32, 0x08, 0x25, 0xe6, 0x66, 0x91, 0xc5, 0x32, 0x91, 0x32, + 0xe1, 0x55, 0x9a, 0x0b, 0x2b, 0xdb, 0x02, 0xbf, 0xc3, 0xb3, 0x12, 0x0b, 0x43, 0x4c, + 0xcb, 0xc0, 0x15, 0x2f, 0xdb, 0x90, 0x32, 0x3d, 0x5c, 0xd6, 0x68, 0x52, 0x85, 0x47, + 0x1a, 0x6d, 0x0e, 0x35, 0x6d, 0xe2, 0x33, 0x9a, + ]; + + let ctext_bytes: [u8; 64] = [ + 0xa5, 0x22, 0xd4, 0x85, 0x19, 0xe7, 0x98, 0x90, 0xef, 0x49, 0xff, 0xe5, 0xd0, 0x06, + 0x48, 0x8e, 0xc8, 0x51, 0xea, 0xa7, 0x71, 0x5f, 0x91, 0xba, 0x32, 0xb3, 0xb3, 0x53, + 0x9d, 0x54, 0x26, 0x7c, 0xa3, 0xe5, 0xd8, 0x39, 0xcb, 0xbc, 0xfe, 0xb6, 0x49, 0xbb, + 0x58, 0xb7, 0xac, 0x6d, 0x04, 0x34, 0xc1, 0x77, 0x39, 0xae, 0xf1, 0xd0, 0xde, 0x62, + 0xa5, 0xcd, 0x0e, 0x1f, 0x77, 0x9f, 0xb0, 0x8f, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct DesCbcTestVec { + pub key: DesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for DesCbcTestVec { + fn default() -> Self { + Self::new() + } +} + +impl DesCbcTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 8] = [0xdb, 0x4f, 0x74, 0x41, 0x8a, 0xf9, 0x56, 0xdf]; + let iv_bytes: [u8; 8] = [0x7e, 0xa0, 0xd0, 0x3f, 0xd6, 0x58, 0xe5, 0x89]; + let ptext_bytes: [u8; 64] = [ + 0xff, 0xb1, 0x8c, 0x27, 0x24, 0x20, 0x34, 0x7c, 0x1d, 0xed, 0x7a, 0x0b, 0x5d, 0xb9, + 0xe1, 0x21, 0xf1, 0x5e, 0x96, 0x4c, 0x84, 0x39, 0x6f, 0x34, 0x96, 0xfc, 0x76, 0x56, + 0x9e, 0xa0, 0xa7, 0x6e, 0x38, 0x56, 0xd8, 0xf2, 0x11, 0xc0, 0x4a, 0x69, 0x69, 0xfa, + 0xc8, 0x55, 0x00, 0xc0, 0xd7, 0x1b, 0x2c, 0x07, 0x20, 0x6f, 0xd1, 0x31, 0x76, 0x56, + 0xb7, 0xa5, 0x96, 0xb7, 0xab, 0x04, 0xe2, 0x6d, + ]; + let ctext_bytes: [u8; 64] = [ + 0x1b, 0xcc, 0x69, 0x4a, 0x7c, 0xe2, 0xdd, 0x4c, 0xf9, 0x34, 0x40, 0x41, 0x56, 0x6c, + 0xe5, 0x40, 0xfd, 0x7c, 0x54, 0x1d, 0x2d, 0x84, 0xe4, 0xbb, 0x7e, 0x46, 0xfd, 0xa6, + 0x6b, 0x0d, 0xb9, 0x73, 0x77, 0xac, 0xeb, 0x3c, 0x4f, 0xa4, 0xb2, 0xe5, 0xfa, 0x4e, + 0x72, 0x1f, 0xf6, 0x70, 0x06, 0x50, 0x52, 0xfd, 0x0a, 0x55, 0x3f, 0xbb, 0x6e, 0x5e, + 0xb7, 0x4f, 0xfd, 0x50, 0x27, 0xb8, 0x34, 0xa0, + ]; + + Self { + key: DesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct TdesCbcTestVec { + pub key: TdesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for TdesCbcTestVec { + fn default() -> Self { + Self::new() + } +} + +impl TdesCbcTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0x2c, 0x9e, 0x20, 0x57, 0x73, 0xfb, 0x83, 0x0e, 0x68, 0x1f, 0xb0, 0xab, 0x7c, 0x91, + 0x4a, 0x62, 0x97, 0x70, 0xef, 0xd9, 0x20, 0xf7, 0x70, 0x86, + ]; + let iv_bytes: [u8; 8] = [0x1f, 0xac, 0xe8, 0x69, 0x4a, 0xc2, 0xcb, 0x66]; + let ptext_bytes: [u8; 64] = [ + 0xf8, 0x4c, 0x5e, 0x04, 0xcf, 0xba, 0xab, 0x0a, 0x03, 0xc2, 0x7c, 0xba, 0x44, 0xd6, + 0xd3, 0x1a, 0xc9, 0x0b, 0x9d, 0xe1, 0x39, 0xd4, 0xb7, 0x70, 0xb3, 0x50, 0x57, 0x78, + 0x11, 0xf8, 0xa6, 0x23, 0xc2, 0x74, 0x5e, 0xc0, 0x5c, 0x2b, 0x44, 0x96, 0x94, 0x36, + 0x90, 0xbf, 0x01, 0xe3, 0x92, 0xbc, 0x62, 0x86, 0x22, 0xbe, 0x68, 0x72, 0x0a, 0x25, + 0x05, 0x04, 0x70, 0x60, 0x93, 0x7b, 0xbc, 0x6f, + ]; + let ctext_bytes: [u8; 64] = [ + 0xb6, 0xc4, 0xfc, 0xad, 0xa6, 0x4b, 0x1e, 0x37, 0xc4, 0x48, 0x44, 0xd0, 0x2f, 0xde, + 0x91, 0x4a, 0x95, 0x57, 0x54, 0x48, 0x65, 0x57, 0x1b, 0xcd, 0x4a, 0x6e, 0x89, 0x7c, + 0x65, 0x0b, 0x45, 0x17, 0x6d, 0x6f, 0x62, 0x05, 0xca, 0xb5, 0xaa, 0x3b, 0x2f, 0xb2, + 0x24, 0x0f, 0xa1, 0x0e, 0x38, 0x15, 0xdd, 0x3b, 0x08, 0x21, 0xbe, 0xf0, 0xb1, 0x1d, + 0x0f, 0x28, 0x2f, 0xa0, 0xe6, 0xcc, 0x5f, 0x7e, + ]; + + Self { + key: TdesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} diff --git a/src/tests/functional/cfb_test_vec.rs b/src/tests/functional/cfb_test_vec.rs new file mode 100644 index 0000000..2f66dd7 --- /dev/null +++ b/src/tests/functional/cfb_test_vec.rs @@ -0,0 +1,236 @@ +// Licensed under the Apache-2.0 license + +use crate::symmetric_cipher::{AesKey, CipherText, DesKey, Iv, PlainText, TdesKey}; +use proposed_traits::common::{Endian, FromBytes}; + +pub struct Aes128CfbTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes128CfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes128CfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 16] = [ + 0x9d, 0x79, 0xb1, 0xa3, 0x7f, 0x31, 0x80, 0x1c, 0xd1, 0x1a, 0x67, 0x06, 0xfb, 0x40, + 0xd6, 0xbd, + ]; + let iv_bytes: [u8; 16] = [ + 0x57, 0x52, 0x68, 0x46, 0x90, 0x3b, 0xb1, 0x3e, 0xde, 0x56, 0x24, 0x39, 0xe9, 0xc1, + 0xb8, 0x23, + ]; + let ptext_bytes: [u8; 64] = [ + 0xa9, 0x60, 0x89, 0xbc, 0xa7, 0x1f, 0x3d, 0x1a, 0x6d, 0x2d, 0x3c, 0xad, 0xb3, 0x66, + 0x9c, 0xbd, 0x50, 0xe1, 0x65, 0xe4, 0x34, 0x24, 0x9d, 0x8b, 0x82, 0x9f, 0x41, 0x16, + 0x69, 0x84, 0x2a, 0x97, 0x99, 0x11, 0x03, 0x6c, 0xf3, 0xe8, 0x22, 0x08, 0x6e, 0xca, + 0xa0, 0x07, 0x5a, 0x69, 0xfc, 0x17, 0x8b, 0xa8, 0xf8, 0x37, 0x18, 0xaa, 0x8f, 0x3b, + 0xd1, 0xf6, 0x5e, 0x81, 0x44, 0xe6, 0x1d, 0x9a, + ]; + let ctext_bytes: [u8; 64] = [ + 0x62, 0xae, 0xb7, 0xad, 0x93, 0xd3, 0x7a, 0xc4, 0x2b, 0x0d, 0xdd, 0xa8, 0xca, 0xa4, + 0x00, 0x23, 0x3a, 0x52, 0x9c, 0xcf, 0xc1, 0x8d, 0x50, 0xa5, 0x19, 0xda, 0xfc, 0xb4, + 0x1c, 0x53, 0x4c, 0xdb, 0x9a, 0x73, 0xfd, 0x4d, 0xbe, 0x8b, 0x5a, 0xdb, 0x5a, 0xf1, + 0xe8, 0xe6, 0xcd, 0xd4, 0x01, 0x66, 0x14, 0x09, 0x0f, 0xe3, 0xb8, 0xbf, 0xab, 0x59, + 0x7d, 0xd7, 0x25, 0x86, 0xd3, 0xde, 0x36, 0x2d, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes192CfbTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes192CfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes192CfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0x32, 0xdd, 0x53, 0xd4, 0xae, 0x89, 0xee, 0xa0, 0x7a, 0x4f, 0x57, 0x9e, 0x2f, 0xf7, + 0xac, 0xe2, 0xc1, 0xd2, 0x98, 0xdc, 0xf0, 0x1c, 0x94, 0x5c, + ]; + let iv_bytes: [u8; 16] = [ + 0xbf, 0x59, 0xcd, 0x93, 0x2c, 0xd3, 0x39, 0x31, 0xf0, 0xd1, 0x5e, 0xb4, 0xd2, 0x5d, + 0xce, 0x11, + ]; + let ptext_bytes: [u8; 64] = [ + 0x99, 0x25, 0xbb, 0x0b, 0x99, 0x8d, 0x48, 0xa9, 0x8e, 0x8a, 0x57, 0x3a, 0x8a, 0xce, + 0xe7, 0xc5, 0x4d, 0x54, 0x15, 0x4a, 0x4c, 0x7a, 0x37, 0xfc, 0x31, 0x3f, 0x6d, 0x14, + 0x26, 0x1a, 0xf6, 0xda, 0xf8, 0x2e, 0x98, 0x3b, 0xb2, 0xdf, 0xd1, 0xdd, 0xd0, 0x3a, + 0xdb, 0x19, 0xd7, 0xf3, 0x4f, 0x61, 0x39, 0x47, 0x29, 0x47, 0x93, 0xb2, 0x12, 0x74, + 0x2f, 0x37, 0xbc, 0xa2, 0xde, 0x42, 0x88, 0xd5, + ]; + let ctext_bytes: [u8; 64] = [ + 0x8a, 0x6e, 0x30, 0x8b, 0x46, 0x19, 0x13, 0x9a, 0x9e, 0x8c, 0xf3, 0x87, 0x96, 0x3a, + 0x61, 0xb7, 0x26, 0x26, 0xda, 0x79, 0x64, 0x6f, 0x5b, 0x8c, 0x77, 0xc8, 0x9f, 0x60, + 0x50, 0x58, 0x17, 0x9c, 0xda, 0x20, 0xf2, 0x5a, 0xbf, 0x3e, 0x7d, 0x3b, 0xa1, 0x6f, + 0x74, 0xd1, 0xd4, 0xb5, 0xf2, 0x8d, 0xb0, 0x0f, 0x81, 0x51, 0x6c, 0x46, 0x66, 0xf2, + 0x8b, 0x2b, 0x2c, 0xef, 0x88, 0x6a, 0x9f, 0x9f, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes256CfbTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes256CfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes256CfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 32] = [ + 0xd0, 0x21, 0x48, 0x65, 0x4d, 0x98, 0x7a, 0xe2, 0x65, 0xca, 0x1f, 0xea, 0xb2, 0xf0, + 0x91, 0xa4, 0xa9, 0x50, 0x77, 0x75, 0x83, 0x3b, 0x93, 0x24, 0xde, 0x2f, 0xcf, 0x43, + 0x1d, 0xd0, 0xbe, 0x23, + ]; + let iv_bytes: [u8; 16] = [ + 0xf8, 0xfa, 0x22, 0x3f, 0x19, 0x99, 0xb7, 0xbe, 0x7b, 0xd2, 0xb5, 0x8f, 0x68, 0x6a, + 0xfa, 0x89, + ]; + let ptext_bytes: [u8; 64] = [ + 0xbc, 0x08, 0x43, 0x43, 0x06, 0x4c, 0x3c, 0xbf, 0x79, 0x6d, 0xa7, 0x95, 0xc7, 0xd6, + 0xad, 0x6d, 0x75, 0xb8, 0xd7, 0xe5, 0xf0, 0x69, 0x62, 0x95, 0x97, 0x1c, 0x3f, 0x66, + 0x97, 0xcc, 0xab, 0x5c, 0xb8, 0x67, 0x25, 0x38, 0xe4, 0xbd, 0x50, 0xff, 0xf0, 0x9f, + 0x5e, 0xff, 0x84, 0xb5, 0x69, 0x23, 0xa8, 0x50, 0x70, 0x82, 0xdf, 0x0d, 0x57, 0x7e, + 0xd8, 0xd6, 0x45, 0x17, 0x8a, 0xf0, 0x7a, 0xc1, + ]; + let ctext_bytes: [u8; 64] = [ + 0xf6, 0xe6, 0x59, 0x56, 0x85, 0x33, 0xea, 0xe6, 0xb1, 0xcb, 0xbc, 0x69, 0xb3, 0x34, + 0xe4, 0x44, 0x63, 0xce, 0xd0, 0x90, 0x4b, 0x2f, 0x5c, 0xb1, 0x12, 0xbc, 0xe5, 0xe3, + 0xf4, 0x57, 0x66, 0x97, 0xc1, 0xdf, 0x4c, 0x6b, 0xd3, 0xfa, 0x8a, 0x63, 0x49, 0x3a, + 0xb9, 0xdf, 0xa1, 0xb8, 0xc5, 0x37, 0xb4, 0xa0, 0x54, 0xcd, 0x7f, 0x4d, 0xd4, 0x6d, + 0xca, 0x6c, 0x39, 0xd0, 0x67, 0xa4, 0x19, 0xd4, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct DesCfbTestVec { + pub key: DesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for DesCfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl DesCfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 8] = [0xa7, 0x31, 0x92, 0xa3, 0xd4, 0x31, 0xf6, 0x81]; + let iv_bytes: [u8; 8] = [0xc7, 0x78, 0xe5, 0x9b, 0x89, 0xd6, 0xeb, 0x32]; + let ptext_bytes: [u8; 64] = [ + 0x7d, 0x79, 0x20, 0x27, 0x6c, 0xd1, 0xb8, 0x5f, 0x61, 0xe8, 0x33, 0xc3, 0x15, 0x47, + 0x5b, 0x29, 0x62, 0xbe, 0x14, 0x8a, 0x3f, 0x8f, 0x18, 0xf4, 0x8f, 0x10, 0x54, 0xc7, + 0xc5, 0xa3, 0x24, 0xec, 0x1e, 0x42, 0xc5, 0x87, 0xdd, 0x63, 0x22, 0xeb, 0xd1, 0x7a, + 0x25, 0x00, 0xb4, 0x6e, 0x54, 0x99, 0x3b, 0xe4, 0xfb, 0x52, 0x85, 0x43, 0x15, 0x7d, + 0x82, 0x6d, 0xfc, 0x04, 0xfb, 0x5c, 0xa3, 0x1c, + ]; + let ctext_bytes: [u8; 64] = [ + 0xc2, 0x06, 0x8d, 0x6a, 0x1d, 0x7a, 0xc9, 0x1c, 0xe9, 0xc5, 0x03, 0x00, 0xd0, 0xb1, + 0x4f, 0x8a, 0xaa, 0x9d, 0x42, 0x77, 0x75, 0x61, 0x4b, 0xa9, 0xb8, 0x84, 0xbc, 0xb6, + 0x9f, 0xcf, 0xcf, 0xf9, 0xe7, 0xfa, 0x95, 0x3e, 0xc4, 0x08, 0x9c, 0xdc, 0x18, 0xd0, + 0x24, 0xd9, 0xde, 0xac, 0x52, 0x3b, 0x67, 0x90, 0xe4, 0xb9, 0xb0, 0x64, 0x91, 0x6b, + 0x20, 0x0a, 0xb1, 0xdf, 0x1e, 0xc3, 0xd8, 0x94, + ]; + + Self { + key: DesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct TdesCfbTestVec { + pub key: TdesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for TdesCfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl TdesCfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0x2a, 0xc2, 0xdc, 0xba, 0x5d, 0x2a, 0x9b, 0xb0, 0xdf, 0xa2, 0x7f, 0x32, 0xe6, 0xd3, + 0x83, 0xb6, 0x9b, 0xa2, 0xcd, 0x4f, 0xfb, 0x5b, 0x25, 0x67, + ]; + let iv_bytes: [u8; 8] = [0xbe, 0x1b, 0xc2, 0xfe, 0x39, 0xad, 0xf3, 0xab]; + let ptext_bytes: [u8; 64] = [ + 0x8e, 0x68, 0x5e, 0xa6, 0x71, 0x7c, 0x98, 0x5f, 0xa1, 0x53, 0x27, 0x70, 0xcb, 0x1b, + 0x4d, 0xe6, 0xb4, 0xd9, 0x7f, 0x84, 0x8f, 0x98, 0x94, 0x73, 0x97, 0x21, 0xfa, 0x1e, + 0x1d, 0xbe, 0x76, 0x3f, 0xcf, 0xc3, 0x85, 0x39, 0x5c, 0x00, 0x64, 0x10, 0x9b, 0xc6, + 0x8c, 0x56, 0x59, 0x80, 0x62, 0x05, 0x62, 0x66, 0x9b, 0x96, 0x03, 0xcd, 0xcd, 0x8d, + 0x93, 0xcc, 0xe8, 0x3a, 0xf2, 0x02, 0xa4, 0x96, + ]; + let ctext_bytes: [u8; 64] = [ + 0x44, 0x12, 0x25, 0x9a, 0x8e, 0x40, 0xb7, 0x23, 0x3a, 0x80, 0x14, 0x2a, 0xc3, 0x95, + 0x29, 0xab, 0x64, 0x15, 0x99, 0xeb, 0x9b, 0xed, 0x2f, 0x51, 0x37, 0x91, 0xcc, 0xfe, + 0xcd, 0x77, 0x15, 0x3d, 0x07, 0x58, 0x63, 0x20, 0xb8, 0xe7, 0xd2, 0xd0, 0x4e, 0xc8, + 0xfa, 0x43, 0x4a, 0xb7, 0xe4, 0xa5, 0x1d, 0x2e, 0x7c, 0x27, 0x15, 0x80, 0xbe, 0xc7, + 0x89, 0x91, 0x1e, 0x37, 0x2c, 0x82, 0x6d, 0x17, + ]; + + Self { + key: TdesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} diff --git a/src/tests/functional/ctr_test_vec.rs b/src/tests/functional/ctr_test_vec.rs new file mode 100644 index 0000000..2fb99fc --- /dev/null +++ b/src/tests/functional/ctr_test_vec.rs @@ -0,0 +1,236 @@ +// Licensed under the Apache-2.0 license + +use crate::symmetric_cipher::{AesKey, CipherText, DesKey, Iv, PlainText, TdesKey}; +use proposed_traits::common::{Endian, FromBytes}; + +pub struct Aes128CtrTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes128CtrTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes128CtrTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 16] = [ + 0x63, 0xea, 0x0b, 0xf5, 0xee, 0x59, 0x74, 0xc3, 0x79, 0x0f, 0x2b, 0x56, 0xed, 0x73, + 0x2a, 0x1a, + ]; + let iv_bytes: [u8; 16] = [ + 0x11, 0x31, 0xbe, 0x17, 0x7d, 0xea, 0x42, 0x61, 0x97, 0x67, 0xc2, 0x18, 0x8e, 0x12, + 0xe6, 0x5b, + ]; + let ptext_bytes: [u8; 64] = [ + 0x13, 0x64, 0xf5, 0xd8, 0x71, 0x7b, 0x0d, 0x58, 0x03, 0xca, 0x8d, 0x9a, 0xa6, 0xa3, + 0xb7, 0x43, 0x7f, 0xf5, 0x9f, 0xce, 0x63, 0x91, 0x1f, 0x0b, 0xd0, 0xb3, 0xcf, 0xba, + 0x66, 0xde, 0x9c, 0x75, 0x85, 0x3e, 0x46, 0x89, 0x78, 0x9b, 0xf4, 0x1f, 0x4c, 0x1d, + 0x1e, 0xf9, 0xa1, 0x8c, 0x1b, 0xec, 0x13, 0xa1, 0xe7, 0x60, 0xe8, 0x3f, 0x2c, 0x14, + 0xf1, 0x88, 0x52, 0x8d, 0x41, 0xbb, 0x0d, 0x4b, + ]; + let ctext_bytes: [u8; 64] = [ + 0xdd, 0xba, 0xad, 0x73, 0x41, 0xde, 0xd2, 0xff, 0x47, 0x9e, 0x14, 0x96, 0xaf, 0xfa, + 0x76, 0x8f, 0x67, 0x26, 0x98, 0x2d, 0x87, 0x2d, 0xe7, 0x88, 0x5f, 0x66, 0x17, 0x1e, + 0x40, 0x8c, 0x3b, 0xc7, 0x8d, 0xff, 0xa7, 0x76, 0x68, 0xdd, 0xbe, 0x9c, 0x33, 0xc2, + 0x94, 0xba, 0x6d, 0x85, 0x18, 0xcc, 0x37, 0x13, 0x91, 0x1b, 0xbe, 0xd0, 0x4e, 0xe9, + 0x00, 0x40, 0x4a, 0x15, 0xac, 0xaf, 0xf8, 0x9c, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes192CtrTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes192CtrTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes192CtrTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0x39, 0x42, 0x94, 0x8e, 0x26, 0xb3, 0x38, 0x38, 0x2f, 0xe1, 0x42, 0xaf, 0x7f, 0x31, + 0x04, 0x53, 0xa5, 0x24, 0xc5, 0xd7, 0xcc, 0x32, 0xb0, 0xc4, + ]; + let iv_bytes: [u8; 16] = [ + 0x39, 0xee, 0xa7, 0xc6, 0x0d, 0xf3, 0x51, 0x0e, 0xf9, 0xe4, 0xa2, 0x3a, 0xab, 0xa7, + 0x61, 0xd2, + ]; + let ptext_bytes: [u8; 64] = [ + 0xa3, 0xb8, 0x37, 0x08, 0x4e, 0x7b, 0x17, 0xce, 0xfc, 0x87, 0xc1, 0x50, 0x5b, 0xbc, + 0xb2, 0x66, 0x9e, 0xaa, 0x8a, 0x44, 0x81, 0xbc, 0xf1, 0x10, 0xac, 0xf8, 0x02, 0x36, + 0xe0, 0x49, 0xc3, 0xe9, 0xe4, 0x87, 0x62, 0xf1, 0x3e, 0xb6, 0x32, 0x91, 0xee, 0xa0, + 0x59, 0xe0, 0xcf, 0x3a, 0xc9, 0xb7, 0xd7, 0xba, 0x8e, 0x50, 0x6f, 0xb1, 0x6e, 0x36, + 0x15, 0xd4, 0xca, 0xa7, 0xb1, 0x9e, 0xcd, 0x7f, + ]; + let ctext_bytes: [u8; 64] = [ + 0x84, 0xe2, 0x65, 0x95, 0xd2, 0xa1, 0x74, 0xe3, 0x53, 0x47, 0x3f, 0x47, 0x9a, 0xf1, + 0xd8, 0x2d, 0x5e, 0x35, 0xae, 0xfc, 0xb4, 0x3c, 0xd0, 0xf5, 0x86, 0xfd, 0x62, 0x29, + 0xf7, 0x5f, 0x3d, 0xe2, 0x95, 0x56, 0x16, 0x54, 0x0a, 0x14, 0x2b, 0xcc, 0x32, 0x65, + 0x3e, 0x7e, 0x84, 0x41, 0x6b, 0x0e, 0x84, 0xe1, 0x79, 0xa3, 0x1d, 0xb9, 0x3c, 0xa9, + 0x43, 0x6b, 0x26, 0x22, 0xd7, 0xff, 0x5c, 0x62, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes256CtrTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes256CtrTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes256CtrTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 32] = [ + 0x34, 0xe3, 0x76, 0x89, 0x10, 0x87, 0x39, 0xc0, 0xc8, 0xa7, 0x4e, 0x44, 0xe3, 0xe2, + 0xc2, 0xc4, 0x93, 0x12, 0x16, 0xa4, 0x6f, 0xbd, 0x15, 0x57, 0xe9, 0xae, 0x8e, 0x1c, + 0x08, 0xd3, 0x22, 0x4b, + ]; + let iv_bytes: [u8; 16] = [ + 0x9a, 0xc6, 0x4c, 0x6f, 0xca, 0x06, 0x7d, 0x28, 0xa3, 0x3c, 0x27, 0x74, 0x59, 0xaf, + 0xd4, 0x00, + ]; + let ptext_bytes: [u8; 64] = [ + 0xcc, 0x47, 0x2d, 0xf4, 0x72, 0x06, 0xdb, 0xb8, 0xed, 0xe5, 0x37, 0xe0, 0x0b, 0xfe, + 0x3c, 0xb8, 0xe2, 0x76, 0x6d, 0x43, 0x8b, 0xa8, 0xcd, 0xf8, 0x5f, 0x69, 0x26, 0x80, + 0x6e, 0xf4, 0x0f, 0xc3, 0x34, 0x21, 0xbc, 0x2d, 0x1c, 0x6d, 0xf7, 0x81, 0x6f, 0xfa, + 0xa1, 0xe9, 0x5c, 0xbd, 0x3d, 0x1b, 0x16, 0x4e, 0xda, 0xde, 0x6e, 0xac, 0x13, 0xa0, + 0xa8, 0xe0, 0x66, 0x4c, 0x77, 0xa4, 0x77, 0xd7, + ]; + let ctext_bytes: [u8; 64] = [ + 0xd3, 0x44, 0x80, 0x13, 0xa5, 0x7b, 0xa6, 0x1a, 0xa7, 0x80, 0xe4, 0x88, 0x8f, 0xa1, + 0x25, 0x88, 0xf3, 0x77, 0x53, 0xff, 0x6d, 0x39, 0x1f, 0x87, 0xa5, 0xb1, 0xce, 0x62, + 0x65, 0xf5, 0x0d, 0xe4, 0xe4, 0xbe, 0x37, 0x01, 0x09, 0xfa, 0xbd, 0xef, 0x4c, 0xb3, + 0xa7, 0x9a, 0x66, 0xab, 0x37, 0x2e, 0xb4, 0xa5, 0xc2, 0x44, 0xcb, 0xa1, 0x0e, 0xd5, + 0x85, 0xda, 0xec, 0x4b, 0xdc, 0x71, 0x15, 0xda, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct DesCtrTestVec { + pub key: DesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for DesCtrTestVec { + fn default() -> Self { + Self::new() + } +} + +impl DesCtrTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 8] = [0xc5, 0xd2, 0xb6, 0xc2, 0x66, 0x6e, 0x5f, 0x88]; + let iv_bytes: [u8; 8] = [0xb4, 0xb9, 0x0d, 0xc4, 0x50, 0xd7, 0x31, 0x20]; + let ptext_bytes: [u8; 64] = [ + 0x5d, 0x43, 0xde, 0x20, 0x0c, 0x6e, 0xe5, 0xa8, 0x1e, 0x1b, 0xac, 0x79, 0xcc, 0xac, + 0x64, 0xf2, 0xb0, 0xed, 0xbf, 0x8c, 0xab, 0xc2, 0x45, 0x2a, 0x43, 0xc0, 0xda, 0x43, + 0x03, 0xa1, 0x15, 0x87, 0x9a, 0xc5, 0x57, 0xdf, 0x26, 0xbd, 0x49, 0x9b, 0x9f, 0xc4, + 0x52, 0x6c, 0xc0, 0x7c, 0xe0, 0xf6, 0x21, 0x68, 0x38, 0x36, 0x5e, 0x46, 0xcd, 0xed, + 0xfb, 0x4e, 0x0f, 0x8a, 0x53, 0x0f, 0x59, 0xc1, + ]; + let ctext_bytes: [u8; 64] = [ + 0x2c, 0xa3, 0x30, 0x91, 0x69, 0x36, 0xd9, 0xe6, 0x5c, 0xf1, 0x1d, 0x08, 0x2f, 0xa9, + 0xdf, 0xf0, 0x80, 0x2e, 0xb8, 0x78, 0xe4, 0xa9, 0xa7, 0x02, 0xc7, 0xe4, 0x53, 0xff, + 0xb8, 0x99, 0x3b, 0x58, 0x98, 0x8e, 0x5c, 0x24, 0x26, 0x5e, 0xf3, 0x66, 0x4e, 0x13, + 0xf1, 0xe5, 0x46, 0xd1, 0xda, 0xfb, 0xb2, 0xff, 0xbc, 0xaa, 0xbc, 0xd3, 0xba, 0xe2, + 0x11, 0x1e, 0x96, 0x89, 0x75, 0x00, 0xd3, 0x1c, + ]; + + Self { + key: DesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct TdesCtrTestVec { + pub key: TdesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for TdesCtrTestVec { + fn default() -> Self { + Self::new() + } +} + +impl TdesCtrTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0x5b, 0xe0, 0x2f, 0x92, 0x43, 0x9b, 0x83, 0x92, 0xf8, 0xf7, 0x01, 0x79, 0x29, 0x10, + 0x34, 0x3e, 0x9e, 0xd0, 0xdc, 0xc8, 0x20, 0xc1, 0x15, 0x79, + ]; + let iv_bytes: [u8; 8] = [0x9d, 0x1f, 0xb8, 0xce, 0xf2, 0x14, 0x35, 0x68]; + let ptext_bytes: [u8; 64] = [ + 0x5f, 0xb4, 0xbe, 0x30, 0x54, 0xbc, 0x25, 0x18, 0x2b, 0x75, 0xd0, 0x18, 0xfa, 0x17, + 0xb3, 0xa8, 0xd3, 0x5e, 0x59, 0x6e, 0xdf, 0x3e, 0xb3, 0x5a, 0x11, 0xa6, 0x6f, 0x6c, + 0xbc, 0xff, 0x3d, 0x69, 0xb3, 0xed, 0x8e, 0x77, 0xac, 0x67, 0x24, 0xdd, 0x1a, 0xb7, + 0xa4, 0xba, 0xa6, 0x29, 0xde, 0x0d, 0x63, 0x9e, 0x61, 0xac, 0xcf, 0xdb, 0x48, 0xa7, + 0x50, 0x40, 0xf2, 0xfb, 0x41, 0x09, 0x6c, 0xa5, + ]; + let ctext_bytes: [u8; 64] = [ + 0xa7, 0x79, 0xcb, 0xdd, 0x7f, 0x11, 0x4a, 0x7e, 0x76, 0xc5, 0x3e, 0x6b, 0x64, 0xb2, + 0x3b, 0x63, 0xe1, 0xdc, 0xdf, 0x11, 0x4e, 0xd3, 0x75, 0x3a, 0x8b, 0xce, 0x1d, 0xce, + 0x89, 0x56, 0x17, 0x19, 0xac, 0xd5, 0xe0, 0xda, 0x52, 0xf3, 0xde, 0x02, 0xa1, 0x75, + 0xa5, 0x86, 0x2f, 0xcf, 0x3a, 0x15, 0xf0, 0xbd, 0xab, 0x21, 0x43, 0xef, 0x90, 0x5c, + 0xcf, 0x90, 0xa5, 0x01, 0x0c, 0x06, 0x59, 0xf2, + ]; + + Self { + key: TdesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} diff --git a/src/tests/functional/ecb_test_vec.rs b/src/tests/functional/ecb_test_vec.rs new file mode 100644 index 0000000..a9222f8 --- /dev/null +++ b/src/tests/functional/ecb_test_vec.rs @@ -0,0 +1,213 @@ +// Licensed under the Apache-2.0 license + +use crate::symmetric_cipher::{AesKey, CipherText, DesKey, PlainText, TdesKey}; +use proposed_traits::common::{Endian, FromBytes}; + +// Auto-generated by gen_aes_ecb_vectors_random.py +pub struct Aes128EcbTestVec { + pub key: AesKey, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes128EcbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes128EcbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 16] = [ + 0xad, 0x24, 0x46, 0xd6, 0x79, 0x5e, 0xce, 0xf4, 0xf0, 0x98, 0x29, 0x12, 0x16, 0x6f, + 0xa1, 0x49, + ]; + let ptext_bytes: [u8; 64] = [ + 0xf9, 0xea, 0x7e, 0xf9, 0x57, 0x0c, 0x83, 0x9c, 0xbb, 0xf4, 0x4d, 0x8c, 0x65, 0xa3, + 0xad, 0xd2, 0xc9, 0x1b, 0x6c, 0x81, 0x85, 0x8c, 0xc2, 0x22, 0x23, 0x9b, 0x5b, 0x75, + 0xef, 0x5f, 0xdf, 0xcb, 0x9b, 0x77, 0x65, 0x4f, 0xf9, 0xf2, 0x51, 0xe0, 0xc2, 0xbb, + 0xb6, 0x7d, 0xf4, 0x29, 0xef, 0xd7, 0xa3, 0xf1, 0xc1, 0x51, 0x29, 0xab, 0xf4, 0x44, + 0xe0, 0x4e, 0xed, 0x47, 0xb8, 0x87, 0xd0, 0x09, + ]; + let ctext_bytes: [u8; 64] = [ + 0xdc, 0x58, 0xc4, 0xd6, 0x15, 0xdf, 0x5a, 0xdd, 0xe5, 0xac, 0x9a, 0x97, 0x16, 0xa5, + 0xbd, 0x09, 0x56, 0x62, 0xdc, 0x24, 0x6b, 0x1d, 0x0f, 0xec, 0x2f, 0x07, 0x4e, 0xd6, + 0x5d, 0xfa, 0x4d, 0xf0, 0x79, 0xff, 0x74, 0x4f, 0xf4, 0x1c, 0xae, 0x86, 0x14, 0x5b, + 0x1b, 0x4c, 0xed, 0x06, 0x25, 0x83, 0xfa, 0x04, 0x5f, 0x93, 0x15, 0x44, 0xb9, 0xc0, + 0x70, 0xf3, 0xaa, 0x5e, 0xe7, 0xd7, 0x54, 0x05, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes192EcbTestVec { + pub key: AesKey, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes192EcbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes192EcbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0x3b, 0xeb, 0xfc, 0xd8, 0x78, 0x19, 0x5c, 0x20, 0xc8, 0x98, 0x94, 0x1c, 0x42, 0x6c, + 0x14, 0xed, 0xce, 0x99, 0xca, 0xc8, 0x7a, 0xd0, 0x40, 0x79, + ]; + let ptext_bytes: [u8; 64] = [ + 0xb4, 0xbc, 0x1f, 0x74, 0xf9, 0x22, 0xd1, 0xf8, 0x9e, 0x6f, 0x71, 0x04, 0x76, 0x1f, + 0x23, 0xc8, 0x52, 0xda, 0x71, 0x55, 0xc7, 0x34, 0x8a, 0x93, 0x42, 0x2b, 0x19, 0x05, + 0xa3, 0x2b, 0x0a, 0x3f, 0xd0, 0x34, 0x5c, 0xad, 0x73, 0x7f, 0xf4, 0xb1, 0x99, 0xdc, + 0x6a, 0x55, 0xde, 0x07, 0xb9, 0x54, 0xac, 0xb7, 0xca, 0x72, 0x7a, 0x02, 0x53, 0x49, + 0xaa, 0xbc, 0x63, 0x21, 0xe9, 0xf2, 0x5b, 0xeb, + ]; + let ctext_bytes: [u8; 64] = [ + 0xa1, 0x2e, 0x9f, 0x5a, 0x1b, 0x95, 0xac, 0xa2, 0xbd, 0xd9, 0xa8, 0xde, 0x3b, 0x3e, + 0x65, 0xc5, 0x6c, 0x1d, 0x61, 0x46, 0x16, 0x49, 0x80, 0x2f, 0x1b, 0xb4, 0x59, 0xec, + 0xcd, 0xb7, 0xa7, 0x69, 0xb5, 0xd1, 0x46, 0x3e, 0x9d, 0x5d, 0xea, 0xc7, 0x90, 0xd7, + 0x01, 0x50, 0x39, 0x0b, 0x2b, 0x55, 0xf2, 0x24, 0x92, 0xf3, 0x91, 0x59, 0xb4, 0x40, + 0xf6, 0x47, 0xf2, 0x01, 0x4c, 0xf9, 0x14, 0x3b, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes256EcbTestVec { + pub key: AesKey, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes256EcbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes256EcbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 32] = [ + 0xe9, 0x89, 0xed, 0x29, 0x1d, 0x6d, 0xd7, 0xcd, 0xae, 0x61, 0x24, 0xca, 0x77, 0xbf, + 0xa8, 0x5f, 0x44, 0xd2, 0xe9, 0x1a, 0xeb, 0x4d, 0xb0, 0xe0, 0xe6, 0xc5, 0xef, 0xdb, + 0x4b, 0x8b, 0xa9, 0xdf, + ]; + let ptext_bytes: [u8; 64] = [ + 0xb6, 0xe0, 0xd2, 0x01, 0xde, 0xf2, 0x84, 0x3d, 0xa5, 0x0c, 0x2a, 0x76, 0x0b, 0x08, + 0xd8, 0x87, 0x2a, 0x4a, 0xa5, 0x13, 0xd5, 0x24, 0x24, 0x13, 0x72, 0x74, 0xfa, 0x40, + 0xc6, 0x8d, 0x90, 0x97, 0xbb, 0x4a, 0x40, 0x9b, 0x5b, 0xd0, 0x32, 0xdf, 0x1b, 0x47, + 0xa8, 0x73, 0xb3, 0x09, 0x04, 0x64, 0x2a, 0x41, 0x3f, 0xc8, 0xef, 0xa1, 0xa1, 0xd2, + 0x38, 0xe2, 0xda, 0x8b, 0x66, 0x73, 0x9c, 0x8d, + ]; + let ctext_bytes: [u8; 64] = [ + 0x84, 0xa4, 0xef, 0x2a, 0x1d, 0xf7, 0x28, 0x98, 0x59, 0xb6, 0x27, 0xd0, 0x90, 0x1c, + 0x3c, 0xba, 0xee, 0xf1, 0x90, 0x0b, 0xe2, 0xd1, 0xfd, 0xbc, 0x88, 0x9f, 0x06, 0x81, + 0x9f, 0x8a, 0xbd, 0x69, 0x4d, 0x01, 0x18, 0xd5, 0xd2, 0x61, 0x52, 0x6d, 0xaf, 0x5c, + 0xce, 0x12, 0xc7, 0x4a, 0xe4, 0x9c, 0x13, 0xd6, 0xb4, 0xea, 0x8d, 0x18, 0xe0, 0x99, + 0x5b, 0x62, 0x96, 0x42, 0xbc, 0x51, 0x62, 0x78, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct DesEcbTestVec { + pub key: DesKey, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for DesEcbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl DesEcbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 8] = [0xf3, 0x27, 0xcf, 0x76, 0x17, 0x0d, 0xff, 0x45]; + let ptext_bytes: [u8; 64] = [ + 0x29, 0x8c, 0x89, 0xdb, 0xb5, 0xe3, 0x7b, 0xaf, 0xa2, 0x73, 0x45, 0xd4, 0x7d, 0x3c, + 0x69, 0x52, 0x33, 0x6d, 0xdb, 0x97, 0x12, 0xc0, 0x4b, 0x02, 0x81, 0x03, 0xa2, 0x2c, + 0x8e, 0x35, 0xf5, 0x80, 0xb7, 0x22, 0xb9, 0xb4, 0xd1, 0x13, 0x13, 0x76, 0x60, 0xad, + 0x4e, 0xa0, 0x05, 0x4e, 0x56, 0x85, 0x2b, 0x46, 0xd4, 0xef, 0xbc, 0xa4, 0x1a, 0x05, + 0xee, 0x0d, 0x86, 0x44, 0x65, 0x9d, 0xdc, 0x16, + ]; + let ctext_bytes: [u8; 64] = [ + 0x6c, 0x36, 0x97, 0x9d, 0xd8, 0xd7, 0x78, 0x15, 0xa5, 0x63, 0x2a, 0xdc, 0x6d, 0x04, + 0xcc, 0x88, 0x7d, 0x87, 0xea, 0x85, 0xb1, 0x26, 0x7d, 0x43, 0xea, 0xdf, 0x55, 0xfb, + 0x69, 0xfc, 0x43, 0xb9, 0xa9, 0x1a, 0xd4, 0x2b, 0x04, 0x40, 0xf7, 0xb6, 0xea, 0x37, + 0x64, 0x4a, 0xfa, 0xdd, 0x86, 0x6b, 0xca, 0x5c, 0xe5, 0xaf, 0xe4, 0x33, 0xbd, 0x86, + 0xfa, 0x9a, 0x5f, 0x0b, 0x8d, 0x64, 0x07, 0x76, + ]; + + Self { + key: DesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct TdesEcbTestVec { + pub key: TdesKey, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for TdesEcbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl TdesEcbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0x9d, 0xbc, 0xd3, 0x64, 0x8a, 0x0d, 0x25, 0xd5, 0xcb, 0xb9, 0xd3, 0x86, 0xad, 0xb9, + 0x19, 0x57, 0xa1, 0x58, 0x4c, 0x97, 0x91, 0x6e, 0xad, 0x79, + ]; + let ptext_bytes: [u8; 64] = [ + 0xbe, 0xdf, 0xfa, 0x9d, 0xe8, 0x11, 0xd4, 0xca, 0x05, 0x6a, 0xe2, 0xcb, 0xc4, 0x62, + 0xaf, 0x60, 0x32, 0x55, 0xe2, 0xb2, 0x12, 0x9e, 0x55, 0x14, 0xaf, 0x8f, 0x16, 0x19, + 0xf6, 0x93, 0xfd, 0x39, 0xf5, 0xe4, 0x92, 0x90, 0x31, 0x5c, 0x34, 0xbc, 0x7d, 0x48, + 0x72, 0x70, 0x37, 0xcb, 0x35, 0xec, 0xca, 0x18, 0x8b, 0xae, 0xb0, 0x15, 0xa6, 0x04, + 0xb9, 0xf8, 0x4e, 0x82, 0xaa, 0xa6, 0xd1, 0xb1, + ]; + let ctext_bytes: [u8; 64] = [ + 0xc0, 0x7a, 0x3f, 0x1a, 0x4b, 0x17, 0x1f, 0x97, 0xef, 0x4e, 0x89, 0x1a, 0xd2, 0x34, + 0x39, 0xa6, 0x98, 0xf5, 0x56, 0x41, 0x8b, 0xad, 0x69, 0xf6, 0x61, 0x72, 0x7f, 0x29, + 0xa7, 0x8a, 0x42, 0x9a, 0xb0, 0xbb, 0x74, 0x2d, 0xdd, 0x97, 0x1f, 0xd3, 0xcb, 0xc7, + 0x65, 0x82, 0x17, 0x45, 0x7b, 0x02, 0x70, 0xa7, 0xee, 0x73, 0x1f, 0x41, 0x66, 0x12, + 0x90, 0x87, 0x0e, 0x8a, 0xe8, 0xcc, 0x6e, 0xe8, + ]; + + Self { + key: TdesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} diff --git a/src/tests/functional/mod.rs b/src/tests/functional/mod.rs index f37c0d5..8ea69ce 100644 --- a/src/tests/functional/mod.rs +++ b/src/tests/functional/mod.rs @@ -1,10 +1,16 @@ // Licensed under the Apache-2.0 license +pub mod cbc_test_vec; +pub mod cfb_test_vec; +pub mod ctr_test_vec; +pub mod ecb_test_vec; pub mod ecdsa_test; pub mod gpio_test; pub mod hash_test; pub mod hmac_test; pub mod i2c_test; +pub mod ofb_test_vec; pub mod rsa_test; pub mod rsa_test_vec; +pub mod symm_cipher_test; pub mod timer_test; diff --git a/src/tests/functional/ofb_test_vec.rs b/src/tests/functional/ofb_test_vec.rs new file mode 100644 index 0000000..871a93b --- /dev/null +++ b/src/tests/functional/ofb_test_vec.rs @@ -0,0 +1,236 @@ +// Licensed under the Apache-2.0 license + +use crate::symmetric_cipher::{AesKey, CipherText, DesKey, Iv, PlainText, TdesKey}; +use proposed_traits::common::{Endian, FromBytes}; + +pub struct Aes128OfbTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes128OfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes128OfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 16] = [ + 0xb3, 0x0f, 0xcb, 0x06, 0xa6, 0xc1, 0xad, 0x8f, 0x29, 0x06, 0xe7, 0x32, 0xb1, 0x0f, + 0x4d, 0xb7, + ]; + let iv_bytes: [u8; 16] = [ + 0x89, 0xd3, 0x5e, 0xa6, 0x8c, 0x08, 0x8a, 0xb3, 0xf6, 0x48, 0x81, 0x8b, 0xa4, 0xa6, + 0x65, 0x6b, + ]; + let ptext_bytes: [u8; 64] = [ + 0xe0, 0xcb, 0x6e, 0x38, 0x2a, 0x5d, 0xff, 0x72, 0xac, 0x1d, 0xda, 0x96, 0x90, 0x81, + 0x37, 0x47, 0x8b, 0xd5, 0x36, 0xcf, 0x4b, 0x77, 0x8a, 0xde, 0x1f, 0xe7, 0xa9, 0x01, + 0x0b, 0x33, 0x41, 0xc2, 0xbd, 0x2b, 0x4a, 0xce, 0xc4, 0x6e, 0xdf, 0x28, 0x7a, 0x43, + 0xb9, 0xb2, 0x11, 0x75, 0x30, 0x6c, 0x76, 0xa8, 0x1a, 0x57, 0x89, 0x93, 0x22, 0x47, + 0x30, 0x81, 0xcd, 0x27, 0x7b, 0xcd, 0x1e, 0x37, + ]; + let ctext_bytes: [u8; 64] = [ + 0x72, 0xd8, 0x8c, 0x2a, 0x81, 0x55, 0x18, 0x3f, 0x27, 0xff, 0xbc, 0x2c, 0x82, 0x76, + 0xce, 0xe4, 0xeb, 0x44, 0xdb, 0xf4, 0x58, 0x9d, 0x9a, 0x47, 0xbb, 0xc3, 0x78, 0xe0, + 0xa8, 0x43, 0x41, 0xb1, 0xa3, 0x43, 0x2a, 0x7e, 0x02, 0xa4, 0x65, 0x05, 0x4e, 0xf3, + 0x0d, 0xbd, 0xef, 0xbd, 0xd3, 0x32, 0x1f, 0x49, 0xf7, 0x86, 0x3e, 0xb7, 0x67, 0x87, + 0x35, 0x91, 0xa2, 0x76, 0x6a, 0x3e, 0x93, 0x24, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes192OfbTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes192OfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes192OfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0x41, 0xa4, 0x65, 0x5d, 0xe9, 0xb2, 0xa3, 0x29, 0x08, 0x2e, 0xc4, 0x5e, 0x53, 0x05, + 0xf3, 0x5a, 0xae, 0x40, 0xa2, 0x35, 0xa4, 0x99, 0x90, 0xab, + ]; + let iv_bytes: [u8; 16] = [ + 0x85, 0xa8, 0x58, 0x44, 0xfe, 0x7e, 0xaa, 0xb3, 0x49, 0x98, 0xc8, 0xef, 0xd8, 0xfa, + 0xfc, 0xae, + ]; + let ptext_bytes: [u8; 64] = [ + 0xab, 0xa5, 0xe5, 0xa5, 0x57, 0x6f, 0x47, 0x12, 0x73, 0x02, 0xf0, 0x9b, 0xe3, 0xef, + 0x8d, 0xa2, 0x01, 0xbe, 0xcf, 0x2b, 0x07, 0x64, 0xbd, 0x88, 0xd4, 0x0d, 0xa8, 0xba, + 0xcb, 0xed, 0xab, 0x3e, 0xef, 0xbe, 0xd4, 0x29, 0x72, 0xaf, 0x56, 0x76, 0xf7, 0xfd, + 0x23, 0x61, 0xf3, 0x4c, 0x1b, 0x45, 0xe6, 0x66, 0x51, 0xfd, 0xa2, 0x6f, 0xe6, 0xec, + 0x28, 0x06, 0xd7, 0xa3, 0xc4, 0x61, 0x2b, 0xb0, + ]; + let ctext_bytes: [u8; 64] = [ + 0x9e, 0xa8, 0xf5, 0xf5, 0x69, 0xf3, 0x32, 0x08, 0x83, 0x46, 0xaa, 0xa0, 0xe6, 0x36, + 0xf0, 0xba, 0x7d, 0x67, 0x26, 0x22, 0x2c, 0xbd, 0xb8, 0xf6, 0x7d, 0x22, 0xa0, 0xad, + 0x0e, 0xfa, 0x40, 0x40, 0xb8, 0x7f, 0x21, 0x03, 0xb8, 0xb1, 0xce, 0xa8, 0xb0, 0xe0, + 0xc9, 0x38, 0xea, 0xbf, 0x0e, 0x7c, 0x29, 0xb3, 0x9f, 0x63, 0x1a, 0x52, 0x93, 0xab, + 0x8e, 0x1b, 0x28, 0xc4, 0x23, 0xc8, 0xce, 0x11, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct Aes256OfbTestVec { + pub key: AesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for Aes256OfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl Aes256OfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 32] = [ + 0x95, 0xd1, 0x0f, 0x0c, 0x96, 0x3d, 0x71, 0xdc, 0x35, 0xf7, 0x11, 0x1c, 0xdf, 0x9b, + 0x20, 0x27, 0xc4, 0x4d, 0xa0, 0xa0, 0x81, 0x94, 0xf4, 0x28, 0x8c, 0xb6, 0xc5, 0xca, + 0x54, 0x04, 0x34, 0xae, + ]; + let iv_bytes: [u8; 16] = [ + 0xe8, 0xac, 0x12, 0x6c, 0x34, 0x43, 0xae, 0x98, 0x10, 0x5a, 0x43, 0x10, 0x45, 0x1c, + 0x80, 0x62, + ]; + let ptext_bytes: [u8; 64] = [ + 0x22, 0xcd, 0xb1, 0x61, 0xc9, 0x24, 0x8c, 0x98, 0x99, 0xcf, 0x01, 0xff, 0x02, 0x1e, + 0xd2, 0x77, 0xa9, 0x09, 0x74, 0x87, 0xec, 0xac, 0x5c, 0x40, 0xb9, 0x97, 0x98, 0xf8, + 0x5b, 0x36, 0xa0, 0x8d, 0xed, 0x0e, 0x5c, 0xdc, 0x2f, 0x26, 0x43, 0xf1, 0x90, 0x6b, + 0xf0, 0x02, 0xa7, 0x0d, 0x27, 0xae, 0xb9, 0x39, 0x81, 0xb8, 0x4b, 0x43, 0x53, 0x1d, + 0x17, 0x92, 0x84, 0xae, 0xfd, 0x7e, 0x81, 0xe2, + ]; + let ctext_bytes: [u8; 64] = [ + 0x06, 0x82, 0xa0, 0xb8, 0x15, 0x43, 0x8b, 0x67, 0xc9, 0xac, 0x17, 0x0e, 0xa9, 0xeb, + 0x93, 0xa7, 0x37, 0xe7, 0xb8, 0x00, 0x4c, 0x3b, 0x0c, 0x8b, 0xad, 0xce, 0x31, 0x6a, + 0x22, 0x7c, 0x57, 0xb7, 0xa4, 0xa9, 0x28, 0x8b, 0x9f, 0x28, 0xfd, 0x53, 0xa0, 0x5d, + 0xcf, 0xd3, 0x13, 0x82, 0x11, 0xb8, 0x3d, 0xb8, 0xe0, 0x1e, 0xd4, 0xb3, 0x14, 0x5b, + 0x9c, 0xb4, 0x24, 0x22, 0x8f, 0x1c, 0x97, 0xe7, + ]; + + Self { + key: AesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct DesOfbTestVec { + pub key: DesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for DesOfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl DesOfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 8] = [0x31, 0x68, 0xd9, 0xed, 0xb5, 0x4e, 0xec, 0x5c]; + let iv_bytes: [u8; 8] = [0xb0, 0xea, 0xf3, 0xe0, 0x8b, 0x05, 0x3e, 0xfc]; + let ptext_bytes: [u8; 64] = [ + 0x39, 0x08, 0xe8, 0xd4, 0x2d, 0xcb, 0x88, 0xce, 0xff, 0x3e, 0xb9, 0x4e, 0x37, 0xbf, + 0x4c, 0x3d, 0x1a, 0x2f, 0xd4, 0x0e, 0xa9, 0xc2, 0xa9, 0x3d, 0xb8, 0x3c, 0xc5, 0xe0, + 0xe2, 0x4d, 0x3e, 0x91, 0x76, 0x47, 0x6b, 0xf2, 0x07, 0x6c, 0x29, 0x14, 0x69, 0x62, + 0xed, 0x15, 0xcf, 0x4b, 0x5e, 0xbb, 0xe1, 0xde, 0x69, 0x7c, 0x60, 0xe6, 0xe6, 0xd0, + 0x48, 0xe9, 0xb7, 0x11, 0x00, 0x31, 0x5d, 0xfa, + ]; + let ctext_bytes: [u8; 64] = [ + 0xaa, 0x13, 0x80, 0x46, 0x09, 0x02, 0x53, 0xf4, 0x58, 0x7d, 0x02, 0x23, 0x60, 0x4b, + 0x15, 0x1e, 0x61, 0x27, 0xf9, 0x91, 0x3b, 0x5b, 0xdc, 0x6c, 0x99, 0x0e, 0xda, 0x36, + 0xa8, 0x16, 0x03, 0x9b, 0xc6, 0x84, 0x44, 0xa7, 0xb1, 0x9a, 0x32, 0xf4, 0x22, 0x06, + 0x0e, 0x53, 0xdc, 0xaf, 0x5d, 0x0a, 0x9c, 0x49, 0x74, 0xc0, 0x59, 0xec, 0xf4, 0x48, + 0xfa, 0xfc, 0xeb, 0xf9, 0xcc, 0xbd, 0x18, 0x46, + ]; + + Self { + key: DesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} + +pub struct TdesOfbTestVec { + pub key: TdesKey, + pub iv: Iv, + pub ptext: PlainText, + pub ctext: CipherText, +} + +impl Default for TdesOfbTestVec { + fn default() -> Self { + Self::new() + } +} + +impl TdesOfbTestVec { + #[must_use] + pub fn new() -> Self { + let key_bytes: [u8; 24] = [ + 0xb6, 0x2a, 0x61, 0x38, 0x57, 0x43, 0xd6, 0x01, 0x57, 0x9b, 0x2c, 0x13, 0x6e, 0x10, + 0x34, 0xb5, 0xb6, 0xf7, 0x8f, 0xa1, 0xe0, 0x58, 0x13, 0x0e, + ]; + let iv_bytes: [u8; 8] = [0xd4, 0xed, 0x9b, 0x3a, 0xc6, 0x25, 0x41, 0x11]; + let ptext_bytes: [u8; 64] = [ + 0x26, 0x9b, 0xc9, 0xe7, 0xfb, 0xad, 0x0a, 0x08, 0xc1, 0x10, 0x11, 0xdc, 0x3c, 0xf6, + 0x96, 0x54, 0x13, 0xb5, 0x23, 0x12, 0x50, 0xbc, 0x9f, 0x83, 0x2d, 0xdf, 0xed, 0x3c, + 0x3b, 0x49, 0x4a, 0x47, 0xa7, 0x20, 0x42, 0xab, 0xe7, 0x1f, 0x44, 0x7c, 0x3a, 0x39, + 0xd8, 0x36, 0x33, 0x3c, 0x0b, 0x8a, 0x6f, 0x30, 0xdf, 0x21, 0x2b, 0xa2, 0x2d, 0xb9, + 0x76, 0xdc, 0x7d, 0xef, 0x63, 0xdb, 0xe3, 0xe1, + ]; + let ctext_bytes: [u8; 64] = [ + 0xb4, 0xfc, 0x5c, 0xe4, 0x0a, 0xc1, 0x39, 0xd5, 0x0a, 0x91, 0x9c, 0x06, 0x5a, 0x12, + 0xe3, 0x0b, 0x8c, 0xa3, 0x8c, 0xd8, 0x2b, 0xb3, 0x59, 0xdf, 0x67, 0x50, 0x5f, 0x17, + 0xe7, 0x27, 0x19, 0x3b, 0x99, 0x88, 0x2f, 0x29, 0xdc, 0xd3, 0xc1, 0x62, 0x36, 0xd6, + 0x75, 0xb3, 0xde, 0xce, 0x01, 0xfb, 0x75, 0x77, 0x85, 0x15, 0x05, 0x50, 0x63, 0xfc, + 0xd9, 0x72, 0xcf, 0xdf, 0xe5, 0x48, 0xc2, 0x8a, + ]; + + Self { + key: TdesKey::from_bytes(&key_bytes, Endian::Big).unwrap(), + iv: Iv::from_bytes(&iv_bytes, Endian::Big).unwrap(), + ptext: PlainText::from_bytes(&ptext_bytes, Endian::Big).unwrap(), + ctext: CipherText::from_bytes(&ctext_bytes, Endian::Big).unwrap(), + } + } +} diff --git a/src/tests/functional/symm_cipher_test.rs b/src/tests/functional/symm_cipher_test.rs new file mode 100644 index 0000000..7985fac --- /dev/null +++ b/src/tests/functional/symm_cipher_test.rs @@ -0,0 +1,364 @@ +// Licensed under the Apache-2.0 license + +use crate::hace_controller::{Cbc, Cfb, Ctr, Ecb, HaceController, HasCryptoAlgo, KeyMaterial, Ofb}; +use crate::symmetric_cipher::{AesKey, CipherText, DesKey, HaceSymmetric, Iv, PlainText, TdesKey}; +use crate::uart::UartController; +use embedded_io::Write; +use proposed_traits::common::{FromBytes, ToBytes}; +use proposed_traits::symm_cipher::{BlockCipherMode, CipherInit, CipherOp}; + +use crate::tests::functional::cbc_test_vec::{ + Aes128CbcTestVec, Aes192CbcTestVec, Aes256CbcTestVec, DesCbcTestVec, TdesCbcTestVec, +}; +use crate::tests::functional::cfb_test_vec::{ + Aes128CfbTestVec, Aes192CfbTestVec, Aes256CfbTestVec, DesCfbTestVec, TdesCfbTestVec, +}; +use crate::tests::functional::ctr_test_vec::{ + Aes128CtrTestVec, Aes192CtrTestVec, Aes256CtrTestVec, DesCtrTestVec, TdesCtrTestVec, +}; +use crate::tests::functional::ecb_test_vec::{ + Aes128EcbTestVec, Aes192EcbTestVec, Aes256EcbTestVec, DesEcbTestVec, TdesEcbTestVec, +}; +use crate::tests::functional::ofb_test_vec::{ + Aes128OfbTestVec, Aes192OfbTestVec, Aes256OfbTestVec, DesOfbTestVec, TdesOfbTestVec, +}; + +fn print_hex_array(uart: &mut UartController, data: &[u8], bytes_per_line: usize) { + for (i, b) in data.iter().enumerate() { + if i % bytes_per_line == 0 { + let _ = writeln!(uart, "\r"); + } else { + let _ = write!(uart, " "); + } + let _ = write!(uart, "{b:02x}"); + } + let _ = writeln!(uart); +} + +fn key_bytes(k: &K) -> &[u8] { + let klen = k.key_len(); + &k.as_bytes()[..klen] +} + +// Pretty-print mode names via type. +trait ModeInfo { + const NAME: &'static str; +} +impl ModeInfo for Cfb { + const NAME: &'static str = "CFB"; +} +impl ModeInfo for Ctr { + const NAME: &'static str = "CTR"; +} +impl ModeInfo for Ofb { + const NAME: &'static str = "OFB"; +} +impl ModeInfo for Cbc { + const NAME: &'static str = "CBC"; +} +impl ModeInfo for Ecb { + const NAME: &'static str = "ECB"; +} + +// ------------------------- Generic runners ------------------------- + +struct IvModeCase<'a, K> { + name: &'a str, + key: &'a K, + iv: &'a Iv, + pt: &'a PlainText, + ct_expected: &'a CipherText, +} + +/// One generic runner for all IV modes: CFB / CTR / OFB / CBC. +fn run_iv_mode_case( + uart: &mut UartController, + symm: &mut HaceSymmetric<'_, '_, K>, + case: &IvModeCase<'_, K>, + mode: M, +) where + M: ModeInfo + BlockCipherMode + Copy + 'static, + K: KeyMaterial + FromBytes + ToBytes + HasCryptoAlgo, +{ + // Encrypt + { + let mut ctx_enc = symm.init(case.key, case.iv, mode).unwrap(); + let ct: CipherText = ctx_enc.encrypt(case.pt.clone()).unwrap(); + + let _ = write!(uart, "\r\n[{}] {} Encrypt Input (PT):", case.name, M::NAME); + print_hex_array(uart, &case.pt.data[..case.pt.len], 16); + let _ = write!(uart, "\r\n[{}] {} Encrypt Key:", case.name, M::NAME); + print_hex_array(uart, key_bytes(case.key), 16); + let _ = write!(uart, "\r\n[{}] {} Encrypt IV:", case.name, M::NAME); + print_hex_array(uart, &case.iv.data[..case.iv.len], 16); + let _ = write!(uart, "\r\n[{}] {} Encrypt Output (CT):", case.name, M::NAME); + print_hex_array(uart, &ct.data[..case.ct_expected.len], 16); + + if ct.data[..case.ct_expected.len] == case.ct_expected.data[..case.ct_expected.len] { + let _ = writeln!(uart, "\r\n[{}] ✅ Encrypt: PASS", case.name); + } else { + let _ = writeln!(uart, "\r\n[{}] ❌ Encrypt: FAIL", case.name); + } + } + + // Decrypt + { + let mut ctx_dec = symm.init(case.key, case.iv, mode).unwrap(); + let pt_out: PlainText = ctx_dec.decrypt(case.ct_expected.clone()).unwrap(); + + let _ = write!(uart, "\r\n[{}] {} Decrypt Input (CT):", case.name, M::NAME); + print_hex_array(uart, &case.ct_expected.data[..case.ct_expected.len], 16); + let _ = write!(uart, "\r\n[{}] {} Decrypt Output (PT):", case.name, M::NAME); + print_hex_array(uart, &pt_out.data[..pt_out.len], 16); + + if pt_out.data[..case.pt.len] == case.pt.data[..case.pt.len] { + let _ = writeln!(uart, "\r\n[{}] ✅ Decrypt: PASS", case.name); + } else { + let _ = writeln!(uart, "\r\n[{}] ❌ Decrypt: FAIL", case.name); + } + } +} + +/// ECB has no IV. +fn run_ecb_case_generic( + uart: &mut UartController, + symm: &mut HaceSymmetric<'_, '_, K>, + name: &str, + key: &K, + pt: &PlainText, + ct_expected: &CipherText, +) where + K: KeyMaterial + FromBytes + ToBytes + HasCryptoAlgo, +{ + let iv = Iv::NONE; + + // Encrypt + { + let mut ctx_enc = symm.init(key, &iv, Ecb).unwrap(); + let ct: CipherText = ctx_enc.encrypt(pt.clone()).unwrap(); + + let _ = write!(uart, "\r\n[{name}] ECB Encrypt Input (PT):"); + print_hex_array(uart, &pt.data[..pt.len], 16); + let _ = write!(uart, "\r\n[{name}] ECB Encrypt Key:"); + print_hex_array(uart, key_bytes(key), 16); + let _ = write!(uart, "\r\n[{name}] ECB Encrypt Output (CT):"); + print_hex_array(uart, &ct.data[..ct_expected.len], 16); + + if ct.data[..ct_expected.len] == ct_expected.data[..ct_expected.len] { + let _ = writeln!(uart, "\r\n[{name}] ✅ Encrypt: PASS"); + } else { + let _ = writeln!(uart, "\r\n[{name}] ❌ Encrypt: FAIL"); + } + } + + // Decrypt + { + let mut ctx_dec = symm.init(key, &iv, Ecb).unwrap(); + let pt_out: PlainText = ctx_dec.decrypt(ct_expected.clone()).unwrap(); + + let _ = write!(uart, "\r\n[{name}] ECB Decrypt Input (CT):"); + print_hex_array(uart, &ct_expected.data[..ct_expected.len], 16); + let _ = write!(uart, "\r\n[{name}] ECB Decrypt Output (PT):"); + print_hex_array(uart, &pt_out.data[..pt_out.len], 16); + + if pt_out.data[..pt.len] == pt.data[..pt.len] { + let _ = writeln!(uart, "\r\n[{name}] ✅ Decrypt: PASS"); + } else { + let _ = writeln!(uart, "\r\n[{name}] ❌ Decrypt: FAIL"); + } + } +} + +// ------------------------- Tiny macros on top of generics ------------------------- + +macro_rules! run_ivmode_tv { + ($mode:expr, $uart:expr, $symm:expr, $label:expr, $tv:expr) => {{ + let tv = $tv; + let case = IvModeCase { + name: $label, + key: &tv.key, + iv: &tv.iv, + pt: &tv.ptext, + ct_expected: &tv.ctext, + }; + run_iv_mode_case($uart, $symm, &case, $mode); + }}; +} + +macro_rules! run_ecb_tv { + ($uart:expr, $symm:expr, $label:expr, $tv:expr) => {{ + let tv = $tv; + run_ecb_case_generic($uart, $symm, $label, &tv.key, &tv.ptext, &tv.ctext); + }}; +} + +// ------------------------- Per-suite wrappers ------------------------- + +fn run_aes_cbc_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, AesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running AES-CBC tests..."); + run_ivmode_tv!(Cbc, uart, &mut symm, "AES-128", Aes128CbcTestVec::new()); + run_ivmode_tv!(Cbc, uart, &mut symm, "AES-192", Aes192CbcTestVec::new()); + run_ivmode_tv!(Cbc, uart, &mut symm, "AES-256", Aes256CbcTestVec::new()); +} + +fn run_des_cbc_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, DesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running DES-CBC tests..."); + run_ivmode_tv!(Cbc, uart, &mut symm, "DES", DesCbcTestVec::new()); +} + +fn run_tdes_cbc_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, TdesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running TDES-CBC tests..."); + run_ivmode_tv!(Cbc, uart, &mut symm, "TDES", TdesCbcTestVec::new()); +} + +fn run_aes_cfb_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, AesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running AES-CFB tests..."); + run_ivmode_tv!(Cfb, uart, &mut symm, "AES-128", Aes128CfbTestVec::new()); + run_ivmode_tv!(Cfb, uart, &mut symm, "AES-192", Aes192CfbTestVec::new()); + run_ivmode_tv!(Cfb, uart, &mut symm, "AES-256", Aes256CfbTestVec::new()); +} + +fn run_des_cfb_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, DesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running DES-CFB tests..."); + run_ivmode_tv!(Cfb, uart, &mut symm, "DES", DesCfbTestVec::new()); +} + +fn run_tdes_cfb_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, TdesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running TDES-CFB tests..."); + run_ivmode_tv!(Cfb, uart, &mut symm, "TDES", TdesCfbTestVec::new()); +} + +fn run_aes_ctr_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, AesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running AES-CTR tests..."); + run_ivmode_tv!(Ctr, uart, &mut symm, "AES-128", Aes128CtrTestVec::new()); + run_ivmode_tv!(Ctr, uart, &mut symm, "AES-192", Aes192CtrTestVec::new()); + run_ivmode_tv!(Ctr, uart, &mut symm, "AES-256", Aes256CtrTestVec::new()); +} + +fn run_des_ctr_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, DesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running DES-CTR tests..."); + run_ivmode_tv!(Ctr, uart, &mut symm, "DES", DesCtrTestVec::new()); +} + +fn run_tdes_ctr_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, TdesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running TDES-CTR tests..."); + run_ivmode_tv!(Ctr, uart, &mut symm, "TDES", TdesCtrTestVec::new()); +} + +fn run_aes_ofb_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, AesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running AES-OFB tests..."); + run_ivmode_tv!(Ofb, uart, &mut symm, "AES-128", Aes128OfbTestVec::new()); + run_ivmode_tv!(Ofb, uart, &mut symm, "AES-192", Aes192OfbTestVec::new()); + run_ivmode_tv!(Ofb, uart, &mut symm, "AES-256", Aes256OfbTestVec::new()); +} + +fn run_des_ofb_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, DesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running DES-OFB tests..."); + run_ivmode_tv!(Ofb, uart, &mut symm, "DES", DesOfbTestVec::new()); +} + +fn run_tdes_ofb_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, TdesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running TDES-OFB tests..."); + run_ivmode_tv!(Ofb, uart, &mut symm, "TDES", TdesOfbTestVec::new()); +} + +fn run_aes_ecb_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, AesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running AES-ECB tests..."); + run_ecb_tv!(uart, &mut symm, "AES-128", Aes128EcbTestVec::new()); + run_ecb_tv!(uart, &mut symm, "AES-192", Aes192EcbTestVec::new()); + run_ecb_tv!(uart, &mut symm, "AES-256", Aes256EcbTestVec::new()); +} + +fn run_des_ecb_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, DesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running DES-ECB tests..."); + run_ecb_tv!(uart, &mut symm, "DES", DesEcbTestVec::new()); +} + +fn run_tdes_ecb_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + let mut symm: HaceSymmetric<'_, '_, TdesKey> = HaceSymmetric { + controller: hace, + _key: core::marker::PhantomData, + }; + let _ = writeln!(uart, "\r\n\n#################### Running TDES-ECB tests..."); + run_ecb_tv!(uart, &mut symm, "TDES", TdesEcbTestVec::new()); +} + +// ------------------------- Entry point ------------------------- + +pub fn run_symm_cipher_tests(uart: &mut UartController, hace: &mut HaceController<'_>) { + run_aes_cbc_tests(uart, &mut *hace); + run_des_cbc_tests(uart, &mut *hace); + run_tdes_cbc_tests(uart, &mut *hace); + + run_aes_cfb_tests(uart, &mut *hace); + run_des_cfb_tests(uart, &mut *hace); + run_tdes_cfb_tests(uart, &mut *hace); + + run_aes_ctr_tests(uart, &mut *hace); + run_des_ctr_tests(uart, &mut *hace); + run_tdes_ctr_tests(uart, &mut *hace); + + run_aes_ofb_tests(uart, &mut *hace); + run_des_ofb_tests(uart, &mut *hace); + run_tdes_ofb_tests(uart, &mut *hace); + + run_aes_ecb_tests(uart, &mut *hace); + run_des_ecb_tests(uart, &mut *hace); + run_tdes_ecb_tests(uart, &mut *hace); +}