Skip to content

Commit

Permalink
Adds a trait for crypto, porting EC first (#606)
Browse files Browse the repository at this point in the history
* Adds a trait for crypto, porting EC first

* Moves crypto implementation next to its trait

* Renames constants and types
  • Loading branch information
kaczmarczyck authored Apr 4, 2023
1 parent 80b82ff commit c168141
Show file tree
Hide file tree
Showing 25 changed files with 880 additions and 219 deletions.
1 change: 0 additions & 1 deletion libraries/crypto/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@ impl PubKey {
ExponentP256::modn(u.to_int()) == *sign.r.as_exponent()
}

#[cfg(feature = "std")]
pub fn verify_vartime<H>(&self, msg: &[u8], sign: &Signature) -> bool
where
H: Hash256,
Expand Down
3 changes: 3 additions & 0 deletions libraries/opensk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ subtle = { version = "2.2", default-features = false, features = ["nightly"] }
arbitrary = { version = "0.4.7", features = ["derive"], optional = true }
rand = { version = "0.8.4", optional = true }
ed25519-compact = { version = "1", default-features = false, optional = true }
p256 = { version = "0.13.0", features = ["ecdh"], optional = true }
rand_core = { version = "0.6.4", optional = true }

[features]
debug_ctap = []
Expand All @@ -30,6 +32,7 @@ with_ctap1 = ["crypto/with_ctap1"]
vendor_hid = []
fuzz = ["arbitrary", "std"]
ed25519 = ["ed25519-compact"]
rust_crypto = ["p256", "rand_core"]

[dev-dependencies]
enum-iterator = "0.6.0"
Expand Down
53 changes: 53 additions & 0 deletions libraries/opensk/src/api/crypto/ecdh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::EC_FIELD_SIZE;
use rng256::Rng256;

/// Container for all ECDH cryptographic material.
pub trait Ecdh {
type SecretKey: SecretKey<PublicKey = Self::PublicKey, SharedSecret = Self::SharedSecret>;
type PublicKey: PublicKey;
type SharedSecret: SharedSecret;
}

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

/// Generates a new random secret key.
fn random(rng: &mut impl Rng256) -> Self;

/// Computes the corresponding public key for this private key.
fn public_key(&self) -> Self::PublicKey;

/// Computes the shared secret when using Elliptic-curve Diffie–Hellman.
fn diffie_hellman(&self, public_key: &Self::PublicKey) -> Self::SharedSecret;
}

/// ECDH public key.
pub trait PublicKey: Sized {
/// Creates a public key from its coordinates.
fn from_coordinates(x: &[u8; EC_FIELD_SIZE], y: &[u8; EC_FIELD_SIZE]) -> Option<Self>;

/// Writes the public key coordinates into the passed in parameters.
fn to_coordinates(&self, x: &mut [u8; EC_FIELD_SIZE], y: &mut [u8; EC_FIELD_SIZE]);
}

/// ECDH shared secret.
pub trait SharedSecret {
/// Exports the x component of the point computed by Diffie–Hellman.
fn raw_secret_bytes(&self) -> [u8; EC_FIELD_SIZE];
}
72 changes: 72 additions & 0 deletions libraries/opensk/src/api/crypto/ecdsa.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::{EC_FIELD_SIZE, EC_SIGNATURE_SIZE};
use alloc::vec::Vec;
use rng256::Rng256;

/// Container for all ECDSA cryptographic material.
pub trait Ecdsa {
type SecretKey: SecretKey<PublicKey = Self::PublicKey, Signature = Self::Signature>;
type PublicKey: PublicKey<Signature = Self::Signature>;
type Signature: Signature;
}

/// ECDSA signing key.
pub trait SecretKey: Sized {
type PublicKey: PublicKey;
type Signature: Signature;

/// Generates a new random secret key.
fn random(rng: &mut impl Rng256) -> Self;

/// Creates a signing key from its representation in bytes.
fn from_slice(bytes: &[u8; EC_FIELD_SIZE]) -> Option<Self>;

/// Computes the corresponding public key for this private key.
fn public_key(&self) -> Self::PublicKey;

/// Signs the message.
///
/// For hashing, SHA256 is used implicitly.
fn sign(&self, message: &[u8]) -> Self::Signature;

/// Writes the signing key bytes into the passed in parameter.
fn to_slice(&self, bytes: &mut [u8; EC_FIELD_SIZE]);
}

/// ECDSA verifying key.
pub trait PublicKey: Sized {
type Signature: Signature;

/// Creates a public key from its coordinates.
fn from_coordinates(x: &[u8; EC_FIELD_SIZE], y: &[u8; EC_FIELD_SIZE]) -> Option<Self>;

/// Verifies if the signature matches the message.
///
/// For hashing, SHA256 is used implicitly.
fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;

/// Writes the public key coordinates into the passed in parameters.
fn to_coordinates(&self, x: &mut [u8; EC_FIELD_SIZE], y: &mut [u8; EC_FIELD_SIZE]);
}

/// ECDSA signature.
pub trait Signature: Sized {
/// Creates a signature from its affine coordinates, represented as concatenated bytes.
fn from_slice(bytes: &[u8; EC_SIGNATURE_SIZE]) -> Option<Self>;

/// Encodes the signatures as ASN1 DER.
fn to_der(&self) -> Vec<u8>;
}
37 changes: 37 additions & 0 deletions libraries/opensk/src/api/crypto/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod ecdh;
pub mod ecdsa;
#[cfg(feature = "rust_crypto")]
pub mod rust_crypto;
#[cfg(not(feature = "rust_crypto"))]
pub mod software_crypto;
#[cfg(feature = "rust_crypto")]
pub use rust_crypto as software_crypto;

use self::ecdh::Ecdh;
use self::ecdsa::Ecdsa;

/// The size of field elements in the elliptic curve P256.
pub const EC_FIELD_SIZE: usize = 32;

/// The size of a serialized ECDSA signature.
pub const EC_SIGNATURE_SIZE: usize = 2 * EC_FIELD_SIZE;

/// Necessary cryptographic primitives for CTAP.
pub trait Crypto {
type Ecdh: Ecdh;
type Ecdsa: Ecdsa;
}
Loading

0 comments on commit c168141

Please sign in to comment.