From aa1536715e205f65f04dde251cf9aa825ab2f968 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: Wed, 12 Feb 2025 16:41:14 +0300 Subject: [PATCH 1/4] des: tweak weak key test --- Cargo.lock | 1 - des/Cargo.toml | 1 - des/src/consts.rs | 67 +++++++++++++++++++++++++++++++++++++++++ des/src/des.rs | 77 +++-------------------------------------------- des/src/tdes.rs | 40 ++++++------------------ 5 files changed, 82 insertions(+), 104 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a85c2b26..9f55077c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,7 +114,6 @@ version = "0.9.0-pre.2" dependencies = [ "cipher", "hex-literal", - "subtle", ] [[package]] diff --git a/des/Cargo.toml b/des/Cargo.toml index 12f396bc..550d5441 100644 --- a/des/Cargo.toml +++ b/des/Cargo.toml @@ -14,7 +14,6 @@ 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"] } diff --git a/des/src/consts.rs b/des/src/consts.rs index 5bac66e1..b6414a8c 100644 --- a/des/src/consts.rs +++ b/des/src/consts.rs @@ -57,3 +57,70 @@ pub const SBOXES: [[u8; 64]; 8] = [ 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11, ], ]; + +pub(crate) static WEAK_KEYS: &[u64; 64] = &[ + u64::from_ne_bytes([0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01]), + u64::from_ne_bytes([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE]), + u64::from_ne_bytes([0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1]), + u64::from_ne_bytes([0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E]), + u64::from_ne_bytes([0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E]), + u64::from_ne_bytes([0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01]), + u64::from_ne_bytes([0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1]), + u64::from_ne_bytes([0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01]), + u64::from_ne_bytes([0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE]), + u64::from_ne_bytes([0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01]), + u64::from_ne_bytes([0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1]), + u64::from_ne_bytes([0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E]), + u64::from_ne_bytes([0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE]), + u64::from_ne_bytes([0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E]), + u64::from_ne_bytes([0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE]), + u64::from_ne_bytes([0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1]), + u64::from_ne_bytes([0x01, 0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E]), + u64::from_ne_bytes([0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01, 0x01]), + u64::from_ne_bytes([0xE0, 0xE0, 0x1F, 0x1F, 0xF1, 0xF1, 0x0E, 0x0E]), + u64::from_ne_bytes([0x01, 0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1]), + u64::from_ne_bytes([0x1F, 0x1F, 0xE0, 0xE0, 0x0E, 0x0E, 0xF1, 0xF1]), + u64::from_ne_bytes([0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE, 0xFE]), + u64::from_ne_bytes([0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE]), + u64::from_ne_bytes([0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE, 0xFE]), + u64::from_ne_bytes([0xE0, 0xFE, 0x01, 0x1F, 0xF1, 0xFE, 0x01, 0x0E]), + u64::from_ne_bytes([0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01]), + u64::from_ne_bytes([0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01, 0xFE]), + u64::from_ne_bytes([0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E, 0x01]), + u64::from_ne_bytes([0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE]), + u64::from_ne_bytes([0x1F, 0xE0, 0xE0, 0x1F, 0x0E, 0xF1, 0xF1, 0x0E]), + u64::from_ne_bytes([0xE0, 0xFE, 0xFE, 0xE0, 0xF1, 0xFE, 0xFE, 0xF1]), + u64::from_ne_bytes([0x01, 0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1]), + u64::from_ne_bytes([0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE, 0x01]), + u64::from_ne_bytes([0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE]), + u64::from_ne_bytes([0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE]), + u64::from_ne_bytes([0x1F, 0xFE, 0x01, 0xE0, 0x0E, 0xFE, 0x01, 0xF1]), + u64::from_ne_bytes([0xFE, 0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1]), + u64::from_ne_bytes([0xFE, 0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E]), + u64::from_ne_bytes([0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1, 0x01]), + u64::from_ne_bytes([0xFE, 0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1]), + u64::from_ne_bytes([0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01]), + u64::from_ne_bytes([0x1F, 0xFE, 0xFE, 0x1F, 0x0E, 0xFE, 0xFE, 0x0E]), + u64::from_ne_bytes([0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01]), + u64::from_ne_bytes([0x01, 0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E]), + u64::from_ne_bytes([0xE0, 0x01, 0x01, 0xE0, 0xF1, 0x01, 0x01, 0xF1]), + u64::from_ne_bytes([0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE]), + u64::from_ne_bytes([0x01, 0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1]), + u64::from_ne_bytes([0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E, 0xFE]), + u64::from_ne_bytes([0xFE, 0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E]), + u64::from_ne_bytes([0x01, 0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E]), + u64::from_ne_bytes([0xE0, 0x01, 0xFE, 0x1F, 0xF1, 0x01, 0xFE, 0x0E]), + u64::from_ne_bytes([0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01]), + u64::from_ne_bytes([0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01]), + u64::from_ne_bytes([0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01, 0xFE]), + u64::from_ne_bytes([0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE]), + u64::from_ne_bytes([0x1F, 0x01, 0x01, 0x1F, 0x0E, 0x01, 0x01, 0x0E]), + u64::from_ne_bytes([0xE0, 0x1F, 0x1F, 0xE0, 0xF1, 0x0E, 0x0E, 0xF1]), + u64::from_ne_bytes([0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01]), + u64::from_ne_bytes([0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1, 0xFE]), + u64::from_ne_bytes([0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE, 0x01]), + u64::from_ne_bytes([0xFE, 0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E]), + u64::from_ne_bytes([0x1F, 0x01, 0xFE, 0xE0, 0x0E, 0x01, 0xFE, 0xF1]), + u64::from_ne_bytes([0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01, 0x01]), + u64::from_ne_bytes([0xFE, 0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1]), +]; diff --git a/des/src/des.rs b/des/src/des.rs index 2e520e41..45c92527 100644 --- a/des/src/des.rs +++ b/des/src/des.rs @@ -10,7 +10,6 @@ use cipher::{ KeyInit, KeySizeUser, ParBlocksSizeUser, }; use core::fmt; -use subtle::{Choice, ConstantTimeEq}; #[cfg(feature = "zeroize")] use cipher::zeroize::{Zeroize, ZeroizeOnDrop}; @@ -45,73 +44,6 @@ 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 { @@ -121,13 +53,14 @@ impl KeyInit for Des { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - let mut weak = Choice::from(0); + let key = u64::from_ne_bytes(key.0); + let mut is_weak = 0u8; - for weak_key in &WEAK_KEYS { - weak |= key.ct_eq(weak_key); + for &weak_key in crate::consts::WEAK_KEYS { + is_weak |= u8::from(key == weak_key); } - if weak.unwrap_u8() == 0 { + if is_weak == 0 { Ok(()) } else { Err(WeakKeyError) diff --git a/des/src/tdes.rs b/des/src/tdes.rs index 024f7990..dad78c4e 100644 --- a/des/src/tdes.rs +++ b/des/src/tdes.rs @@ -12,34 +12,14 @@ use cipher::{ use core::fmt; #[cfg(feature = "zeroize")] -use cipher::zeroize::{ZeroizeOnDrop, Zeroizing}; +use cipher::zeroize::ZeroizeOnDrop; #[inline] -fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - #[cfg(feature = "zeroize")] - let mut tmp = Zeroizing::new(Key::::default()); - #[cfg(not(feature = "zeroize"))] - 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)?; +fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + let sub_key_size = ::KeySize::USIZE; + assert_eq!(key.len() % sub_key_size, 0); + for des_key in key.chunks_exact(sub_key_size) { + Des::weak_key_test(des_key.try_into().unwrap())?; } Ok(()) } @@ -70,7 +50,7 @@ impl KeyInit for TdesEde3 { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test::<3, Self>(key) + weak_key_test::(key) } } @@ -159,7 +139,7 @@ impl KeyInit for TdesEee3 { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test::<3, Self>(key) + weak_key_test::(key) } } @@ -245,7 +225,7 @@ impl KeyInit for TdesEde2 { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test::<2, Self>(key) + weak_key_test::(key) } } @@ -331,7 +311,7 @@ impl KeyInit for TdesEee2 { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test::<2, Self>(key) + weak_key_test::(key) } } From 67d7440e5d74660c83e6e2795b094d9dc42de535 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: Wed, 12 Feb 2025 17:00:11 +0300 Subject: [PATCH 2/4] tweak --- des/src/des.rs | 8 +------- des/src/lib.rs | 13 +++++++++++++ des/src/tdes.rs | 22 +++++++++++++++------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/des/src/des.rs b/des/src/des.rs index 45c92527..620218af 100644 --- a/des/src/des.rs +++ b/des/src/des.rs @@ -53,13 +53,7 @@ impl KeyInit for Des { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - let key = u64::from_ne_bytes(key.0); - let mut is_weak = 0u8; - - for &weak_key in crate::consts::WEAK_KEYS { - is_weak |= u8::from(key == weak_key); - } - + let is_weak = super::weak_key_test(&key.0); if is_weak == 0 { Ok(()) } else { diff --git a/des/src/lib.rs b/des/src/lib.rs index 7dc04377..ddf6be85 100644 --- a/des/src/lib.rs +++ b/des/src/lib.rs @@ -30,3 +30,16 @@ mod utils; pub use crate::des::Des; pub use crate::tdes::{TdesEde2, TdesEde3, TdesEee2, TdesEee3}; + +/// Checks whether the key is weak. +/// +/// Returns 1 if key is weak and 0 otherwise. +fn weak_key_test(key: &[u8; 8]) -> u8 { + let key = u64::from_ne_bytes(*key); + let mut is_weak = 0u8; + + for &weak_key in crate::consts::WEAK_KEYS { + is_weak |= u8::from(key == weak_key); + } + is_weak +} diff --git a/des/src/tdes.rs b/des/src/tdes.rs index dad78c4e..73a1d06b 100644 --- a/des/src/tdes.rs +++ b/des/src/tdes.rs @@ -15,13 +15,21 @@ use core::fmt; use cipher::zeroize::ZeroizeOnDrop; #[inline] -fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { +fn weak_key_test(key: &[u8]) -> Result<(), WeakKeyError> { let sub_key_size = ::KeySize::USIZE; assert_eq!(key.len() % sub_key_size, 0); + + let mut is_weak = 0u8; for des_key in key.chunks_exact(sub_key_size) { - Des::weak_key_test(des_key.try_into().unwrap())?; + let des_key = des_key.try_into().unwrap(); + is_weak |= super::weak_key_test(des_key); + } + + if is_weak == 0 { + Ok(()) + } else { + Err(WeakKeyError) } - Ok(()) } /// Triple DES (3DES) block cipher. @@ -50,7 +58,7 @@ impl KeyInit for TdesEde3 { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test::(key) + weak_key_test(key) } } @@ -139,7 +147,7 @@ impl KeyInit for TdesEee3 { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test::(key) + weak_key_test(key) } } @@ -225,7 +233,7 @@ impl KeyInit for TdesEde2 { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test::(key) + weak_key_test(key) } } @@ -311,7 +319,7 @@ impl KeyInit for TdesEee2 { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - weak_key_test::(key) + weak_key_test(key) } } From 923ef3281ea705efd865ca1255715414e9213354 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: Wed, 12 Feb 2025 17:14:04 +0300 Subject: [PATCH 3/4] Use macro to reduce number of `u64::from_ne_bytes` --- des/src/consts.rs | 136 ++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 65 deletions(-) diff --git a/des/src/consts.rs b/des/src/consts.rs index b6414a8c..90f67f68 100644 --- a/des/src/consts.rs +++ b/des/src/consts.rs @@ -58,69 +58,75 @@ pub const SBOXES: [[u8; 64]; 8] = [ ], ]; -pub(crate) static WEAK_KEYS: &[u64; 64] = &[ - u64::from_ne_bytes([0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01]), - u64::from_ne_bytes([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE]), - u64::from_ne_bytes([0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1]), - u64::from_ne_bytes([0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E]), - u64::from_ne_bytes([0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E]), - u64::from_ne_bytes([0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01]), - u64::from_ne_bytes([0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1]), - u64::from_ne_bytes([0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01]), - u64::from_ne_bytes([0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE]), - u64::from_ne_bytes([0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01]), - u64::from_ne_bytes([0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1]), - u64::from_ne_bytes([0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E]), - u64::from_ne_bytes([0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE]), - u64::from_ne_bytes([0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E]), - u64::from_ne_bytes([0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE]), - u64::from_ne_bytes([0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1]), - u64::from_ne_bytes([0x01, 0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E]), - u64::from_ne_bytes([0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01, 0x01]), - u64::from_ne_bytes([0xE0, 0xE0, 0x1F, 0x1F, 0xF1, 0xF1, 0x0E, 0x0E]), - u64::from_ne_bytes([0x01, 0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1]), - u64::from_ne_bytes([0x1F, 0x1F, 0xE0, 0xE0, 0x0E, 0x0E, 0xF1, 0xF1]), - u64::from_ne_bytes([0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE, 0xFE]), - u64::from_ne_bytes([0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE]), - u64::from_ne_bytes([0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE, 0xFE]), - u64::from_ne_bytes([0xE0, 0xFE, 0x01, 0x1F, 0xF1, 0xFE, 0x01, 0x0E]), - u64::from_ne_bytes([0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01]), - u64::from_ne_bytes([0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01, 0xFE]), - u64::from_ne_bytes([0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E, 0x01]), - u64::from_ne_bytes([0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE]), - u64::from_ne_bytes([0x1F, 0xE0, 0xE0, 0x1F, 0x0E, 0xF1, 0xF1, 0x0E]), - u64::from_ne_bytes([0xE0, 0xFE, 0xFE, 0xE0, 0xF1, 0xFE, 0xFE, 0xF1]), - u64::from_ne_bytes([0x01, 0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1]), - u64::from_ne_bytes([0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE, 0x01]), - u64::from_ne_bytes([0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE]), - u64::from_ne_bytes([0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE]), - u64::from_ne_bytes([0x1F, 0xFE, 0x01, 0xE0, 0x0E, 0xFE, 0x01, 0xF1]), - u64::from_ne_bytes([0xFE, 0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1]), - u64::from_ne_bytes([0xFE, 0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E]), - u64::from_ne_bytes([0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1, 0x01]), - u64::from_ne_bytes([0xFE, 0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1]), - u64::from_ne_bytes([0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01]), - u64::from_ne_bytes([0x1F, 0xFE, 0xFE, 0x1F, 0x0E, 0xFE, 0xFE, 0x0E]), - u64::from_ne_bytes([0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01]), - u64::from_ne_bytes([0x01, 0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E]), - u64::from_ne_bytes([0xE0, 0x01, 0x01, 0xE0, 0xF1, 0x01, 0x01, 0xF1]), - u64::from_ne_bytes([0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE]), - u64::from_ne_bytes([0x01, 0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1]), - u64::from_ne_bytes([0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E, 0xFE]), - u64::from_ne_bytes([0xFE, 0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E]), - u64::from_ne_bytes([0x01, 0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E]), - u64::from_ne_bytes([0xE0, 0x01, 0xFE, 0x1F, 0xF1, 0x01, 0xFE, 0x0E]), - u64::from_ne_bytes([0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01]), - u64::from_ne_bytes([0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01]), - u64::from_ne_bytes([0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01, 0xFE]), - u64::from_ne_bytes([0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE]), - u64::from_ne_bytes([0x1F, 0x01, 0x01, 0x1F, 0x0E, 0x01, 0x01, 0x0E]), - u64::from_ne_bytes([0xE0, 0x1F, 0x1F, 0xE0, 0xF1, 0x0E, 0x0E, 0xF1]), - u64::from_ne_bytes([0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01]), - u64::from_ne_bytes([0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1, 0xFE]), - u64::from_ne_bytes([0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE, 0x01]), - u64::from_ne_bytes([0xFE, 0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E]), - u64::from_ne_bytes([0x1F, 0x01, 0xFE, 0xE0, 0x0E, 0x01, 0xFE, 0xF1]), - u64::from_ne_bytes([0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01, 0x01]), - u64::from_ne_bytes([0xFE, 0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1]), +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 4bd3d516b6b8ebe0553f6307d81f5e0a1fbd5f3c 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: Wed, 12 Feb 2025 17:38:06 +0300 Subject: [PATCH 4/4] minor code tweak --- des/src/des.rs | 8 +++----- des/src/lib.rs | 3 +-- des/src/tdes.rs | 7 +++---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/des/src/des.rs b/des/src/des.rs index 620218af..917871f6 100644 --- a/des/src/des.rs +++ b/des/src/des.rs @@ -53,11 +53,9 @@ impl KeyInit for Des { #[inline] fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { - let is_weak = super::weak_key_test(&key.0); - if is_weak == 0 { - Ok(()) - } else { - Err(WeakKeyError) + match super::weak_key_test(&key.0) { + 0 => Ok(()), + _ => Err(WeakKeyError), } } } diff --git a/des/src/lib.rs b/des/src/lib.rs index ddf6be85..7bd0f9c3 100644 --- a/des/src/lib.rs +++ b/des/src/lib.rs @@ -33,11 +33,10 @@ pub use crate::tdes::{TdesEde2, TdesEde3, TdesEee2, TdesEee3}; /// Checks whether the key is weak. /// -/// Returns 1 if key is weak and 0 otherwise. +/// Returns 1 if the key is weak; otherwise, returns 0. fn weak_key_test(key: &[u8; 8]) -> u8 { let key = u64::from_ne_bytes(*key); let mut is_weak = 0u8; - for &weak_key in crate::consts::WEAK_KEYS { is_weak |= u8::from(key == weak_key); } diff --git a/des/src/tdes.rs b/des/src/tdes.rs index 73a1d06b..16b242ed 100644 --- a/des/src/tdes.rs +++ b/des/src/tdes.rs @@ -25,10 +25,9 @@ fn weak_key_test(key: &[u8]) -> Result<(), WeakKeyError> { is_weak |= super::weak_key_test(des_key); } - if is_weak == 0 { - Ok(()) - } else { - Err(WeakKeyError) + match is_weak { + 0 => Ok(()), + _ => Err(WeakKeyError), } }