Skip to content

Commit

Permalink
Add support for p384 and p521 nist curves
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Apr 19, 2024
1 parent b77dbd4 commit 029e7c8
Show file tree
Hide file tree
Showing 9 changed files with 1,207 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ littlefs2 = "0.4.0"
p256-cortex-m4 = { version = "0.1.0-alpha.6", features = ["prehash", "sec1-signatures"] }
salty = { version = "0.3.0", features = ["cose"] }
serde-indexed = "0.1.0"
p384 = { version = "0.13.0", optional = true, default-features = false, features = ["sha384", "ecdh", "ecdsa"] }
p521 = { version = "0.13.3", optional = true, default-features = false, features = ["sha512", "ecdh", "ecdsa"] }
ecdsa = { version = "0.16.9", optional = true, default-features = false }

[dev-dependencies]
# Testing
Expand Down Expand Up @@ -110,6 +113,8 @@ hmac-sha1 = []
hmac-sha256 = []
hmac-sha512 = []
p256 = []
p384 = ["dep:p384"]
p521 = ["dep:p521", "ecdsa"]
sha256 = []
tdes = ["des"]
totp = ["sha-1"]
Expand Down
179 changes: 179 additions & 0 deletions src/client/mechanisms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,185 @@ pub trait P256: CryptoClient {
}
}

#[cfg(feature = "p384")]
impl<S: Syscall, E> P384 for ClientImplementation<S, E> {}

#[cfg(feature = "p384")]
pub trait P384: CryptoClient {
fn generate_p384_private_key(
&mut self,
persistence: Location,
) -> ClientResult<'_, reply::GenerateKey, Self> {
self.generate_key(
Mechanism::P384,
StorageAttributes::new().set_persistence(persistence),
)
}

fn derive_p384_public_key(
&mut self,
private_key: KeyId,
persistence: Location,
) -> ClientResult<'_, reply::DeriveKey, Self> {
self.derive_key(
Mechanism::P384,
private_key,
None,
StorageAttributes::new().set_persistence(persistence),
)
}

fn deserialize_p384_key<'c>(
&'c mut self,
serialized_key: &[u8],
format: KeySerialization,
attributes: StorageAttributes,
) -> ClientResult<'c, reply::DeserializeKey, Self> {
self.deserialize_key(Mechanism::P384, serialized_key, format, attributes)
}

fn serialize_p384_key(
&mut self,
key: KeyId,
format: KeySerialization,
) -> ClientResult<'_, reply::SerializeKey, Self> {
self.serialize_key(Mechanism::P384, key, format)
}

// generally, don't offer multiple versions of a mechanism, if possible.
// try using the simplest when given the choice.
// hashing is something users can do themselves hopefully :)
//
// on the other hand: if users need sha256, then if the service runs in secure trustzone
// domain, we'll maybe need two copies of the sha2 code
fn sign_p384<'c>(
&'c mut self,
key: KeyId,
message: &[u8],
format: SignatureSerialization,
) -> ClientResult<'c, reply::Sign, Self> {
self.sign(Mechanism::P384, key, message, format)
}

fn verify_p384<'c>(
&'c mut self,
key: KeyId,
message: &[u8],
signature: &[u8],
) -> ClientResult<'c, reply::Verify, Self> {
self.verify(
Mechanism::P384,
key,
message,
signature,
SignatureSerialization::Raw,
)
}

fn agree_p384(
&mut self,
private_key: KeyId,
public_key: KeyId,
persistence: Location,
) -> ClientResult<'_, reply::Agree, Self> {
self.agree(
Mechanism::P384,
private_key,
public_key,
StorageAttributes::new().set_persistence(persistence),
)
}
}

#[cfg(feature = "p521")]
impl<S: Syscall, E> P521 for ClientImplementation<S, E> {}

pub trait P521: CryptoClient {
fn generate_p521_private_key(
&mut self,
persistence: Location,
) -> ClientResult<'_, reply::GenerateKey, Self> {
self.generate_key(
Mechanism::P521,
StorageAttributes::new().set_persistence(persistence),
)
}

fn derive_p521_public_key(
&mut self,
private_key: KeyId,
persistence: Location,
) -> ClientResult<'_, reply::DeriveKey, Self> {
self.derive_key(
Mechanism::P521,
private_key,
None,
StorageAttributes::new().set_persistence(persistence),
)
}

fn deserialize_p521_key<'c>(
&'c mut self,
serialized_key: &[u8],
format: KeySerialization,
attributes: StorageAttributes,
) -> ClientResult<'c, reply::DeserializeKey, Self> {
self.deserialize_key(Mechanism::P521, serialized_key, format, attributes)
}

fn serialize_p521_key(
&mut self,
key: KeyId,
format: KeySerialization,
) -> ClientResult<'_, reply::SerializeKey, Self> {
self.serialize_key(Mechanism::P521, key, format)
}

// generally, don't offer multiple versions of a mechanism, if possible.
// try using the simplest when given the choice.
// hashing is something users can do themselves hopefully :)
//
// on the other hand: if users need sha256, then if the service runs in secure trustzone
// domain, we'll maybe need two copies of the sha2 code
fn sign_p521<'c>(
&'c mut self,
key: KeyId,
message: &[u8],
format: SignatureSerialization,
) -> ClientResult<'c, reply::Sign, Self> {
self.sign(Mechanism::P521, key, message, format)
}

fn verify_p521<'c>(
&'c mut self,
key: KeyId,
message: &[u8],
signature: &[u8],
) -> ClientResult<'c, reply::Verify, Self> {
self.verify(
Mechanism::P521,
key,
message,
signature,
SignatureSerialization::Raw,
)
}

fn agree_p521(
&mut self,
private_key: KeyId,
public_key: KeyId,
persistence: Location,
) -> ClientResult<'_, reply::Agree, Self> {
self.agree(
Mechanism::P521,
private_key,
public_key,
StorageAttributes::new().set_persistence(persistence),
)
}
}

#[cfg(feature = "sha256")]
impl<S: Syscall, E> Sha256 for ClientImplementation<S, E> {}

Expand Down
6 changes: 6 additions & 0 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ pub enum Kind {
Rsa4096,
Ed255,
P256,
P384,
P521,
X255,
}

Expand Down Expand Up @@ -211,6 +213,8 @@ impl Kind {
Kind::Rsa2048 => 7,
Kind::Rsa3072 => 8,
Kind::Rsa4096 => 9,
Kind::P384 => 10,
Kind::P521 => 11,
}
}

Expand All @@ -225,6 +229,8 @@ impl Kind {
7 => Kind::Rsa2048,
8 => Kind::Rsa3072,
9 => Kind::Rsa4096,
10 => Kind::P384,
11 => Kind::P521,
_ => return Err(Error::InvalidSerializedKey),
})
}
Expand Down
8 changes: 8 additions & 0 deletions src/mechanisms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ pub struct P256 {}
pub struct P256Prehashed {}
mod p256;

pub struct P384 {}
pub struct P384Prehashed {}
mod p384;

pub struct P521 {}
pub struct P521Prehashed {}
mod p521;

pub struct Sha256 {}
mod sha256;

Expand Down
Loading

0 comments on commit 029e7c8

Please sign in to comment.