From 7945bea5ec298d670779cc441630d1f0868ac8c1 Mon Sep 17 00:00:00 2001 From: Zach Halvorsen Date: Tue, 8 Aug 2023 07:26:04 -0700 Subject: [PATCH] Add more transparency into some EC structures. This adds the ability to create ECDH keys from raw bytes and export signatures as raw bytes. --- libraries/crypto/src/ecdh.rs | 11 +++++++++++ libraries/crypto/src/ecdsa.rs | 5 +---- libraries/opensk/src/api/crypto/ecdh.rs | 5 ++++- libraries/opensk/src/api/crypto/ecdsa.rs | 1 - libraries/opensk/src/api/crypto/rust_crypto.rs | 5 +++++ libraries/opensk/src/api/crypto/software_crypto.rs | 5 ++++- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/libraries/crypto/src/ecdh.rs b/libraries/crypto/src/ecdh.rs index ed5bec03..dc7f0583 100644 --- a/libraries/crypto/src/ecdh.rs +++ b/libraries/crypto/src/ecdh.rs @@ -78,6 +78,17 @@ impl SecKey { p.getx().to_int().to_bin(&mut x); x } + + /// Creates a private key from the exponent's bytes, or None if checks fail. + pub fn from_bytes(bytes: &[u8; 32]) -> Option { + let a = NonZeroExponentP256::from_int_checked(Int256::from_bin(bytes)); + // The branching here is fine because all this reveals is whether the key was invalid. + if bool::from(a.is_none()) { + return None; + } + let a = a.unwrap(); + Some(SecKey { a }) + } } impl PubKey { diff --git a/libraries/crypto/src/ecdsa.rs b/libraries/crypto/src/ecdsa.rs index f4e66211..ca29b8da 100644 --- a/libraries/crypto/src/ecdsa.rs +++ b/libraries/crypto/src/ecdsa.rs @@ -19,9 +19,7 @@ use super::ec::point::PointP256; use super::Hash256; use alloc::vec; use alloc::vec::Vec; -#[cfg(feature = "std")] -use arrayref::array_mut_ref; -use arrayref::{array_ref, mut_array_refs}; +use arrayref::{array_mut_ref, array_ref, mut_array_refs}; use core::marker::PhantomData; use rand_core::RngCore; use zeroize::Zeroize; @@ -220,7 +218,6 @@ impl Signature { Some(Signature { r, s }) } - #[cfg(feature = "std")] pub fn to_bytes(&self, bytes: &mut [u8; Signature::BYTES_LENGTH]) { self.r .to_int() diff --git a/libraries/opensk/src/api/crypto/ecdh.rs b/libraries/opensk/src/api/crypto/ecdh.rs index 1c4b74fb..40bc3b2c 100644 --- a/libraries/opensk/src/api/crypto/ecdh.rs +++ b/libraries/opensk/src/api/crypto/ecdh.rs @@ -23,7 +23,7 @@ pub trait Ecdh { } /// ECDH ephemeral key. -pub trait SecretKey { +pub trait SecretKey: Sized { type PublicKey: PublicKey; type SharedSecret: SharedSecret; @@ -35,6 +35,9 @@ pub trait SecretKey { /// Computes the shared secret when using Elliptic-curve Diffie–Hellman. fn diffie_hellman(&self, public_key: &Self::PublicKey) -> Self::SharedSecret; + + /// Creates a secret key from its representation in bytes. + fn from_slice(bytes: &[u8; EC_FIELD_SIZE]) -> Option; } /// ECDH public key. diff --git a/libraries/opensk/src/api/crypto/ecdsa.rs b/libraries/opensk/src/api/crypto/ecdsa.rs index 1dad533b..6c76e12b 100644 --- a/libraries/opensk/src/api/crypto/ecdsa.rs +++ b/libraries/opensk/src/api/crypto/ecdsa.rs @@ -73,7 +73,6 @@ pub trait Signature: Sized { fn from_slice(bytes: &[u8; EC_SIGNATURE_SIZE]) -> Option; /// Writes the signature bytes into the passed in parameter. - #[cfg(feature = "std")] fn to_slice(&self, bytes: &mut [u8; EC_SIGNATURE_SIZE]); /// Encodes the signatures as ASN1 DER. diff --git a/libraries/opensk/src/api/crypto/rust_crypto.rs b/libraries/opensk/src/api/crypto/rust_crypto.rs index a70199c4..da7b41fc 100644 --- a/libraries/opensk/src/api/crypto/rust_crypto.rs +++ b/libraries/opensk/src/api/crypto/rust_crypto.rs @@ -85,6 +85,11 @@ impl ecdh::SecretKey for SoftwareEcdhSecretKey { let shared_secret = self.ephemeral_secret.diffie_hellman(&public_key.public_key); SoftwareEcdhSharedSecret { shared_secret } } + + fn from_slice(_bytes: &[u8; EC_FIELD_SIZE]) -> Option { + // Currently (8/8/2023) cannot create EphemeralSecret from a slice. Update this, if needed. + unimplemented!(); + } } pub struct SoftwareEcdhPublicKey { diff --git a/libraries/opensk/src/api/crypto/software_crypto.rs b/libraries/opensk/src/api/crypto/software_crypto.rs index f0cd2216..745a9891 100644 --- a/libraries/opensk/src/api/crypto/software_crypto.rs +++ b/libraries/opensk/src/api/crypto/software_crypto.rs @@ -69,6 +69,10 @@ impl ecdh::SecretKey for SoftwareEcdhSecretKey { let shared_secret = self.sec_key.exchange_x(&public_key.pub_key); SoftwareEcdhSharedSecret { shared_secret } } + + fn from_slice(bytes: &[u8; EC_FIELD_SIZE]) -> Option { + crypto::ecdh::SecKey::from_bytes(bytes).map(|k| Self { sec_key: k }) + } } pub struct SoftwareEcdhPublicKey { @@ -169,7 +173,6 @@ impl ecdsa::Signature for SoftwareEcdsaSignature { crypto::ecdsa::Signature::from_bytes(bytes).map(|s| SoftwareEcdsaSignature { signature: s }) } - #[cfg(feature = "std")] fn to_slice(&self, bytes: &mut [u8; EC_SIGNATURE_SIZE]) { self.signature.to_bytes(bytes); }