use core::fmt;
#[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 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),
}
}
#[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],
];