xref: /aosp_15_r20/system/keymint/ta/src/secret.rs (revision 9860b7637a5f185913c70aa0caabe3ecb78441e4)
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 shared secret negotiation.
16 
17 use crate::device::DeviceHmac;
18 use alloc::{boxed::Box, vec::Vec};
19 use kmr_common::{crypto, crypto::hmac, km_err, vec_try, Error, FallibleAllocExt};
20 use kmr_wire::{keymint::Digest, sharedsecret::SharedSecretParameters};
21 use log::info;
22 
23 impl crate::KeyMintTa {
get_shared_secret_params(&mut self) -> Result<SharedSecretParameters, Error>24     pub(crate) fn get_shared_secret_params(&mut self) -> Result<SharedSecretParameters, Error> {
25         if self.shared_secret_params.is_none() {
26             let mut nonce = vec_try![0u8; 32]?;
27             self.imp.rng.fill_bytes(&mut nonce);
28             self.shared_secret_params = Some(SharedSecretParameters { seed: Vec::new(), nonce });
29         }
30         Ok(self.shared_secret_params.as_ref().unwrap().clone()) // safe: filled above
31     }
32 
compute_shared_secret( &mut self, params: &[SharedSecretParameters], ) -> Result<Vec<u8>, Error>33     pub(crate) fn compute_shared_secret(
34         &mut self,
35         params: &[SharedSecretParameters],
36     ) -> Result<Vec<u8>, Error> {
37         info!("Setting HMAC key from {} shared secret parameters", params.len());
38         let local_params = match &self.shared_secret_params {
39             Some(params) => params,
40             None => return Err(km_err!(HardwareNotYetAvailable, "no local shared secret params")),
41         };
42 
43         let context = shared_secret_context(params, local_params)?;
44         let key = hmac::Key(self.imp.ckdf.ckdf(
45             &self.dev.keys.kak()?,
46             kmr_wire::sharedsecret::KEY_AGREEMENT_LABEL.as_bytes(),
47             &[&context],
48             kmr_common::crypto::SHA256_DIGEST_LEN,
49         )?);
50 
51         // Potentially hand the negotiated HMAC key off to hardware.
52         self.device_hmac = Some(self.dev.keys.hmac_key_agreed(&key).unwrap_or_else(|| {
53             // Key not installed into hardware, so build & use a local impl.
54             Box::new(SoftDeviceHmac { key })
55         }));
56         self.device_hmac(kmr_wire::sharedsecret::KEY_CHECK_LABEL.as_bytes())
57     }
58 }
59 
60 /// Build the shared secret context from the given `params`, which
61 /// is required to include `must_include` (our own parameters).
shared_secret_context( params: &[SharedSecretParameters], must_include: &SharedSecretParameters, ) -> Result<Vec<u8>, crate::Error>62 pub fn shared_secret_context(
63     params: &[SharedSecretParameters],
64     must_include: &SharedSecretParameters,
65 ) -> Result<Vec<u8>, crate::Error> {
66     let mut result = Vec::new();
67     let mut seen = false;
68     for param in params {
69         result.try_extend_from_slice(&param.seed)?;
70         if param.nonce.len() != 32 {
71             return Err(km_err!(InvalidArgument, "nonce len {} not 32", param.nonce.len()));
72         }
73         result.try_extend_from_slice(&param.nonce)?;
74         if param == must_include {
75             seen = true;
76         }
77     }
78     if !seen {
79         Err(km_err!(InvalidArgument, "shared secret params missing local value"))
80     } else {
81         Ok(result)
82     }
83 }
84 
85 /// Device HMAC implementation that holds the HMAC key in memory.
86 struct SoftDeviceHmac {
87     key: crypto::hmac::Key,
88 }
89 
90 impl DeviceHmac for SoftDeviceHmac {
hmac(&self, imp: &dyn crypto::Hmac, data: &[u8]) -> Result<Vec<u8>, Error>91     fn hmac(&self, imp: &dyn crypto::Hmac, data: &[u8]) -> Result<Vec<u8>, Error> {
92         let mut hmac_op = imp.begin(self.key.clone().into(), Digest::Sha256)?;
93         hmac_op.update(data)?;
94         hmac_op.finish()
95     }
96 
get_hmac_key(&self) -> Option<crypto::hmac::Key>97     fn get_hmac_key(&self) -> Option<crypto::hmac::Key> {
98         Some(self.key.clone())
99     }
100 }
101