diff --git a/src/lib.rs b/src/lib.rs index 7cb3b95..117a5b4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,8 +33,8 @@ use core::convert::TryInto; use flexiber::EncodableHeapless; use heapless_bytes::Bytes; use iso7816::{Data, Status}; -use trussed::client; -use trussed::{syscall, try_syscall}; +use trussed::types::{Location, StorageAttributes}; +use trussed::{client, syscall, try_syscall}; use constants::*; @@ -671,17 +671,11 @@ impl<'a, T: trussed::Client + trussed::client::Ed255> LoadedAuthenticator<'a, T> Status::IncorrectDataParameter })?; - // ble policy - // if let Some(key) = self.state.persistent.keys.authentication_key { - // // syscall!(self.trussed.delete(key)); - // } - - // let key = syscall!(self.trussed.generate_p256_private_key( - // let key = syscall!(self.trussed.generate_p256_private_key( - let key = syscall!(self - .trussed - .generate_ed255_private_key(trussed::types::Location::Internal,)) - .key; + let secret_key = self.state.persistent.generate_asymmetric_key( + reference, + parsed_mechanism, + self.trussed, + ); // // TEMP // let mechanism = trussed::types::Mechanism::P256Prehashed; @@ -702,33 +696,25 @@ impl<'a, T: trussed::Client + trussed::client::Ed255> LoadedAuthenticator<'a, T> // .signature; // blocking::dbg!(&signature); // self.state.persistent.keys.authentication_key = Some(key); - self.state.persistent.save(self.trussed); + // self.state.persistent.save(self.trussed); // let public_key = syscall!(self.trussed.derive_p256_public_key( - let public_key = syscall!(self - .trussed - .derive_ed255_public_key(key, trussed::types::Location::Volatile,)) + let public_key = syscall!(self.trussed.derive_key( + parsed_mechanism.mechanism(), + secret_key, + None, + StorageAttributes::default().set_persistence(Location::Volatile) + )) .key; - let serialized_public_key = syscall!(self.trussed.serialize_key( - // trussed::types::Mechanism::P256, - trussed::types::Mechanism::Ed255, - public_key, - trussed::types::KeySerialization::Raw, - )) - .serialized_key; - - // info!("supposed SEC1 pubkey, len {}: {:X?}", serialized_public_key.len(), &serialized_public_key); - - // P256 SEC1 has 65 bytes, Ed255 pubkeys have 32 - // let l2 = 65; - let l2 = 32; - let l1 = l2 + 2; - - reply - .extend_from_slice(&[0x7f, 0x49, l1, 0x86, l2]) - .unwrap(); - reply.extend_from_slice(&serialized_public_key).unwrap(); + match parsed_mechanism { + AsymmetricAlgorithms::P256 => { + todo!() + } + AsymmetricAlgorithms::Rsa2048 | AsymmetricAlgorithms::Rsa4096 => { + todo!() + } + }; Ok(()) } diff --git a/src/piv_types.rs b/src/piv_types.rs index df2e128..ce12924 100644 --- a/src/piv_types.rs +++ b/src/piv_types.rs @@ -6,6 +6,7 @@ use core::convert::{TryFrom, TryInto}; use flexiber::Encodable; use hex_literal::hex; use serde::{Deserialize, Serialize}; +use trussed::types::Mechanism; #[macro_export] macro_rules! enum_u8 { @@ -155,6 +156,16 @@ crate::container::enum_subset! { } } +impl AsymmetricAlgorithms { + pub fn mechanism(self) -> Mechanism { + match self { + Self::Rsa2048 => Mechanism::Rsa2048Pkcs, + Self::Rsa4096 => Mechanism::Rsa4096Pkcs, + Self::P256 => Mechanism::P256, + } + } +} + /// TODO: #[derive(Clone, Copy, Default, Eq, PartialEq)] pub struct CryptographicAlgorithmTemplate<'a> { diff --git a/src/state.rs b/src/state.rs index 7ce5ee4..489d3b5 100644 --- a/src/state.rs +++ b/src/state.rs @@ -9,7 +9,7 @@ use trussed::{ api::reply::Metadata, config::MAX_MESSAGE_LENGTH, syscall, try_syscall, - types::{KeyId, KeySerialization, Location, Mechanism, PathBuf}, + types::{KeyId, KeySerialization, Location, Mechanism, PathBuf, StorageAttributes}, }; use crate::{constants::*, piv_types::AsymmetricAlgorithms}; @@ -17,11 +17,6 @@ use crate::{container::AsymmetricKeyReference, piv_types::Algorithms}; use crate::{Pin, Puk}; -pub enum Key { - Ed25519(KeyId), - P256(KeyId), - X25519(KeyId), -} pub enum PinPolicy { Never, Once, @@ -35,105 +30,6 @@ pub enum TouchPolicy { Cached, } -pub struct Slot { - pub key: Option, - pub pin_policy: PinPolicy, - // touch_policy: TouchPolicy, -} - -impl Default for Slot { - fn default() -> Self { - Self { - key: None, - pin_policy: PinPolicy::Once, /*touch_policy: TouchPolicy::Never*/ - } - } -} - -impl Slot { - pub fn default(name: SlotName) -> Self { - use SlotName::*; - match name { - // Management => Slot { pin_policy: PinPolicy::Never, ..Default::default() }, - Signature => Slot { - pin_policy: PinPolicy::Always, - ..Default::default() - }, - Pinless => Slot { - pin_policy: PinPolicy::Never, - ..Default::default() - }, - _ => Default::default(), - } - } -} - -pub struct RetiredSlotIndex(u8); - -impl core::convert::TryFrom for RetiredSlotIndex { - type Error = u8; - fn try_from(i: u8) -> core::result::Result { - if (1..=20).contains(&i) { - Ok(Self(i)) - } else { - Err(i) - } - } -} -pub enum SlotName { - Identity, - Management, // Personalization? Administration? - Signature, - Decryption, // Management after all? - Pinless, - Retired(RetiredSlotIndex), - Attestation, -} - -impl SlotName { - pub fn default_pin_policy(&self) -> PinPolicy { - use PinPolicy::*; - use SlotName::*; - match *self { - Signature => Always, - Pinless | Management | Attestation => Never, - _ => Once, - } - } - - pub fn default_slot(&self) -> Slot { - Slot { - key: None, - pin_policy: self.default_pin_policy(), - } - } - - pub fn reference(&self) -> u8 { - use SlotName::*; - match *self { - Identity => 0x9a, - Management => 0x9b, - Signature => 0x9c, - Decryption => 0x9d, - Pinless => 0x9e, - Retired(RetiredSlotIndex(i)) => 0x81 + i, - Attestation => 0xf9, - } - } - pub fn tag(&self) -> u32 { - use SlotName::*; - match *self { - Identity => 0x5fc105, - Management => 0, - Signature => 0x5fc10a, - Decryption => 0x5fc10b, - Pinless => 0x5fc101, - Retired(RetiredSlotIndex(i)) => 0x5fc10c + i as u32, - Attestation => 0x5fff01, - } - } -} - crate::container::enum_subset! { #[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)] pub enum AdministrationAlgorithm: Algorithms { @@ -204,6 +100,18 @@ impl Keys { AsymmetricKeyReference::CardAuthentication => &self.card_authentication, } } + + pub fn asymetric_for_reference_mut( + &mut self, + key: AsymmetricKeyReference, + ) -> &mut Option> { + match key { + AsymmetricKeyReference::PivAuthentication => &mut self.authentication, + AsymmetricKeyReference::DigitalSignature => &mut self.signature, + AsymmetricKeyReference::KeyManagement => &mut self.key_management, + AsymmetricKeyReference::CardAuthentication => &mut self.card_authentication, + } + } } #[derive(Debug, Default, Eq, PartialEq)] @@ -486,23 +394,34 @@ impl Persistent { syscall!(client.delete(old_management_key)); } - pub fn set_asymmetric_key( + fn set_asymmetric_key( &mut self, - _key: AsymmetricKeyReference, - _id: KeyId, - _alg: AsymmetricAlgorithms, - _client: &mut impl trussed::Client, - ) -> Result>, Status> { - todo!() + key: AsymmetricKeyReference, + id: KeyId, + alg: AsymmetricAlgorithms, + ) -> Option> { + self.keys + .asymetric_for_reference_mut(key) + .replace(KeyWithAlg { id, alg }) } pub fn generate_asymmetric_key( &mut self, - _key: AsymmetricKeyReference, - _alg: AsymmetricAlgorithms, - _client: &mut impl trussed::Client, - ) -> Result { - todo!() + key: AsymmetricKeyReference, + alg: AsymmetricAlgorithms, + client: &mut impl trussed::Client, + ) -> KeyId { + let id = syscall!(client.generate_key( + alg.mechanism(), + StorageAttributes::default().set_persistence(Location::Internal) + )) + .key; + let old = self.set_asymmetric_key(key, id, alg); + self.save(client); + if let Some(old) = old { + syscall!(client.delete(old.id)); + } + id } pub fn initialize(client: &mut impl trussed::Client) -> Self {