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

Use upstream trussed #149

Merged
merged 2 commits into from
Apr 26, 2023
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
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ serde = { version = "1.0", default-features = false }
subtle = { version = "2.4.1", default-features = false }
trussed = "0.1.0"
trussed-rsa-alloc = { version = "0.1.0", optional = true }
trussed-staging = { version = "0.1.0", features = ["wrap-key-to-file"]}
serde_repr = "0.1"
hex-literal = "0.3.4"
trussed-auth = "0.2.1"
Expand Down Expand Up @@ -85,11 +86,11 @@ log-warn = []
log-error = []

[patch.crates-io]
littlefs2 = { git = "https://github.com/Nitrokey/littlefs2", tag = "v0.3.2-nitrokey-2" }
p256-cortex-m4 = { git = "https://github.com/Nitrokey/p256-cortex-m4", tag = "v0.1.0-alpha.6-nitrokey-1" }
trussed = { git = "https://github.com/Nitrokey/trussed" , tag = "v0.1.0-nitrokey.9" }
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth.git", tag= "v0.2.1"}
trussed = { git = "https://github.com/trussed-dev/trussed" , rev = "55ea391367fce4bf5093ff2d3c79041d7aef0485" }
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth.git", branch = "core-context"}
robin-nitrokey marked this conversation as resolved.
Show resolved Hide resolved
trussed-rsa-alloc = { git = "https://github.com/Nitrokey/trussed-rsa-backend", tag = "v0.1.0" }
trussed-staging = { git = "https://github.com/Nitrokey/trussed-staging", branch = "main" }
robin-nitrokey marked this conversation as resolved.
Show resolved Hide resolved

[package.metadata.docs.rs]
all-features = true
Expand Down
9 changes: 4 additions & 5 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,29 @@
//!
//! As this crate is designed to be usable on any platform, it cannot rely on a specific data
//! storage and cryptography implementation. Instead, a [`Card`][`crate::Card`] has to be provided
//! with a Backend wrapping a [`trussed::Client`][trussed::Client]
//! with a Backend wrapping a [`crate::card::Client`][crate::card::Client]

use core::fmt::Debug;

use trussed::try_syscall;
use trussed_auth::AuthClient;

use crate::error::Error;

/// Backend that provides data storage and cryptography operations.
/// Mostly a wrapper around a trussed client
#[derive(Clone)]
pub struct Backend<T: trussed::Client + AuthClient> {
pub struct Backend<T: crate::card::Client> {
client: T,
}

impl<T: trussed::Client + AuthClient> Debug for Backend<T> {
impl<T: crate::card::Client> Debug for Backend<T> {
fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let Self { client: _client } = self;
fmt.debug_struct("Backend").finish()
}
}

impl<T: trussed::Client + AuthClient> Backend<T> {
impl<T: crate::card::Client> Backend<T> {
/// Create new backend from a trussed client
pub fn new(client: T) -> Self {
Self { client }
Expand Down
26 changes: 15 additions & 11 deletions src/card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ pub const PGP_SMARTCARD_VERSION: [u8; 2] = [3, 4];
/// This is the main entry point for this crate. It takes care of the command handling and state
/// management.
#[derive(Clone, Debug)]
pub struct Card<T: trussed::Client + AuthClient> {
pub struct Card<T: Client> {
backend: Backend<T>,
options: Options,
state: State,
}

impl<T: trussed::Client + AuthClient> Card<T> {
impl<T: Client> Card<T> {
/// Creates a new OpenPGP card with the given backend and options.
pub fn new(client: T, options: Options) -> Self {
let state = State::default();
Expand Down Expand Up @@ -73,23 +73,21 @@ impl<T: trussed::Client + AuthClient> Card<T> {
}
}

impl<T: trussed::Client + AuthClient> Drop for Card<T> {
impl<T: Client> Drop for Card<T> {
fn drop(&mut self) {
self.reset()
}
}

impl<T: trussed::Client + AuthClient> iso7816::App for Card<T> {
impl<T: Client> iso7816::App for Card<T> {
fn aid(&self) -> iso7816::Aid {
// TODO: check truncation length
iso7816::Aid::new_truncatable(&self.options.aid(), RID.len())
}
}

#[cfg(feature = "apdu-dispatch")]
impl<T: trussed::Client + AuthClient, const C: usize, const R: usize> apdu_dispatch::App<C, R>
for Card<T>
{
impl<T: Client, const C: usize, const R: usize> apdu_dispatch::App<C, R> for Card<T> {
fn select(
&mut self,
command: &iso7816::Command<C>,
Expand Down Expand Up @@ -172,15 +170,15 @@ impl Default for Options {
}

#[derive(Debug)]
pub struct Context<'a, const R: usize, T: trussed::Client + AuthClient> {
pub struct Context<'a, const R: usize, T: Client> {
pub backend: &'a mut Backend<T>,
pub options: &'a Options,
pub state: &'a mut State,
pub data: &'a [u8],
pub reply: Reply<'a, R>,
}

impl<'a, const R: usize, T: trussed::Client + AuthClient> Context<'a, R, T> {
impl<'a, const R: usize, T: Client> Context<'a, R, T> {
pub fn load_state(&mut self) -> Result<LoadedContext<'_, R, T>, Status> {
Ok(LoadedContext {
state: self
Expand Down Expand Up @@ -211,15 +209,15 @@ impl<'a, const R: usize, T: trussed::Client + AuthClient> Context<'a, R, T> {

#[derive(Debug)]
/// Context with the persistent state loaded from flash
pub struct LoadedContext<'a, const R: usize, T: trussed::Client + AuthClient> {
pub struct LoadedContext<'a, const R: usize, T: Client> {
pub backend: &'a mut Backend<T>,
pub options: &'a Options,
pub state: LoadedState<'a>,
pub data: &'a [u8],
pub reply: Reply<'a, R>,
}

impl<'a, const R: usize, T: trussed::Client + AuthClient> LoadedContext<'a, R, T> {
impl<'a, const R: usize, T: Client> LoadedContext<'a, R, T> {
/// Lend the context
///
/// The resulting `LoadedContext` has a shorter lifetime than the original one, meaning that it
Expand Down Expand Up @@ -248,3 +246,9 @@ mod tests {
)
}
}

use trussed_staging::wrap_key_to_file::WrapKeyToFileClient;

/// Super trait with all trussed extensions required by opcard
pub trait Client: trussed::Client + AuthClient + WrapKeyToFileClient {}
impl<C: trussed::Client + WrapKeyToFileClient + AuthClient> Client for C {}
30 changes: 15 additions & 15 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod pso;

use hex_literal::hex;
use iso7816::Status;
use trussed_auth::{AuthClient, PinId};
use trussed_auth::PinId;

use crate::card::{Context, LoadedContext, RID};
use crate::error::Error;
Expand Down Expand Up @@ -55,7 +55,7 @@ impl Command {
}
}

pub fn exec<const R: usize, T: trussed::Client + AuthClient>(
pub fn exec<const R: usize, T: crate::card::Client>(
&self,
mut ctx: Context<'_, R, T>,
) -> Result<(), Status> {
Expand Down Expand Up @@ -336,7 +336,7 @@ impl TryFrom<u8> for ManageSecurityEnvironmentMode {
}

// § 7.2.1
fn select<const R: usize, T: trussed::Client + AuthClient>(
fn select<const R: usize, T: crate::card::Client>(
context: Context<'_, R, T>,
) -> Result<(), Status> {
if context.data.starts_with(&RID) {
Expand All @@ -350,7 +350,7 @@ fn select<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.2
fn verify<const R: usize, T: trussed::Client + AuthClient>(
fn verify<const R: usize, T: crate::card::Client>(
mut ctx: LoadedContext<'_, R, T>,
mode: VerifyMode,
password: PasswordMode,
Expand Down Expand Up @@ -401,7 +401,7 @@ fn verify<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.3
fn change_reference_data<const R: usize, T: trussed::Client + AuthClient>(
fn change_reference_data<const R: usize, T: crate::card::Client>(
mut ctx: LoadedContext<'_, R, T>,
password: Password,
) -> Result<(), Status> {
Expand Down Expand Up @@ -438,7 +438,7 @@ fn change_reference_data<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.14
fn gen_keypair<const R: usize, T: trussed::Client + AuthClient>(
fn gen_keypair<const R: usize, T: crate::card::Client>(
context: LoadedContext<'_, R, T>,
mode: GenerateAsymmetricKeyPairMode,
) -> Result<(), Status> {
Expand All @@ -464,7 +464,7 @@ fn gen_keypair<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.16
fn terminate_df<const R: usize, T: trussed::Client + AuthClient>(
fn terminate_df<const R: usize, T: crate::card::Client>(
mut ctx: Context<'_, R, T>,
) -> Result<(), Status> {
if let Ok(ctx) = ctx.load_state() {
Expand All @@ -490,7 +490,7 @@ fn unspecified_delete_error<E: core::fmt::Debug>(_err: E) -> Status {
Status::UnspecifiedPersistentExecutionError
}

fn factory_reset<const R: usize, T: trussed::Client + AuthClient>(
fn factory_reset<const R: usize, T: crate::card::Client>(
ctx: Context<'_, R, T>,
) -> Result<(), Status> {
ctx.state.volatile.clear(ctx.backend.client_mut());
Expand Down Expand Up @@ -521,7 +521,7 @@ fn factory_reset<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.17
fn activate_file<const R: usize, T: trussed::Client + AuthClient>(
fn activate_file<const R: usize, T: crate::card::Client>(
mut ctx: Context<'_, R, T>,
) -> Result<(), Status> {
if State::lifecycle(ctx.backend.client_mut(), ctx.options.storage) == LifeCycle::Operational {
Expand All @@ -542,7 +542,7 @@ fn activate_file<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.4
fn reset_retry_conter<const R: usize, T: trussed::Client + AuthClient>(
fn reset_retry_conter<const R: usize, T: crate::card::Client>(
ctx: LoadedContext<'_, R, T>,
mode: ResetRetryCounterMode,
) -> Result<(), Status> {
Expand All @@ -552,7 +552,7 @@ fn reset_retry_conter<const R: usize, T: trussed::Client + AuthClient>(
}
}

fn reset_retry_conter_with_p3<const R: usize, T: trussed::Client + AuthClient>(
fn reset_retry_conter_with_p3<const R: usize, T: crate::card::Client>(
mut ctx: LoadedContext<'_, R, T>,
) -> Result<(), Status> {
if ctx.data.len() < MIN_LENGTH_USER_PIN || ctx.data.len() > MAX_PIN_LENGTH {
Expand All @@ -575,7 +575,7 @@ fn reset_retry_conter_with_p3<const R: usize, T: trussed::Client + AuthClient>(
})
}

fn reset_retry_conter_with_code<const R: usize, T: trussed::Client + AuthClient>(
fn reset_retry_conter_with_code<const R: usize, T: crate::card::Client>(
mut ctx: LoadedContext<'_, R, T>,
) -> Result<(), Status> {
let code_len = ctx.state.persistent.reset_code_len().ok_or_else(|| {
Expand Down Expand Up @@ -626,7 +626,7 @@ fn reset_retry_conter_with_code<const R: usize, T: trussed::Client + AuthClient>
}

// § 7.2.5
fn select_data<const R: usize, T: trussed::Client + AuthClient>(
fn select_data<const R: usize, T: crate::card::Client>(
ctx: Context<'_, R, T>,
occurrence: Occurrence,
) -> Result<(), Status> {
Expand All @@ -643,7 +643,7 @@ fn select_data<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.15
fn get_challenge<const R: usize, T: trussed::Client + AuthClient>(
fn get_challenge<const R: usize, T: crate::card::Client>(
mut ctx: Context<'_, R, T>,
expected: usize,
) -> Result<(), Status> {
Expand All @@ -665,7 +665,7 @@ fn get_challenge<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.18
fn manage_security_environment<const R: usize, T: trussed::Client + AuthClient>(
fn manage_security_environment<const R: usize, T: crate::card::Client>(
ctx: Context<'_, R, T>,
mode: ManageSecurityEnvironmentMode,
) -> Result<(), Status> {
Expand Down
Loading