Skip to content

Commit

Permalink
Encrypt keys
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Apr 11, 2023
1 parent b8d080e commit 09e07cc
Show file tree
Hide file tree
Showing 8 changed files with 408 additions and 200 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ log-error = []
interchange = { git = "https://github.com/trussed-dev/interchange", rev = "fe5633466640e1e9a8c06d9b5dd1d0af08c272af" }
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" , rev = "56848118cefa74eaa4f33e93d79930d7e66717ee" }
trussed = { git = "https://github.com/Nitrokey/trussed" , rev = "fc4758a0ee3b23b3f358e94dec461ace843eecc5" }
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth.git", tag= "v0.2.1"}
trussed-rsa-alloc = { git = "https://github.com/Nitrokey/trussed-rsa-backend", rev = "311d2366f99cc300b03d61e7f6a0a07abd3e8700" }

Expand Down
14 changes: 4 additions & 10 deletions src/command/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,12 +849,9 @@ fn get_arbitrary_user_enc_do<const R: usize, T: trussed::Client + AuthClient>(
ctx: LoadedContext<'_, R, T>,
obj: ArbitraryDO,
) -> Result<(), Status> {
if !ctx.state.volatile.other_verified() {
let Some(k) = ctx.state.volatile.other_verified_kek() else {
return Err(Status::SecurityStatusNotSatisfied);
}
// Unwrap cannnot fail becaus of above check
#[allow(clippy::unwrap_used)]
let k = ctx.state.volatile.user_kek().unwrap();
};
get_arbitrary_enc_do(ctx, obj, k)
}

Expand Down Expand Up @@ -1269,12 +1266,9 @@ fn put_arbitrary_user_enc_do<const R: usize, T: trussed::Client + AuthClient>(
ctx: LoadedContext<'_, R, T>,
obj: ArbitraryDO,
) -> Result<(), Status> {
if !ctx.state.volatile.other_verified() {
let Some(k) =ctx.state.volatile.other_verified_kek() else {
return Err(Status::SecurityStatusNotSatisfied);
}
// Unwrap cannnot fail becaus of above check
#[allow(clippy::unwrap_used)]
let k = ctx.state.volatile.user_kek().unwrap();
};
put_arbitrary_enc_do(ctx, obj, k)
}

Expand Down
103 changes: 43 additions & 60 deletions src/command/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@

use hex_literal::hex;
use iso7816::Status;
use trussed::try_syscall;
use trussed::types::{KeyId, KeySerialization, Location, Mechanism, StorageAttributes};
use trussed::{syscall, try_syscall};
use trussed_auth::AuthClient;

use crate::card::LoadedContext;
use crate::state::KeyOrigin;
use crate::types::*;
use crate::utils::InspectErr;

const KEYGEN_DO_TAG: &[u8] = &hex!("7f49");

Expand Down Expand Up @@ -103,76 +102,79 @@ pub fn aut<const R: usize, T: trussed::Client + AuthClient>(

#[cfg(feature = "rsa")]
fn gen_rsa_key<const R: usize, T: trussed::Client + AuthClient>(
ctx: LoadedContext<'_, R, T>,
mut ctx: LoadedContext<'_, R, T>,
key: KeyType,
mechanism: Mechanism,
) -> Result<(), Status> {
let client = ctx.backend.client_mut();
let key_id = try_syscall!(client.generate_key(
mechanism,
StorageAttributes::new().set_persistence(ctx.options.storage)
StorageAttributes::default().set_persistence(Location::Volatile)
))
.map_err(|_err| {
error!("Failed to generate key: {_err:?}");
Status::UnspecifiedNonpersistentExecutionError
})?
.key;

if let Some((old_key, _)) = ctx
.state
.persistent
.set_key_id(
let pubkey = try_syscall!(client.derive_key(
mechanism,
key_id,
None,
StorageAttributes::default().set_persistence(ctx.options.storage)
))
.map_err(|_err| {
warn!("Failed to derive_ke: {_err:?}");
Status::UnspecifiedNonpersistentExecutionError
})?
.key;
ctx.state
.set_key(
key,
Some((key_id, KeyOrigin::Generated)),
Some((key_id, (pubkey, KeyOrigin::Generated))),
client,
ctx.options.storage,
)
.map_err(|_| Status::UnspecifiedNonpersistentExecutionError)?
{
// Deletion is not a fatal error
try_syscall!(client.delete(old_key))
.inspect_err_stable(|_err| {
error!("Failed to delete old key: {_err:?}");
})
.ok();
}
read_rsa_key(ctx, key_id, mechanism)
.map_err(|_| Status::UnspecifiedNonpersistentExecutionError)?;
read_rsa_key(ctx, pubkey, mechanism)
}

fn gen_ec_key<const R: usize, T: trussed::Client + AuthClient>(
ctx: LoadedContext<'_, R, T>,
mut ctx: LoadedContext<'_, R, T>,
key: KeyType,
curve: CurveAlgo,
) -> Result<(), Status> {
let client = ctx.backend.client_mut();
let key_id = try_syscall!(client.generate_key(
curve.mechanism(),
StorageAttributes::new().set_persistence(ctx.options.storage)
StorageAttributes::default().set_persistence(Location::Volatile)
))
.map_err(|_err| {
error!("Failed to generate key: {_err:?}");
Status::UnspecifiedNonpersistentExecutionError
})?
.key;
if let Some((old_key, _)) = ctx
.state
.persistent
.set_key_id(

let pubkey = try_syscall!(client.derive_key(
curve.mechanism(),
key_id,
None,
StorageAttributes::default().set_persistence(ctx.options.storage)
))
.map_err(|_err| {
warn!("Failed to derive_ke: {_err:?}");
Status::UnspecifiedNonpersistentExecutionError
})?
.key;
ctx.state
.set_key(
key,
Some((key_id, KeyOrigin::Generated)),
Some((key_id, (pubkey, KeyOrigin::Generated))),
client,
ctx.options.storage,
)
.map_err(|_| Status::UnspecifiedNonpersistentExecutionError)?
{
// Deletion is not a fatal error
try_syscall!(client.delete(old_key))
.inspect_err_stable(|_err| {
error!("Failed to delete old key: {_err:?}");
})
.ok();
}
read_ec_key(ctx, key_id, curve)
.map_err(|_| Status::UnspecifiedNonpersistentExecutionError)?;
read_ec_key(ctx, pubkey, curve)
}

pub fn read_sign<const R: usize, T: trussed::Client + AuthClient>(
Expand All @@ -181,7 +183,7 @@ pub fn read_sign<const R: usize, T: trussed::Client + AuthClient>(
let key_id = ctx
.state
.persistent
.key_id(KeyType::Sign)
.public_key_id(KeyType::Sign)
.ok_or(Status::KeyReferenceNotFound)?;

let algo = ctx.state.persistent.sign_alg();
Expand All @@ -200,7 +202,7 @@ pub fn read_dec<const R: usize, T: trussed::Client + AuthClient>(
let key_id = ctx
.state
.persistent
.key_id(KeyType::Dec)
.public_key_id(KeyType::Dec)
.ok_or(Status::KeyReferenceNotFound)?;

let algo = ctx.state.persistent.dec_alg();
Expand All @@ -225,7 +227,7 @@ pub fn read_aut<const R: usize, T: trussed::Client + AuthClient>(
let key_id = ctx
.state
.persistent
.key_id(KeyType::Aut)
.public_key_id(KeyType::Aut)
.ok_or(Status::KeyReferenceNotFound)?;

let algo = ctx.state.persistent.aut_alg();
Expand Down Expand Up @@ -265,26 +267,17 @@ fn serialize_25519<const R: usize, T: trussed::Client + AuthClient>(

fn read_ec_key<const R: usize, T: trussed::Client + AuthClient>(
mut ctx: LoadedContext<'_, R, T>,
key_id: KeyId,
public_key: KeyId,
curve: CurveAlgo,
) -> Result<(), Status> {
let client = ctx.backend.client_mut();
let public_key = syscall!(client.derive_key(
curve.mechanism(),
key_id,
None,
StorageAttributes::new().set_persistence(Location::Volatile)
))
.key;
let serialized =
try_syscall!(client.serialize_key(curve.mechanism(), public_key, KeySerialization::Raw))
.map_err(|_err| {
error!("Failed to serialize public key: {_err:?}");
syscall!(client.delete(public_key));
Status::UnspecifiedNonpersistentExecutionError
})?
.serialized_key;
syscall!(client.delete(public_key));
ctx.reply.expand(KEYGEN_DO_TAG)?;
let offset = ctx.reply.len();
serialize_pub(curve, ctx.lend(), &serialized)?;
Expand All @@ -294,32 +287,23 @@ fn read_ec_key<const R: usize, T: trussed::Client + AuthClient>(
#[cfg(feature = "rsa")]
fn read_rsa_key<const R: usize, T: trussed::Client + AuthClient>(
mut ctx: LoadedContext<'_, R, T>,
key_id: KeyId,
public_key: KeyId,
mechanism: Mechanism,
) -> Result<(), Status> {
let client = ctx.backend.client_mut();
let public_key = syscall!(client.derive_key(
mechanism,
key_id,
None,
StorageAttributes::new().set_persistence(Location::Volatile)
))
.key;
ctx.reply.expand(KEYGEN_DO_TAG)?;
let offset = ctx.reply.len();

let pubkey_data =
try_syscall!(client.serialize_key(mechanism, public_key, KeySerialization::RsaParts))
.map_err(|_err| {
error!("Failed to serialize public key N: {_err:?}");
syscall!(client.delete(public_key));
Status::UnspecifiedNonpersistentExecutionError
})?
.serialized_key;
let parsed_pubkey_data: RsaPublicParts =
trussed::postcard_deserialize(&pubkey_data).map_err(|_err| {
error!("Failed to deserialize public key");
syscall!(client.delete(public_key));
Status::UnspecifiedNonpersistentExecutionError
})?;
ctx.reply.expand(&[0x81])?;
Expand All @@ -332,7 +316,6 @@ fn read_rsa_key<const R: usize, T: trussed::Client + AuthClient>(

ctx.reply.prepend_len(offset)?;

syscall!(client.delete(public_key));
Ok(())
}

Expand Down
Loading

0 comments on commit 09e07cc

Please sign in to comment.