Skip to content

Commit d4f259c

Browse files
achimccbrycx
andauthored
Make Zeroization Optional (#592)
* introduce feature zeroize * use zeroize_wrap macro * implement feedback from PR * ci: Add zeroize-only featureset test * Fix compiler warnings for unused imports and needless mut assignments --------- Co-authored-by: brycx <brycx@protonmail.com>
1 parent b3bb8b0 commit d4f259c

31 files changed

+237
-108
lines changed

.github/workflows/test.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ jobs:
6060
- name: Test debug-mode, no-default + serde feature (enables alloc)
6161
run: cargo test --no-default-features --features serde --tests
6262

63+
- name: Test debug-mode, no-default + safe_api (without zeroize)
64+
run: cargo test --no-default-features --features safe_api --tests
65+
66+
- name: Test debug-mode, no-default + zeroize (zeroize-only)
67+
run: cargo test --no-default-features --features zeroize --tests
68+
6369
- name: Test release-mode, default features
6470
run: cargo test --release
6571

@@ -75,6 +81,12 @@ jobs:
7581
- name: Test release-mode, no-default + serde feature (enables alloc)
7682
run: cargo test --release --no-default-features --features serde --tests
7783

84+
- name: Test release-mode, no-default + safe_api (without zeroize)
85+
run: cargo test --release --no-default-features --features safe_api --tests
86+
87+
- name: Test release-mode, no-default + zeroize (zeroize-only)
88+
run: cargo test --release --no-default-features --features zeroize --tests
89+
7890
sanitizers:
7991
name: Tests w. sanitizers
8092
runs-on: ubuntu-latest

Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description = "Usable, easy and safe pure-Rust crypto"
66
keywords = ["cryptography", "crypto", "aead", "pqc", "kem"]
77
categories = ["cryptography", "no-std"]
88
edition = "2021"
9-
rust-version = "1.86" # Update CI (MSRV) test + README along with this.
9+
rust-version = "1.86" # Update CI (MSRV) test + README along with this.
1010
readme = "README.md"
1111
repository = "https://github.com/orion-rs/orion"
1212
documentation = "https://docs.rs/orion"
@@ -15,7 +15,7 @@ exclude = [".gitignore", ".travis.yml", "tests/*"]
1515

1616
[dependencies]
1717
subtle = { version = "^2.2.2", default-features = false }
18-
zeroize = { version = "1.1.0", default-features = false }
18+
zeroize = { version = "1.1.0", optional = true, default-features = false }
1919
fiat-crypto = { version = "0.3.0", default-features = false }
2020
getrandom = { version = "0.3.0", optional = true }
2121
ct-codecs = { version = "1.1.1", optional = true }
@@ -27,8 +27,9 @@ default-features = false
2727
features = ["alloc"]
2828

2929
[features]
30-
default = ["safe_api"]
31-
safe_api = ["getrandom", "ct-codecs"]
30+
default = ["safe_api", "zeroize"]
31+
zeroize = ["dep:zeroize"]
32+
safe_api = ["getrandom", "ct-codecs", "zeroize?/alloc"]
3233
alloc = []
3334
serde = ["dep:serde", "alloc"]
3435
experimental = []

src/hazardous/aead/chacha20poly1305.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
//! [`C_MAX`]: chacha20poly1305::C_MAX
112112
113113
pub use crate::hazardous::stream::chacha20::{Nonce, SecretKey};
114+
use crate::ZeroizeWrap;
114115
use crate::{
115116
errors::UnknownCryptoError,
116117
hazardous::{
@@ -120,7 +121,6 @@ use crate::{
120121
util,
121122
};
122123
use core::convert::TryInto;
123-
use zeroize::Zeroizing;
124124

125125
/// The initial counter used for encryption and decryption.
126126
pub(crate) const ENC_CTR: u32 = 1;
@@ -140,7 +140,7 @@ pub const A_MAX: u64 = u64::MAX;
140140
/// Poly1305 key generation using IETF ChaCha20.
141141
pub(crate) fn poly1305_key_gen(
142142
ctx: &mut ChaCha20,
143-
tmp_buffer: &mut Zeroizing<[u8; CHACHA_BLOCKSIZE]>,
143+
tmp_buffer: &mut ZeroizeWrap<[u8; CHACHA_BLOCKSIZE]>,
144144
) -> OneTimeKey {
145145
ctx.keystream_block(AUTH_CTR, tmp_buffer.as_mut());
146146
OneTimeKey::from_slice(&tmp_buffer[..POLY1305_KEYSIZE]).unwrap()
@@ -196,7 +196,7 @@ pub fn seal(
196196

197197
let mut stream =
198198
ChaCha20::new(secret_key.unprotected_as_bytes(), nonce.as_ref(), true).unwrap();
199-
let mut tmp = Zeroizing::new([0u8; CHACHA_BLOCKSIZE]);
199+
let mut tmp = zeroize_wrap!([0u8; CHACHA_BLOCKSIZE]);
200200

201201
let mut auth_ctx = Poly1305::new(&poly1305_key_gen(&mut stream, &mut tmp));
202202
let ad_len = ad.len();
@@ -285,7 +285,7 @@ pub fn open(
285285

286286
let mut dec_ctx =
287287
ChaCha20::new(secret_key.unprotected_as_bytes(), nonce.as_ref(), true).unwrap();
288-
let mut tmp = Zeroizing::new([0u8; CHACHA_BLOCKSIZE]);
288+
let mut tmp = zeroize_wrap!([0u8; CHACHA_BLOCKSIZE]);
289289
let mut auth_ctx = Poly1305::new(&poly1305_key_gen(&mut dec_ctx, &mut tmp));
290290

291291
let ciphertext_len = ciphertext_with_tag.len() - POLY1305_OUTSIZE;
@@ -355,7 +355,7 @@ mod test_vectors {
355355

356356
let mut chacha20_ctx =
357357
ChaCha20::new(key.unprotected_as_bytes(), nonce.as_ref(), true).unwrap();
358-
let mut tmp_block = Zeroizing::new([0u8; CHACHA_BLOCKSIZE]);
358+
let mut tmp_block = zeroize_wrap!([0u8; CHACHA_BLOCKSIZE]);
359359

360360
assert_eq!(
361361
poly1305_key_gen(&mut chacha20_ctx, &mut tmp_block).unprotected_as_bytes(),
@@ -383,7 +383,7 @@ mod test_vectors {
383383

384384
let mut chacha20_ctx =
385385
ChaCha20::new(key.unprotected_as_bytes(), nonce.as_ref(), true).unwrap();
386-
let mut tmp_block = Zeroizing::new([0u8; CHACHA_BLOCKSIZE]);
386+
let mut tmp_block = zeroize_wrap!([0u8; CHACHA_BLOCKSIZE]);
387387

388388
assert_eq!(
389389
poly1305_key_gen(&mut chacha20_ctx, &mut tmp_block).unprotected_as_bytes(),
@@ -411,7 +411,7 @@ mod test_vectors {
411411

412412
let mut chacha20_ctx =
413413
ChaCha20::new(key.unprotected_as_bytes(), nonce.as_ref(), true).unwrap();
414-
let mut tmp_block = Zeroizing::new([0u8; CHACHA_BLOCKSIZE]);
414+
let mut tmp_block = zeroize_wrap!([0u8; CHACHA_BLOCKSIZE]);
415415

416416
assert_eq!(
417417
poly1305_key_gen(&mut chacha20_ctx, &mut tmp_block).unprotected_as_bytes(),

src/hazardous/aead/streaming.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ use crate::hazardous::stream::xchacha20::subkey_and_nonce;
114114
pub use crate::hazardous::stream::xchacha20::Nonce;
115115
use core::convert::TryFrom;
116116
use subtle::ConstantTimeEq;
117-
use zeroize::{Zeroize, Zeroizing};
118117

119118
#[derive(Debug, Clone, Copy)]
120119
/// Tag that indicates the type of message.
@@ -233,7 +232,7 @@ impl StreamXChaCha20Poly1305 {
233232
true,
234233
)
235234
.unwrap();
236-
let mut tmp_block = Zeroizing::new([0u8; CHACHA_BLOCKSIZE]);
235+
let mut tmp_block = zeroize_wrap!([0u8; CHACHA_BLOCKSIZE]);
237236

238237
let mut pad = [0u8; 16];
239238
let mut poly = Poly1305::new(&poly1305_key_gen(&mut chacha20_ctx, &mut tmp_block));
@@ -297,7 +296,7 @@ impl StreamXChaCha20Poly1305 {
297296
self.inonce
298297
.copy_from_slice(&new_key_and_inonce[CHACHA_KEYSIZE..]);
299298
self.counter = 1;
300-
new_key_and_inonce.zeroize();
299+
zeroize_call!(new_key_and_inonce);
301300

302301
Ok(())
303302
}

src/hazardous/cae/chacha20poly1305blake2b.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ use crate::hazardous::mac::poly1305::Poly1305;
126126
use crate::hazardous::mac::poly1305::POLY1305_OUTSIZE;
127127
use crate::hazardous::stream::chacha20::{self, ChaCha20, CHACHA_BLOCKSIZE};
128128
use crate::util;
129-
use zeroize::Zeroizing;
130129

131130
pub use crate::hazardous::aead::chacha20poly1305::A_MAX;
132131
pub use crate::hazardous::aead::chacha20poly1305::P_MAX;
@@ -217,7 +216,7 @@ pub fn open(
217216

218217
let mut dec_ctx =
219218
ChaCha20::new(secret_key.unprotected_as_bytes(), nonce.as_ref(), true).unwrap();
220-
let mut tmp = Zeroizing::new([0u8; CHACHA_BLOCKSIZE]);
219+
let mut tmp = zeroize_wrap!([0u8; CHACHA_BLOCKSIZE]);
221220
let mut auth_ctx = Poly1305::new(&poly1305_key_gen(&mut dec_ctx, &mut tmp));
222221

223222
let ciphertext_len = ciphertext_with_tag.len() - TAG_SIZE;

src/hazardous/cae/xchacha20poly1305blake2b.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ use crate::hazardous::stream::chacha20::{self, ChaCha20, CHACHA_BLOCKSIZE};
118118
use crate::hazardous::stream::xchacha20::subkey_and_nonce;
119119
pub use crate::hazardous::stream::{chacha20::SecretKey, xchacha20::Nonce};
120120
use crate::util;
121-
use zeroize::Zeroizing;
122121

123122
#[must_use = "SECURITY WARNING: Ignoring a Result can have real security implications."]
124123
/// CTX XChaCha20Poly1305 with BLAKE2b-256.
@@ -201,7 +200,7 @@ pub fn open(
201200
let (subkey, ietf_nonce) = subkey_and_nonce(secret_key, nonce);
202201
let mut dec_ctx =
203202
ChaCha20::new(subkey.unprotected_as_bytes(), ietf_nonce.as_ref(), true).unwrap();
204-
let mut tmp = Zeroizing::new([0u8; CHACHA_BLOCKSIZE]);
203+
let mut tmp = zeroize_wrap!([0u8; CHACHA_BLOCKSIZE]);
205204
let mut auth_ctx = Poly1305::new(&poly1305_key_gen(&mut dec_ctx, &mut tmp));
206205

207206
let ciphertext_len = ciphertext_with_tag.len() - TAG_SIZE;

src/hazardous/ecc/x25519.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ impl FieldElement {
301301
/// Represents a Scalar decoded from a byte array.
302302
struct Scalar([u8; PRIVATE_KEY_SIZE]);
303303

304+
#[cfg(feature = "zeroize")]
304305
impl Drop for Scalar {
305306
fn drop(&mut self) {
306307
use zeroize::Zeroize;

src/hazardous/hash/blake2/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ pub(crate) mod blake2b_core {
128128
pub(crate) size: usize,
129129
}
130130

131+
#[cfg(feature = "zeroize")]
131132
impl Drop for State {
132133
fn drop(&mut self) {
133134
use zeroize::Zeroize;

src/hazardous/hash/sha2/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,19 @@ pub(crate) mod sha2_core {
3434
use core::fmt::Debug;
3535
use core::marker::PhantomData;
3636
use core::ops::*;
37+
#[cfg(feature = "zeroize")]
3738
use zeroize::Zeroize;
3839

40+
#[cfg(feature = "zeroize")]
41+
pub(crate) trait MaybeZeroize: Zeroize {}
42+
#[cfg(feature = "zeroize")]
43+
impl<T: Zeroize> MaybeZeroize for T {}
44+
45+
#[cfg(not(feature = "zeroize"))]
46+
pub(crate) trait MaybeZeroize {}
47+
#[cfg(not(feature = "zeroize"))]
48+
impl<T> MaybeZeroize for T {}
49+
3950
/// Word used within the SHA2 internal state.
4051
pub(crate) trait Word:
4152
Sized
@@ -49,7 +60,7 @@ pub(crate) mod sha2_core {
4960
+ Copy
5061
+ Debug
5162
+ PartialEq<Self>
52-
+ Zeroize
63+
+ MaybeZeroize
5364
{
5465
#[cfg(any(debug_assertions, test))]
5566
const MAX: Self;
@@ -136,6 +147,7 @@ pub(crate) mod sha2_core {
136147
pub(crate) is_finalized: bool,
137148
}
138149

150+
#[cfg(feature = "zeroize")]
139151
impl<
140152
W: Word,
141153
T: Variant<W, { N_CONSTS }>,
@@ -411,11 +423,13 @@ pub(crate) mod sha2_core {
411423
pub(crate) mod w32 {
412424
use core::convert::{From, TryFrom, TryInto};
413425
use core::ops::*;
426+
#[cfg(feature = "zeroize")]
414427
use zeroize::Zeroize;
415428

416429
#[derive(Debug, PartialEq, Copy, Clone, Default)]
417430
pub(crate) struct WordU32(pub(crate) u32);
418431

432+
#[cfg(feature = "zeroize")]
419433
impl Zeroize for WordU32 {
420434
fn zeroize(&mut self) {
421435
self.0.zeroize();
@@ -554,11 +568,13 @@ pub(crate) mod w32 {
554568
pub(crate) mod w64 {
555569
use core::convert::{From, TryFrom, TryInto};
556570
use core::ops::*;
571+
#[cfg(feature = "zeroize")]
557572
use zeroize::Zeroize;
558573

559574
#[derive(Debug, PartialEq, Copy, Clone, Default)]
560575
pub(crate) struct WordU64(pub(crate) u64);
561576

577+
#[cfg(feature = "zeroize")]
562578
impl Zeroize for WordU64 {
563579
fn zeroize(&mut self) {
564580
self.0.zeroize();

src/hazardous/hash/sha3/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub mod shake256;
4040

4141
use crate::errors::UnknownCryptoError;
4242
use core::fmt::Debug;
43+
#[cfg(feature = "zeroize")]
4344
use zeroize::Zeroize;
4445

4546
/// Round constants. See NIST intermediate test vectors for source.
@@ -401,6 +402,7 @@ pub(crate) struct Sha3<const RATE: usize> {
401402
is_finalized: bool,
402403
}
403404

405+
#[cfg(feature = "zeroize")]
404406
impl<const RATE: usize> Drop for Sha3<RATE> {
405407
fn drop(&mut self) {
406408
self.state.iter_mut().zeroize();
@@ -597,6 +599,7 @@ pub(crate) struct Shake<const RATE: usize> {
597599
is_finalized: bool,
598600
}
599601

602+
#[cfg(feature = "zeroize")]
600603
impl<const RATE: usize> Drop for Shake<RATE> {
601604
fn drop(&mut self) {
602605
self.state.iter_mut().zeroize();

0 commit comments

Comments
 (0)