blob: 2df534362998af5b6928decf2c0ae2967bf5dfc0 [file] [log] [blame]
Janis Danisevskisb42fc182020-12-15 08:41:27 -08001// Copyright 2020, 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#![allow(dead_code)]
16
17use crate::{
Hasini Gunasingheda895552021-01-27 19:34:37 +000018 database::BlobMetaData, database::BlobMetaEntry, database::EncryptedBy, database::KeyEntry,
Hasini Gunasinghedeab85d2021-02-01 21:10:02 +000019 database::KeyType, database::KeystoreDB, enforcements::Enforcements, error::Error,
20 error::ResponseCode, key_parameter::KeyParameter, legacy_blob::LegacyBlobLoader,
Janis Danisevskisb42fc182020-12-15 08:41:27 -080021};
22use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain;
23use anyhow::{Context, Result};
24use keystore2_crypto::{
Hasini Gunasingheda895552021-01-27 19:34:37 +000025 aes_gcm_decrypt, aes_gcm_encrypt, derive_key_from_password, generate_aes256_key, generate_salt,
26 ZVec, AES_256_KEY_LENGTH,
Janis Danisevskisb42fc182020-12-15 08:41:27 -080027};
Hasini Gunasinghedeab85d2021-02-01 21:10:02 +000028use std::ops::Deref;
Janis Danisevskisb42fc182020-12-15 08:41:27 -080029use std::{
30 collections::HashMap,
31 sync::Arc,
32 sync::{Mutex, Weak},
33};
34
35type UserId = u32;
36
37#[derive(Default)]
38struct UserSuperKeys {
39 /// The per boot key is used for LSKF binding of authentication bound keys. There is one
40 /// key per android user. The key is stored on flash encrypted with a key derived from a
41 /// secret, that is itself derived from the user's lock screen knowledge factor (LSKF).
42 /// When the user unlocks the device for the first time, this key is unlocked, i.e., decrypted,
43 /// and stays memory resident until the device reboots.
Hasini Gunasinghe0e161452021-01-27 19:34:37 +000044 per_boot: Option<SuperKey>,
Janis Danisevskisb42fc182020-12-15 08:41:27 -080045 /// The screen lock key works like the per boot key with the distinction that it is cleared
46 /// from memory when the screen lock is engaged.
47 /// TODO the life cycle is not fully implemented at this time.
48 screen_lock: Option<Arc<ZVec>>,
49}
50
Hasini Gunasinghe0e161452021-01-27 19:34:37 +000051#[derive(Default, Clone)]
52pub struct SuperKey {
53 key: Arc<ZVec>,
54 // id of the super key in the database.
55 id: i64,
56}
57
58impl SuperKey {
59 pub fn get_key(&self) -> &Arc<ZVec> {
60 &self.key
61 }
62
63 pub fn get_id(&self) -> i64 {
64 self.id
65 }
66}
67
Janis Danisevskisb42fc182020-12-15 08:41:27 -080068#[derive(Default)]
69struct SkmState {
70 user_keys: HashMap<UserId, UserSuperKeys>,
71 key_index: HashMap<i64, Weak<ZVec>>,
72}
73
74#[derive(Default)]
75pub struct SuperKeyManager {
76 data: Mutex<SkmState>,
77}
78
79impl SuperKeyManager {
80 pub fn new() -> Self {
81 Self { data: Mutex::new(Default::default()) }
82 }
83
84 pub fn forget_screen_lock_key_for_user(&self, user: UserId) {
85 let mut data = self.data.lock().unwrap();
86 if let Some(usk) = data.user_keys.get_mut(&user) {
87 usk.screen_lock = None;
88 }
89 }
90
91 pub fn forget_screen_lock_keys(&self) {
92 let mut data = self.data.lock().unwrap();
93 for (_, usk) in data.user_keys.iter_mut() {
94 usk.screen_lock = None;
95 }
96 }
97
98 pub fn forget_all_keys_for_user(&self, user: UserId) {
99 let mut data = self.data.lock().unwrap();
100 data.user_keys.remove(&user);
101 }
102
103 pub fn forget_all_keys(&self) {
104 let mut data = self.data.lock().unwrap();
105 data.user_keys.clear();
106 data.key_index.clear();
107 }
108
Hasini Gunasingheda895552021-01-27 19:34:37 +0000109 fn install_per_boot_key_for_user(&self, user: UserId, super_key: SuperKey) {
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800110 let mut data = self.data.lock().unwrap();
Hasini Gunasingheda895552021-01-27 19:34:37 +0000111 data.key_index.insert(super_key.id, Arc::downgrade(&(super_key.key)));
112 data.user_keys.entry(user).or_default().per_boot = Some(super_key);
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800113 }
114
115 fn get_key(&self, key_id: &i64) -> Option<Arc<ZVec>> {
116 self.data.lock().unwrap().key_index.get(key_id).and_then(|k| k.upgrade())
117 }
118
Hasini Gunasinghe0e161452021-01-27 19:34:37 +0000119 pub fn get_per_boot_key_by_user_id(&self, user_id: u32) -> Option<SuperKey> {
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800120 let data = self.data.lock().unwrap();
121 data.user_keys.get(&user_id).map(|e| e.per_boot.clone()).flatten()
122 }
123
124 /// This function unlocks the super keys for a given user.
125 /// This means the key is loaded from the database, decrypted and placed in the
126 /// super key cache. If there is no such key a new key is created, encrypted with
127 /// a key derived from the given password and stored in the database.
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -0800128 pub fn unlock_user_key(
129 &self,
Hasini Gunasingheda895552021-01-27 19:34:37 +0000130 db: &mut KeystoreDB,
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -0800131 user: UserId,
132 pw: &[u8],
Janis Danisevskisa51ccbc2020-11-25 21:04:24 -0800133 legacy_blob_loader: &LegacyBlobLoader,
134 ) -> Result<()> {
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800135 let (_, entry) = db
Max Bires8e93d2b2021-01-14 13:17:59 -0800136 .get_or_create_key_with(
137 Domain::APP,
138 user as u64 as i64,
Hasini Gunasinghe0e161452021-01-27 19:34:37 +0000139 KeystoreDB::USER_SUPER_KEY_ALIAS,
Max Bires8e93d2b2021-01-14 13:17:59 -0800140 crate::database::KEYSTORE_UUID,
141 || {
142 // For backward compatibility we need to check if there is a super key present.
143 let super_key = legacy_blob_loader
144 .load_super_key(user, pw)
145 .context("In create_new_key: Failed to load legacy key blob.")?;
146 let super_key = match super_key {
147 None => {
148 // No legacy file was found. So we generate a new key.
Hasini Gunasingheda895552021-01-27 19:34:37 +0000149 generate_aes256_key()
Max Bires8e93d2b2021-01-14 13:17:59 -0800150 .context("In create_new_key: Failed to generate AES 256 key.")?
151 }
152 Some(key) => key,
153 };
Hasini Gunasingheda895552021-01-27 19:34:37 +0000154 // Regardless of whether we loaded an old AES128 key or generated a new AES256
155 // key as the super key, we derive a AES256 key from the password and re-encrypt
156 // the super key before we insert it in the database. The length of the key is
157 // preserved by the encryption so we don't need any extra flags to inform us
158 // which algorithm to use it with.
159 Self::encrypt_with_password(&super_key, pw).context("In create_new_key.")
Max Bires8e93d2b2021-01-14 13:17:59 -0800160 },
161 )
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800162 .context("In unlock_user_key: Failed to get key id.")?;
163
Hasini Gunasingheda895552021-01-27 19:34:37 +0000164 self.populate_cache_from_super_key_blob(user, entry, pw).context("In unlock_user_key.")?;
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800165 Ok(())
166 }
167
168 /// Unwraps an encrypted key blob given metadata identifying the encryption key.
169 /// The function queries `metadata.encrypted_by()` to determine the encryption key.
170 /// It then check if the required key is memory resident, and if so decrypts the
171 /// blob.
Hasini Gunasinghedeab85d2021-02-01 21:10:02 +0000172 pub fn unwrap_key<'a>(&self, blob: &'a [u8], metadata: &BlobMetaData) -> Result<KeyBlob<'a>> {
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800173 match metadata.encrypted_by() {
174 Some(EncryptedBy::KeyId(key_id)) => match self.get_key(key_id) {
Hasini Gunasinghedeab85d2021-02-01 21:10:02 +0000175 Some(key) => Ok(KeyBlob::Sensitive(
176 Self::unwrap_key_with_key(blob, metadata, &key).context("In unwrap_key.")?,
177 SuperKey { key: key.clone(), id: *key_id },
178 )),
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800179 None => Err(Error::Rc(ResponseCode::LOCKED))
180 .context("In unwrap_key: Key is not usable until the user entered their LSKF."),
181 },
182 _ => Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
183 .context("In unwrap_key: Cannot determined wrapping key."),
184 }
185 }
186
187 /// Unwraps an encrypted key blob given an encryption key.
Janis Danisevskis7e8b4622021-02-13 10:01:59 -0800188 fn unwrap_key_with_key(blob: &[u8], metadata: &BlobMetaData, key: &[u8]) -> Result<ZVec> {
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800189 match (metadata.iv(), metadata.aead_tag()) {
190 (Some(iv), Some(tag)) => aes_gcm_decrypt(blob, iv, tag, key)
191 .context("In unwrap_key_with_key: Failed to decrypt the key blob."),
192 (iv, tag) => Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
193 concat!(
194 "In unwrap_key_with_key: Key has incomplete metadata.",
195 "Present: iv: {}, aead_tag: {}."
196 ),
197 iv.is_some(),
198 tag.is_some(),
199 )),
200 }
201 }
Hasini Gunasinghe0e161452021-01-27 19:34:37 +0000202
203 /// Checks if user has setup LSKF, even when super key cache is empty for the user.
204 pub fn super_key_exists_in_db_for_user(db: &mut KeystoreDB, user_id: u32) -> Result<bool> {
205 let key_in_db = db
206 .key_exists(
207 Domain::APP,
208 user_id as u64 as i64,
209 KeystoreDB::USER_SUPER_KEY_ALIAS,
210 KeyType::Super,
211 )
212 .context("In super_key_exists_in_db_for_user.")?;
213
214 if key_in_db {
215 Ok(key_in_db)
216 } else {
217 //TODO (b/159371296): add a function to legacy blob loader to check if super key exists
218 //given user id
219 Ok(false)
220 }
221 }
Hasini Gunasingheda895552021-01-27 19:34:37 +0000222
223 /// Checks if user has already setup LSKF (i.e. a super key is persisted in the database or the
224 /// legacy database). If so, return LskfLocked state.
225 /// If the password is provided, generate a new super key, encrypt with the password,
226 /// store in the database and populate the super key cache for the new user
227 /// and return LskfUnlocked state.
228 /// If the password is not provided, return Uninitialized state.
229 pub fn check_and_initialize_super_key(
230 &self,
231 db: &mut KeystoreDB,
232 user_id: u32,
233 pw: Option<&[u8]>,
234 ) -> Result<UserState> {
235 let super_key_exists_in_db = Self::super_key_exists_in_db_for_user(db, user_id)
236 .context("In check_and_initialize_super_key. Failed to check if super key exists.")?;
237
238 if super_key_exists_in_db {
239 Ok(UserState::LskfLocked)
240 } else {
241 //TODO: 159371296. check if super key exists in legacy key database. If so, return
242 //LskfLocked. Otherwise, if pw is provided, initialize the super key.
243 if let Some(pw) = pw {
244 //generate a new super key.
245 let super_key = generate_aes256_key().context(
246 "In check_and_initialize_super_key: Failed to generate AES 256 key.",
247 )?;
248 //derive an AES256 key from the password and re-encrypt the super key
249 //before we insert it in the database.
250 let (encrypted_super_key, blob_metadata) =
251 Self::encrypt_with_password(&super_key, pw)
252 .context("In check_and_initialize_super_key.")?;
253
254 let key_entry = db
255 .store_super_key(user_id as u64 as i64, &(&encrypted_super_key, &blob_metadata))
256 .context("In check_and_initialize_super_key. Failed to store super key.")?;
257
258 let super_key = self
259 .populate_cache_from_super_key_blob(user_id, key_entry, pw)
260 .context("In check_and_initialize_super_key.")?;
261 Ok(UserState::LskfUnlocked(super_key))
262 } else {
263 Ok(UserState::Uninitialized)
264 }
265 }
266 }
267
268 //helper function to populate super key cache from the super key blob loaded from the database
269 fn populate_cache_from_super_key_blob(
270 &self,
271 user_id: u32,
272 entry: KeyEntry,
273 pw: &[u8],
274 ) -> Result<SuperKey> {
275 let super_key = Self::extract_super_key_from_key_entry(entry, pw).context(
276 "In populate_cache_from_super_key_blob. Failed to extract super key from key entry",
277 )?;
278 self.install_per_boot_key_for_user(user_id, super_key.clone());
279 Ok(super_key)
280 }
281
282 /// Extracts super key from the entry loaded from the database
283 pub fn extract_super_key_from_key_entry(entry: KeyEntry, pw: &[u8]) -> Result<SuperKey> {
284 if let Some((blob, metadata)) = entry.key_blob_info() {
285 let key = match (
286 metadata.encrypted_by(),
287 metadata.salt(),
288 metadata.iv(),
289 metadata.aead_tag(),
290 ) {
291 (Some(&EncryptedBy::Password), Some(salt), Some(iv), Some(tag)) => {
292 let key = derive_key_from_password(pw, Some(salt), AES_256_KEY_LENGTH).context(
293 "In extract_super_key_from_key_entry: Failed to generate key from password.",
294 )?;
295
296 aes_gcm_decrypt(blob, iv, tag, &key).context(
297 "In extract_super_key_from_key_entry: Failed to decrypt key blob.",
298 )?
299 }
300 (enc_by, salt, iv, tag) => {
301 return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
302 concat!(
303 "In extract_super_key_from_key_entry: Super key has incomplete metadata.",
304 "Present: encrypted_by: {}, salt: {}, iv: {}, aead_tag: {}."
305 ),
306 enc_by.is_some(),
307 salt.is_some(),
308 iv.is_some(),
309 tag.is_some()
310 ));
311 }
312 };
313 Ok(SuperKey { key: Arc::new(key), id: entry.id() })
314 } else {
315 Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
316 .context("In extract_super_key_from_key_entry: No key blob info.")
317 }
318 }
319
320 /// Encrypts the super key from a key derived from the password, before storing in the database.
321 pub fn encrypt_with_password(super_key: &[u8], pw: &[u8]) -> Result<(Vec<u8>, BlobMetaData)> {
322 let salt = generate_salt().context("In encrypt_with_password: Failed to generate salt.")?;
323 let derived_key = derive_key_from_password(pw, Some(&salt), AES_256_KEY_LENGTH)
324 .context("In encrypt_with_password: Failed to derive password.")?;
325 let mut metadata = BlobMetaData::new();
326 metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
327 metadata.add(BlobMetaEntry::Salt(salt));
328 let (encrypted_key, iv, tag) = aes_gcm_encrypt(super_key, &derived_key)
329 .context("In encrypt_with_password: Failed to encrypt new super key.")?;
330 metadata.add(BlobMetaEntry::Iv(iv));
331 metadata.add(BlobMetaEntry::AeadTag(tag));
332 Ok((encrypted_key, metadata))
333 }
Hasini Gunasinghedeab85d2021-02-01 21:10:02 +0000334
335 // Encrypt the given key blob with the user's super key, if the super key exists and the device
336 // is unlocked. If the super key exists and the device is locked, or LSKF is not setup,
337 // return error. Note that it is out of the scope of this function to check if super encryption
338 // is required. Such check should be performed before calling this function.
339 fn super_encrypt_on_key_init(
340 db: &mut KeystoreDB,
341 skm: &SuperKeyManager,
342 user_id: u32,
343 key_blob: &[u8],
344 ) -> Result<(Vec<u8>, BlobMetaData)> {
345 match UserState::get(db, skm, user_id)
346 .context("In super_encrypt. Failed to get user state.")?
347 {
348 UserState::LskfUnlocked(super_key) => {
349 Self::encrypt_with_super_key(key_blob, &super_key)
350 .context("In super_encrypt_on_key_init. Failed to encrypt the key.")
351 }
352 UserState::LskfLocked => {
353 Err(Error::Rc(ResponseCode::LOCKED)).context("In super_encrypt. Device is locked.")
354 }
355 UserState::Uninitialized => Err(Error::Rc(ResponseCode::UNINITIALIZED))
356 .context("In super_encrypt. LSKF is not setup for the user."),
357 }
358 }
359
360 //Helper function to encrypt a key with the given super key. Callers should select which super
361 //key to be used. This is called when a key is super encrypted at its creation as well as at its
362 //upgrade.
363 fn encrypt_with_super_key(
364 key_blob: &[u8],
365 super_key: &SuperKey,
366 ) -> Result<(Vec<u8>, BlobMetaData)> {
367 let mut metadata = BlobMetaData::new();
368 let (encrypted_key, iv, tag) = aes_gcm_encrypt(key_blob, &(super_key.key))
369 .context("In encrypt_with_super_key: Failed to encrypt new super key.")?;
370 metadata.add(BlobMetaEntry::Iv(iv));
371 metadata.add(BlobMetaEntry::AeadTag(tag));
372 metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::KeyId(super_key.id)));
373 Ok((encrypted_key, metadata))
374 }
375
376 /// Check if super encryption is required and if so, super-encrypt the key to be stored in
377 /// the database.
378 pub fn handle_super_encryption_on_key_init(
379 db: &mut KeystoreDB,
380 skm: &SuperKeyManager,
381 domain: &Domain,
382 key_parameters: &[KeyParameter],
383 flags: Option<i32>,
384 user_id: u32,
385 key_blob: &[u8],
386 ) -> Result<(Vec<u8>, BlobMetaData)> {
387 match (*domain, Enforcements::super_encryption_required(key_parameters, flags)) {
388 (Domain::APP, true) => Self::super_encrypt_on_key_init(db, skm, user_id, &key_blob)
389 .context(
390 "In handle_super_encryption_on_key_init.
391 Failed to super encrypt the key.",
392 ),
393 _ => Ok((key_blob.to_vec(), BlobMetaData::new())),
394 }
395 }
396
397 /// Check if a given key is super-encrypted, from its metadata. If so, unwrap the key using
398 /// the relevant super key.
399 pub fn unwrap_key_if_required<'a>(
400 &self,
401 metadata: &BlobMetaData,
402 key_blob: &'a [u8],
403 ) -> Result<KeyBlob<'a>> {
404 if Self::key_super_encrypted(&metadata) {
405 let unwrapped_key = self
406 .unwrap_key(key_blob, metadata)
407 .context("In unwrap_key_if_required. Error in unwrapping the key.")?;
408 Ok(unwrapped_key)
409 } else {
410 Ok(KeyBlob::Ref(key_blob))
411 }
412 }
413
414 /// Check if a given key needs re-super-encryption, from its KeyBlob type.
415 /// If so, re-super-encrypt the key and return a new set of metadata,
416 /// containing the new super encryption information.
417 pub fn reencrypt_on_upgrade_if_required<'a>(
418 key_blob_before_upgrade: &KeyBlob,
419 key_after_upgrade: &'a [u8],
420 ) -> Result<(KeyBlob<'a>, Option<BlobMetaData>)> {
421 match key_blob_before_upgrade {
422 KeyBlob::Sensitive(_, super_key) => {
423 let (key, metadata) = Self::encrypt_with_super_key(key_after_upgrade, super_key)
424 .context(
425 "In reencrypt_on_upgrade_if_required. Failed to re-super-encrypt key on key upgrade.",
426 )?;
427 Ok((KeyBlob::NonSensitive(key), Some(metadata)))
428 }
429 _ => Ok((KeyBlob::Ref(key_after_upgrade), None)),
430 }
431 }
432
433 // Helper function to decide if a key is super encrypted, given metadata.
434 fn key_super_encrypted(metadata: &BlobMetaData) -> bool {
435 if let Some(&EncryptedBy::KeyId(_)) = metadata.encrypted_by() {
436 return true;
437 }
438 false
439 }
Hasini Gunasinghe0e161452021-01-27 19:34:37 +0000440}
441
442/// This enum represents different states of the user's life cycle in the device.
443/// For now, only three states are defined. More states may be added later.
444pub enum UserState {
445 // The user has registered LSKF and has unlocked the device by entering PIN/Password,
446 // and hence the per-boot super key is available in the cache.
447 LskfUnlocked(SuperKey),
448 // The user has registered LSKF, but has not unlocked the device using password, after reboot.
449 // Hence the per-boot super-key(s) is not available in the cache.
450 // However, the encrypted super key is available in the database.
451 LskfLocked,
452 // There's no user in the device for the given user id, or the user with the user id has not
453 // setup LSKF.
454 Uninitialized,
455}
456
457impl UserState {
Hasini Gunasingheda895552021-01-27 19:34:37 +0000458 pub fn get(db: &mut KeystoreDB, skm: &SuperKeyManager, user_id: u32) -> Result<UserState> {
Hasini Gunasinghe0e161452021-01-27 19:34:37 +0000459 match skm.get_per_boot_key_by_user_id(user_id) {
460 Some(super_key) => Ok(UserState::LskfUnlocked(super_key)),
461 None => {
462 //Check if a super key exists in the database or legacy database.
463 //If so, return locked user state.
464 if SuperKeyManager::super_key_exists_in_db_for_user(db, user_id)
Hasini Gunasingheda895552021-01-27 19:34:37 +0000465 .context("In get.")?
Hasini Gunasinghe0e161452021-01-27 19:34:37 +0000466 {
467 Ok(UserState::LskfLocked)
468 } else {
469 Ok(UserState::Uninitialized)
470 }
471 }
472 }
473 }
Hasini Gunasingheda895552021-01-27 19:34:37 +0000474
475 /// Queries user state when serving password change requests.
476 pub fn get_with_password_changed(
477 db: &mut KeystoreDB,
478 skm: &SuperKeyManager,
479 user_id: u32,
480 password: Option<&[u8]>,
481 ) -> Result<UserState> {
482 match skm.get_per_boot_key_by_user_id(user_id) {
483 Some(super_key) => {
484 if password.is_none() {
485 //transitioning to swiping, delete only the super key in database and cache, and
486 //super-encrypted keys in database (and in KM)
487 Self::reset_user(db, skm, user_id, true)
488 .context("In get_with_password_changed.")?;
489 //Lskf is now removed in Keystore
490 Ok(UserState::Uninitialized)
491 } else {
492 //Keystore won't be notified when changing to a new password when LSKF is
493 //already setup. Therefore, ideally this path wouldn't be reached.
494 Ok(UserState::LskfUnlocked(super_key))
495 }
496 }
497 None => {
498 //Check if a super key exists in the database or legacy database.
499 //If so, return LskfLocked state.
500 //Otherwise, i) if the password is provided, initialize the super key and return
501 //LskfUnlocked state ii) if password is not provided, return Uninitialized state.
502 skm.check_and_initialize_super_key(db, user_id, password)
503 }
504 }
505 }
506
507 /// Delete all the keys created on behalf of the user.
508 /// If 'keep_non_super_encrypted_keys' is set to true, delete only the super key and super
509 /// encrypted keys.
510 pub fn reset_user(
511 db: &mut KeystoreDB,
512 skm: &SuperKeyManager,
513 user_id: u32,
514 keep_non_super_encrypted_keys: bool,
515 ) -> Result<()> {
516 // mark keys created on behalf of the user as unreferenced.
517 db.unbind_keys_for_user(user_id as u32, keep_non_super_encrypted_keys)
518 .context("In reset user. Error in unbinding keys.")?;
519
520 //delete super key in cache, if exists
521 skm.forget_all_keys_for_user(user_id as u32);
522 Ok(())
523 }
Janis Danisevskisb42fc182020-12-15 08:41:27 -0800524}
Hasini Gunasinghedeab85d2021-02-01 21:10:02 +0000525
526/// This enum represents two states a Keymint Blob can be in, w.r.t super encryption.
527/// Sensitive variant represents a Keymint blob that is supposed to be super encrypted,
528/// but unwrapped during usage. Therefore, it has the super key along with the unwrapped key.
529/// Ref variant represents a Keymint blob that is not required to super encrypt or that is
530/// already super encrypted.
531pub enum KeyBlob<'a> {
532 Sensitive(ZVec, SuperKey),
533 NonSensitive(Vec<u8>),
534 Ref(&'a [u8]),
535}
536
537/// Deref returns a reference to the key material in both variants.
538impl<'a> Deref for KeyBlob<'a> {
539 type Target = [u8];
540
541 fn deref(&self) -> &Self::Target {
542 match self {
543 Self::Sensitive(key, _) => &key,
544 Self::NonSensitive(key) => &key,
545 Self::Ref(key) => key,
546 }
547 }
548}