blob: d6c2ba49fa7d92b4dc351bd81c87abd1fb457c8c [file] [log] [blame]
Janis Danisevskisa75e2082020-10-07 16:44:26 -07001// 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//! This module holds global state of Keystore such as the thread local
16//! database connections and connections to services that Keystore needs
17//! to talk to.
18
Janis Danisevskisb42fc182020-12-15 08:41:27 -080019use crate::super_key::SuperKeyManager;
Janis Danisevskisba998992020-12-29 16:08:40 -080020use crate::utils::Asp;
21use crate::{
22 database::KeystoreDB,
23 error::{map_binder_status_code, Error, ErrorCode},
24};
25use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
26 IKeyMintDevice::IKeyMintDevice, SecurityLevel::SecurityLevel,
27};
28use anyhow::{Context, Result};
Janis Danisevskisb42fc182020-12-15 08:41:27 -080029use lazy_static::lazy_static;
Janis Danisevskisa75e2082020-10-07 16:44:26 -070030use std::cell::RefCell;
Janis Danisevskisba998992020-12-29 16:08:40 -080031use std::collections::HashMap;
32use std::sync::Mutex;
Janis Danisevskisa75e2082020-10-07 16:44:26 -070033
34thread_local! {
35 /// Database connections are not thread safe, but connecting to the
36 /// same database multiple times is safe as long as each connection is
37 /// used by only one thread. So we store one database connection per
38 /// thread in this thread local key.
39 pub static DB: RefCell<KeystoreDB> =
Janis Danisevskisbf15d732020-12-08 10:35:26 -080040 RefCell::new(
41 KeystoreDB::new(
42 // Keystore changes to the database directory on startup
43 // (see keystor2_main.rs).
44 &std::env::current_dir()
45 .expect("Could not get the current working directory.")
46 )
47 .expect("Failed to open database."));
Janis Danisevskisa75e2082020-10-07 16:44:26 -070048}
Janis Danisevskisb42fc182020-12-15 08:41:27 -080049
50lazy_static! {
51 /// Runtime database of unwrapped super keys.
52 pub static ref SUPER_KEY: SuperKeyManager = Default::default();
Janis Danisevskisba998992020-12-29 16:08:40 -080053 /// Map of KeyMint devices.
54 static ref KEY_MINT_DEVICES: Mutex<HashMap<SecurityLevel, Asp>> = Default::default();
55}
56
57static KEYMINT_SERVICE_NAME: &str = "android.hardware.security.keymint.IKeyMintDevice";
58
59/// Make a new connection to a KeyMint device of the given security level.
60fn connect_keymint(security_level: SecurityLevel) -> Result<Asp> {
61 let service_name = match security_level {
62 SecurityLevel::TRUSTED_ENVIRONMENT => format!("{}/default", KEYMINT_SERVICE_NAME),
63 SecurityLevel::STRONGBOX => format!("{}/strongbox", KEYMINT_SERVICE_NAME),
64 _ => {
65 return Err(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
66 .context("In connect_keymint.")
67 }
68 };
69
70 let keymint: Box<dyn IKeyMintDevice> =
71 map_binder_status_code(binder::get_interface(&service_name))
72 .context("In connect_keymint: Trying to connect to genuine KeyMint service.")?;
73
74 Ok(Asp::new(keymint.as_binder()))
75}
76
77/// Get a keymint device for the given security level either from our cache or
78/// by making a new connection.
79pub fn get_keymint_device(security_level: SecurityLevel) -> Result<Asp> {
80 let mut devices_map = KEY_MINT_DEVICES.lock().unwrap();
81 if let Some(dev) = devices_map.get(&security_level) {
82 Ok(dev.clone())
83 } else {
84 let dev = connect_keymint(security_level).map_err(|e| {
85 anyhow::anyhow!(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
86 .context(format!("In get_keymint_device: {:?}", e))
87 })?;
88 devices_map.insert(security_level, dev.clone());
89 Ok(dev)
90 }
Janis Danisevskisb42fc182020-12-15 08:41:27 -080091}