1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements.  See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.  The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License.  You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied.  See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 use crate::{Error, Result};
19 use optee_utee_sys as raw;
20 use std::fmt;
21 
22 /// A millisecond resolution structure for saving the time.
23 pub struct Time {
24     /// The field for the seconds.
25     pub seconds: u32,
26     /// The field for the milliseconds within this second.
27     pub millis: u32,
28 }
29 
30 impl Time {
31     /// Create a new empty time structure.
new() -> Self32     pub fn new() -> Self {
33         Time {
34             seconds: 0,
35             millis: 0,
36         }
37     }
38 
39     /// Retrieve the current system time.
40     /// The origin of this system time is arbitrary and implementation-dependent.
41     /// Different TA instances may even have different system times.
42     /// The only guarantee is that the system time is not reset or rolled back during the life of a
43     /// given TA instance, so it can be used to compute time differences and operation deadlines.
44     ///
45     /// # Example
46     ///
47     /// ```no_run
48     /// let mut time = Time::new();
49     /// time.system_time()?;
50     /// ```
51     ///
52     /// # Panics
53     ///
54     /// 1) If the Implementation detects any error.
system_time(&mut self)55     pub fn system_time(&mut self) {
56         unsafe {
57             raw::TEE_GetSystemTime(self as *mut _ as _);
58         }
59     }
60 
61     /// Wait  for the specified number of milliseconds or wait forever if timeout equals
62     /// `raw::TEE_TIMEOUT_INFINITE` (0xFFFFFFFF). The waiting timer is `System Time`.
63     ///
64     /// # Parameters
65     ///
66     /// 1) `timeout`: The number of milliseconds to wait, or `raw::TEE_TIMEOUT_INFINITE`.
67     ///
68     /// # Example
69     ///
70     /// ```no_run
71     /// Time::wait(1000)?;
72     /// ```
73     ///
74     /// # Errors
75     ///
76     /// 1) `Cancel`: If the wait has been cancelled.
77     ///
78     /// # Panics
79     ///
80     /// 1) If the Implementation detects any error.
81 
wait(timeout: u32) -> Result<()>82     pub fn wait(timeout: u32) -> Result<()> {
83         match unsafe { raw::TEE_Wait(timeout) } {
84             raw::TEE_SUCCESS => Ok(()),
85             code => Err(Error::from_raw_error(code)),
86         }
87     }
88 
89     /// Retrieve the persisten time of the Trusted Application. Since the timer is not
90     /// automatically set, this function should be called after [set_ta_time](Time::set_ta_time).
91     /// The time is a real-time source of time and the origin of this time is set individually by each Trusted Application.
92     /// Also, the time SHALL persist across reboots.
93     ///
94     /// # Example
95     ///
96     /// ```no_run
97     /// let mut time = Time()?;
98     /// time.system_time()?;
99     /// time.set_ta_time()?;
100     /// time.ta_time()?;
101     /// ```
102     ///
103     /// # Errors
104     ///
105     /// 1) `TimeNotSet`: Time is not set.
106     /// 2) `TimeNeedsReset`: Time needs to be reset.
107     /// 3) `Overflow`: The number of seconds in the TA Persistent Time overflows the range of a
108     ///    `u32`. The field `seconds` is still set to the TA Persistent Time truncated to 32 bits.
109     ///
110     /// # Panics
111     ///
112     /// 1) If the Implementation detects any error.
ta_time(&mut self) -> Result<()>113     pub fn ta_time(&mut self) -> Result<()> {
114         match unsafe { raw::TEE_GetTAPersistentTime(self as *mut _ as _) } {
115             raw::TEE_SUCCESS => Ok(()),
116             code => Err(Error::from_raw_error(code)),
117         }
118     }
119 
120     /// Set the persistent time of the current Trusted Application.
121     ///
122     /// # Errors
123     ///
124     /// 1) `OutOfMemory`: If not enough memory is available to complete the operation.
125     /// 2) `SotrageNoSpace`: If insufficient storage space is available to complete the operation.
126     ///
127     /// # Panics
128     ///
129     /// 1) If the Implementation detects any error.
set_ta_time(&self) -> Result<()>130     pub fn set_ta_time(&self) -> Result<()> {
131         match unsafe { raw::TEE_SetTAPersistentTime(self as *const _ as _) } {
132             raw::TEE_SUCCESS => Ok(()),
133             code => Err(Error::from_raw_error(code)),
134         }
135     }
136 
137     /// Retrieve the current REE system time.
138     /// The time is as trusted as the REE itself and may also be tampered by the user.
139     ///
140     /// Panics
141     ///
142     /// 1) If the Implementation detects any error.
ree_time(&mut self)143     pub fn ree_time(&mut self) {
144         unsafe {
145             raw::TEE_GetREETime(self as *mut _ as _);
146         }
147     }
148 }
149 
150 impl fmt::Display for Time {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result151     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
152         write!(
153             f,
154             "(second: {}, millisecond: {})",
155             self.seconds, self.millis
156         )
157     }
158 }
159