Skip to main content

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