diff --git a/src/api/firmware_protection.rs b/src/api/firmware_protection.rs new file mode 100644 index 0000000..9f73b3c --- /dev/null +++ b/src/api/firmware_protection.rs @@ -0,0 +1,6 @@ +pub trait FirmwareProtection { + /// Locks the firmware. + /// + /// Returns whether the operation was successful. + fn lock(&mut self) -> bool; +} diff --git a/src/api/mod.rs b/src/api/mod.rs index b8c5bcb..6738124 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -3,4 +3,5 @@ //! The [environment](crate::env::Env) is split into components. Each component has an API described //! by a trait. This module gathers the API of those components. +pub mod firmware_protection; pub mod upgrade_storage; diff --git a/src/ctap/mod.rs b/src/ctap/mod.rs index b21efab..cac6cea 100644 --- a/src/ctap/mod.rs +++ b/src/ctap/mod.rs @@ -64,6 +64,7 @@ use self::storage::PersistentStore; use self::timed_permission::TimedPermission; #[cfg(feature = "with_ctap1")] use self::timed_permission::U2fUserPresenceState; +use crate::api::firmware_protection::FirmwareProtection; use crate::api::upgrade_storage::UpgradeStorage; use crate::env::{Env, UserPresence}; use alloc::boxed::Box; @@ -82,7 +83,6 @@ use crypto::sha256::Sha256; use crypto::Hash256; #[cfg(feature = "debug_ctap")] use libtock_drivers::console::Console; -use libtock_drivers::crp; use libtock_drivers::timer::{ClockValue, Duration}; use sk_cbor as cbor; use sk_cbor::cbor_map_options; @@ -1254,7 +1254,7 @@ impl CtapState { let need_certificate = USE_BATCH_ATTESTATION; if (need_certificate && !(response.pkey_programmed && response.cert_programmed)) - || crp::set_protection(crp::ProtectionLevel::FullyLocked).is_err() + || !env.firmware_protection().lock() { return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR); } diff --git a/src/env/mod.rs b/src/env/mod.rs index dcb8f93..e04d1d8 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -1,3 +1,4 @@ +use crate::api::firmware_protection::FirmwareProtection; use crate::api::upgrade_storage::UpgradeStorage; use crate::ctap::hid::ChannelID; use crate::ctap::status_code::Ctap2StatusCode; @@ -21,6 +22,7 @@ pub trait Env { type UserPresence: UserPresence; type Storage: Storage; type UpgradeStorage: UpgradeStorage; + type FirmwareProtection: FirmwareProtection; fn rng(&mut self) -> &mut Self::Rng; fn user_presence(&mut self) -> &mut Self::UserPresence; @@ -34,4 +36,6 @@ pub trait Env { /// /// This function is called at most once. Implementation may panic if called more than once. fn upgrade_storage(&mut self) -> StorageResult; + + fn firmware_protection(&mut self) -> &mut Self::FirmwareProtection; } diff --git a/src/env/test/mod.rs b/src/env/test/mod.rs index 02a89c7..e1ace12 100644 --- a/src/env/test/mod.rs +++ b/src/env/test/mod.rs @@ -1,4 +1,5 @@ use self::upgrade_storage::BufferUpgradeStorage; +use crate::api::firmware_protection::FirmwareProtection; use crate::ctap::hid::ChannelID; use crate::ctap::status_code::Ctap2StatusCode; use crate::env::{Env, UserPresence}; @@ -38,11 +39,18 @@ impl UserPresence for TestUserPresence { } } +impl FirmwareProtection for TestEnv { + fn lock(&mut self) -> bool { + true + } +} + impl Env for TestEnv { type Rng = ThreadRng256; type UserPresence = TestUserPresence; type Storage = BufferStorage; type UpgradeStorage = BufferUpgradeStorage; + type FirmwareProtection = Self; fn rng(&mut self) -> &mut Self::Rng { &mut self.rng @@ -70,4 +78,8 @@ impl Env for TestEnv { fn upgrade_storage(&mut self) -> StorageResult { BufferUpgradeStorage::new() } + + fn firmware_protection(&mut self) -> &mut Self::FirmwareProtection { + self + } } diff --git a/src/env/tock/mod.rs b/src/env/tock/mod.rs index 1facc85..2c9e5f1 100644 --- a/src/env/tock/mod.rs +++ b/src/env/tock/mod.rs @@ -1,4 +1,5 @@ use self::storage::{SyscallStorage, SyscallUpgradeStorage}; +use crate::api::firmware_protection::FirmwareProtection; use crate::ctap::hid::{ChannelID, CtapHid, KeepaliveStatus, ProcessedPacket}; use crate::ctap::status_code::Ctap2StatusCode; use crate::env::{Env, UserPresence}; @@ -13,7 +14,7 @@ use libtock_drivers::buttons::{self, ButtonState}; use libtock_drivers::console::Console; use libtock_drivers::result::{FlexUnwrap, TockError}; use libtock_drivers::timer::Duration; -use libtock_drivers::{led, timer, usb_ctap_hid}; +use libtock_drivers::{crp, led, timer, usb_ctap_hid}; use persistent_store::StorageResult; mod storage; @@ -62,11 +63,18 @@ impl UserPresence for TockEnv { } } +impl FirmwareProtection for TockEnv { + fn lock(&mut self) -> bool { + crp::set_protection(crp::ProtectionLevel::FullyLocked).is_ok() + } +} + impl Env for TockEnv { type Rng = TockRng256; type UserPresence = Self; type Storage = SyscallStorage; type UpgradeStorage = SyscallUpgradeStorage; + type FirmwareProtection = Self; fn rng(&mut self) -> &mut Self::Rng { &mut self.rng @@ -85,6 +93,10 @@ impl Env for TockEnv { assert_once(&mut self.upgrade_storage); SyscallUpgradeStorage::new() } + + fn firmware_protection(&mut self) -> &mut Self::FirmwareProtection { + self + } } /// Asserts a boolean is false and sets it to true.