From 130db2b9afaa11d271bdce69d3144a52b443cbda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Fri, 30 Jan 2026 18:42:49 +0300 Subject: [PATCH 1/3] des: implement weak key test as a free-standing function --- des/src/consts.rs | 73 ---------------------------- des/src/des.rs | 10 ---- des/src/lib.rs | 13 +---- des/src/tdes.rs | 57 ---------------------- des/src/weak_key.rs | 113 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+), 151 deletions(-) create mode 100644 des/src/weak_key.rs diff --git a/des/src/consts.rs b/des/src/consts.rs index 90f67f68..5bac66e1 100644 --- a/des/src/consts.rs +++ b/des/src/consts.rs @@ -57,76 +57,3 @@ pub const SBOXES: [[u8; 64]; 8] = [ 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11, ], ]; - -macro_rules! as_ne_u64 { - [$($key:expr,)*] => { - [$(u64::from_ne_bytes($key),)*] - }; -} - -pub(crate) static WEAK_KEYS: &[u64; 64] = &as_ne_u64![ - [0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01], - [0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE], - [0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1], - [0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E], - [0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E], - [0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01], - [0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1], - [0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01], - [0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE], - [0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01], - [0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1], - [0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E], - [0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE], - [0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E], - [0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE], - [0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1], - [0x01, 0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E], - [0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01, 0x01], - [0xE0, 0xE0, 0x1F, 0x1F, 0xF1, 0xF1, 0x0E, 0x0E], - [0x01, 0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1], - [0x1F, 0x1F, 0xE0, 0xE0, 0x0E, 0x0E, 0xF1, 0xF1], - [0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE, 0xFE], - [0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE], - [0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE, 0xFE], - [0xE0, 0xFE, 0x01, 0x1F, 0xF1, 0xFE, 0x01, 0x0E], - [0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01], - [0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01, 0xFE], - [0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E, 0x01], - [0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE], - [0x1F, 0xE0, 0xE0, 0x1F, 0x0E, 0xF1, 0xF1, 0x0E], - [0xE0, 0xFE, 0xFE, 0xE0, 0xF1, 0xFE, 0xFE, 0xF1], - [0x01, 0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1], - [0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE, 0x01], - [0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE], - [0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE], - [0x1F, 0xFE, 0x01, 0xE0, 0x0E, 0xFE, 0x01, 0xF1], - [0xFE, 0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1], - [0xFE, 0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E], - [0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1, 0x01], - [0xFE, 0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1], - [0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01], - [0x1F, 0xFE, 0xFE, 0x1F, 0x0E, 0xFE, 0xFE, 0x0E], - [0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01], - [0x01, 0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E], - [0xE0, 0x01, 0x01, 0xE0, 0xF1, 0x01, 0x01, 0xF1], - [0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE], - [0x01, 0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1], - [0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E, 0xFE], - [0xFE, 0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E], - [0x01, 0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E], - [0xE0, 0x01, 0xFE, 0x1F, 0xF1, 0x01, 0xFE, 0x0E], - [0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01], - [0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01], - [0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01, 0xFE], - [0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE], - [0x1F, 0x01, 0x01, 0x1F, 0x0E, 0x01, 0x01, 0x0E], - [0xE0, 0x1F, 0x1F, 0xE0, 0xF1, 0x0E, 0x0E, 0xF1], - [0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01], - [0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1, 0xFE], - [0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE, 0x01], - [0xFE, 0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E], - [0x1F, 0x01, 0xFE, 0xE0, 0x0E, 0x01, 0xFE, 0xF1], - [0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01, 0x01], - [0xFE, 0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1], -]; diff --git a/des/src/des.rs b/des/src/des.rs index acee7a46..baea54b7 100644 --- a/des/src/des.rs +++ b/des/src/des.rs @@ -7,7 +7,6 @@ use cipher::{ BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, InOut, Key, KeyInit, KeySizeUser, ParBlocksSizeUser, consts::{U1, U8}, - crypto_common::WeakKeyError, }; use core::fmt; @@ -50,15 +49,6 @@ impl KeyInit for Des { let keys = gen_keys(u64::from_be_bytes(key.0)); Self { keys } } - - #[inline] - fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - let key = u64::from_ne_bytes(key.0); - match super::weak_key_test(key) { - 0 => Ok(()), - _ => Err(WeakKeyError), - } - } } impl BlockSizeUser for Des { diff --git a/des/src/lib.rs b/des/src/lib.rs index f72d1b86..590cdb7e 100644 --- a/des/src/lib.rs +++ b/des/src/lib.rs @@ -27,17 +27,8 @@ mod consts; mod des; mod tdes; mod utils; +mod weak_key; pub use crate::des::Des; pub use crate::tdes::{TdesEde2, TdesEde3, TdesEee2, TdesEee3}; - -/// Checks whether the key is weak. -/// -/// Returns 1 if the key is weak; otherwise, returns 0. -fn weak_key_test(key: u64) -> u8 { - let mut is_weak = 0u8; - for &weak_key in crate::consts::WEAK_KEYS { - is_weak |= u8::from(key == weak_key); - } - is_weak -} +pub use weak_key::{WeakKeyError, weak_key_test}; diff --git a/des/src/tdes.rs b/des/src/tdes.rs index 5126e2ae..1307b47b 100644 --- a/des/src/tdes.rs +++ b/des/src/tdes.rs @@ -6,49 +6,12 @@ use cipher::{ BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, InOut, Key, KeyInit, KeySizeUser, ParBlocksSizeUser, consts::{U1, U8, U16, U24}, - crypto_common::WeakKeyError, }; use core::fmt; #[cfg(feature = "zeroize")] use cipher::zeroize::ZeroizeOnDrop; -#[inline] -fn weak_key_test2(key: &[u8; 16]) -> Result<(), WeakKeyError> { - let k1 = u64::from_ne_bytes(key[..8].try_into().unwrap()); - let k2 = u64::from_ne_bytes(key[8..16].try_into().unwrap()); - - let mut is_weak = 0u8; - is_weak |= super::weak_key_test(k1); - is_weak |= super::weak_key_test(k2); - is_weak |= u8::from(k1 == k2); - - match is_weak { - 0 => Ok(()), - _ => Err(WeakKeyError), - } -} - -#[inline] -fn weak_key_test3(key: &[u8; 24]) -> Result<(), WeakKeyError> { - let k1 = u64::from_ne_bytes(key[..8].try_into().unwrap()); - let k2 = u64::from_ne_bytes(key[8..16].try_into().unwrap()); - let k3 = u64::from_ne_bytes(key[16..24].try_into().unwrap()); - - let mut is_weak = 0u8; - is_weak |= super::weak_key_test(k1); - is_weak |= super::weak_key_test(k2); - is_weak |= super::weak_key_test(k3); - is_weak |= u8::from(k1 == k2); - is_weak |= u8::from(k1 == k3); - is_weak |= u8::from(k2 == k3); - - match is_weak { - 0 => Ok(()), - _ => Err(WeakKeyError), - } -} - /// Triple DES (3DES) block cipher. #[derive(Clone)] pub struct TdesEde3 { @@ -72,11 +35,6 @@ impl KeyInit for TdesEde3 { let d3 = Des { keys: gen_keys(k3) }; Self { d1, d2, d3 } } - - #[inline] - fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test3(&key.0) - } } impl BlockSizeUser for TdesEde3 { @@ -161,11 +119,6 @@ impl KeyInit for TdesEee3 { let d3 = Des { keys: gen_keys(k3) }; Self { d1, d2, d3 } } - - #[inline] - fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test3(&key.0) - } } impl BlockSizeUser for TdesEee3 { @@ -247,11 +200,6 @@ impl KeyInit for TdesEde2 { let d2 = Des { keys: gen_keys(k2) }; Self { d1, d2 } } - - #[inline] - fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test2(&key.0) - } } impl BlockSizeUser for TdesEde2 { @@ -333,11 +281,6 @@ impl KeyInit for TdesEee2 { let d2 = Des { keys: gen_keys(k2) }; Self { d1, d2 } } - - #[inline] - fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test2(&key.0) - } } impl BlockSizeUser for TdesEee2 { diff --git a/des/src/weak_key.rs b/des/src/weak_key.rs new file mode 100644 index 00000000..ca84939c --- /dev/null +++ b/des/src/weak_key.rs @@ -0,0 +1,113 @@ +use core::fmt; + +/// Checks whether `key` contains one of the known [weak DES keys][TCG]. +/// +/// [TCG]: https://trustedcomputinggroup.org/wp-content/uploads/TPM-2.0-1.83-Part-1-Architecture.pdf#page=82 +/// +/// # Panics +/// If `key` length is not equal to 8, 16, or 24. +#[inline] +pub fn weak_key_test(key: &[u8]) -> Result<(), WeakKeyError> { + assert!( + matches!(key.len(), 8 | 16 | 24), + "key size is not equal to 8, 16, or 24 bytes" + ); + + let mut is_weak = 0u8; + for subkey in key.chunks_exact(8) { + let key = u64::from_ne_bytes(subkey.try_into().expect("`subkey` length is equal to 8")); + for &weak_key in WEAK_KEYS { + is_weak |= u8::from(key == weak_key); + } + } + match is_weak { + 0 => Ok(()), + _ => Err(WeakKeyError), + } +} + +/// The error type returned when a key is found to be weak. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct WeakKeyError; + +impl fmt::Display for WeakKeyError { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("WeakKey") + } +} + +impl core::error::Error for WeakKeyError {} + +macro_rules! as_ne_u64 { + [$($key:expr,)*] => { + [$(u64::from_ne_bytes($key),)*] + }; +} + +pub(crate) static WEAK_KEYS: &[u64; 64] = &as_ne_u64![ + [0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01], + [0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE], + [0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1], + [0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E], + [0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E], + [0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01], + [0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1], + [0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01], + [0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE], + [0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01], + [0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1], + [0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E], + [0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE], + [0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E], + [0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE], + [0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1], + [0x01, 0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E], + [0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01, 0x01], + [0xE0, 0xE0, 0x1F, 0x1F, 0xF1, 0xF1, 0x0E, 0x0E], + [0x01, 0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1], + [0x1F, 0x1F, 0xE0, 0xE0, 0x0E, 0x0E, 0xF1, 0xF1], + [0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE, 0xFE], + [0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE], + [0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE, 0xFE], + [0xE0, 0xFE, 0x01, 0x1F, 0xF1, 0xFE, 0x01, 0x0E], + [0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01], + [0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01, 0xFE], + [0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E, 0x01], + [0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE], + [0x1F, 0xE0, 0xE0, 0x1F, 0x0E, 0xF1, 0xF1, 0x0E], + [0xE0, 0xFE, 0xFE, 0xE0, 0xF1, 0xFE, 0xFE, 0xF1], + [0x01, 0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1], + [0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE, 0x01], + [0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE], + [0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE], + [0x1F, 0xFE, 0x01, 0xE0, 0x0E, 0xFE, 0x01, 0xF1], + [0xFE, 0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1], + [0xFE, 0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E], + [0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1, 0x01], + [0xFE, 0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1], + [0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01], + [0x1F, 0xFE, 0xFE, 0x1F, 0x0E, 0xFE, 0xFE, 0x0E], + [0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01], + [0x01, 0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E], + [0xE0, 0x01, 0x01, 0xE0, 0xF1, 0x01, 0x01, 0xF1], + [0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE], + [0x01, 0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1], + [0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E, 0xFE], + [0xFE, 0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E], + [0x01, 0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E], + [0xE0, 0x01, 0xFE, 0x1F, 0xF1, 0x01, 0xFE, 0x0E], + [0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01], + [0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01], + [0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01, 0xFE], + [0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE], + [0x1F, 0x01, 0x01, 0x1F, 0x0E, 0x01, 0x01, 0x0E], + [0xE0, 0x1F, 0x1F, 0xE0, 0xF1, 0x0E, 0x0E, 0xF1], + [0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01], + [0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1, 0xFE], + [0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE, 0x01], + [0xFE, 0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E], + [0x1F, 0x01, 0xFE, 0xE0, 0x0E, 0x01, 0xFE, 0xF1], + [0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01, 0x01], + [0xFE, 0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1], +]; From 9a53ec8047e0884b6543948b5a9e845b425d9fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Fri, 30 Jan 2026 18:45:05 +0300 Subject: [PATCH 2/3] update changelog --- des/CHANGELOG.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/des/CHANGELOG.md b/des/CHANGELOG.md index d844f1f3..f4f4f846 100644 --- a/des/CHANGELOG.md +++ b/des/CHANGELOG.md @@ -7,19 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.9.0 (UNRELEASED) ### Added -- Weak key detection in the `KeyInit::weak_key_test` method ([#465], [#468], [#469], [#470]) +- `weak_key_test` function for weak key detection ([#528]) ### Changed - Bump `cipher` dependency to v0.5.0 - Edition changed to 2024 and MSRV bumped to 1.85 ([#472]) - Relax MSRV policy and allow MSRV bumps in patch releases ([#477]) -[#465]: https://github.com/RustCrypto/block-ciphers/pull/465 -[#468]: https://github.com/RustCrypto/block-ciphers/pull/468 -[#469]: https://github.com/RustCrypto/block-ciphers/pull/469 -[#470]: https://github.com/RustCrypto/block-ciphers/pull/470 [#472]: https://github.com/RustCrypto/block-ciphers/pull/472 [#477]: https://github.com/RustCrypto/block-ciphers/pull/477 +[#528]: https://github.com/RustCrypto/block-ciphers/pull/528 ## 0.8.1 (2022-02-17) ### Fixed From 429467c8f340748e05e4a5a7ac40fae0bbad8313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Fri, 30 Jan 2026 19:05:46 +0300 Subject: [PATCH 3/3] test subkeys equality, update test --- des/src/weak_key.rs | 17 +++++++++++++++++ des/tests/weak.rs | 14 ++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/des/src/weak_key.rs b/des/src/weak_key.rs index ca84939c..fbb322ed 100644 --- a/des/src/weak_key.rs +++ b/des/src/weak_key.rs @@ -14,12 +14,29 @@ pub fn weak_key_test(key: &[u8]) -> Result<(), WeakKeyError> { ); let mut is_weak = 0u8; + for subkey in key.chunks_exact(8) { let key = u64::from_ne_bytes(subkey.try_into().expect("`subkey` length is equal to 8")); for &weak_key in WEAK_KEYS { is_weak |= u8::from(key == weak_key); } } + + match key.len() { + 16 => { + is_weak |= u8::from(key[..8] == key[8..]); + } + 24 => { + let k1 = &key[..8]; + let k2 = &key[8..16]; + let k3 = &key[16..]; + is_weak |= u8::from(k1 == k2); + is_weak |= u8::from(k1 == k3); + is_weak |= u8::from(k2 == k3); + } + _ => {} + } + match is_weak { 0 => Ok(()), _ => Err(WeakKeyError), diff --git a/des/tests/weak.rs b/des/tests/weak.rs index 04e44392..67bb9037 100644 --- a/des/tests/weak.rs +++ b/des/tests/weak.rs @@ -1,5 +1,4 @@ -use cipher::{Key, KeyInit}; -use des::{Des, TdesEde2, TdesEde3, TdesEee2, TdesEee3}; +use des::weak_key_test; use hex_literal::hex; #[test] @@ -9,8 +8,7 @@ fn weak_des() { hex!("fefefefefefefefe"), hex!("e0e0e0e0f1f1f1f1"), ] { - let k = Key::::from(*k); - assert!(Des::weak_key_test(&k).is_err()); + assert!(weak_key_test(k).is_err()); } for k in &[ @@ -21,9 +19,7 @@ fn weak_des() { hex!("010203040506070811121314151617180102030405060708"), hex!("111213141516171801020304050607080102030405060708"), ] { - let k = Key::::from(*k); - assert!(TdesEde3::weak_key_test(&k).is_err()); - assert!(TdesEee3::weak_key_test(&k).is_err()); + assert!(weak_key_test(k).is_err()); } for k in &[ @@ -32,8 +28,6 @@ fn weak_des() { hex!("0000000000000000e0e0e0e0f1f1f1f1"), hex!("01020304050607080102030405060708"), ] { - let k = Key::::from(*k); - assert!(TdesEde2::weak_key_test(&k).is_err()); - assert!(TdesEee2::weak_key_test(&k).is_err()); + assert!(weak_key_test(k).is_err()); } }