Skip to content

Commit

Permalink
Zeroize SharedSecret on drop
Browse files Browse the repository at this point in the history
  • Loading branch information
nickray committed Jul 6, 2023
1 parent 8b1f83a commit 20239ba
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 32 deletions.
25 changes: 20 additions & 5 deletions src/agreement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
montgomery::MontgomeryPoint,
scalar::Scalar,
};
use zeroize::{Zeroize, ZeroizeOnDrop};

#[derive(PartialEq, Eq, /*Hash,*/ Copy, Clone, Debug)]
pub struct PublicKey(pub(crate) MontgomeryPoint);
Expand All @@ -13,16 +14,13 @@ pub struct PublicKey(pub(crate) MontgomeryPoint);
///
/// This is a wrapper around a `Scalar`. To obtain the corresponding `PublicKey`,
/// use `PublicKey::from(&secret_key)`.
// #[derive(Zeroize)]
// #[zeroize(drop)]
#[derive(Clone /*, Zeroize*/)]
#[derive(Clone)]
pub struct SecretKey(pub(crate) Scalar);

/// The result of a Diffie-Hellman key exchange.
///
/// Each party computes this using their [`SecretKey`] and their counterparty's [`PublicKey`].
// #[derive(Zeroize)]
// #[zeroize(drop)]
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
pub struct SharedSecret(pub(crate) MontgomeryPoint);

impl From<[u8; 32]> for PublicKey {
Expand Down Expand Up @@ -77,6 +75,11 @@ impl SecretKey {
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}

/// Corresponding public key.
pub fn public(&self) -> PublicKey {
self.into()
}
}

/// "Decode" a scalar from a 32-byte array.
Expand Down Expand Up @@ -225,11 +228,23 @@ mod tests {
#[test]
fn zeroize_on_drop() {
let mut secret = SecretKey::from_seed(&[1u8; 32]);
let public = PublicKey::from([2u8; 32]);
let mut shared_secret = secret.agree(&public);

assert_ne!(secret.0.as_bytes(), &[0u8; 32]);

unsafe {
core::ptr::drop_in_place(&mut secret);
}

assert_eq!(secret.0.as_bytes(), &[0u8; 32]);

assert_ne!(shared_secret.0.to_bytes(), [0u8; 32]);

unsafe {
core::ptr::drop_in_place(&mut shared_secret);
}

assert_eq!(shared_secret.0.to_bytes(), [0u8; 32]);
}
}
3 changes: 2 additions & 1 deletion src/field/haase.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};

use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
use zeroize::Zeroize;

use super::FieldImplementation;

Expand All @@ -16,7 +17,7 @@ extern "C" {
pub fn fe25519_square_asm(result: *mut U256, value: *const U256);
}

#[derive(Clone, Copy, Debug, Default)]
#[derive(Clone, Copy, Debug, Default, Zeroize)]
pub struct FieldElement(pub Limbs);

impl ConditionallySelectable for FieldElement {
Expand Down
3 changes: 2 additions & 1 deletion src/field/tweetnacl.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};

use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
use zeroize::Zeroize;

use super::FieldImplementation;

pub type Limbs = [i64; 16];

/// Element of the base field of the elliptic curve
#[derive(Clone, Copy, Debug, Default)]
#[derive(Clone, Copy, Debug, Default, Zeroize)]
pub struct FieldElement(pub Limbs);

impl ConditionallySelectable for FieldElement {
Expand Down
24 changes: 3 additions & 21 deletions src/montgomery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,27 @@ use core::ops::{
use subtle::Choice;
use subtle::ConditionallySelectable;
use subtle::ConstantTimeEq;
// use zeroize::Zeroize;
use zeroize::Zeroize;

use crate::{
// constants::COMPRESSED_Y_LENGTH,
edwards::{CompressedY as CompressedEdwardsY, EdwardsPoint},
field::{FieldElement, FieldImplementation as _},
scalar::Scalar,
Error,
Result,
Error, Result,
};

// #[derive(Clone,Copy,Debug,Default)]
/// Holds the \\(u\\)-coordinate of a point on the Montgomery form of
/// Curve25519 or its twist.
#[derive(Clone, Copy, Debug, Default /*,Hash*/)]
#[derive(Clone, Copy, Debug, Default, Zeroize)]
pub struct MontgomeryPoint(pub FieldElement);

impl ConstantTimeEq for MontgomeryPoint {
fn ct_eq(&self, other: &MontgomeryPoint) -> Choice {
// let self_fe = FieldElement::from_bytes(&self.0);
// let other_fe = FieldElement::from_bytes(&other.0);

// self_fe.ct_eq(&other_fe)
self.0.ct_eq(&other.0)
}
}

// impl Default for MontgomeryPoint {
// fn default() -> MontgomeryPoint {
// MontgomeryPoint([0u8; 32])
// }
// }

impl PartialEq for MontgomeryPoint {
fn eq(&self, other: &MontgomeryPoint) -> bool {
self.ct_eq(other).unwrap_u8() == 1u8
Expand All @@ -52,12 +40,6 @@ impl PartialEq for MontgomeryPoint {

impl Eq for MontgomeryPoint {}

// impl Zeroize for MontgomeryPoint {
// fn zeroize(&mut self) {
// self.0.zeroize();
// }
// }

impl MontgomeryPoint {
// /// View this `MontgomeryPoint` as an array of bytes.
// pub fn as_bytes(&self) -> &[u8; 32] {
Expand Down
6 changes: 2 additions & 4 deletions src/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ pub type U512le = [u8; 64];
/// structure, consisting of these scalars. They are the
/// integers modulo "ell", where "ell" is 2**252 + something something.
#[repr(C)]
#[derive(Clone, Debug,Default,PartialEq, Zeroize, ZeroizeOnDrop)]
pub struct Scalar(
pub [u8; SCALAR_LENGTH]
);
#[derive(Clone, Debug, Default, PartialEq, Zeroize, ZeroizeOnDrop)]
pub struct Scalar(pub [u8; SCALAR_LENGTH]);

type UnpackedScalar = crate::scalar29::Scalar29;

Expand Down

0 comments on commit 20239ba

Please sign in to comment.