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