xref: /aosp_15_r20/system/keymint/common/src/keyblob/sdd_mem.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 //! In-memory secure deletion secret manager.
16 //!
17 //! Only suitable for development/testing (as secrets are lost on restart).
18 
19 use super::{SecureDeletionData, SecureDeletionSecretManager, SecureDeletionSlot, SlotPurpose};
20 use crate::{crypto, km_err, Error};
21 
22 /// Secure deletion secret manager that keeps state in memory. Provided as an example only; do not
23 /// use in a real system (keys will not survive reboot if you do).
24 pub struct InMemorySlotManager<const N: usize> {
25     factory_secret: Option<[u8; 32]>,
26     slots: [Option<SecureDeletionData>; N],
27 }
28 
29 impl<const N: usize> Default for InMemorySlotManager<N> {
default() -> Self30     fn default() -> Self {
31         Self {
32             factory_secret: None,
33             // Work around Rust limitation that `[None; N]` doesn't work.
34             slots: [(); N].map(|_| Option::<SecureDeletionData>::default()),
35         }
36     }
37 }
38 
39 impl<const N: usize> SecureDeletionSecretManager for InMemorySlotManager<N> {
get_or_create_factory_reset_secret( &mut self, rng: &mut dyn crypto::Rng, ) -> Result<SecureDeletionData, Error>40     fn get_or_create_factory_reset_secret(
41         &mut self,
42         rng: &mut dyn crypto::Rng,
43     ) -> Result<SecureDeletionData, Error> {
44         if self.factory_secret.is_none() {
45             // No factory reset secret created yet, so do so now.
46             let mut secret = [0; 32];
47             rng.fill_bytes(&mut secret[..]);
48             self.factory_secret = Some(secret);
49         }
50         self.get_factory_reset_secret()
51     }
52 
get_factory_reset_secret(&self) -> Result<SecureDeletionData, Error>53     fn get_factory_reset_secret(&self) -> Result<SecureDeletionData, Error> {
54         match self.factory_secret {
55             Some(secret) => Ok(SecureDeletionData {
56                 factory_reset_secret: secret,
57                 secure_deletion_secret: [0; 16],
58             }),
59             None => Err(km_err!(UnknownError, "no factory secret available!")),
60         }
61     }
62 
new_secret( &mut self, rng: &mut dyn crypto::Rng, _purpose: SlotPurpose, ) -> Result<(SecureDeletionSlot, SecureDeletionData), Error>63     fn new_secret(
64         &mut self,
65         rng: &mut dyn crypto::Rng,
66         _purpose: SlotPurpose,
67     ) -> Result<(SecureDeletionSlot, SecureDeletionData), Error> {
68         for idx in 0..N {
69             if self.slots[idx].is_none() {
70                 let mut sdd = self.get_or_create_factory_reset_secret(rng)?;
71                 rng.fill_bytes(&mut sdd.secure_deletion_secret[..]);
72                 self.slots[idx] = Some(sdd.clone());
73                 return Ok((SecureDeletionSlot(idx as u32), sdd));
74             }
75         }
76         Err(km_err!(RollbackResistanceUnavailable, "full"))
77     }
78 
get_secret(&self, slot: SecureDeletionSlot) -> Result<SecureDeletionData, Error>79     fn get_secret(&self, slot: SecureDeletionSlot) -> Result<SecureDeletionData, Error> {
80         let idx = slot.0 as usize;
81         if !(0..N).contains(&idx) {
82             return Err(km_err!(InvalidKeyBlob, "slot idx out of bounds"));
83         }
84         match &self.slots[idx] {
85             Some(data) => Ok(data.clone()),
86             None => Err(km_err!(InvalidKeyBlob, "slot idx empty")),
87         }
88     }
89 
delete_secret(&mut self, slot: SecureDeletionSlot) -> Result<(), Error>90     fn delete_secret(&mut self, slot: SecureDeletionSlot) -> Result<(), Error> {
91         match self.slots[slot.0 as usize].take() {
92             Some(_data) => Ok(()),
93             None => Err(km_err!(InvalidKeyBlob, "slot idx empty")),
94         }
95     }
96 
delete_all(&mut self)97     fn delete_all(&mut self) {
98         self.factory_secret = None;
99         for idx in 0..N {
100             self.slots[idx] = None;
101         }
102     }
103 }
104