Skip to content
This repository was archived by the owner on Oct 17, 2022. It is now read-only.

Commit 58e6954

Browse files
authored
crypto: zeroize private key in BLS12377 (#850)
1 parent c6b9f05 commit 58e6954

File tree

2 files changed

+81
-2
lines changed

2 files changed

+81
-2
lines changed

crypto/src/bls12377/mod.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use serde_with::serde_as;
2727
use signature::{Signer, Verifier};
2828

2929
use fastcrypto::traits::{Authenticator, KeyPair, SigningKey, VerifyingKey};
30+
use zeroize::Zeroize;
3031

3132
mod ark_serialize;
3233

@@ -400,7 +401,7 @@ impl KeyPair for BLS12377KeyPair {
400401
}
401402

402403
fn private(self) -> Self::PrivKey {
403-
self.secret
404+
BLS12377PrivateKey::from_bytes(self.secret.as_ref()).unwrap()
404405
}
405406

406407
fn generate<R: rand::CryptoRng + rand::RngCore>(rng: &mut R) -> Self {
@@ -592,3 +593,32 @@ impl From<&BLS12377PublicKey> for BLS12377PublicKeyBytes {
592593
BLS12377PublicKeyBytes::from_bytes(pk.as_ref()).unwrap()
593594
}
594595
}
596+
597+
impl zeroize::Zeroize for BLS12377PrivateKey {
598+
fn zeroize(&mut self) {
599+
// PrivateKey.zeroize here is not necessary here because the underlying implicitly zeroizes.
600+
self.bytes.take().zeroize();
601+
}
602+
}
603+
604+
impl zeroize::ZeroizeOnDrop for BLS12377PrivateKey {}
605+
606+
impl Drop for BLS12377PrivateKey {
607+
fn drop(&mut self) {
608+
self.zeroize();
609+
}
610+
}
611+
612+
impl zeroize::Zeroize for BLS12377KeyPair {
613+
fn zeroize(&mut self) {
614+
self.secret.zeroize()
615+
}
616+
}
617+
618+
impl zeroize::ZeroizeOnDrop for BLS12377KeyPair {}
619+
620+
impl Drop for BLS12377KeyPair {
621+
fn drop(&mut self) {
622+
self.zeroize();
623+
}
624+
}

crypto/src/tests/bls12377_tests.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ use fastcrypto::traits::{
99
};
1010
use fastcrypto::{Hash, SignatureService};
1111

12+
use crate::bls12377::CELO_BLS_PRIVATE_KEY_LENGTH;
1213
use rand::{rngs::StdRng, SeedableRng as _};
1314
use signature::{Signer, Verifier};
14-
1515
pub fn keys() -> Vec<BLS12377KeyPair> {
1616
let mut rng = StdRng::from_seed([0; 32]);
1717
(0..4)
@@ -370,3 +370,52 @@ async fn signature_service() {
370370
// Verify the signature we received.
371371
assert!(pk.verify(digest.as_ref(), &signature).is_ok());
372372
}
373+
374+
#[test]
375+
fn test_sk_zeroization_on_drop() {
376+
let ptr: *const u8;
377+
let bytes_ptr: *const u8;
378+
379+
let mut sk_bytes = Vec::new();
380+
381+
{
382+
let mut rng = StdRng::from_seed([9; 32]);
383+
let kp = BLS12377KeyPair::generate(&mut rng);
384+
let sk = kp.private();
385+
sk_bytes.extend_from_slice(sk.as_ref());
386+
387+
ptr = std::ptr::addr_of!(sk.privkey) as *const u8;
388+
bytes_ptr = &sk.as_ref()[0] as *const u8;
389+
390+
// Assert the exact location in SecretKey is stored as private key bytes.
391+
unsafe {
392+
for (i, &byte) in sk_bytes
393+
.iter()
394+
.enumerate()
395+
.take(CELO_BLS_PRIVATE_KEY_LENGTH)
396+
{
397+
assert_eq!(*ptr.add(i + 41), byte);
398+
}
399+
}
400+
let sk_memory: &[u8] =
401+
unsafe { ::std::slice::from_raw_parts(bytes_ptr, CELO_BLS_PRIVATE_KEY_LENGTH) };
402+
// Assert that this is equal to sk_bytes before deletion.
403+
assert_eq!(sk_memory, &sk_bytes[..]);
404+
}
405+
406+
// Assert the exact position in SecretKey is no longer private key bytes.
407+
unsafe {
408+
for (i, &byte) in sk_bytes
409+
.iter()
410+
.enumerate()
411+
.take(CELO_BLS_PRIVATE_KEY_LENGTH)
412+
{
413+
assert_ne!(*ptr.add(i + 41), byte);
414+
}
415+
}
416+
417+
// Check that self.bytes is reset to OnceCell default.
418+
let sk_memory: &[u8] =
419+
unsafe { ::std::slice::from_raw_parts(bytes_ptr, CELO_BLS_PRIVATE_KEY_LENGTH) };
420+
assert_ne!(sk_memory, &sk_bytes[..]);
421+
}

0 commit comments

Comments
 (0)