From 8efd1da78fc29a053108d1b90544955c3a7f7caa Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Thu, 28 Sep 2023 19:34:55 +0100 Subject: [PATCH] Zeroize secp256k1 keys on drop --- core/src/types/key/secp256k1.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/core/src/types/key/secp256k1.rs b/core/src/types/key/secp256k1.rs index ec7a02f62b8..9ffbf580ef0 100644 --- a/core/src/types/key/secp256k1.rs +++ b/core/src/types/key/secp256k1.rs @@ -12,11 +12,13 @@ use data_encoding::HEXLOWER; use ethabi::Token; use k256::ecdsa::RecoveryId; use k256::elliptic_curve::sec1::ToEncodedPoint; +use k256::elliptic_curve::ScalarPrimitive; #[cfg(feature = "rand")] use rand::{CryptoRng, RngCore}; use serde::de::{Error, SeqAccess, Visitor}; use serde::ser::SerializeTuple; use serde::{Deserialize, Serialize, Serializer}; +use zeroize::{Zeroize, ZeroizeOnDrop}; use super::{ ParsePublicKeyError, ParseSecretKeyError, ParseSignatureError, RefTo, @@ -167,6 +169,20 @@ impl From<&PublicKey> for EthAddress { #[derive(Debug, Clone)] pub struct SecretKey(pub Box); +impl Zeroize for SecretKey { + fn zeroize(&mut self) { + let scalar: &mut ScalarPrimitive = unsafe { + // SAFETY: a libsecp256k1 secret key is just + // a wrapper around a scalar value, which itself + // is a wrapper around a byte buffer + std::mem::transmute(&mut *self.0) + }; + scalar.zeroize(); + } +} + +impl ZeroizeOnDrop for SecretKey {} + impl super::SecretKey for SecretKey { type PublicKey = PublicKey;