Skip to content

Commit

Permalink
Simplify delete_all_items
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Jun 5, 2024
1 parent 7efc746 commit 33bbb97
Showing 1 changed file with 61 additions and 58 deletions.
119 changes: 61 additions & 58 deletions src/core_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crypto_bigint::{
};
use embedded_hal::blocking::delay::DelayUs;
use hex_literal::hex;
use iso7816::Status;
use littlefs2::path::PathBuf;
use rand::{CryptoRng, RngCore};
use se05x::{
Expand Down Expand Up @@ -233,7 +232,7 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
se050_keystore: &mut impl Keystore,
) -> Result<reply::Delete, Error> {
let (parsed_key, _parsed_ty) = parse_key_id(*key, ns).ok_or_else(|| {
debug!("Failed to parse key id");
debug!("Failed to parse key id to delete: {key:?}");
Error::RequestNotAvailable
})?;
debug!("Deleting {key:?}, {parsed_key:?}, {_parsed_ty:?}");
Expand Down Expand Up @@ -2020,7 +2019,7 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
) -> Result<reply::Clear, Error> {
debug!("Clearing: {:?}", req.key);
let (parsed_key, _parsed_ty) = parse_key_id(req.key, ns).ok_or_else(|| {
debug!("Failed to parse key id");
debug!("Failed to parse key id to clear: {:?}", req.key);
Error::RequestNotAvailable
})?;

Expand Down Expand Up @@ -2059,7 +2058,7 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
return Err(Error::RequestNotAvailable);
}
let (parsed_key, _parsed_ty) = parse_key_id(req.key, ns).ok_or_else(|| {
debug!("Failed to parse key id");
debug!("Failed to parse key id to wrap: {:?}", req.key);
// Let non-se050 keys be wrapped by the core backend
Error::RequestNotAvailable
})?;
Expand Down Expand Up @@ -2247,7 +2246,7 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
ns: NamespaceValue,
) -> Result<reply::Exists, Error> {
let (parsed_key, parsed_ty) = parse_key_id(req.key, ns).ok_or_else(|| {
debug!("Failed to parse key id");
debug!("Failed to parse key id to check if exists: {:?}", req.key);
// Let non-se050 keys be checked by the core backend
Error::RequestNotAvailable
})?;
Expand Down Expand Up @@ -2315,6 +2314,16 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
Ok(reply::Exists { exists })
}

fn delete_object(&mut self, object_id: ObjectId, buf: &mut [u8]) -> Result<(), Error> {
self.se
.run_command(&DeleteSecureObject { object_id }, buf)
.map_err(|_err| {
error!("Failed to delete object: {object_id:02x?} {_err:?}");
Error::FunctionFailed
})?;
Ok(())
}

pub(crate) fn delete_all_items(
&mut self,
kinds: ItemsToDelete,
Expand All @@ -2325,8 +2334,18 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
let buf2 = &mut [0; 128];
let mut count = 0u16;
let mut offset = 0;
let mut cont = true;

let should_delete_internal = locations.contains(&Location::Internal);
let should_delete_external = locations.contains(&Location::External);
let should_delete_volatile = locations.contains(&Location::Volatile);
// Persistent keys do not have a "location"
let should_delete_persistent = should_delete_internal || should_delete_external;

loop {
let should_delete_keys = kinds.contains(ItemsToDelete::KEYS);
let should_delete_pins = kinds.contains(ItemsToDelete::PINS);

while cont {
let to_delete = self
.se
.run_command(
Expand All @@ -2340,98 +2359,82 @@ impl<Twi: I2CForT1, D: DelayUs<u32>> Se050Backend<Twi, D> {
error!("Failed to read id_list: {_err:?}");
Error::FunctionFailed
})?;
cont = to_delete.more.is_more();

assert_eq!(to_delete.ids.len() % 4, 0);
offset += (to_delete.ids.len() / 4) as u16;
for obj_slice in to_delete.ids.chunks_exact(4) {
let obj = ObjectId(obj_slice.try_into().unwrap());
debug!("Dealing with obj: {obj:02x?}");
debug_now!("Dealing with obj: {obj_slice:02x?}");
if !object_in_range(obj) {
continue;
}
debug!("In range");
debug!("In range for a non-native object");
let Some((ns_to_check, parsed_obj_id)) = ParsedObjectId::parse(obj) else {
debug!("Failed to parse object id");
continue;
};
if ns_to_check != ns {
continue;
}
debug!("In ns");
debug!("In namespace");
debug!("Got parsed: {parsed_obj_id:02x?}");
match parsed_obj_id {
ParsedObjectId::PersistentKey(obj)
if locations.contains(&Location::Internal)
|| locations.contains(&Location::External)
&& kinds.contains(ItemsToDelete::KEYS) =>
{
ParsedObjectId::PersistentKey(obj) => {
if !should_delete_persistent || !should_delete_keys {
continue;
}

self.delete_object(obj.0, buf2)?;
count += 1;
offset = offset.saturating_sub(1);
self.se
.run_command(&DeleteSecureObject { object_id: obj.0 }, buf2)
.map_err(|_err| {
error!("Failed to delete object: {obj:02x?} {_err:?}");
Error::FunctionFailed
})?;
}
ParsedObjectId::VolatileKey(obj)
if locations.contains(&Location::Volatile)
&& kinds.contains(ItemsToDelete::KEYS) =>
{
ParsedObjectId::VolatileKey(obj) => {
if !should_delete_volatile || !should_delete_keys {
continue;
}

self.delete_object(obj.0, buf2)?;
count += 1;
offset = offset.saturating_sub(1);
self.se
.run_command(&DeleteSecureObject { object_id: obj.0 }, buf2)
.map_err(|_err| {
error!("Failed to delete object: {obj:02x?} {_err:?}");
Error::FunctionFailed
})?;
}
ParsedObjectId::VolatileRsaKey(obj)
if locations.contains(&Location::Volatile)
&& kinds.contains(ItemsToDelete::KEYS) =>
{
ParsedObjectId::VolatileRsaKey(obj) => {
if !should_delete_volatile || !should_delete_keys {
continue;
}

let deleted_count = self.delete_volatile_rsa_key_on_se050(obj)?;
// VolatileRsaKeys can appear twice (intermediary and real key. They should be counted as one)
count += if deleted_count == 0 { 0 } else { 1 };
offset = offset.saturating_sub(deleted_count);
}
ParsedObjectId::Pin(se_id) if kinds.contains(ItemsToDelete::PINS) => {
debug!("Deleting simple pin");
let res = self
.se
.run_command(&DeleteSecureObject { object_id: se_id.0 }, buf2);
match res {
Err(se05x::se05x::Error::Status(Status::KeyReferenceNotFound))
| Ok(_) => {}
Err(_err) => {
error_now!("Failed to delete pin: {_err:?}");
return Err(Error::FunctionFailed);
}
ParsedObjectId::Pin(se_id) => {
if !should_delete_pins {
continue;
}

debug!("Deleting simple pin");
self.delete_object(se_id.0, buf2)?;
count += 1;
offset = offset.saturating_sub(1);
}
ParsedObjectId::PinWithDerived(se_id)
if kinds.contains(ItemsToDelete::PINS) =>
{
ParsedObjectId::PinWithDerived(se_id) => {
if !should_delete_pins {
continue;
}

use crate::trussed_auth_impl::data::PinData;
let deleted_count = PinData::delete_with_derived(&mut self.se, se_id)?;
count += if deleted_count == 0 { 0 } else { 1 };
offset = offset.saturating_sub(deleted_count);
}
ParsedObjectId::Pin(_)
| ParsedObjectId::PinWithDerived(_)
| ParsedObjectId::SaltValue(_) => {}
ParsedObjectId::VolatileKey(_) | ParsedObjectId::VolatileRsaKey(_) => {}
ParsedObjectId::PersistentKey(_) => {}
// Salt value is not part of any namespace
// It is only deteled through the full device factory reset
ParsedObjectId::SaltValue(_) => {}
}
}

if !to_delete.more.is_more() {
break;
}
}
debug_now!("Deleted {count} items");
Ok(count.into())
}

Expand Down

0 comments on commit 33bbb97

Please sign in to comment.