Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ default-mechanisms = [
# "hmac-blake2s",
"hmac-sha1",
"hmac-sha256",
"hmac-sha256-p256",
# For some reason, this breaks Solo 2 firmware
# At minimum, this seems to have a huge "block" method
# "hmac-sha512",
Expand All @@ -98,6 +99,7 @@ x255 = []
hmac-blake2s = ["blake2"]
hmac-sha1 = []
hmac-sha256 = []
hmac-sha256-p256 = []
hmac-sha512 = []
p256 = []
sha256 = []
Expand Down
27 changes: 27 additions & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! [pkcs11-v3]: https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/pkcs11-base-v3.0.html
//! [pkcs11-headers]: https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/cs01/include/pkcs11-v3.0/

use crate::key::Kind;
use crate::types::*;
use core::hint::unreachable_unchecked;
use core::time::Duration;
Expand Down Expand Up @@ -99,10 +100,19 @@ generate_enums! {
ReadCertificate: 61
WriteCertificate: 62

///////////////////
// SW-Encryption //
///////////////////
SetClientContextPin: 63
ChangePin: 64
ResetPin: 65

///////////
// Other //
///////////
DebugDumpStore: 0x79


}

pub mod request {
Expand Down Expand Up @@ -281,6 +291,7 @@ pub mod request {
UnsafeInjectSharedKey:
- location: Location
- raw_key: ShortData
- kind: Kind

UnwrapKey:
- mechanism: Mechanism
Expand Down Expand Up @@ -331,6 +342,15 @@ pub mod request {
- location: Location
- der: Message

SetClientContextPin:
- pin: ShortData

ChangePin:
- new_pin: ShortData

ResetPin:
- new_pin: ShortData

}
}

Expand Down Expand Up @@ -481,5 +501,12 @@ pub mod reply {

WriteCertificate:
- id: CertId

SetClientContextPin:

ChangePin:

ResetPin:

}
}
25 changes: 25 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ pub use crate::platform::Syscall;
pub mod mechanisms;
pub use mechanisms::*;

use crate::key::Kind;

// to be fair, this is a programmer error,
// and could also just panic
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -544,10 +546,12 @@ pub trait CryptoClient: PollClient {
&mut self,
raw_key: &[u8],
location: Location,
kind: Kind,
) -> ClientResult<'_, reply::UnsafeInjectSharedKey, Self> {
let r = self.request(request::UnsafeInjectSharedKey {
raw_key: ShortData::from_slice(raw_key).unwrap(),
location,
kind,
})?;
r.client.syscall();
Ok(r)
Expand Down Expand Up @@ -749,6 +753,27 @@ pub trait FilesystemClient: PollClient {
r.client.syscall();
Ok(r)
}

fn change_pin(&mut self, new_pin: ShortData) -> ClientResult<'_, reply::ChangePin, Self> {
let r = self.request(request::ChangePin { new_pin })?;
r.client.syscall();
Ok(r)
}

fn reset_pin(&mut self, new_pin: ShortData) -> ClientResult<'_, reply::ResetPin, Self> {
let r = self.request(request::ResetPin { new_pin })?;
r.client.syscall();
Ok(r)
}

fn set_client_context_pin(
&mut self,
pin: ShortData,
) -> ClientResult<'_, reply::SetClientContextPin, Self> {
let r = self.request(request::SetClientContextPin { pin })?;
r.client.syscall();
Ok(r)
}
}

/// All the other methods that are fit to expose.
Expand Down
14 changes: 14 additions & 0 deletions src/client/mechanisms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,20 @@ pub trait HmacSha256: CryptoClient {
}
}

#[cfg(feature = "hmac-sha256-p256")]
impl<S: Syscall> HmacSha256P256 for ClientImplementation<S> {}

pub trait HmacSha256P256: CryptoClient {
fn hmacsha256p256_derive_key(&mut self, base_key: KeyId, message: &[u8], persistence: Location)
-> ClientResult<'_, reply::DeriveKey, Self>
{
self.derive_key(
Mechanism::HmacSha256P256, base_key,
Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?),
StorageAttributes::new().set_persistence(persistence))
}
}

#[cfg(feature = "hmac-sha512")]
impl<S: Syscall> HmacSha512 for ClientImplementation<S> {}

Expand Down
3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ pub enum Error {
WrongKeyKind,
WrongMessageLength,
WrongSignatureLength,

// sw encryption errors
FilesystemEncryptionError,
}

// pub struct FutureResult<'a, 'c> {
Expand Down
3 changes: 3 additions & 0 deletions src/mechanisms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ mod hmacsha1;
pub struct HmacSha256 {}
mod hmacsha256;

pub struct HmacSha256P256 {}
mod hmacsha256_p256;

pub struct HmacSha512 {}
#[cfg(feature = "hmac-sha512")]
mod hmacsha512;
Expand Down
95 changes: 95 additions & 0 deletions src/mechanisms/hmacsha256_p256.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#[cfg(feature = "hmac-sha256-p256")]
use crate::api::*;
#[cfg(feature = "hmac-sha256-p256")]
use crate::error::Error;
use crate::service::*;
#[cfg(feature = "hmac-sha256-p256")]
use hmac::crypto_mac::InvalidKeyLength;

#[cfg(feature = "hmac-sha256-p256")]
use hmac::{Hmac, Mac, NewMac};
#[cfg(feature = "hmac-sha256-p256")]
type HmacSha256 = Hmac<sha2::Sha256>;

#[cfg(feature = "hmac-sha256-p256")]
fn get_hmac(key: &[u8]) -> Result<HmacSha256, InvalidKeyLength> {
let mac = HmacSha256::new_from_slice(&key.as_ref())?;
Ok(mac)
}

#[cfg(feature = "hmac-sha256-p256")]
impl DeriveKey for super::HmacSha256P256 {
#[inline(never)]
fn derive_key(
keystore: &mut impl Keystore,
request: &request::DeriveKey,
) -> Result<reply::DeriveKey, Error> {
//TODO: identical as HmacSha256 implementation, but stores key as Kind::P256
let key_id = request.base_key;
let material_raw = keystore
.load_key(key::Secrecy::Secret, None, &key_id)?
.material;
let shared_secret = material_raw.as_slice();
let mut mac = get_hmac(&shared_secret[..32]).map_err(|_| Error::InternalError)?;

if let Some(additional_data) = &request.additional_data {
mac.update(&additional_data);
}
let derived_key: [u8; 32] = mac
.finalize()
.into_bytes()
.try_into()
.map_err(|_| Error::InternalError)?;

let key_id = keystore.store_key(
request.attributes.persistence,
key::Secrecy::Secret,
key::Kind::P256,
&derived_key,
)?;

Ok(reply::DeriveKey { key: key_id })
}
}

#[cfg(not(feature = "hmac-sha256-p256"))]
impl DeriveKey for super::HmacSha256P256 {}

#[cfg(feature = "hmac-sha256-p256")]
#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_hmac() {
let expected1 = [
111, 176, 100, 219, 221, 79, 157, 119, 246, 23, 196, 57, 85, 6, 201, 243, 17, 168, 135,
139, 137, 129, 236, 115, 170, 209, 159, 98, 111, 80, 173, 36,
];
let data1 = b"test data 1";
let res1: [u8; 32] = get_hmac(&data1[..])
.unwrap()
.finalize()
.into_bytes()
.try_into()
.unwrap();
assert_eq!(res1, expected1);

let data2 = b"test data 2";
let res2: [u8; 32] = get_hmac(&data2[..])
.unwrap()
.finalize()
.into_bytes()
.try_into()
.unwrap();
assert_ne!(res1, res2);

let res3: [u8; 32] = get_hmac(&data2[..])
.unwrap()
.finalize()
.into_bytes()
.try_into()
.unwrap();
assert_eq!(res3, res2);
}
}
4 changes: 2 additions & 2 deletions src/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use interchange::Responder;

use crate::api::{Reply, Request};
use crate::error::Error;
use crate::types::ClientId;
use crate::types::ClientContext;

cfg_if::cfg_if! {

Expand Down Expand Up @@ -72,7 +72,7 @@ pub struct ServiceEndpoint {
pub interchange: Responder<TrussedInterchange>,
// service (trusted) has this, not client (untrusted)
// used among other things to namespace cryptographic material
pub client_id: ClientId,
pub client_ctx: ClientContext,
}

// pub type ClientEndpoint = Requester<TrussedInterchange>;
Loading