trussed/
platform.rs

1//! Trait for platforms to implement that use Trussed.
2//!
3//! Trussed requires access to a cryptographically secure random number generator,
4//! facilities for persistent and volatile storage, and some user interface to ensure
5//! operations do not happen without user consent. Implementing this trait enables this.
6//!
7//! TODO: Currently, `Platform::R` lacks the `CryptoRng` bound.
8
9// pub use rand_core::{CryptoRng, RngCore};
10pub use rand_core::{CryptoRng, RngCore};
11pub use crate::store::Store;
12pub use crate::types::{ui, reboot};
13pub use crate::types::consent;
14
15
16pub trait UserInterface {
17    /// Check if the user has indicated their presence so as to give
18    /// consent to an action.
19    fn check_user_presence(&mut self) -> consent::Level {
20        consent::Level::None
21    }
22
23    /// Set the state of Trussed to give potential feedback to the user.
24    fn set_status(&mut self, status: ui::Status) {
25        let _ = status;
26    }
27
28    fn status(&self) -> ui::Status {
29        ui::Status::Idle
30    }
31
32    /// May be called during idle periods to give the UI the opportunity to update.
33    fn refresh(&mut self) {}
34
35    /// Return the duration since startup.
36    fn uptime(&mut self) -> core::time::Duration {
37        Default::default()
38    }
39
40    /// Exit / reset the application
41    fn reboot (&mut self, to: reboot::To) -> ! {
42        let _ = to;
43        loop {
44            continue
45        }
46    }
47
48    /// Trigger a visible or audible effect for the given duration that allows the user to identify
49    /// the device.
50    fn wink(&mut self, duration: core::time::Duration) {
51        let _ = duration;
52    }
53}
54
55// This is the same trick as in "store.rs",
56// replacing generic parameters with associated types
57// and a macro.
58pub unsafe trait Platform {
59    // temporarily remove CryptoRng bound until HALs come along
60    type R: CryptoRng + RngCore;
61    type S: Store;
62    type UI: UserInterface;
63
64    fn rng(&mut self) -> &mut Self::R;
65    fn store(&self) -> Self::S;
66    fn user_interface(&mut self) -> &mut Self::UI;
67}
68
69#[macro_export]
70macro_rules! platform { (
71    $PlatformName:ident,
72    R: $Rng:ty,
73    S: $Store:ty,
74    UI: $UserInterface:ty,
75) => {
76
77    /// Platform struct implemented `trussed::Platform`, generated
78    /// by a Trussed-supplied macro at call site, using the platform-specific
79    /// implementations of its components.
80    pub struct $PlatformName {
81        rng: $Rng,
82        store: $Store,
83        user_interface: $UserInterface,
84    }
85
86    impl $PlatformName {
87        pub fn new(rng: $Rng, store: $Store, user_interface: $UserInterface) -> Self {
88            Self { rng, store, user_interface }
89        }
90    }
91
92    unsafe impl $crate::platform::Platform for $PlatformName {
93        type R = $Rng;
94        type S = $Store;
95        type UI = $UserInterface;
96
97        fn user_interface(&mut self) -> &mut Self::UI {
98            &mut self.user_interface
99        }
100
101        fn rng(&mut self) -> &mut Self::R {
102            &mut self.rng
103        }
104
105        fn store(&self) -> Self::S {
106            self.store
107        }
108    }
109}}
110
111/// Trussed client will call this method when making a Trussed request.
112/// This is intended to trigger a secure context on the platform.
113pub trait Syscall {
114    fn syscall(&mut self);
115}
116