Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions des/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
73 changes: 0 additions & 73 deletions des/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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],
];
10 changes: 0 additions & 10 deletions des/src/des.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use cipher::{
BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, InOut, Key,
KeyInit, KeySizeUser, ParBlocksSizeUser,
consts::{U1, U8},
crypto_common::WeakKeyError,
};
use core::fmt;

Expand Down Expand Up @@ -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<Self>) -> Result<(), WeakKeyError> {
let key = u64::from_ne_bytes(key.0);
match super::weak_key_test(key) {
0 => Ok(()),
_ => Err(WeakKeyError),
}
}
}

impl BlockSizeUser for Des {
Expand Down
13 changes: 2 additions & 11 deletions des/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
57 changes: 0 additions & 57 deletions des/src/tdes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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<Self>) -> Result<(), WeakKeyError> {
weak_key_test3(&key.0)
}
}

impl BlockSizeUser for TdesEde3 {
Expand Down Expand Up @@ -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<Self>) -> Result<(), WeakKeyError> {
weak_key_test3(&key.0)
}
}

impl BlockSizeUser for TdesEee3 {
Expand Down Expand Up @@ -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<Self>) -> Result<(), WeakKeyError> {
weak_key_test2(&key.0)
}
}

impl BlockSizeUser for TdesEde2 {
Expand Down Expand Up @@ -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<Self>) -> Result<(), WeakKeyError> {
weak_key_test2(&key.0)
}
}

impl BlockSizeUser for TdesEee2 {
Expand Down
130 changes: 130 additions & 0 deletions des/src/weak_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
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 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),
}
}

/// 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],
];
Loading