1*9860b763SAndroid Build Coastguard Worker // Copyright 2022, The Android Open Source Project 2*9860b763SAndroid Build Coastguard Worker // 3*9860b763SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*9860b763SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*9860b763SAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*9860b763SAndroid Build Coastguard Worker // 7*9860b763SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*9860b763SAndroid Build Coastguard Worker // 9*9860b763SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*9860b763SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*9860b763SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9860b763SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*9860b763SAndroid Build Coastguard Worker // limitations under the License. 14*9860b763SAndroid Build Coastguard Worker 15*9860b763SAndroid Build Coastguard Worker //! In-memory secure deletion secret manager. 16*9860b763SAndroid Build Coastguard Worker //! 17*9860b763SAndroid Build Coastguard Worker //! Only suitable for development/testing (as secrets are lost on restart). 18*9860b763SAndroid Build Coastguard Worker 19*9860b763SAndroid Build Coastguard Worker use super::{SecureDeletionData, SecureDeletionSecretManager, SecureDeletionSlot, SlotPurpose}; 20*9860b763SAndroid Build Coastguard Worker use crate::{crypto, km_err, Error}; 21*9860b763SAndroid Build Coastguard Worker 22*9860b763SAndroid Build Coastguard Worker /// Secure deletion secret manager that keeps state in memory. Provided as an example only; do not 23*9860b763SAndroid Build Coastguard Worker /// use in a real system (keys will not survive reboot if you do). 24*9860b763SAndroid Build Coastguard Worker pub struct InMemorySlotManager<const N: usize> { 25*9860b763SAndroid Build Coastguard Worker factory_secret: Option<[u8; 32]>, 26*9860b763SAndroid Build Coastguard Worker slots: [Option<SecureDeletionData>; N], 27*9860b763SAndroid Build Coastguard Worker } 28*9860b763SAndroid Build Coastguard Worker 29*9860b763SAndroid Build Coastguard Worker impl<const N: usize> Default for InMemorySlotManager<N> { default() -> Self30*9860b763SAndroid Build Coastguard Worker fn default() -> Self { 31*9860b763SAndroid Build Coastguard Worker Self { 32*9860b763SAndroid Build Coastguard Worker factory_secret: None, 33*9860b763SAndroid Build Coastguard Worker // Work around Rust limitation that `[None; N]` doesn't work. 34*9860b763SAndroid Build Coastguard Worker slots: [(); N].map(|_| Option::<SecureDeletionData>::default()), 35*9860b763SAndroid Build Coastguard Worker } 36*9860b763SAndroid Build Coastguard Worker } 37*9860b763SAndroid Build Coastguard Worker } 38*9860b763SAndroid Build Coastguard Worker 39*9860b763SAndroid Build Coastguard Worker 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*9860b763SAndroid Build Coastguard Worker fn get_or_create_factory_reset_secret( 41*9860b763SAndroid Build Coastguard Worker &mut self, 42*9860b763SAndroid Build Coastguard Worker rng: &mut dyn crypto::Rng, 43*9860b763SAndroid Build Coastguard Worker ) -> Result<SecureDeletionData, Error> { 44*9860b763SAndroid Build Coastguard Worker if self.factory_secret.is_none() { 45*9860b763SAndroid Build Coastguard Worker // No factory reset secret created yet, so do so now. 46*9860b763SAndroid Build Coastguard Worker let mut secret = [0; 32]; 47*9860b763SAndroid Build Coastguard Worker rng.fill_bytes(&mut secret[..]); 48*9860b763SAndroid Build Coastguard Worker self.factory_secret = Some(secret); 49*9860b763SAndroid Build Coastguard Worker } 50*9860b763SAndroid Build Coastguard Worker self.get_factory_reset_secret() 51*9860b763SAndroid Build Coastguard Worker } 52*9860b763SAndroid Build Coastguard Worker get_factory_reset_secret(&self) -> Result<SecureDeletionData, Error>53*9860b763SAndroid Build Coastguard Worker fn get_factory_reset_secret(&self) -> Result<SecureDeletionData, Error> { 54*9860b763SAndroid Build Coastguard Worker match self.factory_secret { 55*9860b763SAndroid Build Coastguard Worker Some(secret) => Ok(SecureDeletionData { 56*9860b763SAndroid Build Coastguard Worker factory_reset_secret: secret, 57*9860b763SAndroid Build Coastguard Worker secure_deletion_secret: [0; 16], 58*9860b763SAndroid Build Coastguard Worker }), 59*9860b763SAndroid Build Coastguard Worker None => Err(km_err!(UnknownError, "no factory secret available!")), 60*9860b763SAndroid Build Coastguard Worker } 61*9860b763SAndroid Build Coastguard Worker } 62*9860b763SAndroid Build Coastguard Worker new_secret( &mut self, rng: &mut dyn crypto::Rng, _purpose: SlotPurpose, ) -> Result<(SecureDeletionSlot, SecureDeletionData), Error>63*9860b763SAndroid Build Coastguard Worker fn new_secret( 64*9860b763SAndroid Build Coastguard Worker &mut self, 65*9860b763SAndroid Build Coastguard Worker rng: &mut dyn crypto::Rng, 66*9860b763SAndroid Build Coastguard Worker _purpose: SlotPurpose, 67*9860b763SAndroid Build Coastguard Worker ) -> Result<(SecureDeletionSlot, SecureDeletionData), Error> { 68*9860b763SAndroid Build Coastguard Worker for idx in 0..N { 69*9860b763SAndroid Build Coastguard Worker if self.slots[idx].is_none() { 70*9860b763SAndroid Build Coastguard Worker let mut sdd = self.get_or_create_factory_reset_secret(rng)?; 71*9860b763SAndroid Build Coastguard Worker rng.fill_bytes(&mut sdd.secure_deletion_secret[..]); 72*9860b763SAndroid Build Coastguard Worker self.slots[idx] = Some(sdd.clone()); 73*9860b763SAndroid Build Coastguard Worker return Ok((SecureDeletionSlot(idx as u32), sdd)); 74*9860b763SAndroid Build Coastguard Worker } 75*9860b763SAndroid Build Coastguard Worker } 76*9860b763SAndroid Build Coastguard Worker Err(km_err!(RollbackResistanceUnavailable, "full")) 77*9860b763SAndroid Build Coastguard Worker } 78*9860b763SAndroid Build Coastguard Worker get_secret(&self, slot: SecureDeletionSlot) -> Result<SecureDeletionData, Error>79*9860b763SAndroid Build Coastguard Worker fn get_secret(&self, slot: SecureDeletionSlot) -> Result<SecureDeletionData, Error> { 80*9860b763SAndroid Build Coastguard Worker let idx = slot.0 as usize; 81*9860b763SAndroid Build Coastguard Worker if !(0..N).contains(&idx) { 82*9860b763SAndroid Build Coastguard Worker return Err(km_err!(InvalidKeyBlob, "slot idx out of bounds")); 83*9860b763SAndroid Build Coastguard Worker } 84*9860b763SAndroid Build Coastguard Worker match &self.slots[idx] { 85*9860b763SAndroid Build Coastguard Worker Some(data) => Ok(data.clone()), 86*9860b763SAndroid Build Coastguard Worker None => Err(km_err!(InvalidKeyBlob, "slot idx empty")), 87*9860b763SAndroid Build Coastguard Worker } 88*9860b763SAndroid Build Coastguard Worker } 89*9860b763SAndroid Build Coastguard Worker delete_secret(&mut self, slot: SecureDeletionSlot) -> Result<(), Error>90*9860b763SAndroid Build Coastguard Worker fn delete_secret(&mut self, slot: SecureDeletionSlot) -> Result<(), Error> { 91*9860b763SAndroid Build Coastguard Worker match self.slots[slot.0 as usize].take() { 92*9860b763SAndroid Build Coastguard Worker Some(_data) => Ok(()), 93*9860b763SAndroid Build Coastguard Worker None => Err(km_err!(InvalidKeyBlob, "slot idx empty")), 94*9860b763SAndroid Build Coastguard Worker } 95*9860b763SAndroid Build Coastguard Worker } 96*9860b763SAndroid Build Coastguard Worker delete_all(&mut self)97*9860b763SAndroid Build Coastguard Worker fn delete_all(&mut self) { 98*9860b763SAndroid Build Coastguard Worker self.factory_secret = None; 99*9860b763SAndroid Build Coastguard Worker for idx in 0..N { 100*9860b763SAndroid Build Coastguard Worker self.slots[idx] = None; 101*9860b763SAndroid Build Coastguard Worker } 102*9860b763SAndroid Build Coastguard Worker } 103*9860b763SAndroid Build Coastguard Worker } 104