Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encrypt data on external flash #57

Merged
merged 18 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fix warnings
  • Loading branch information
sosthene-nitrokey committed Aug 26, 2024
commit 0579bd03f80b80db02a2dc50d8d98962fb121f98
150 changes: 3 additions & 147 deletions src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,6 @@ macro_rules! enum_subset {
}
}

macro_rules! impl_transitive_into (
($leaf:ident, $($interemediary:ident),+ => $grandfather:ident) => {
impl From<$leaf> for $grandfather {
fn from(value: $leaf) -> $grandfather {
$(let value = $interemediary::from(value);)+
$grandfather::from(value)
}
}
}
);

pub(crate) use enum_subset;
use trussed::types::Location;

Expand Down Expand Up @@ -162,17 +151,13 @@ crate::enum_u8! {
impl KeyReference {
#[deprecated]
pub fn use_security_condition(self) -> SecurityCondition {
self.use_key_security_condition().into()
}

pub fn use_key_security_condition(self) -> KeySecurityCondition {
match self {
Self::SecureMessaging
| Self::CardAuthentication
| Self::PivCardApplicationAdministration
| Self::KeyManagement => KeySecurityCondition::Always,
Self::DigitalSignature => KeySecurityCondition::PinAlways(self.name()),
_ => KeySecurityCondition::Pin(self.name()),
| Self::KeyManagement => SecurityCondition::Always,
Self::DigitalSignature => SecurityCondition::PinAlways,
_ => SecurityCondition::Pin,
}
}

Expand Down Expand Up @@ -220,17 +205,11 @@ macro_rules! impl_sub_enum_methods {
($($name:ident,)*) => {
$(
impl $name {
#[deprecated]
pub fn use_security_condition(self) -> SecurityCondition {
let tmp: KeyReference = self.into();
#[allow(deprecated)]
tmp.use_security_condition()
}
pub fn use_key_security_condition(self) -> KeySecurityCondition {
let tmp: KeyReference = self.into();
tmp.use_key_security_condition()
}

pub fn name(self) -> &'static Path {
let tmp: KeyReference = self.into();
tmp.name()
Expand Down Expand Up @@ -278,11 +257,6 @@ enum_subset! {
}
}

enum AsymmetricKeyMaybeProtected {
Unprocteced(UnprotectedAsymmetricKeyReference),
Protected(ProtectedAsymmetricKeyReference),
}

impl AsymmetricKeyReference {
/// Get the location to store a new key (important for keys that are encrypted and should be generated in volatile stoarge)
pub fn storage(self, storage: Location) -> Location {
Expand All @@ -291,122 +265,6 @@ impl AsymmetricKeyReference {
_ => Location::Volatile,
}
}

pub fn encrypted_or_plain(self) -> AsymmetricKeyMaybeProtected {
match self {
Self::PivAuthentication => AsymmetricKeyMaybeProtected::Protected(
ProtectedAsymmetricKeyReference::PivAuthentication,
),
Self::DigitalSignature => AsymmetricKeyMaybeProtected::Protected(
ProtectedAsymmetricKeyReference::DigitalSignature,
),
Self::KeyManagement => AsymmetricKeyMaybeProtected::Unprocteced(
UnprotectedAsymmetricKeyReference::KeyManagement,
),
Self::CardAuthentication => AsymmetricKeyMaybeProtected::Unprocteced(
UnprotectedAsymmetricKeyReference::CardAuthentication,
),
Self::Retired01 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired01)
}
Self::Retired02 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired02)
}
Self::Retired03 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired03)
}
Self::Retired04 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired04)
}
Self::Retired05 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired05)
}
Self::Retired06 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired06)
}
Self::Retired07 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired07)
}
Self::Retired08 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired08)
}
Self::Retired09 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired09)
}
Self::Retired10 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired10)
}
Self::Retired11 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired11)
}
Self::Retired12 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired12)
}
Self::Retired13 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired13)
}
Self::Retired14 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired14)
}
Self::Retired15 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired15)
}
Self::Retired16 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired16)
}
Self::Retired17 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired17)
}
Self::Retired18 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired18)
}
Self::Retired19 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired19)
}
Self::Retired20 => {
AsymmetricKeyMaybeProtected::Protected(ProtectedAsymmetricKeyReference::Retired20)
}
}
}
}

enum_subset! {
#[derive(Debug)]
pub enum UnprotectedAsymmetricKeyReference: AsymmetricKeyReference {
KeyManagement,
CardAuthentication,
}
}

impl_transitive_into!(UnprotectedAsymmetricKeyReference, AsymmetricKeyReference => KeyReference);
impl_transitive_into!(ProtectedAsymmetricKeyReference, AsymmetricKeyReference => KeyReference);

enum_subset! {
#[derive(Debug)]
pub enum ProtectedAsymmetricKeyReference: AsymmetricKeyReference {
PivAuthentication,
DigitalSignature,
Retired01,
Retired02,
Retired03,
Retired04,
Retired05,
Retired06,
Retired07,
Retired08,
Retired09,
Retired10,
Retired11,
Retired12,
Retired13,
Retired14,
Retired15,
Retired16,
Retired17,
Retired18,
Retired19,
Retired20,
}
}

pub type GenerateKeyReference = AsymmetricKeyReference;
Expand Down Expand Up @@ -468,8 +326,6 @@ enum_subset! {
impl_sub_enum_methods!(
AttestKeyReference,
AsymmetricKeyReference,
UnprotectedAsymmetricKeyReference,
ProtectedAsymmetricKeyReference,
ChangeReferenceKeyReference,
VerifyKeyReference,
AuthenticateKeyReference,
Expand Down
17 changes: 8 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ pub type Result<O = ()> = iso7816::Result<O>;
use reply::Reply;
use state::{AdministrationAlgorithm, CommandCache, KeyWithAlg, LoadedState, State, TouchPolicy};

use crate::container::SecurityCondition;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Options {
storage: Location,
Expand Down Expand Up @@ -491,7 +489,7 @@ impl<'a, T: Client> LoadedAuthenticator<'a, T> {
challenge: None,
response: Some([]),
exponentiation: Some(p),
} => self.key_agreement(auth, p, reply.lend())?,
} => self.key_agreement(auth, p, reply.lend(), just_verified)?,
Auth {
witness: None,
challenge: Some([]),
Expand Down Expand Up @@ -698,9 +696,9 @@ impl<'a, T: Client> LoadedAuthenticator<'a, T> {
return Err(Status::IncorrectP1OrP2Parameter);
};

let Some(key) = self
.state
.use_valid_key(key_ref, self.trussed, self.options)?
let Some(key) =
self.state
.use_valid_key(key_ref, self.trussed, self.options, just_verified)?
else {
return Err(Status::ConditionsOfUseNotSatisfied);
};
Expand Down Expand Up @@ -765,6 +763,7 @@ impl<'a, T: Client> LoadedAuthenticator<'a, T> {
auth: GeneralAuthenticate,
data: &[u8],
mut reply: Reply<'_, R>,
just_verified: bool,
) -> Result {
info!("Request for exponentiation");
let key_reference = auth.key_reference.try_into().map_err(|_| {
Expand All @@ -774,9 +773,9 @@ impl<'a, T: Client> LoadedAuthenticator<'a, T> {
);
Status::IncorrectP1OrP2Parameter
})?;
let Some(key) = self
.state
.use_valid_key(key_reference, self.trussed, self.options)?
let Some(key) =
self.state
.use_valid_key(key_reference, self.trussed, self.options, just_verified)?
else {
return Err(Status::ConditionsOfUseNotSatisfied);
};
Expand Down
47 changes: 23 additions & 24 deletions src/state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::convert::{TryFrom, TryInto};
use core::mem::{self, replace};
use core::mem;

use flexiber::EncodableHeapless;
use heapless::Vec;
Expand All @@ -15,7 +15,6 @@ use trussed::{
};
use trussed_chunked::utils;

use crate::container::KeySecurityCondition;
use crate::piv_types::CardHolderUniqueIdentifier;
use crate::reply::Reply;
use crate::{constants::*, piv_types::AsymmetricAlgorithms};
Expand Down Expand Up @@ -213,26 +212,26 @@ impl Keys {
Some(mem::replace(&mut self.authentication_alg, new.alg))
}
AsymmetricKeyReference::DigitalSignature => self.signature_alg.replace(new.alg),
AsymmetricKeyReference::Retired01 => self.retired_keys[01].replace(new.alg),
AsymmetricKeyReference::Retired02 => self.retired_keys[02].replace(new.alg),
AsymmetricKeyReference::Retired03 => self.retired_keys[03].replace(new.alg),
AsymmetricKeyReference::Retired04 => self.retired_keys[04].replace(new.alg),
AsymmetricKeyReference::Retired05 => self.retired_keys[05].replace(new.alg),
AsymmetricKeyReference::Retired06 => self.retired_keys[06].replace(new.alg),
AsymmetricKeyReference::Retired07 => self.retired_keys[07].replace(new.alg),
AsymmetricKeyReference::Retired08 => self.retired_keys[08].replace(new.alg),
AsymmetricKeyReference::Retired09 => self.retired_keys[09].replace(new.alg),
AsymmetricKeyReference::Retired10 => self.retired_keys[10].replace(new.alg),
AsymmetricKeyReference::Retired11 => self.retired_keys[11].replace(new.alg),
AsymmetricKeyReference::Retired12 => self.retired_keys[12].replace(new.alg),
AsymmetricKeyReference::Retired13 => self.retired_keys[13].replace(new.alg),
AsymmetricKeyReference::Retired14 => self.retired_keys[14].replace(new.alg),
AsymmetricKeyReference::Retired15 => self.retired_keys[15].replace(new.alg),
AsymmetricKeyReference::Retired16 => self.retired_keys[16].replace(new.alg),
AsymmetricKeyReference::Retired17 => self.retired_keys[17].replace(new.alg),
AsymmetricKeyReference::Retired18 => self.retired_keys[18].replace(new.alg),
AsymmetricKeyReference::Retired19 => self.retired_keys[19].replace(new.alg),
AsymmetricKeyReference::Retired20 => self.retired_keys[20].replace(new.alg),
AsymmetricKeyReference::Retired01 => self.retired_keys[0].replace(new.alg),
AsymmetricKeyReference::Retired02 => self.retired_keys[1].replace(new.alg),
AsymmetricKeyReference::Retired03 => self.retired_keys[2].replace(new.alg),
AsymmetricKeyReference::Retired04 => self.retired_keys[3].replace(new.alg),
AsymmetricKeyReference::Retired05 => self.retired_keys[4].replace(new.alg),
AsymmetricKeyReference::Retired06 => self.retired_keys[5].replace(new.alg),
AsymmetricKeyReference::Retired07 => self.retired_keys[6].replace(new.alg),
AsymmetricKeyReference::Retired08 => self.retired_keys[7].replace(new.alg),
AsymmetricKeyReference::Retired09 => self.retired_keys[8].replace(new.alg),
AsymmetricKeyReference::Retired10 => self.retired_keys[9].replace(new.alg),
AsymmetricKeyReference::Retired11 => self.retired_keys[10].replace(new.alg),
AsymmetricKeyReference::Retired12 => self.retired_keys[11].replace(new.alg),
AsymmetricKeyReference::Retired13 => self.retired_keys[12].replace(new.alg),
AsymmetricKeyReference::Retired14 => self.retired_keys[13].replace(new.alg),
AsymmetricKeyReference::Retired15 => self.retired_keys[14].replace(new.alg),
AsymmetricKeyReference::Retired16 => self.retired_keys[15].replace(new.alg),
AsymmetricKeyReference::Retired17 => self.retired_keys[16].replace(new.alg),
AsymmetricKeyReference::Retired18 => self.retired_keys[17].replace(new.alg),
AsymmetricKeyReference::Retired19 => self.retired_keys[18].replace(new.alg),
AsymmetricKeyReference::Retired20 => self.retired_keys[19].replace(new.alg),
AsymmetricKeyReference::KeyManagement
| AsymmetricKeyReference::CardAuthentication => unreachable!(),
})
Expand Down Expand Up @@ -313,11 +312,11 @@ impl<'t> LoadedState<'t> {
key: AsymmetricKeyReference,
client: &mut impl crate::Client,
options: &crate::Options,
just_verified: bool,
) -> Result<Option<UseValidKey>, Status> {
let security_condition = key.use_security_condition();
match security_condition {
SecurityCondition::PinAlways if self.volatile.app_security_status.pin_just_verified => {
}
SecurityCondition::PinAlways if just_verified => {}
SecurityCondition::Pin if self.volatile.app_security_status.pin_verified.is_some() => {}
SecurityCondition::Always => {}
_ => return Err(Status::SecurityStatusNotSatisfied),
Expand Down