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