From b4be1bb21640397429fec036c577106938ffe9a1 Mon Sep 17 00:00:00 2001 From: "Tony Arcieri (iqlusion)" Date: Wed, 13 Aug 2025 15:36:53 -0600 Subject: [PATCH] mgm: use `TdesEde3::weak_key_test` (#621) Replaces the vendored weak key test with the upstream one from the `des` crate which was added in RustCrypto/block-ciphers#465 --- src/mgm.rs | 12 +++++---- src/mgm/tdes.rs | 70 ------------------------------------------------- 2 files changed, 7 insertions(+), 75 deletions(-) delete mode 100644 src/mgm/tdes.rs diff --git a/src/mgm.rs b/src/mgm.rs index 9740bd2..ee857d0 100644 --- a/src/mgm.rs +++ b/src/mgm.rs @@ -70,12 +70,14 @@ pub(crate) const APPLET_NAME: &str = "YubiKey MGMT"; #[cfg(feature = "untested")] pub(crate) const APPLET_ID: &[u8] = &[0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17]; -mod tdes; -pub(crate) use tdes::DES_LEN_3DES; -use tdes::DES_LEN_DES; - pub(crate) const ADMIN_FLAGS_1_PROTECTED_MGM: u8 = 0x02; +/// Size of a DES key +pub(super) const DES_LEN_DES: usize = 8; + +/// Size of a 3DES key +pub(crate) const DES_LEN_3DES: usize = DES_LEN_DES * 3; + #[cfg(feature = "untested")] const CB_ADMIN_SALT: usize = 16; @@ -172,7 +174,7 @@ impl MgmKey { /// /// Returns an error if the key is weak. pub fn new(key_bytes: [u8; DES_LEN_3DES]) -> Result { - if tdes::is_weak_key(&key_bytes) { + if TdesEde3::weak_key_test(key_bytes.as_ref()).is_err() { error!( "blacklisting key '{:?}' since it's weak (with odd parity)", &key_bytes diff --git a/src/mgm/tdes.rs b/src/mgm/tdes.rs deleted file mode 100644 index ba1105b..0000000 --- a/src/mgm/tdes.rs +++ /dev/null @@ -1,70 +0,0 @@ -use zeroize::Zeroizing; - -/// Size of a DES key -pub(super) const DES_LEN_DES: usize = 8; - -/// Size of a 3DES key -pub(crate) const DES_LEN_3DES: usize = DES_LEN_DES * 3; - -/// Weak and semi weak DES keys as taken from: -/// %A D.W. Davies -/// %A W.L. Price -/// %T Security for Computer Networks -/// %I John Wiley & Sons -/// %D 1984 -const WEAK_DES_KEYS: &[[u8; DES_LEN_DES]] = &[ - // weak keys - [0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01], - [0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE], - [0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E], - [0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1], - // semi-weak keys - [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], - [0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1], - [0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01], - [0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE], - [0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E], - [0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E], - [0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01], - [0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE], - [0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1], -]; - -/// Is this 3DES key weak? -/// -/// This check is performed automatically when the key is instantiated to -/// ensure no such keys are used. -pub(super) fn is_weak_key(key: &[u8; DES_LEN_3DES]) -> bool { - // set odd parity of key - let mut tmp = Zeroizing::new([0u8; DES_LEN_3DES]); - - for i in 0..DES_LEN_3DES { - // 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); - } - - // check odd parity key against table by DES key block - let mut is_weak = false; - - for weak_key in WEAK_DES_KEYS.iter() { - if weak_key == &tmp[0..DES_LEN_DES] - || weak_key == &tmp[DES_LEN_DES..2 * DES_LEN_DES] - || weak_key == &tmp[2 * DES_LEN_DES..3 * DES_LEN_DES] - { - is_weak = true; - break; - } - } - - is_weak -}