Skip to content

Commit 717c382

Browse files
authored
des: tweak weak key test (#468)
The new code results in a slightly better codegen while still being const time, including 32 bit targets: https://rust.godbolt.org/z/K7cjj5d1P
1 parent b40a003 commit 717c382

File tree

6 files changed

+103
-108
lines changed

6 files changed

+103
-108
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

des/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ categories = ["cryptography", "no-std"]
1414

1515
[dependencies]
1616
cipher = "=0.5.0-pre.7"
17-
subtle = { version = "2.6", default-features = false }
1817

1918
[dev-dependencies]
2019
cipher = { version = "=0.5.0-pre.7", features = ["dev"] }

des/src/consts.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,76 @@ pub const SBOXES: [[u8; 64]; 8] = [
5757
0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11,
5858
],
5959
];
60+
61+
macro_rules! as_ne_u64 {
62+
[$($key:expr,)*] => {
63+
[$(u64::from_ne_bytes($key),)*]
64+
};
65+
}
66+
67+
pub(crate) static WEAK_KEYS: &[u64; 64] = &as_ne_u64![
68+
[0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01],
69+
[0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE],
70+
[0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1],
71+
[0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E],
72+
[0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E],
73+
[0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01],
74+
[0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1],
75+
[0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01],
76+
[0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE],
77+
[0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01],
78+
[0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1],
79+
[0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E],
80+
[0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE],
81+
[0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E],
82+
[0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE],
83+
[0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1],
84+
[0x01, 0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E],
85+
[0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01, 0x01],
86+
[0xE0, 0xE0, 0x1F, 0x1F, 0xF1, 0xF1, 0x0E, 0x0E],
87+
[0x01, 0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1],
88+
[0x1F, 0x1F, 0xE0, 0xE0, 0x0E, 0x0E, 0xF1, 0xF1],
89+
[0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE, 0xFE],
90+
[0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE],
91+
[0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE, 0xFE],
92+
[0xE0, 0xFE, 0x01, 0x1F, 0xF1, 0xFE, 0x01, 0x0E],
93+
[0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01],
94+
[0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01, 0xFE],
95+
[0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E, 0x01],
96+
[0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE],
97+
[0x1F, 0xE0, 0xE0, 0x1F, 0x0E, 0xF1, 0xF1, 0x0E],
98+
[0xE0, 0xFE, 0xFE, 0xE0, 0xF1, 0xFE, 0xFE, 0xF1],
99+
[0x01, 0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1],
100+
[0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE, 0x01],
101+
[0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE],
102+
[0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE],
103+
[0x1F, 0xFE, 0x01, 0xE0, 0x0E, 0xFE, 0x01, 0xF1],
104+
[0xFE, 0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1],
105+
[0xFE, 0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E],
106+
[0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1, 0x01],
107+
[0xFE, 0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1],
108+
[0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01],
109+
[0x1F, 0xFE, 0xFE, 0x1F, 0x0E, 0xFE, 0xFE, 0x0E],
110+
[0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01],
111+
[0x01, 0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E],
112+
[0xE0, 0x01, 0x01, 0xE0, 0xF1, 0x01, 0x01, 0xF1],
113+
[0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE],
114+
[0x01, 0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1],
115+
[0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E, 0xFE],
116+
[0xFE, 0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E],
117+
[0x01, 0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E],
118+
[0xE0, 0x01, 0xFE, 0x1F, 0xF1, 0x01, 0xFE, 0x0E],
119+
[0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01],
120+
[0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01],
121+
[0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01, 0xFE],
122+
[0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE],
123+
[0x1F, 0x01, 0x01, 0x1F, 0x0E, 0x01, 0x01, 0x0E],
124+
[0xE0, 0x1F, 0x1F, 0xE0, 0xF1, 0x0E, 0x0E, 0xF1],
125+
[0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01],
126+
[0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1, 0xFE],
127+
[0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE, 0x01],
128+
[0xFE, 0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E],
129+
[0x1F, 0x01, 0xFE, 0xE0, 0x0E, 0x01, 0xFE, 0xF1],
130+
[0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01, 0x01],
131+
[0xFE, 0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1],
132+
];

des/src/des.rs

Lines changed: 3 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use cipher::{
1010
KeyInit, KeySizeUser, ParBlocksSizeUser,
1111
};
1212
use core::fmt;
13-
use subtle::{Choice, ConstantTimeEq};
1413

1514
#[cfg(feature = "zeroize")]
1615
use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
@@ -45,73 +44,6 @@ impl KeySizeUser for Des {
4544
type KeySize = U8;
4645
}
4746

48-
static WEAK_KEYS: [[u8; 8]; 64] = [
49-
[0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01],
50-
[0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE],
51-
[0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1],
52-
[0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E],
53-
[0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E],
54-
[0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01],
55-
[0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1],
56-
[0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01],
57-
[0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE],
58-
[0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01],
59-
[0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1],
60-
[0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E],
61-
[0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE],
62-
[0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E],
63-
[0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE],
64-
[0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1],
65-
[0x01, 0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E],
66-
[0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01, 0x01],
67-
[0xE0, 0xE0, 0x1F, 0x1F, 0xF1, 0xF1, 0x0E, 0x0E],
68-
[0x01, 0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1],
69-
[0x1F, 0x1F, 0xE0, 0xE0, 0x0E, 0x0E, 0xF1, 0xF1],
70-
[0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE, 0xFE],
71-
[0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE],
72-
[0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE, 0xFE],
73-
[0xE0, 0xFE, 0x01, 0x1F, 0xF1, 0xFE, 0x01, 0x0E],
74-
[0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01],
75-
[0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01, 0xFE],
76-
[0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E, 0x01],
77-
[0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE],
78-
[0x1F, 0xE0, 0xE0, 0x1F, 0x0E, 0xF1, 0xF1, 0x0E],
79-
[0xE0, 0xFE, 0xFE, 0xE0, 0xF1, 0xFE, 0xFE, 0xF1],
80-
[0x01, 0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1],
81-
[0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE, 0x01],
82-
[0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE],
83-
[0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE],
84-
[0x1F, 0xFE, 0x01, 0xE0, 0x0E, 0xFE, 0x01, 0xF1],
85-
[0xFE, 0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1],
86-
[0xFE, 0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E],
87-
[0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1, 0x01],
88-
[0xFE, 0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1],
89-
[0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01],
90-
[0x1F, 0xFE, 0xFE, 0x1F, 0x0E, 0xFE, 0xFE, 0x0E],
91-
[0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01],
92-
[0x01, 0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E],
93-
[0xE0, 0x01, 0x01, 0xE0, 0xF1, 0x01, 0x01, 0xF1],
94-
[0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE],
95-
[0x01, 0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1],
96-
[0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E, 0xFE],
97-
[0xFE, 0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E],
98-
[0x01, 0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E],
99-
[0xE0, 0x01, 0xFE, 0x1F, 0xF1, 0x01, 0xFE, 0x0E],
100-
[0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01],
101-
[0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01],
102-
[0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01, 0xFE],
103-
[0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE],
104-
[0x1F, 0x01, 0x01, 0x1F, 0x0E, 0x01, 0x01, 0x0E],
105-
[0xE0, 0x1F, 0x1F, 0xE0, 0xF1, 0x0E, 0x0E, 0xF1],
106-
[0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01],
107-
[0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1, 0xFE],
108-
[0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE, 0x01],
109-
[0xFE, 0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E],
110-
[0x1F, 0x01, 0xFE, 0xE0, 0x0E, 0x01, 0xFE, 0xF1],
111-
[0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01, 0x01],
112-
[0xFE, 0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1],
113-
];
114-
11547
impl KeyInit for Des {
11648
#[inline]
11749
fn new(key: &Key<Self>) -> Self {
@@ -121,16 +53,9 @@ impl KeyInit for Des {
12153

12254
#[inline]
12355
fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
124-
let mut weak = Choice::from(0);
125-
126-
for weak_key in &WEAK_KEYS {
127-
weak |= key.ct_eq(weak_key);
128-
}
129-
130-
if weak.unwrap_u8() == 0 {
131-
Ok(())
132-
} else {
133-
Err(WeakKeyError)
56+
match super::weak_key_test(&key.0) {
57+
0 => Ok(()),
58+
_ => Err(WeakKeyError),
13459
}
13560
}
13661
}

des/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,15 @@ mod utils;
3030

3131
pub use crate::des::Des;
3232
pub use crate::tdes::{TdesEde2, TdesEde3, TdesEee2, TdesEee3};
33+
34+
/// Checks whether the key is weak.
35+
///
36+
/// Returns 1 if the key is weak; otherwise, returns 0.
37+
fn weak_key_test(key: &[u8; 8]) -> u8 {
38+
let key = u64::from_ne_bytes(*key);
39+
let mut is_weak = 0u8;
40+
for &weak_key in crate::consts::WEAK_KEYS {
41+
is_weak |= u8::from(key == weak_key);
42+
}
43+
is_weak
44+
}

des/src/tdes.rs

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,23 @@ use cipher::{
1212
use core::fmt;
1313

1414
#[cfg(feature = "zeroize")]
15-
use cipher::zeroize::{ZeroizeOnDrop, Zeroizing};
15+
use cipher::zeroize::ZeroizeOnDrop;
1616

1717
#[inline]
18-
fn weak_key_test<const SIZE: usize, U: KeyInit>(key: &Key<U>) -> Result<(), WeakKeyError> {
19-
#[cfg(feature = "zeroize")]
20-
let mut tmp = Zeroizing::new(Key::<U>::default());
21-
#[cfg(not(feature = "zeroize"))]
22-
let mut tmp = Key::<U>::default();
18+
fn weak_key_test(key: &[u8]) -> Result<(), WeakKeyError> {
19+
let sub_key_size = <Des as KeySizeUser>::KeySize::USIZE;
20+
assert_eq!(key.len() % sub_key_size, 0);
2321

24-
for i in 0..<U as KeySizeUser>::KeySize::USIZE {
25-
// count number of set bits in byte, excluding the low-order bit - SWAR method
26-
let mut c = key[i] & 0xFE;
27-
28-
c = (c & 0x55) + ((c >> 1) & 0x55);
29-
c = (c & 0x33) + ((c >> 2) & 0x33);
30-
c = (c & 0x0F) + ((c >> 4) & 0x0F);
31-
32-
// if count is even, set low key bit to 1, otherwise 0
33-
tmp[i] = (key[i] & 0xFE) | u8::from(c & 0x01 != 0x01);
22+
let mut is_weak = 0u8;
23+
for des_key in key.chunks_exact(sub_key_size) {
24+
let des_key = des_key.try_into().unwrap();
25+
is_weak |= super::weak_key_test(des_key);
3426
}
3527

36-
let mut des_key = Key::<Des>::default();
37-
for i in 0..SIZE {
38-
des_key.copy_from_slice(
39-
&tmp.as_slice()[i * <Des as KeySizeUser>::KeySize::USIZE
40-
..(i + 1) * <Des as KeySizeUser>::KeySize::USIZE],
41-
);
42-
Des::weak_key_test(&des_key)?;
28+
match is_weak {
29+
0 => Ok(()),
30+
_ => Err(WeakKeyError),
4331
}
44-
Ok(())
4532
}
4633

4734
/// Triple DES (3DES) block cipher.
@@ -70,7 +57,7 @@ impl KeyInit for TdesEde3 {
7057

7158
#[inline]
7259
fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
73-
weak_key_test::<3, Self>(key)
60+
weak_key_test(key)
7461
}
7562
}
7663

@@ -159,7 +146,7 @@ impl KeyInit for TdesEee3 {
159146

160147
#[inline]
161148
fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
162-
weak_key_test::<3, Self>(key)
149+
weak_key_test(key)
163150
}
164151
}
165152

@@ -245,7 +232,7 @@ impl KeyInit for TdesEde2 {
245232

246233
#[inline]
247234
fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
248-
weak_key_test::<2, Self>(key)
235+
weak_key_test(key)
249236
}
250237
}
251238

@@ -331,7 +318,7 @@ impl KeyInit for TdesEee2 {
331318

332319
#[inline]
333320
fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
334-
weak_key_test::<2, Self>(key)
321+
weak_key_test(key)
335322
}
336323
}
337324

0 commit comments

Comments
 (0)