Skip to content

Commit ddd0b2f

Browse files
committed
Narrow provider contract hardening scope
1 parent eda00c3 commit ddd0b2f

4 files changed

Lines changed: 17 additions & 39 deletions

File tree

src/aead.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use windows::Win32::Security::Cryptography::{
1212
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION, BCRYPT_CHACHA20_POLY1305_ALG_HANDLE,
1313
BCRYPT_FLAGS, BCRYPT_KEY_HANDLE,
1414
};
15-
use zeroize::Zeroizing;
1615

1716
/// The tag length is 16 bytes for all supported ciphers.
1817
pub(crate) const TAG_LEN: usize = 16;
@@ -114,13 +113,14 @@ impl AeadKey {
114113
..Default::default()
115114
};
116115

117-
let input = Zeroizing::new(data.to_vec());
118116
unsafe {
117+
// SAFETY: CNG supports in-place encryption, so the input and output buffers can be the same.
119118
let mut size = 0u32;
119+
let input = std::slice::from_raw_parts(data.as_ptr().cast(), data.len());
120120

121121
BCryptEncrypt(
122122
*self.handle,
123-
Some(input.as_slice()),
123+
Some(input),
124124
Some(std::ptr::from_ref(&info) as *mut _),
125125
None,
126126
Some(data),
@@ -161,11 +161,14 @@ impl AeadKey {
161161

162162
let mut size = 0u32;
163163

164-
let input = ciphertext.to_vec();
165164
unsafe {
165+
// SAFETY: CNG supports in-place decryption, so the input and output buffers can be the same.
166+
167+
let input = std::slice::from_raw_parts(ciphertext.as_ptr().cast(), ciphertext.len());
168+
166169
BCryptDecrypt(
167170
*self.handle,
168-
Some(&input),
171+
Some(input),
169172
Some(std::ptr::from_ref(&info) as *mut _),
170173
None,
171174
Some(ciphertext),

src/keys.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use windows::{
1616
BCRYPT_RSAPUBLIC_MAGIC, BCRYPT_RSA_ALG_HANDLE,
1717
},
1818
};
19-
use zeroize::Zeroizing;
2019

2120
/// Wrapper for an owned key handle that can be sent between threads.
2221
#[derive(Debug)]
@@ -48,7 +47,7 @@ pub(crate) fn import_rsa_private_key(
4847
+ prime1.len()
4948
+ prime2.len();
5049

51-
let mut blob = Zeroizing::new(Vec::with_capacity(size));
50+
let mut blob = Vec::with_capacity(size);
5251
unsafe {
5352
let p: *const BCRYPT_RSAKEY_BLOB = &header;
5453
let p: *const u8 = p.cast::<u8>();
@@ -68,7 +67,7 @@ pub(crate) fn import_rsa_private_key(
6867
None,
6968
BCRYPT_RSAPRIVATE_BLOB,
7069
&mut *key_handle,
71-
blob.as_slice(),
70+
&blob,
7271
0,
7372
)
7473
.ok()
@@ -147,14 +146,14 @@ fn import_ec_private_key(
147146
cbKey: key_len as u32,
148147
};
149148
let header_size = core::mem::size_of::<BCRYPT_ECCKEY_BLOB>();
150-
let mut blob = Zeroizing::new(Vec::with_capacity(header_size + key_len * 3));
149+
let mut blob = Vec::with_capacity(header_size + key_len * 3);
151150
unsafe {
152151
let p: *const BCRYPT_ECCKEY_BLOB = &header;
153152
let p: *const u8 = p.cast::<u8>();
154153
let slice = std::slice::from_raw_parts(p, header_size);
155154
blob.extend_from_slice(slice);
156155
}
157-
blob.extend(std::iter::repeat_n(0, key_len * 2));
156+
blob.extend_from_slice(&vec![0u8; key_len * 2]);
158157
blob.extend_from_slice(private_key);
159158
let mut key_handle = Owned::default();
160159
unsafe {
@@ -163,7 +162,7 @@ fn import_ec_private_key(
163162
None,
164163
BCRYPT_ECCPRIVATE_BLOB,
165164
&mut *key_handle,
166-
blob.as_slice(),
165+
&blob,
167166
0,
168167
)
169168
.ok()

src/tls12.rs

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,6 @@ use rustls::{
2020

2121
const GCM_EXPLICIT_NONCE_LENGTH: usize = 8;
2222
const GCM_IMPLICIT_NONCE_LENGTH: usize = 4;
23-
const MAX_TLS12_PLAINTEXT_FRAGMENT_LEN: usize = 16_384;
24-
25-
fn reject_oversized_tls12_plaintext(plaintext_len: usize) -> Result<(), Error> {
26-
if plaintext_len > MAX_TLS12_PLAINTEXT_FRAGMENT_LEN {
27-
return Err(Error::PeerSentOversizedRecord);
28-
}
29-
30-
Ok(())
31-
}
3223

3324
static ECDSA_SCHEMES: &[SignatureScheme] = &[
3425
SignatureScheme::ECDSA_NISTP521_SHA512,
@@ -290,7 +281,6 @@ impl MessageDecrypter for AesGcmDecrypter {
290281
&aad,
291282
&mut payload.as_mut()[GCM_EXPLICIT_NONCE_LENGTH..],
292283
)?;
293-
reject_oversized_tls12_plaintext(plaintext_len)?;
294284

295285
// Remove the explicit nonce from the front of the buffer, as it's not part of the plaintext.
296286
payload.copy_within(
@@ -344,7 +334,6 @@ impl MessageDecrypter for ChaCha20Poly1305Crypter {
344334
tag.copy_from_slice(&payload[message_len..]);
345335

346336
let plaintext_len = self.key.open(nonce.0, &aad, payload)?;
347-
reject_oversized_tls12_plaintext(plaintext_len)?;
348337
payload.truncate(plaintext_len);
349338
Ok(msg.into_plain_message())
350339
}
@@ -358,20 +347,4 @@ mod tests {
358347
fn tls12_ecdsa_sign_schemes_do_not_advertise_ed25519() {
359348
assert!(!ECDSA_SCHEMES.contains(&SignatureScheme::ED25519));
360349
}
361-
362-
#[test]
363-
fn aes_gcm_decrypter_rejects_oversized_plaintext() {
364-
assert!(matches!(
365-
reject_oversized_tls12_plaintext(MAX_TLS12_PLAINTEXT_FRAGMENT_LEN + 1),
366-
Err(Error::PeerSentOversizedRecord)
367-
));
368-
}
369-
370-
#[test]
371-
fn chacha20_poly1305_decrypter_rejects_oversized_plaintext() {
372-
assert!(matches!(
373-
reject_oversized_tls12_plaintext(MAX_TLS12_PLAINTEXT_FRAGMENT_LEN + 1),
374-
Err(Error::PeerSentOversizedRecord)
375-
));
376-
}
377350
}

src/verify.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,10 @@ impl<const HASH_SIZE: usize> SignatureVerificationAlgorithm for VerificationAlgo
327327
BCRYPT_PAD_PSS,
328328
)
329329
.ok()
330-
.map_err(|_| InvalidSignature)
330+
.map_err(|e| {
331+
dbg!(e);
332+
InvalidSignature
333+
})
331334
}
332335
}
333336
}

0 commit comments

Comments
 (0)