From 4399a5f2589c33a6d9db20963ae508eac7bddf99 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Wed, 29 Jan 2025 10:44:21 -0800 Subject: [PATCH] aes,des: implement weak key detection --- Cargo.lock | 16 ++++++--- Cargo.toml | 5 +++ aes/Cargo.toml | 1 + aes/src/armv8.rs | 13 +++++++ aes/src/autodetect.rs | 13 +++++++ aes/src/macros.rs | 26 ++++++++++++++ aes/src/ni.rs | 13 +++++++ aes/src/soft.rs | 13 +++++++ aes/tests/weak.rs | 24 +++++++++++++ des/Cargo.toml | 2 ++ des/src/des.rs | 84 +++++++++++++++++++++++++++++++++++++++++++ des/src/tdes.rs | 49 +++++++++++++++++++++++++ des/tests/weak.rs | 35 ++++++++++++++++++ 13 files changed, 290 insertions(+), 4 deletions(-) create mode 100644 aes/tests/weak.rs create mode 100644 des/tests/weak.rs diff --git a/Cargo.lock b/Cargo.lock index 202e3a50..93dfe450 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,6 +10,7 @@ dependencies = [ "cipher", "cpufeatures", "hex-literal", + "subtle", "zeroize", ] @@ -82,8 +83,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" version = "0.5.0-pre.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1425e6ce000f05a73096556cabcfb6a10a3ffe3bb4d75416ca8f00819c0b6a" +source = "git+https://github.com/baloo/traits.git?branch=baloo/cipher/propagate-zeroize#b9af4268fa42f910bc1ee8ec76da6502c41bc526" dependencies = [ "blobby", "crypto-common", @@ -103,8 +103,7 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.2.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" +source = "git+https://github.com/baloo/traits.git?branch=baloo/cipher/propagate-zeroize#b9af4268fa42f910bc1ee8ec76da6502c41bc526" dependencies = [ "hybrid-array", ] @@ -114,6 +113,8 @@ name = "des" version = "0.9.0-pre.2" dependencies = [ "cipher", + "hex-literal", + "subtle", ] [[package]] @@ -137,6 +138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" dependencies = [ "typenum", + "zeroize", ] [[package]] @@ -216,6 +218,12 @@ dependencies = [ "hex-literal", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "threefish" version = "0.6.0-pre" diff --git a/Cargo.toml b/Cargo.toml index cbf5fa31..9fd825fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,8 @@ members = [ [profile.dev] opt-level = 2 + +[patch.crates-io] +# https://github.com/RustCrypto/traits/pull/1742 +crypto-common = { git = "https://github.com/RustCrypto/traits.git" } + diff --git a/aes/Cargo.toml b/aes/Cargo.toml index cbe2c1ce..c4e82b81 100644 --- a/aes/Cargo.toml +++ b/aes/Cargo.toml @@ -15,6 +15,7 @@ categories = ["cryptography", "no-std"] [dependencies] cfg-if = "1" cipher = "=0.5.0-pre.7" +subtle = { version = "2.6", default-features = false } zeroize = { version = "1.5.6", optional = true, default-features = false, features = [ "aarch64", ] } diff --git a/aes/src/armv8.rs b/aes/src/armv8.rs index f0de41fa..114f637f 100644 --- a/aes/src/armv8.rs +++ b/aes/src/armv8.rs @@ -19,6 +19,7 @@ mod test_expand; use cipher::{ consts::{self, U16, U24, U32}, + crypto_common::WeakKeyError, AlgorithmName, BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, Key, KeyInit, KeySizeUser, }; @@ -108,6 +109,10 @@ macro_rules! define_aes_impl { let decrypt = $name_back_dec::from(encrypt.clone()); Self { encrypt, decrypt } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl From<$name_enc> for $name { @@ -193,6 +198,10 @@ macro_rules! define_aes_impl { let backend = $name_back_enc::new(key); Self { backend } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl BlockSizeUser for $name_enc { @@ -255,6 +264,10 @@ macro_rules! define_aes_impl { let backend = encrypt.clone().into(); Self { backend } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl From<$name_enc> for $name_dec { diff --git a/aes/src/autodetect.rs b/aes/src/autodetect.rs index 8c0e6898..8cfd47c4 100644 --- a/aes/src/autodetect.rs +++ b/aes/src/autodetect.rs @@ -4,6 +4,7 @@ use crate::soft; use cipher::{ consts::{U16, U24, U32}, + crypto_common::WeakKeyError, AlgorithmName, BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, Key, KeyInit, KeySizeUser, }; @@ -103,6 +104,10 @@ macro_rules! define_aes_impl { Self { inner, token } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl Clone for $name { @@ -220,6 +225,10 @@ macro_rules! define_aes_impl { Self { inner, token } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl Clone for $name_enc { @@ -347,6 +356,10 @@ macro_rules! define_aes_impl { Self { inner, token } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl Clone for $name_dec { diff --git a/aes/src/macros.rs b/aes/src/macros.rs index e688c00d..28583e99 100644 --- a/aes/src/macros.rs +++ b/aes/src/macros.rs @@ -103,3 +103,29 @@ macro_rules! impl_backends { } }; } + +macro_rules! weak_key_test { + ($key: expr, $k: ty) => {{ + // Check if any bit of the upper half of the key is set + // + // This follows the interpretation laid out in section `11.4.10.4 Reject of weak keys` + // from the TPM specification: + // ``` + // In the case of AES, at least one bit in the upper half of the key must be set + // ``` + // See: https://trustedcomputinggroup.org/wp-content/uploads/TPM-2.0-1.83-Part-1-Architecture.pdf#page=82 + let mut weak = subtle::Choice::from(0); + + for v in &$key + [..(<<$k as cipher::KeySizeUser>::KeySize as cipher::typenum::Unsigned>::USIZE / 2)] + { + weak |= <_ as subtle::ConstantTimeGreater>::ct_gt(v, &0); + } + + if weak.unwrap_u8() == 0 { + Err(cipher::crypto_common::WeakKeyError) + } else { + Ok(()) + } + }}; +} diff --git a/aes/src/ni.rs b/aes/src/ni.rs index a39a7c0c..5833b821 100644 --- a/aes/src/ni.rs +++ b/aes/src/ni.rs @@ -30,6 +30,7 @@ use core::arch::x86_64 as arch; use cipher::{ consts::{self, U16, U24, U32}, + crypto_common::WeakKeyError, AlgorithmName, BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, Key, KeyInit, KeySizeUser, }; @@ -118,6 +119,10 @@ macro_rules! define_aes_impl { let decrypt = $name_dec::from(&encrypt); Self { encrypt, decrypt } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl From<$name_enc> for $name { @@ -193,6 +198,10 @@ macro_rules! define_aes_impl { backend: $name_back_enc::new(key), } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl BlockSizeUser for $name_enc { @@ -253,6 +262,10 @@ macro_rules! define_aes_impl { fn new(key: &Key) -> Self { $name_enc::new(key).into() } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl From<$name_enc> for $name_dec { diff --git a/aes/src/soft.rs b/aes/src/soft.rs index 9e5f9bef..19c2576d 100644 --- a/aes/src/soft.rs +++ b/aes/src/soft.rs @@ -15,6 +15,7 @@ pub(crate) mod fixslice; use crate::Block; use cipher::{ consts::{U16, U24, U32}, + crypto_common::WeakKeyError, inout::InOut, AlgorithmName, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, Key, KeyInit, @@ -67,6 +68,10 @@ macro_rules! define_aes_impl { keys: $fixslice_key_schedule(key.into()), } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl BlockSizeUser for $name { @@ -146,6 +151,10 @@ macro_rules! define_aes_impl { let inner = $name::new(key); Self { inner } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl BlockSizeUser for $name_enc { @@ -197,6 +206,10 @@ macro_rules! define_aes_impl { let inner = $name::new(key); Self { inner } } + + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + weak_key_test!(key, Self) + } } impl From<$name_enc> for $name_dec { diff --git a/aes/tests/weak.rs b/aes/tests/weak.rs new file mode 100644 index 00000000..f95c1bcf --- /dev/null +++ b/aes/tests/weak.rs @@ -0,0 +1,24 @@ +use aes::Aes128; +use cipher::{Key, KeyInit}; +use hex_literal::hex; + +#[test] +fn test_weak_key() { + for k in &[ + hex!("00000000000000000000000000000000"), + hex!("00000000000000000101010101010101"), + hex!("00000000000000000100000000000000"), + ] { + let k = Key::::from(*k); + assert!(Aes128::weak_key_test(&k).is_err()); + } + + for k in &[ + hex!("00000000010000000000000000000000"), + hex!("00000000010000000101010101010101"), + hex!("00000000010000000100000000000000"), + ] { + let k = Key::::from(*k); + assert!(Aes128::weak_key_test(&k).is_ok()); + } +} diff --git a/des/Cargo.toml b/des/Cargo.toml index f839232f..12f396bc 100644 --- a/des/Cargo.toml +++ b/des/Cargo.toml @@ -14,9 +14,11 @@ categories = ["cryptography", "no-std"] [dependencies] cipher = "=0.5.0-pre.7" +subtle = { version = "2.6", default-features = false } [dev-dependencies] cipher = { version = "=0.5.0-pre.7", features = ["dev"] } +hex-literal = "0.4" [features] zeroize = ["cipher/zeroize"] diff --git a/des/src/des.rs b/des/src/des.rs index 128e4c3c..2e520e41 100644 --- a/des/src/des.rs +++ b/des/src/des.rs @@ -4,11 +4,13 @@ use cipher::{ consts::{U1, U8}, + crypto_common::WeakKeyError, AlgorithmName, Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, InOut, Key, KeyInit, KeySizeUser, ParBlocksSizeUser, }; use core::fmt; +use subtle::{Choice, ConstantTimeEq}; #[cfg(feature = "zeroize")] use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; @@ -43,12 +45,94 @@ impl KeySizeUser for Des { type KeySize = U8; } +static WEAK_KEYS: [[u8; 8]; 64] = [ + [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], +]; + impl KeyInit for Des { #[inline] fn new(key: &Key) -> Self { let keys = gen_keys(u64::from_be_bytes(key.0)); Self { keys } } + + #[inline] + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + let mut weak = Choice::from(0); + + for weak_key in &WEAK_KEYS { + weak |= key.ct_eq(weak_key); + } + + if weak.unwrap_u8() == 0 { + Ok(()) + } else { + Err(WeakKeyError) + } + } } impl BlockSizeUser for Des { diff --git a/des/src/tdes.rs b/des/src/tdes.rs index c811c0b3..aee65981 100644 --- a/des/src/tdes.rs +++ b/des/src/tdes.rs @@ -3,6 +3,8 @@ use crate::{utils::gen_keys, Des}; use cipher::{ consts::{U1, U16, U24, U8}, + crypto_common::WeakKeyError, + typenum::Unsigned, AlgorithmName, Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, InOut, Key, KeyInit, KeySizeUser, ParBlocksSizeUser, @@ -12,6 +14,33 @@ use core::fmt; #[cfg(feature = "zeroize")] use cipher::zeroize::ZeroizeOnDrop; +#[inline] +fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + let mut tmp = Key::::default(); + + for i in 0..::KeySize::USIZE { + // count number of set bits in byte, excluding the low-order bit - SWAR method + let mut c = key[i] & 0xFE; + + c = (c & 0x55) + ((c >> 1) & 0x55); + c = (c & 0x33) + ((c >> 2) & 0x33); + c = (c & 0x0F) + ((c >> 4) & 0x0F); + + // if count is even, set low key bit to 1, otherwise 0 + tmp[i] = (key[i] & 0xFE) | u8::from(c & 0x01 != 0x01); + } + + let mut des_key = Key::::default(); + for i in 0..SIZE { + des_key.copy_from_slice( + &tmp.as_slice()[i * ::KeySize::USIZE + ..(i + 1) * ::KeySize::USIZE], + ); + Des::weak_key_test(&des_key)?; + } + Ok(()) +} + /// Triple DES (3DES) block cipher. #[derive(Clone)] pub struct TdesEde3 { @@ -35,6 +64,11 @@ 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_test::<3, Self>(key) + } } impl BlockSizeUser for TdesEde3 { @@ -119,6 +153,11 @@ 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_test::<3, Self>(key) + } } impl BlockSizeUser for TdesEee3 { @@ -200,6 +239,11 @@ 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_test::<2, Self>(key) + } } impl BlockSizeUser for TdesEde2 { @@ -281,6 +325,11 @@ 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_test::<2, Self>(key) + } } impl BlockSizeUser for TdesEee2 { diff --git a/des/tests/weak.rs b/des/tests/weak.rs new file mode 100644 index 00000000..e10f678e --- /dev/null +++ b/des/tests/weak.rs @@ -0,0 +1,35 @@ +use cipher::{Key, KeyInit}; +use des::{Des, TdesEde2, TdesEde3, TdesEee2, TdesEee3}; +use hex_literal::hex; + +#[test] +fn weak_des() { + for k in &[ + hex!("0101010101010101"), + hex!("fefefefefefefefe"), + hex!("e0e0e0e0f1f1f1f1"), + ] { + let k = Key::::from(*k); + assert!(Des::weak_key_test(&k).is_err()); + } + + for k in &[ + hex!("010101010101010100000000000000000000000000000000"), + hex!("0000000000000000fefefefefefefefe0000000000000000"), + hex!("00000000000000000000000000000000e0e0e0e0f1f1f1f1"), + ] { + let k = Key::::from(*k); + assert!(TdesEde3::weak_key_test(&k).is_err()); + assert!(TdesEee3::weak_key_test(&k).is_err()); + } + + for k in &[ + hex!("01010101010101010000000000000000"), + hex!("0000000000000000fefefefefefefefe"), + hex!("0000000000000000e0e0e0e0f1f1f1f1"), + ] { + let k = Key::::from(*k); + assert!(TdesEde2::weak_key_test(&k).is_err()); + assert!(TdesEee2::weak_key_test(&k).is_err()); + } +}