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}