Merge pull request #433 from ia0/firmware_protection
Add firmware protection to the environment
This commit is contained in:
6
src/api/firmware_protection.rs
Normal file
6
src/api/firmware_protection.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
pub trait FirmwareProtection {
|
||||||
|
/// Locks the firmware.
|
||||||
|
///
|
||||||
|
/// Returns whether the operation was successful.
|
||||||
|
fn lock(&mut self) -> bool;
|
||||||
|
}
|
||||||
@@ -3,4 +3,5 @@
|
|||||||
//! The [environment](crate::env::Env) is split into components. Each component has an API described
|
//! 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.
|
//! by a trait. This module gathers the API of those components.
|
||||||
|
|
||||||
|
pub mod firmware_protection;
|
||||||
pub mod upgrade_storage;
|
pub mod upgrade_storage;
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ use self::status_code::Ctap2StatusCode;
|
|||||||
use self::timed_permission::TimedPermission;
|
use self::timed_permission::TimedPermission;
|
||||||
#[cfg(feature = "with_ctap1")]
|
#[cfg(feature = "with_ctap1")]
|
||||||
use self::timed_permission::U2fUserPresenceState;
|
use self::timed_permission::U2fUserPresenceState;
|
||||||
|
use crate::api::firmware_protection::FirmwareProtection;
|
||||||
use crate::api::upgrade_storage::UpgradeStorage;
|
use crate::api::upgrade_storage::UpgradeStorage;
|
||||||
use crate::env::{Env, UserPresence};
|
use crate::env::{Env, UserPresence};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
@@ -81,7 +82,6 @@ use crypto::sha256::Sha256;
|
|||||||
use crypto::Hash256;
|
use crypto::Hash256;
|
||||||
#[cfg(feature = "debug_ctap")]
|
#[cfg(feature = "debug_ctap")]
|
||||||
use libtock_drivers::console::Console;
|
use libtock_drivers::console::Console;
|
||||||
use libtock_drivers::crp;
|
|
||||||
use libtock_drivers::timer::{ClockValue, Duration};
|
use libtock_drivers::timer::{ClockValue, Duration};
|
||||||
use sk_cbor as cbor;
|
use sk_cbor as cbor;
|
||||||
use sk_cbor::cbor_map_options;
|
use sk_cbor::cbor_map_options;
|
||||||
@@ -1234,7 +1234,7 @@ impl CtapState {
|
|||||||
let need_certificate = USE_BATCH_ATTESTATION;
|
let need_certificate = USE_BATCH_ATTESTATION;
|
||||||
|
|
||||||
if (need_certificate && !(response.pkey_programmed && response.cert_programmed))
|
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);
|
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
|
|||||||
4
src/env/mod.rs
vendored
4
src/env/mod.rs
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::api::firmware_protection::FirmwareProtection;
|
||||||
use crate::api::upgrade_storage::UpgradeStorage;
|
use crate::api::upgrade_storage::UpgradeStorage;
|
||||||
use crate::ctap::hid::ChannelID;
|
use crate::ctap::hid::ChannelID;
|
||||||
use crate::ctap::status_code::Ctap2StatusCode;
|
use crate::ctap::status_code::Ctap2StatusCode;
|
||||||
@@ -21,6 +22,7 @@ pub trait Env {
|
|||||||
type UserPresence: UserPresence;
|
type UserPresence: UserPresence;
|
||||||
type Storage: Storage;
|
type Storage: Storage;
|
||||||
type UpgradeStorage: UpgradeStorage;
|
type UpgradeStorage: UpgradeStorage;
|
||||||
|
type FirmwareProtection: FirmwareProtection;
|
||||||
|
|
||||||
fn rng(&mut self) -> &mut Self::Rng;
|
fn rng(&mut self) -> &mut Self::Rng;
|
||||||
fn user_presence(&mut self) -> &mut Self::UserPresence;
|
fn user_presence(&mut self) -> &mut Self::UserPresence;
|
||||||
@@ -31,4 +33,6 @@ pub trait Env {
|
|||||||
/// Upgrade storage is optional, so implementations may return `None`. However, implementations
|
/// Upgrade storage is optional, so implementations may return `None`. However, implementations
|
||||||
/// should either always return `None` or always return `Some`.
|
/// should either always return `None` or always return `Some`.
|
||||||
fn upgrade_storage(&mut self) -> Option<&mut Self::UpgradeStorage>;
|
fn upgrade_storage(&mut self) -> Option<&mut Self::UpgradeStorage>;
|
||||||
|
|
||||||
|
fn firmware_protection(&mut self) -> &mut Self::FirmwareProtection;
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/env/test/mod.rs
vendored
12
src/env/test/mod.rs
vendored
@@ -1,4 +1,5 @@
|
|||||||
use self::upgrade_storage::BufferUpgradeStorage;
|
use self::upgrade_storage::BufferUpgradeStorage;
|
||||||
|
use crate::api::firmware_protection::FirmwareProtection;
|
||||||
use crate::ctap::hid::ChannelID;
|
use crate::ctap::hid::ChannelID;
|
||||||
use crate::ctap::status_code::Ctap2StatusCode;
|
use crate::ctap::status_code::Ctap2StatusCode;
|
||||||
use crate::env::{Env, UserPresence};
|
use crate::env::{Env, UserPresence};
|
||||||
@@ -67,11 +68,18 @@ impl UserPresence for TestUserPresence {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FirmwareProtection for TestEnv {
|
||||||
|
fn lock(&mut self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Env for TestEnv {
|
impl Env for TestEnv {
|
||||||
type Rng = ThreadRng256;
|
type Rng = ThreadRng256;
|
||||||
type UserPresence = TestUserPresence;
|
type UserPresence = TestUserPresence;
|
||||||
type Storage = BufferStorage;
|
type Storage = BufferStorage;
|
||||||
type UpgradeStorage = BufferUpgradeStorage;
|
type UpgradeStorage = BufferUpgradeStorage;
|
||||||
|
type FirmwareProtection = Self;
|
||||||
|
|
||||||
fn rng(&mut self) -> &mut Self::Rng {
|
fn rng(&mut self) -> &mut Self::Rng {
|
||||||
&mut self.rng
|
&mut self.rng
|
||||||
@@ -88,4 +96,8 @@ impl Env for TestEnv {
|
|||||||
fn upgrade_storage(&mut self) -> Option<&mut Self::UpgradeStorage> {
|
fn upgrade_storage(&mut self) -> Option<&mut Self::UpgradeStorage> {
|
||||||
self.upgrade_storage.as_mut()
|
self.upgrade_storage.as_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn firmware_protection(&mut self) -> &mut Self::FirmwareProtection {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/env/tock/mod.rs
vendored
21
src/env/tock/mod.rs
vendored
@@ -1,4 +1,5 @@
|
|||||||
pub use self::storage::{TockStorage, TockUpgradeStorage};
|
pub use self::storage::{TockStorage, TockUpgradeStorage};
|
||||||
|
use crate::api::firmware_protection::FirmwareProtection;
|
||||||
use crate::ctap::hid::{ChannelID, CtapHid, CtapHidCommand, KeepaliveStatus, ProcessedPacket};
|
use crate::ctap::hid::{ChannelID, CtapHid, CtapHidCommand, KeepaliveStatus, ProcessedPacket};
|
||||||
use crate::ctap::status_code::Ctap2StatusCode;
|
use crate::ctap::status_code::Ctap2StatusCode;
|
||||||
use crate::env::{Env, UserPresence};
|
use crate::env::{Env, UserPresence};
|
||||||
@@ -13,7 +14,7 @@ use libtock_drivers::buttons::{self, ButtonState};
|
|||||||
use libtock_drivers::console::Console;
|
use libtock_drivers::console::Console;
|
||||||
use libtock_drivers::result::{FlexUnwrap, TockError};
|
use libtock_drivers::result::{FlexUnwrap, TockError};
|
||||||
use libtock_drivers::timer::Duration;
|
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, Store};
|
use persistent_store::{StorageResult, Store};
|
||||||
|
|
||||||
mod storage;
|
mod storage;
|
||||||
@@ -61,11 +62,25 @@ impl UserPresence for TockEnv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FirmwareProtection for TockEnv {
|
||||||
|
fn lock(&mut self) -> bool {
|
||||||
|
matches!(
|
||||||
|
crp::set_protection(crp::ProtectionLevel::FullyLocked),
|
||||||
|
Ok(())
|
||||||
|
| Err(TockError::Command(CommandError {
|
||||||
|
return_code: EALREADY,
|
||||||
|
..
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Env for TockEnv {
|
impl Env for TockEnv {
|
||||||
type Rng = TockRng256;
|
type Rng = TockRng256;
|
||||||
type UserPresence = Self;
|
type UserPresence = Self;
|
||||||
type Storage = TockStorage;
|
type Storage = TockStorage;
|
||||||
type UpgradeStorage = TockUpgradeStorage;
|
type UpgradeStorage = TockUpgradeStorage;
|
||||||
|
type FirmwareProtection = Self;
|
||||||
|
|
||||||
fn rng(&mut self) -> &mut Self::Rng {
|
fn rng(&mut self) -> &mut Self::Rng {
|
||||||
&mut self.rng
|
&mut self.rng
|
||||||
@@ -82,6 +97,10 @@ impl Env for TockEnv {
|
|||||||
fn upgrade_storage(&mut self) -> Option<&mut Self::UpgradeStorage> {
|
fn upgrade_storage(&mut self) -> Option<&mut Self::UpgradeStorage> {
|
||||||
self.upgrade_storage.as_mut()
|
self.upgrade_storage.as_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn firmware_protection(&mut self) -> &mut Self::FirmwareProtection {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether the keepalive was sent, or false if cancelled.
|
// Returns whether the keepalive was sent, or false if cancelled.
|
||||||
|
|||||||
Reference in New Issue
Block a user