Skip to content

Commit

Permalink
Add ACVP feature.
Browse files Browse the repository at this point in the history
There is some functionality that is helpful when running ACVP tests, but
that functionality should not be allowed during regular operation. For
example, we shouldn't need to create an ECDH secret key from raw bytes.
They should always be from random. But, ACVP tests require testing
specific scenarios so it provides keys that need to be tested.
  • Loading branch information
zhalvorsen committed Aug 8, 2023
1 parent 8868752 commit b2fe8ba
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 5 deletions.
1 change: 1 addition & 0 deletions libraries/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ zeroize = { version = "1.5.7", features = ["derive"] }
[features]
std = ["hex", "ring", "untrusted", "serde", "serde_json", "regex", "rand_core/getrandom"]
with_ctap1 = []
acvp = []
12 changes: 12 additions & 0 deletions libraries/crypto/src/ecdh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ 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.
#[cfg(any(feature = "std", feature = "acvp"))]
pub fn from_bytes(bytes: &[u8; 32]) -> Option<SecKey> {
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 {
Expand Down
4 changes: 2 additions & 2 deletions libraries/crypto/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use super::ec::point::PointP256;
use super::Hash256;
use alloc::vec;
use alloc::vec::Vec;
#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "acvp"))]
use arrayref::array_mut_ref;
use arrayref::{array_ref, mut_array_refs};
use core::marker::PhantomData;
Expand Down Expand Up @@ -220,7 +220,7 @@ impl Signature {
Some(Signature { r, s })
}

#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "acvp"))]
pub fn to_bytes(&self, bytes: &mut [u8; Signature::BYTES_LENGTH]) {
self.r
.to_int()
Expand Down
1 change: 1 addition & 0 deletions libraries/opensk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ vendor_hid = []
fuzz = ["arbitrary", "std"]
ed25519 = ["ed25519-compact"]
rust_crypto = ["p256", "sha2", "hmac", "hkdf", "aes", "cbc"]
acvp = ["crypto/acvp"]

[dev-dependencies]
enum-iterator = "0.6.0"
Expand Down
6 changes: 5 additions & 1 deletion libraries/opensk/src/api/crypto/ecdh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub trait Ecdh {
}

/// ECDH ephemeral key.
pub trait SecretKey {
pub trait SecretKey: Sized {
type PublicKey: PublicKey;
type SharedSecret: SharedSecret;

Expand All @@ -35,6 +35,10 @@ 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 signing key from its representation in bytes.
#[cfg(feature = "acvp")]
fn from_slice(bytes: &[u8; EC_FIELD_SIZE]) -> Option<Self>;
}

/// ECDH public key.
Expand Down
2 changes: 1 addition & 1 deletion libraries/opensk/src/api/crypto/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub trait Signature: Sized {
fn from_slice(bytes: &[u8; EC_SIGNATURE_SIZE]) -> Option<Self>;

/// Writes the signature bytes into the passed in parameter.
#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "acvp"))]
fn to_slice(&self, bytes: &mut [u8; EC_SIGNATURE_SIZE]);

/// Encodes the signatures as ASN1 DER.
Expand Down
7 changes: 6 additions & 1 deletion libraries/opensk/src/api/crypto/software_crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ impl ecdh::SecretKey for SoftwareEcdhSecretKey {
let shared_secret = self.sec_key.exchange_x(&public_key.pub_key);
SoftwareEcdhSharedSecret { shared_secret }
}

#[cfg(feature = "acvp")]
fn from_slice(bytes: &[u8; EC_FIELD_SIZE]) -> Option<Self> {
crypto::ecdh::SecKey::from_bytes(bytes).map(|k| Self { sec_key: k })
}
}

pub struct SoftwareEcdhPublicKey {
Expand Down Expand Up @@ -169,7 +174,7 @@ impl ecdsa::Signature for SoftwareEcdsaSignature {
crypto::ecdsa::Signature::from_bytes(bytes).map(|s| SoftwareEcdsaSignature { signature: s })
}

#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "acvp"))]
fn to_slice(&self, bytes: &mut [u8; EC_SIGNATURE_SIZE]) {
self.signature.to_bytes(bytes);
}
Expand Down
1 change: 1 addition & 0 deletions libraries/opensk/src/ctap/hid/receive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ impl<E: Env> MessageAssembler<E> {
let (cid, processed_packet) = CtapHid::<E>::process_single_packet(packet);
if let Some(locked_cid) = locked_cid {
if locked_cid != cid {
#[cfg(not(feature = "acvp"))]
return Err((cid, CtapHidError::ChannelBusy));
}
}
Expand Down

0 comments on commit b2fe8ba

Please sign in to comment.