Make zeroize an optional dependency (#481)

* Make `zeroize` an optional dependency

The `zeroize` crate provides a defense against memory read oracles which
typically arise from memory unsafety.

Pure Rust programs may not benefit from `zeroize`, and in certain cases
the unsafe code used by `zeroize` may be more concerning.

This commit makes `zeroize` into an optional feature so users may elect
to disable it if they so desire.

* Added zeroize feature flag to README

Co-authored-by: Michael Rosenberg <michael@mrosenberg.pub>
This commit is contained in:
Tony Arcieri 2022-12-26 14:19:55 -07:00 committed by GitHub
parent 06186b8511
commit 39dbaea6f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 36 additions and 7 deletions

View file

@ -28,6 +28,7 @@ jobs:
- run: rustup target add ${{ matrix.target }}
- run: ${{ matrix.deps }}
- run: cargo test --target ${{ matrix.target }} --no-default-features
- run: cargo test --target ${{ matrix.target }} --no-default-features --features zeroize
- run: cargo test --target ${{ matrix.target }}
- run: cargo test --target ${{ matrix.target }} --features serde
- env:

View file

@ -57,7 +57,7 @@ rand_core = { version = "0.6.4", default-features = false, optional = true }
digest = { version = "0.10", default-features = false, optional = true }
subtle = { version = "2.3.0", default-features = false }
serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] }
zeroize = { version = "1", default-features = false }
zeroize = { version = "1", default-features = false, optional = true }
[target.'cfg(curve25519_dalek_backend = "fiat")'.dependencies]
fiat-crypto = "0.1.6"
@ -68,8 +68,8 @@ fiat-crypto = "0.1.6"
packed_simd = { version = "0.3.4", package = "packed_simd_2", features = ["into_bits"] }
[features]
default = ["alloc"]
alloc = ["zeroize/alloc"]
default = ["alloc", "zeroize"]
alloc = ["zeroize/alloc"] # TODO: use weak feature activation
[profile.dev]
opt-level = 2

View file

@ -50,7 +50,8 @@ curve25519-dalek = "4.0.0-pre.5"
| Feature | Default? | Description |
| :--- | :---: | :--- |
| `alloc` | ✓ | Enables Edwards and Ristretto multiscalar multiplication, batch scalar inversion, and batch Ristretto double-and-compress. |
| `alloc` | ✓ | Enables Edwards and Ristretto multiscalar multiplication, batch scalar inversion, and batch Ristretto double-and-compress. Also enables `zeroize`. |
| `zeroize` | ✓ | Enables [`Zeroize`][zeroize-trait] for all scalar and curve point types. |
| `rand_core` | | Enables `Scalar::random` and `RistrettoPoint::random`. This is an optional dependency whose version is not subject to SemVer. See [below](#public-api-semver-exemptions) for more details. |
| `digest` | | Enables `RistrettoPoint::{from_hash, hash_from_bytes}` and `Scalar::{from_hash, hash_from_bytes}`. This is an optional dependency whose version is not subject to SemVer. See [below](#public-api-semver-exemptions) for more details. |
| `serde` | | Enables `serde` serialization/deserialization for all the point and scalar types. |
@ -320,3 +321,4 @@ contributions.
[fiat-crypto]: https://github.com/mit-plv/fiat-crypto
[semver]: https://semver.org/spec/v2.0.0.html
[rngcorestd]: https://github.com/rust-random/rand/tree/7aa25d577e2df84a5156f824077bb7f6bdf28d97/rand_core#crate-features
[zeroize-trait]: https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html

View file

@ -129,6 +129,7 @@ use core::ops::{Add, Neg, Sub};
use subtle::Choice;
use subtle::ConditionallySelectable;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use crate::constants;
@ -186,6 +187,7 @@ pub struct AffineNielsPoint {
pub xy2d: FieldElement,
}
#[cfg(feature = "zeroize")]
impl Zeroize for AffineNielsPoint {
fn zeroize(&mut self) {
self.y_plus_x.zeroize();
@ -208,6 +210,7 @@ pub struct ProjectiveNielsPoint {
pub T2d: FieldElement,
}
#[cfg(feature = "zeroize")]
impl Zeroize for ProjectiveNielsPoint {
fn zeroize(&mut self) {
self.Y_plus_X.zeroize();

View file

@ -27,6 +27,7 @@ use core::ops::{Sub, SubAssign};
use subtle::Choice;
use subtle::ConditionallySelectable;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use fiat_crypto::curve25519_32::*;
@ -62,6 +63,7 @@ impl Debug for FieldElement2625 {
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for FieldElement2625 {
fn zeroize(&mut self) {
self.0.zeroize();

View file

@ -23,6 +23,7 @@ use core::ops::{Sub, SubAssign};
use subtle::Choice;
use subtle::ConditionallySelectable;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use fiat_crypto::curve25519_64::*;
@ -51,6 +52,7 @@ impl Debug for FieldElement51 {
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for FieldElement51 {
fn zeroize(&mut self) {
self.0.zeroize();

View file

@ -25,6 +25,7 @@ use core::ops::{Sub, SubAssign};
use subtle::Choice;
use subtle::ConditionallySelectable;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
/// A `FieldElement2625` represents an element of the field
@ -58,6 +59,7 @@ impl Debug for FieldElement2625 {
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for FieldElement2625 {
fn zeroize(&mut self) {
self.0.zeroize();

View file

@ -13,6 +13,7 @@
use core::fmt::Debug;
use core::ops::{Index, IndexMut};
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use crate::constants;
@ -27,6 +28,7 @@ impl Debug for Scalar29 {
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for Scalar29 {
fn zeroize(&mut self) {
self.0.zeroize();

View file

@ -21,6 +21,7 @@ use core::ops::{Sub, SubAssign};
use subtle::Choice;
use subtle::ConditionallySelectable;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
/// A `FieldElement51` represents an element of the field
@ -47,6 +48,7 @@ impl Debug for FieldElement51 {
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for FieldElement51 {
fn zeroize(&mut self) {
self.0.zeroize();

View file

@ -14,6 +14,7 @@
use core::fmt::Debug;
use core::ops::{Index, IndexMut};
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use crate::constants;
@ -29,6 +30,7 @@ impl Debug for Scalar52 {
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for Scalar52 {
fn zeroize(&mut self) {
self.0.zeroize();

View file

@ -109,6 +109,7 @@ use subtle::ConditionallyNegatable;
use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use crate::constants;
@ -388,6 +389,7 @@ impl Default for EdwardsPoint {
// Zeroize implementations for wiping points from memory
// ------------------------------------------------------------------------
#[cfg(feature = "zeroize")]
impl Zeroize for CompressedEdwardsY {
/// Reset this `CompressedEdwardsY` to the compressed form of the identity element.
fn zeroize(&mut self) {
@ -396,6 +398,7 @@ impl Zeroize for CompressedEdwardsY {
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for EdwardsPoint {
/// Reset this `CompressedEdwardsPoint` to the identity element.
fn zeroize(&mut self) {

View file

@ -65,6 +65,7 @@ use subtle::Choice;
use subtle::ConstantTimeEq;
use subtle::{ConditionallyNegatable, ConditionallySelectable};
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
/// Holds the \\(u\\)-coordinate of a point on the Montgomery form of
@ -109,6 +110,7 @@ impl Identity for MontgomeryPoint {
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for MontgomeryPoint {
fn zeroize(&mut self) {
self.0.zeroize();
@ -351,6 +353,7 @@ impl<'a, 'b> Mul<&'b Scalar> for &'a MontgomeryPoint {
// The final value of prev_bit above is scalar.bits()[0], i.e., the LSB of scalar
ProjectivePoint::conditional_swap(&mut x0, &mut x1, Choice::from(prev_bit as u8));
// Don't leave the bit in the stack
#[cfg(feature = "zeroize")]
prev_bit.zeroize();
x0.as_affine()

View file

@ -187,6 +187,7 @@ use subtle::ConditionallyNegatable;
use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use crate::edwards::EdwardsBasepointTable;
@ -1133,12 +1134,14 @@ impl Debug for RistrettoPoint {
// Zeroize traits
// ------------------------------------------------------------------------
#[cfg(feature = "zeroize")]
impl Zeroize for CompressedRistretto {
fn zeroize(&mut self) {
self.0.zeroize();
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for RistrettoPoint {
fn zeroize(&mut self) {
self.0.zeroize();

View file

@ -165,6 +165,7 @@ use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq;
use subtle::CtOption;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
use crate::backend;
@ -554,6 +555,7 @@ impl From<u128> for Scalar {
}
}
#[cfg(feature = "zeroize")]
impl Zeroize for Scalar {
fn zeroize(&mut self) {
self.bytes.zeroize();

View file

@ -26,6 +26,7 @@ use crate::backend::serial::curve_models::AffineNielsPoint;
use crate::backend::serial::curve_models::ProjectiveNielsPoint;
use crate::edwards::EdwardsPoint;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;
macro_rules! impl_lookup_table {
@ -112,14 +113,13 @@ macro_rules! impl_lookup_table {
}
}
#[cfg(feature = "zeroize")]
impl<T> Zeroize for $name<T>
where
T: Copy + Default + Zeroize,
{
fn zeroize(&mut self) {
for x in self.0.iter_mut() {
x.zeroize();
}
self.0.iter_mut().zeroize();
}
}
};