1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 //! TA functionality for secure clocks.
16
17 use alloc::vec::Vec;
18 use core::mem::size_of;
19 use kmr_common::{km_err, vec_try_with_capacity, Error};
20 use kmr_wire::secureclock::{TimeStampToken, TIME_STAMP_MAC_LABEL};
21
22 impl crate::KeyMintTa {
generate_timestamp(&self, challenge: i64) -> Result<TimeStampToken, Error>23 pub(crate) fn generate_timestamp(&self, challenge: i64) -> Result<TimeStampToken, Error> {
24 if let Some(clock) = &self.imp.clock {
25 let mut ret =
26 TimeStampToken { challenge, timestamp: clock.now().into(), mac: Vec::new() };
27 let mac_input = self.dev.keys.timestamp_token_mac_input(&ret)?;
28 ret.mac = self.device_hmac(&mac_input)?;
29 Ok(ret)
30 } else {
31 Err(km_err!(Unimplemented, "no clock available"))
32 }
33 }
34 }
35
36 /// Build the HMAC input for a [`TimeStampToken`]
timestamp_token_mac_input(token: &TimeStampToken) -> Result<Vec<u8>, Error>37 pub fn timestamp_token_mac_input(token: &TimeStampToken) -> Result<Vec<u8>, Error> {
38 let mut result = vec_try_with_capacity!(
39 TIME_STAMP_MAC_LABEL.len() +
40 size_of::<i64>() + // challenge (BE)
41 size_of::<i64>() + // timestamp (BE)
42 size_of::<u32>() // 1u32 (BE)
43 )?;
44 result.extend_from_slice(TIME_STAMP_MAC_LABEL);
45 result.extend_from_slice(&token.challenge.to_be_bytes()[..]);
46 result.extend_from_slice(&token.timestamp.milliseconds.to_be_bytes()[..]);
47 result.extend_from_slice(&1u32.to_be_bytes()[..]);
48 Ok(result)
49 }
50