Skip to content

Commit

Permalink
Add keys to the runtime state
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Mar 15, 2023
1 parent 7ff797f commit 7fe1555
Show file tree
Hide file tree
Showing 7 changed files with 261 additions and 62 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ log-error = []

[patch.crates-io]
interchange = { git = "https://github.com/trussed-dev/interchange", rev = "fe5633466640e1e9a8c06d9b5dd1d0af08c272af" }
littlefs2 = { git = "https://github.com/Nitrokey/littlefs2", tag = "v0.3.2-nitrokey-1" }
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.6" }
trussed = { git = "https://github.com/Nitrokey/trussed" , tag = "v0.1.0-nitrokey.8" }
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth.git", tag= "v0.1.0"}

[package.metadata.docs.rs]
Expand Down
7 changes: 7 additions & 0 deletions src/card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,18 @@ impl<T: trussed::Client + AuthClient> Card<T> {

/// Resets the state of the card.
pub fn reset(&mut self) {
self.state.volatile.clear(self.backend.client_mut());
let state = State::default();
self.state = state;
}
}

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

impl<T: trussed::Client + AuthClient> iso7816::App for Card<T> {
fn aid(&self) -> iso7816::Aid {
// TODO: check truncation length
Expand Down
66 changes: 29 additions & 37 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,9 @@ fn verify<const R: usize, T: trussed::Client + AuthClient>(
VerifyMode::SetOrCheck => {
if ctx.data.is_empty() {
let already_validated = match password {
PasswordMode::Pw1Sign => ctx.state.volatile.sign_verified,
PasswordMode::Pw1Other => ctx.state.volatile.other_verified,
PasswordMode::Pw3 => ctx.state.volatile.admin_verified,
PasswordMode::Pw1Sign => ctx.state.volatile.sign_verified(),
PasswordMode::Pw1Other => ctx.state.volatile.other_verified(),
PasswordMode::Pw3 => ctx.state.volatile.admin_verified(),
};
if already_validated {
Ok(())
Expand All @@ -373,32 +373,27 @@ fn verify<const R: usize, T: trussed::Client + AuthClient>(
))
}
} else {
let pin = password.into();
if ctx
.state
.verify_pin(ctx.backend.client_mut(), ctx.options.storage, ctx.data, pin)
.is_ok()
{
match password {
PasswordMode::Pw1Sign => ctx.state.volatile.sign_verified = true,
PasswordMode::Pw1Other => ctx.state.volatile.other_verified = true,
PasswordMode::Pw3 => ctx.state.volatile.admin_verified = true,
}
Ok(())
} else {
Err(Status::RemainingRetries(
ctx.state
.persistent
.remaining_tries(ctx.backend.client_mut(), password.into()),
))
}
ctx.state
.verify_pin(
ctx.backend.client_mut(),
ctx.options.storage,
ctx.data,
password,
)
.map_err(|_| {
Status::RemainingRetries(
ctx.state
.persistent
.remaining_tries(ctx.backend.client_mut(), password.into()),
)
})
}
}
VerifyMode::Reset => {
match password {
PasswordMode::Pw1Sign => ctx.state.volatile.sign_verified = false,
PasswordMode::Pw1Other => ctx.state.volatile.other_verified = false,
PasswordMode::Pw3 => ctx.state.volatile.admin_verified = false,
PasswordMode::Pw1Sign => ctx.state.volatile.clear_sign(ctx.backend.client_mut()),
PasswordMode::Pw1Other => ctx.state.volatile.clear_other(ctx.backend.client_mut()),
PasswordMode::Pw3 => ctx.state.volatile.clear_admin(ctx.backend.client_mut()),
}
Ok(())
}
Expand Down Expand Up @@ -430,7 +425,7 @@ fn change_reference_data<const R: usize, T: trussed::Client + AuthClient>(
// Verify the old pin before returning for wrong length to avoid leaking information about the
// length of the PIN
ctx.state
.verify_pin(client_mut, ctx.options.storage, old, password)
.check_pin(client_mut, old, password)
.map_err(|_| Status::VerificationFailed)?;

if current_len + min_len > ctx.data.len() {
Expand All @@ -457,7 +452,7 @@ fn gen_keypair<const R: usize, T: trussed::Client + AuthClient>(
};
}

if !context.state.volatile.admin_verified {
if !context.state.volatile.admin_verified() {
return Err(Status::SecurityStatusNotSatisfied);
}

Expand All @@ -473,7 +468,7 @@ fn terminate_df<const R: usize, T: trussed::Client + AuthClient>(
mut ctx: Context<'_, R, T>,
) -> Result<(), Status> {
if let Ok(ctx) = ctx.load_state() {
if ctx.state.volatile.admin_verified
if ctx.state.volatile.admin_verified()
|| ctx
.state
.persistent
Expand All @@ -498,6 +493,7 @@ fn unspecified_delete_error<E: core::fmt::Debug>(_err: E) -> Status {
fn factory_reset<const R: usize, T: trussed::Client + AuthClient>(
ctx: Context<'_, R, T>,
) -> Result<(), Status> {
ctx.state.volatile.clear(ctx.backend.client_mut());
*ctx.state = Default::default();
try_syscall!(ctx
.backend
Expand Down Expand Up @@ -532,7 +528,6 @@ fn activate_file<const R: usize, T: trussed::Client + AuthClient>(
}

factory_reset(ctx.lend())?;
*ctx.state = Default::default();
let ctx = ctx.load_state()?;
ctx.state
.persistent
Expand Down Expand Up @@ -567,7 +562,7 @@ fn reset_retry_conter_with_p3<const R: usize, T: trussed::Client + AuthClient>(
return Err(Status::IncorrectDataParameter);
}

if !ctx.state.volatile.admin_verified {
if !ctx.state.volatile.admin_verified() {
return Err(Status::SecurityStatusNotSatisfied);
}

Expand Down Expand Up @@ -602,12 +597,9 @@ fn reset_retry_conter_with_code<const R: usize, T: trussed::Client + AuthClient>
ctx.data.split_at(code_len)
};

let res = ctx.state.verify_pin(
ctx.backend.client_mut(),
ctx.options.storage,
old,
Password::ResetCode,
);
let res = ctx
.state
.check_pin(ctx.backend.client_mut(), old, Password::ResetCode);
match res {
Err(Error::InvalidPin) => {
return Err(Status::RemainingRetries(
Expand All @@ -620,7 +612,7 @@ fn reset_retry_conter_with_code<const R: usize, T: trussed::Client + AuthClient>
error!("Failed to check reset code: {_err:?}");
return Err(Status::UnspecifiedNonpersistentExecutionError);
}
Ok(()) => {}
Ok(_reset_kek) => {}
}

if new.len() > MAX_PIN_LENGTH || new.len() < MIN_LENGTH_USER_PIN {
Expand Down
8 changes: 4 additions & 4 deletions src/command/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,10 +796,10 @@ fn get_arbitrary_do<const R: usize, T: trussed::Client + AuthClient>(
obj: ArbitraryDO,
) -> Result<(), Status> {
match obj.read_permission() {
PermissionRequirement::User if !ctx.state.volatile.other_verified => {
PermissionRequirement::User if !ctx.state.volatile.other_verified() => {
return Err(Status::SecurityStatusNotSatisfied);
}
PermissionRequirement::Admin if !ctx.state.volatile.admin_verified => {
PermissionRequirement::Admin if !ctx.state.volatile.admin_verified() => {
return Err(Status::SecurityStatusNotSatisfied);
}
_ => {}
Expand Down Expand Up @@ -827,11 +827,11 @@ pub fn put_data<const R: usize, T: trussed::Client + AuthClient>(
}

match object.write_perm() {
PermissionRequirement::Admin if !context.state.volatile.admin_verified => {
PermissionRequirement::Admin if !context.state.volatile.admin_verified() => {
warn!("Put data for admin authorized object: {object:?}");
return Err(Status::SecurityStatusNotSatisfied);
}
PermissionRequirement::User if !context.state.volatile.other_verified => {
PermissionRequirement::User if !context.state.volatile.other_verified() => {
warn!("Put data for user authorized object: {object:?}");
return Err(Status::SecurityStatusNotSatisfied);
}
Expand Down
10 changes: 5 additions & 5 deletions src/command/pso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ pub fn sign<const R: usize, T: trussed::Client + AuthClient>(
warn!("Attempt to sign without a key set");
Status::KeyReferenceNotFound
})?;
if !ctx.state.volatile.sign_verified {
if !ctx.state.volatile.sign_verified() {
warn!("Attempt to sign without PW1 verified");
return Err(Status::SecurityStatusNotSatisfied);
}

check_uif(ctx.lend(), KeyType::Sign)?;
if !ctx.state.persistent.pw1_valid_multiple() {
ctx.state.volatile.sign_verified = false;
ctx.state.volatile.clear_sign(ctx.backend.client_mut())
}
ctx.state
.persistent
Expand Down Expand Up @@ -171,7 +171,7 @@ fn int_aut_key_mecha_uif<const R: usize, T: trussed::Client + AuthClient>(
pub fn internal_authenticate<const R: usize, T: trussed::Client + AuthClient>(
mut ctx: LoadedContext<'_, R, T>,
) -> Result<(), Status> {
if !ctx.state.volatile.other_verified {
if !ctx.state.volatile.other_verified() {
warn!("Attempt to sign without PW1 verified");
return Err(Status::SecurityStatusNotSatisfied);
}
Expand Down Expand Up @@ -230,7 +230,7 @@ fn decipher_key_mecha_uif<const R: usize, T: trussed::Client + AuthClient>(
pub fn decipher<const R: usize, T: trussed::Client + AuthClient>(
mut ctx: LoadedContext<'_, R, T>,
) -> Result<(), Status> {
if !ctx.state.volatile.other_verified {
if !ctx.state.volatile.other_verified() {
warn!("Attempt to sign without PW1 verified");
return Err(Status::SecurityStatusNotSatisfied);
}
Expand Down Expand Up @@ -391,7 +391,7 @@ fn decipher_aes<const R: usize, T: trussed::Client + AuthClient>(
pub fn encipher<const R: usize, T: trussed::Client + AuthClient>(
mut ctx: LoadedContext<'_, R, T>,
) -> Result<(), Status> {
if !ctx.state.volatile.other_verified {
if !ctx.state.volatile.other_verified() {
warn!("Attempt to encipher without PW1 verified");
return Err(Status::SecurityStatusNotSatisfied);
}
Expand Down
Loading

0 comments on commit 7fe1555

Please sign in to comment.