Skip to content
15 changes: 12 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,26 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
se05x = "0.0.1"
se05x = { version = "0.0.1", features = ["serde", "builder"] }
trussed = { version = "0.1.0", features = ["serde-extensions"] }
trussed-auth = "0.2.2"
trussed-staging = { version = "0.1.0", features = ["wrap-key-to-file", "chunked", "encrypted-chunked"] }
delog = "0.1.6"
embedded-hal = "0.2.7"
hkdf = { version = "0.12.3", default-features = false }
sha2 = { version = "0.10.7", default-features = false }
hex-literal = "0.4.1"
serde-byte-array = "0.1.2"
iso7816 = "0.1.1"
hmac = "0.12.1"
serde = { version = "1.0.185", default-features = false, features = ["derive"] }
rand = { version = "0.8.5", default-features = false }
littlefs2 = "0.4.0"

[patch.crates-io]
se05x = { git = "https://github.com/Nitrokey/se05x.git", rev = "db1ddea25cc382355b4292352652da656abc3005"}
se05x = { git = "https://github.com/Nitrokey/se05x.git", rev = "bf696ee99bc893dda385dbbf47e0cdab9c58aba6"}
trussed = { git = "https://github.com/Nitrokey/trussed", tag = "v0.1.0-nitrokey.12" }
trussed-auth = { git = "https://github.com/Nitrokey/trussed-auth", tag = "v0.2.2-nitrokey.1" }
trussed-auth = { git = "https://github.com/Nitrokey/trussed-auth", rev = "98eb1e5c1283bb68e0a1ae2f6a7d3cdfc33c3697" }
trussed-staging = { git = "https://github.com/Nitrokey/trussed-staging.git", branch = "hmacsha256p256" }
iso7816 = { git = "https://github.com/sosthene-nitrokey/iso7816.git", rev = "160ca3bbd8e21ec4e4ee1e0748e1eaa53a45c97f"}

Expand Down
72 changes: 59 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,74 @@
#![no_std]

use embedded_hal::blocking::delay::DelayUs;
use rand::{CryptoRng, Rng, RngCore};
use se05x::{
se05x::{commands::GetRandom, Se05X},
se05x::{commands::GetRandom, ObjectId, Se05X},
t1::I2CForT1,
};
use trussed::{
api::{reply, request, Request},
backend::Backend,
config::MAX_MESSAGE_LENGTH,
serde_extensions::ExtensionImpl,
types::Message,
types::{Location, Message},
Bytes,
};

#[macro_use]
extern crate delog;
generate_macros!();

mod trussed_auth_impl;
use trussed_auth::MAX_HW_KEY_LEN;
use trussed_auth_impl::{AuthContext, HardwareKey};

/// Need overhead for TLV + SW bytes
const BUFFER_LEN: usize = 2048;
const BACKEND_DIR: &str = "se050-bak";

pub enum Se05xLocation {
Persistent,
Transient,
}

impl From<Location> for Se05xLocation {
fn from(value: Location) -> Self {
match value {
Location::Volatile => Self::Transient,
Location::External | Location::Internal => Self::Persistent,
}
}
}

pub struct Se050Backend<Twi, D> {
se: Se05X<Twi, D>,
enabled: bool,
failed_enable: Option<se05x::se05x::Error>,
metadata_location: Location,
hw_key: HardwareKey,
}

impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
pub fn new(se: Se05X<Twi, D>) -> Self {
pub fn new(
se: Se05X<Twi, D>,
metadata_location: Location,
hardware_key: Option<Bytes<{ MAX_HW_KEY_LEN }>>,
) -> Self {
Se050Backend {
se,
enabled: false,
failed_enable: None,
metadata_location,
hw_key: match hardware_key {
None => HardwareKey::None,
Some(k) => HardwareKey::Raw(k),
},
}
}

fn random_bytes(&mut self, count: usize) -> Result<trussed::Reply, trussed::Error> {
if count >= MAX_MESSAGE_LENGTH {
return Err(trussed::Error::MechanismParamInvalid);
}

fn enable(&mut self) -> Result<(), trussed::Error> {
if !self.enabled {
debug!("Enabling");
if let Err(e) = self.se.enable() {
self.failed_enable = Some(e);
} else {
Expand All @@ -53,6 +81,14 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
return Err(trussed::Error::FunctionFailed);
}

Ok(())
}

fn random_bytes(&mut self, count: usize) -> Result<trussed::Reply, trussed::Error> {
if count >= MAX_MESSAGE_LENGTH {
return Err(trussed::Error::MechanismParamInvalid);
}

let mut buf = [0; BUFFER_LEN];
let res = self
.se
Expand All @@ -77,19 +113,29 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
}
}

#[derive(Default, Debug)]
pub struct Context {
auth: AuthContext,
}

impl<Twi: I2CForT1, D: DelayUs<u32>> Backend for Se050Backend<Twi, D> {
type Context = ();
type Context = Context;

fn request<P: trussed::Platform>(
&mut self,
core_ctx: &mut trussed::types::CoreContext,
backend_ctx: &mut Self::Context,
_core_ctx: &mut trussed::types::CoreContext,
_backend_ctx: &mut Self::Context,
request: &Request,
resources: &mut trussed::service::ServiceResources<P>,
_resources: &mut trussed::service::ServiceResources<P>,
) -> Result<trussed::Reply, trussed::Error> {
self.enable()?;
match request {
Request::RandomBytes(request::RandomBytes { count }) => self.random_bytes(*count),
_ => Err(trussed::Error::RequestNotAvailable),
}
}
}

fn generate_object_id<R: RngCore + CryptoRng>(rng: &mut R) -> ObjectId {
ObjectId(rng.gen_range(0x00000002u32..0x7FFF0000).to_be_bytes())
}
Loading