Keystore 2.0: Use secure clock service.
Test: CtsVerifier Fingerprint Bound Keys Test
Change-Id: Ia93794f7bcd9f5e26a4121a7bf689440fb1eeed4
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index bf91e4b..5339ec5 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -19,6 +19,7 @@
rustlibs: [
"android.hardware.security.keymint-rust",
+ "android.hardware.security.secureclock-rust",
"android.security.apc-rust",
"android.security.authorization-rust",
"android.security.compat-rust",
@@ -48,6 +49,7 @@
test_config: "AndroidTest.xml",
rustlibs: [
"android.hardware.security.keymint-rust",
+ "android.hardware.security.secureclock-rust",
"android.security.apc-rust",
"android.security.authorization-rust",
"android.security.compat-rust",
diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
index 3fd0580..fac36e5 100644
--- a/keystore2/aidl/Android.bp
+++ b/keystore2/aidl/Android.bp
@@ -30,7 +30,10 @@
aidl_interface {
name: "android.security.authorization",
srcs: [ "android/security/authorization/*.aidl" ],
- imports: [ "android.hardware.security.keymint" ],
+ imports: [
+ "android.hardware.security.keymint",
+ "android.hardware.security.secureclock",
+ ],
unstable: true,
backend: {
java: {
diff --git a/keystore2/src/auth_token_handler.rs b/keystore2/src/auth_token_handler.rs
index a1f9399..bedec50 100644
--- a/keystore2/src/auth_token_handler.rs
+++ b/keystore2/src/auth_token_handler.rs
@@ -13,11 +13,15 @@
// limitations under the License.
//! This module defines the AuthTokenHandler enum and its methods. AuthTokenHandler enum represents
-//! the different states an auth token and an associated verification token can be expressed during
+//! the different states an auth token and an associated timestamp token can be expressed during
//! the operation life cycle.
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
- HardwareAuthToken::HardwareAuthToken, VerificationToken::VerificationToken,
+ HardwareAuthToken::HardwareAuthToken,
};
+use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
+ TimeStampToken::TimeStampToken,
+};
+
use anyhow::{Context, Result};
use std::sync::mpsc::Receiver;
@@ -32,48 +36,48 @@
OpAuthRequired,
/// Used to represent the intermediate state between the time the operation is found to be
/// using a time_out key with STRONGBOX keymint, and the time a verficiation token is requested
- /// from the worker thread which obtains verification tokens from the TEE KeyMint.
- VerificationRequired(HardwareAuthToken),
- /// Used to represent the intermediate state between the time a verification token is requested
- /// from the worker thread which obtains verification tokens from the TEE KeyMint and the time
- /// the verification token is received from the worker thread.
- Channel(Receiver<(HardwareAuthToken, VerificationToken)>),
+ /// from the worker thread which obtains timestamp tokens from the TEE KeyMint.
+ TimestampRequired(HardwareAuthToken),
+ /// Used to represent the intermediate state between the time a timestamp token is requested
+ /// from the worker thread which obtains timestamp tokens from the TEE KeyMint and the time
+ /// the timestamp token is received from the worker thread.
+ Channel(Receiver<(HardwareAuthToken, TimeStampToken)>),
/// Used to represent the final state for all operations requiring an auth token for
- /// authorization, after the matching auth token (and the associated verification token if
+ /// authorization, after the matching auth token (and the associated timestamp token if
/// required) is found.
- Token(HardwareAuthToken, Option<VerificationToken>),
+ Token(HardwareAuthToken, Option<TimeStampToken>),
}
impl AuthTokenHandler {
- /// If Channel variant, block on it until the verification token is sent by the
- /// keystore2 worker thread which obtains verification tokens from TEE Keymint and converts the
+ /// If Channel variant, block on it until the timestamp token is sent by the
+ /// keystore2 worker thread which obtains timestamp tokens from TEE Keymint and converts the
/// object from Channel variant to Token variant.
- /// Retrieve auth token and verification token from the Token variant of an AuthTokenHandler
+ /// Retrieve auth token and timestamp token from the Token variant of an AuthTokenHandler
/// instance.
- pub fn retrieve_auth_and_verification_tokens(
+ pub fn retrieve_auth_and_timestamp_tokens(
&mut self,
- ) -> Result<(Option<&HardwareAuthToken>, Option<&VerificationToken>)> {
+ ) -> Result<(Option<&HardwareAuthToken>, Option<&TimeStampToken>)> {
// Converts to Token variant if Channel variant found, after retrieving the
- // VerificationToken
+ // TimeStampToken
if let AuthTokenHandler::Channel(recv) = self {
- let (auth_token, verification_token) =
- recv.recv().context("In receive_verification_token: sender disconnected.")?;
- *self = AuthTokenHandler::Token(auth_token, Some(verification_token));
+ let (auth_token, timestamp_token) =
+ recv.recv().context("In receive_timestamp_token: sender disconnected.")?;
+ *self = AuthTokenHandler::Token(auth_token, Some(timestamp_token));
}
// get the tokens from the Token variant
- if let AuthTokenHandler::Token(auth_token, optional_verification_token) = self {
- Ok((Some(auth_token), optional_verification_token.as_ref()))
+ if let AuthTokenHandler::Token(auth_token, optional_time_stamp_token) = self {
+ Ok((Some(auth_token), optional_time_stamp_token.as_ref()))
} else {
Ok((None, None))
}
}
- /// Retrieve auth token from VerificationRequired and Token variants of an
+ /// Retrieve auth token from TimestampRequired and Token variants of an
/// AuthTokenHandler instance. This method is useful when we only expect an auth token and
- /// do not expect a verification token.
+ /// do not expect a timestamp token.
pub fn get_auth_token(&self) -> Option<&HardwareAuthToken> {
match self {
- AuthTokenHandler::VerificationRequired(auth_token) => Some(auth_token),
+ AuthTokenHandler::TimestampRequired(auth_token) => Some(auth_token),
AuthTokenHandler::Token(auth_token, _) => Some(auth_token),
_ => None,
}
diff --git a/keystore2/src/authorization.rs b/keystore2/src/authorization.rs
index 08ae07c..409feba 100644
--- a/keystore2/src/authorization.rs
+++ b/keystore2/src/authorization.rs
@@ -20,6 +20,8 @@
use crate::utils::check_keystore_permission;
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
HardwareAuthToken::HardwareAuthToken, HardwareAuthenticatorType::HardwareAuthenticatorType,
+};
+use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
Timestamp::Timestamp,
};
use android_security_authorization::binder::{Interface, Result as BinderResult};
diff --git a/keystore2/src/background_task_handler.rs b/keystore2/src/background_task_handler.rs
index fbb6778..b039506 100644
--- a/keystore2/src/background_task_handler.rs
+++ b/keystore2/src/background_task_handler.rs
@@ -16,8 +16,10 @@
//! the timestamp service (or TEE KeyMint in legacy devices), via a separate thread.
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
- HardwareAuthToken::HardwareAuthToken, IKeyMintDevice::IKeyMintDevice,
- SecurityLevel::SecurityLevel, VerificationToken::VerificationToken,
+ HardwareAuthToken::HardwareAuthToken,
+};
+use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
+ ISecureClock::ISecureClock, TimeStampToken::TimeStampToken,
};
use android_system_keystore2::aidl::android::system::keystore2::OperationChallenge::OperationChallenge;
use anyhow::Result;
@@ -25,16 +27,20 @@
use std::sync::mpsc::{Receiver, Sender};
use std::sync::Mutex;
use std::thread::{spawn, JoinHandle};
+
+use crate::globals::get_timestamp_service;
+
/// This is the struct encapsulating the thread which handles background tasks such as
-/// obtaining verification tokens.
+/// obtaining timestamp tokens.
pub struct BackgroundTaskHandler {
task_handler: Mutex<Option<JoinHandle<()>>>,
}
+
/// This enum defines the two variants of a message that can be passed down to the
/// BackgroundTaskHandler via the channel.
pub enum Message {
///This variant represents a message sent down the channel when requesting a timestamp token.
- Inputs((HardwareAuthToken, OperationChallenge, Sender<(HardwareAuthToken, VerificationToken)>)),
+ Inputs((HardwareAuthToken, OperationChallenge, Sender<(HardwareAuthToken, TimeStampToken)>)),
///This variant represents a message sent down the channel when signalling the thread to stop.
Shutdown,
}
@@ -65,34 +71,32 @@
// If either a timestamp service or a keymint instance is expected to be found and neither
// is found, an error is returned.
// If neither is expected to be found, make timestamp_service field None, and in the thread,
- // send a default verification token down the channel to the operation.
+ // send a default timestamp token down the channel to the operation.
// Until timestamp service is available and proper probing of legacy keymaster devices are
// done, the keymint service is initialized here as it is done in security_level module.
Ok(spawn(move || {
- while let Message::Inputs((auth_token, op_challenge, op_sender)) = receiver
- .recv()
- .expect(
- "In background task handler thread. Failed to receive message over the channel.",
- ) {
- // TODO: call the timestamp service/old TEE keymaster to get
- // timestamp/verification tokens and pass it down the sender that is
- // coupled with a particular operation's receiver.
- // If none of the services are available, pass the authtoken and a default
- // verification token down the channel.
- let km_dev: Box<dyn IKeyMintDevice> =
- crate::globals::get_keymint_device(SecurityLevel::TRUSTED_ENVIRONMENT)
- .expect("A TEE Keymint must be present.")
- .get_interface()
- .expect("Fatal: The keymint device does not implement IKeyMintDevice.");
- let result = km_dev.verifyAuthorization(op_challenge.challenge, &auth_token);
+ while let Message::Inputs((auth_token, op_challenge, op_sender)) =
+ receiver.recv().expect(
+ "In background task handler thread. Failed to
+ receive message over the channel.",
+ )
+ {
+ let dev: Box<dyn ISecureClock> = get_timestamp_service()
+ .expect(concat!(
+ "Secure Clock service must be present ",
+ "if TimeStampTokens are required."
+ ))
+ .get_interface()
+ .expect("Fatal: Timestamp service does not implement ISecureClock.");
+ let result = dev.generateTimeStamp(op_challenge.challenge);
match result {
- Ok(verification_token) => {
+ Ok(timestamp_token) => {
// this can fail if the operation is dropped and hence the channel
// is hung up.
- op_sender.send((auth_token, verification_token)).unwrap_or_else(|e| {
+ op_sender.send((auth_token, timestamp_token)).unwrap_or_else(|e| {
error!(
"In background task handler thread. Failed to send
- verification token to operation {} due to error {:?}.",
+ timestamp token to operation {} due to error {:?}.",
op_challenge.challenge, e
)
});
@@ -101,17 +105,17 @@
// log error
error!(
"In background task handler thread. Failed to receive
- verification token for operation {} due to error {:?}.",
+ timestamp token for operation {} due to error {:?}.",
op_challenge.challenge, e
);
- // send default verification token
+ // send default timestamp token
// this can fail if the operation is dropped and the channel is
// hung up.
- op_sender.send((auth_token, VerificationToken::default())).unwrap_or_else(
+ op_sender.send((auth_token, TimeStampToken::default())).unwrap_or_else(
|e| {
error!(
"In background task handler thread. Failed to send default
- verification token to operation {} due to error {:?}.",
+ timestamp token to operation {} due to error {:?}.",
op_challenge.challenge, e
)
},
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index ab8b05f..e25fea2 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -58,6 +58,8 @@
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
ErrorCode::ErrorCode as Ec, HardwareAuthToken::HardwareAuthToken,
HardwareAuthenticatorType::HardwareAuthenticatorType, SecurityLevel::SecurityLevel,
+};
+use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
Timestamp::Timestamp,
};
use android_system_keystore2::aidl::android::system::keystore2::{
@@ -1811,6 +1813,8 @@
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
HardwareAuthToken::HardwareAuthToken,
HardwareAuthenticatorType::HardwareAuthenticatorType as kmhw_authenticator_type,
+ };
+ use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
Timestamp::Timestamp,
};
use rusqlite::NO_PARAMS;
diff --git a/keystore2/src/enforcements.rs b/keystore2/src/enforcements.rs
index ae41432..93e077c 100644
--- a/keystore2/src/enforcements.rs
+++ b/keystore2/src/enforcements.rs
@@ -23,8 +23,10 @@
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
Algorithm::Algorithm, ErrorCode::ErrorCode as Ec, HardwareAuthToken::HardwareAuthToken,
HardwareAuthenticatorType::HardwareAuthenticatorType, KeyPurpose::KeyPurpose,
- SecurityLevel::SecurityLevel, Tag::Tag, Timestamp::Timestamp,
- VerificationToken::VerificationToken,
+ SecurityLevel::SecurityLevel, Tag::Tag,
+};
+use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
+ TimeStampToken::TimeStampToken, Timestamp::Timestamp,
};
use android_system_keystore2::aidl::android::system::keystore2::OperationChallenge::OperationChallenge;
use anyhow::{Context, Result};
@@ -152,8 +154,8 @@
/// With regard to auth tokens, the following steps are taken:
/// If the key is time-bound, find a matching auth token from the database.
/// If the above step is successful, and if the security level is STRONGBOX, return a
- /// VerificationRequired variant of the AuthTokenHandler with the found auth token to signal
- /// the operation that it may need to obtain a verification token from TEE KeyMint.
+ /// TimestampRequired variant of the AuthTokenHandler with the found auth token to signal
+ /// the operation that it may need to obtain a timestamp token from TEE KeyMint.
/// If the security level is not STRONGBOX, return a Token variant of the AuthTokenHandler with
/// the found auth token to signal the operation that no more authorization required.
/// If the key is per-op, return an OpAuthRequired variant of the AuthTokenHandler to signal
@@ -346,7 +348,7 @@
.context("In authorize_create.")?;
if security_level == SecurityLevel::STRONGBOX {
- return Ok(AuthTokenHandler::VerificationRequired(auth_token));
+ return Ok(AuthTokenHandler::TimestampRequired(auth_token));
} else {
return Ok(AuthTokenHandler::Token(auth_token, None));
}
@@ -431,18 +433,18 @@
op_auth_map_guard.insert(op_challenge, None);
}
- /// Requests a verification token from the background task handler which will retrieve it from
+ /// Requests a timestamp token from the background task handler which will retrieve it from
/// Timestamp Service or TEE KeyMint.
/// Once the create_operation receives an operation challenge from KeyMint, if it has
- /// previously received a VerificationRequired variant of AuthTokenHandler during
- /// authorize_create_operation, it calls this method to obtain a VerificationToken.
- pub fn request_verification_token(
+ /// previously received a TimestampRequired variant of AuthTokenHandler during
+ /// authorize_create_operation, it calls this method to obtain a TimeStampToken.
+ pub fn request_timestamp_token(
&self,
auth_token: HardwareAuthToken,
op_challenge: OperationChallenge,
) -> Result<AuthTokenHandler> {
// create a channel for this particular operation
- let (op_sender, op_receiver) = channel::<(HardwareAuthToken, VerificationToken)>();
+ let (op_sender, op_receiver) = channel::<(HardwareAuthToken, TimeStampToken)>();
// it is ok to unwrap here because there is no way this mutex gets poisoned.
let sender_guard = self.sender_to_bth.lock().unwrap();
if let Some(sender) = &*sender_guard {
@@ -452,7 +454,7 @@
.send(Message::Inputs((auth_token, op_challenge, op_sender)))
.map_err(|_| KeystoreError::sys())
.context(
- "In request_verification_token. Sending a request for a verification token
+ "In request_timestamp_token. Sending a request for a timestamp token
failed.",
)?;
}
diff --git a/keystore2/src/globals.rs b/keystore2/src/globals.rs
index 035dac1..3c79eed 100644
--- a/keystore2/src/globals.rs
+++ b/keystore2/src/globals.rs
@@ -80,12 +80,12 @@
pub static ref SUPER_KEY: SuperKeyManager = Default::default();
/// Map of KeyMint devices.
static ref KEY_MINT_DEVICES: Mutex<HashMap<SecurityLevel, Asp>> = Default::default();
+ /// Timestamp service.
+ static ref TIME_STAMP_DEVICE: Mutex<Option<Asp>> = Default::default();
/// A single on-demand worker thread that handles deferred tasks with two different
/// priorities.
pub static ref ASYNC_TASK: AsyncTask = Default::default();
/// Singeleton for enforcements.
- /// It is safe for this enforcements object to be called by multiple threads because the two
- /// data structures which maintain its state are protected by mutexes.
pub static ref ENFORCEMENTS: Enforcements = Enforcements::new();
/// Background task handler is initialized and exists globally.
/// The other modules (e.g. enforcements) communicate with it via a channel initialized during
@@ -142,11 +142,58 @@
if let Some(dev) = devices_map.get(&security_level) {
Ok(dev.clone())
} else {
- let dev = connect_keymint(security_level).map_err(|e| {
- anyhow::anyhow!(Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))
- .context(format!("In get_keymint_device: {:?}", e))
- })?;
+ let dev = connect_keymint(security_level).context("In get_keymint_device.")?;
devices_map.insert(security_level, dev.clone());
Ok(dev)
}
}
+
+static TIME_STAMP_SERVICE_NAME: &str = "android.hardware.security.secureclock.ISecureClock";
+
+/// Make a new connection to a secure clock service.
+/// If no native SecureClock device can be found brings up the compatibility service and attempts
+/// to connect to the legacy wrapper.
+fn connect_secureclock() -> Result<Asp> {
+ let secureclock = map_binder_status_code(binder::get_interface(TIME_STAMP_SERVICE_NAME))
+ .context("In connect_secureclock: Trying to connect to genuine secure clock service.")
+ .or_else(|e| {
+ match e.root_cause().downcast_ref::<Error>() {
+ Some(Error::BinderTransaction(StatusCode::NAME_NOT_FOUND)) => {
+ // This is a no-op if it was called before.
+ keystore2_km_compat::add_keymint_device_service();
+
+ let keystore_compat_service: Box<dyn IKeystoreCompatService> =
+ map_binder_status_code(binder::get_interface("android.security.compat"))
+ .context(
+ "In connect_secureclock: Trying to connect to compat service.",
+ )?;
+
+ // Legacy secure clock services were only implemented by TEE.
+ map_binder_status(keystore_compat_service.getSecureClock())
+ .map_err(|e| match e {
+ Error::BinderTransaction(StatusCode::NAME_NOT_FOUND) => {
+ Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE)
+ }
+ e => e,
+ })
+ .context("In connect_secureclock: Trying to get Legacy wrapper.")
+ }
+ _ => Err(e),
+ }
+ })?;
+
+ Ok(Asp::new(secureclock.as_binder()))
+}
+
+/// Get the timestamp service that verifies auth token timeliness towards security levels with
+/// different clocks.
+pub fn get_timestamp_service() -> Result<Asp> {
+ let mut ts_device = TIME_STAMP_DEVICE.lock().unwrap();
+ if let Some(dev) = &*ts_device {
+ Ok(dev.clone())
+ } else {
+ let dev = connect_secureclock().context("In get_timestamp_service.")?;
+ *ts_device = Some(dev.clone());
+ Ok(dev)
+ }
+}
diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp
index ac16666..d965922 100644
--- a/keystore2/src/km_compat/km_compat.cpp
+++ b/keystore2/src/km_compat/km_compat.cpp
@@ -35,7 +35,6 @@
using ::aidl::android::hardware::security::keymint::Digest;
using ::aidl::android::hardware::security::keymint::PaddingMode;
using ::aidl::android::hardware::security::keymint::Tag;
-using ::aidl::android::hardware::security::keymint::VerificationToken;
using ::aidl::android::system::keystore2::ResponseCode;
using ::android::hardware::hidl_vec;
using ::android::hardware::keymaster::V4_0::TagType;
@@ -100,13 +99,13 @@
return legacyAt;
}
-static V4_0_VerificationToken convertVerificationTokenToLegacy(const VerificationToken& vt) {
+static V4_0_VerificationToken convertTimestampTokenToLegacy(const TimeStampToken& tst) {
V4_0_VerificationToken legacyVt;
- legacyVt.challenge = vt.challenge;
- legacyVt.timestamp = vt.timestamp.milliSeconds;
- legacyVt.securityLevel =
- static_cast<::android::hardware::keymaster::V4_0::SecurityLevel>(vt.securityLevel);
- legacyVt.mac = vt.mac;
+ legacyVt.challenge = tst.challenge;
+ legacyVt.timestamp = tst.timestamp.milliSeconds;
+ // Legacy verification tokens were always minted by TEE.
+ legacyVt.securityLevel = V4_0::SecurityLevel::TRUSTED_ENVIRONMENT;
+ legacyVt.mac = tst.mac;
return legacyVt;
}
@@ -172,14 +171,6 @@
return ScopedAStatus::ok();
}
-// We're not implementing this.
-ScopedAStatus KeyMintDevice::verifyAuthorization(int64_t in_challenge ATTRIBUTE_UNUSED,
- const HardwareAuthToken& in_token ATTRIBUTE_UNUSED,
- VerificationToken* _aidl_return ATTRIBUTE_UNUSED) {
- return ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(V4_0_ErrorCode::UNIMPLEMENTED));
-}
-
ScopedAStatus KeyMintDevice::addRngEntropy(const std::vector<uint8_t>& in_data) {
V4_0_ErrorCode errorCode = mDevice->addRngEntropy(in_data);
return convertErrorCode(errorCode);
@@ -346,13 +337,13 @@
return convertErrorCode(errorCode);
}
-ScopedAStatus
-KeyMintOperation::update(const std::optional<KeyParameterArray>& in_inParams,
- const std::optional<std::vector<uint8_t>>& in_input,
- const std::optional<HardwareAuthToken>& in_inAuthToken,
- const std::optional<VerificationToken>& in_inVerificationToken,
- std::optional<KeyParameterArray>* out_outParams,
- std::optional<ByteArray>* out_output, int32_t* _aidl_return) {
+ScopedAStatus KeyMintOperation::update(const std::optional<KeyParameterArray>& in_inParams,
+ const std::optional<std::vector<uint8_t>>& in_input,
+ const std::optional<HardwareAuthToken>& in_inAuthToken,
+ const std::optional<TimeStampToken>& in_inTimeStampToken,
+ std::optional<KeyParameterArray>* out_outParams,
+ std::optional<ByteArray>* out_output,
+ int32_t* _aidl_return) {
std::vector<V4_0_KeyParameter> legacyParams;
if (in_inParams.has_value()) {
legacyParams = convertKeyParametersToLegacy(in_inParams.value().params);
@@ -363,8 +354,8 @@
authToken = convertAuthTokenToLegacy(in_inAuthToken.value());
}
V4_0_VerificationToken verificationToken;
- if (in_inVerificationToken.has_value()) {
- verificationToken = convertVerificationTokenToLegacy(in_inVerificationToken.value());
+ if (in_inTimeStampToken.has_value()) {
+ verificationToken = convertTimestampTokenToLegacy(in_inTimeStampToken.value());
}
V4_0_ErrorCode errorCode;
auto result = mDevice->update(
@@ -389,14 +380,13 @@
return convertErrorCode(errorCode);
}
-ScopedAStatus
-KeyMintOperation::finish(const std::optional<KeyParameterArray>& in_inParams,
- const std::optional<std::vector<uint8_t>>& in_input,
- const std::optional<std::vector<uint8_t>>& in_inSignature,
- const std::optional<HardwareAuthToken>& in_authToken,
- const std::optional<VerificationToken>& in_inVerificationToken,
- std::optional<KeyParameterArray>* out_outParams,
- std::vector<uint8_t>* _aidl_return) {
+ScopedAStatus KeyMintOperation::finish(const std::optional<KeyParameterArray>& in_inParams,
+ const std::optional<std::vector<uint8_t>>& in_input,
+ const std::optional<std::vector<uint8_t>>& in_inSignature,
+ const std::optional<HardwareAuthToken>& in_authToken,
+ const std::optional<TimeStampToken>& in_inTimeStampToken,
+ std::optional<KeyParameterArray>* out_outParams,
+ std::vector<uint8_t>* _aidl_return) {
V4_0_ErrorCode errorCode;
std::vector<V4_0_KeyParameter> legacyParams;
if (in_inParams.has_value()) {
@@ -409,8 +399,8 @@
authToken = convertAuthTokenToLegacy(in_authToken.value());
}
V4_0_VerificationToken verificationToken;
- if (in_inVerificationToken.has_value()) {
- verificationToken = convertVerificationTokenToLegacy(in_inVerificationToken.value());
+ if (in_inTimeStampToken.has_value()) {
+ verificationToken = convertTimestampTokenToLegacy(in_inTimeStampToken.value());
}
auto result = mDevice->finish(
mOperationHandle, legacyParams, input, signature, authToken, verificationToken,
@@ -454,9 +444,6 @@
errorCode = error;
_aidl_return->challenge = token.challenge;
_aidl_return->timestamp.milliSeconds = token.timestamp;
- _aidl_return->securityLevel =
- static_cast<::aidl::android::hardware::security::keymint::SecurityLevel>(
- token.securityLevel);
_aidl_return->mac = token.mac;
});
if (!result.isOk()) {
@@ -679,8 +666,8 @@
std::optional<KeyParameterArray> outParams;
std::optional<ByteArray> outByte;
int32_t status;
- beginResult.operation->update(std::nullopt, dataVec, HardwareAuthToken(),
- VerificationToken(), &outParams, &outByte, &status);
+ beginResult.operation->update(std::nullopt, dataVec, std::nullopt, std::nullopt,
+ &outParams, &outByte, &status);
if (!status) {
return std::vector<uint8_t>();
}
@@ -920,26 +907,31 @@
}
sp<Keymaster> getDevice(KeyMintSecurityLevel securityLevel) {
- auto secLevel = static_cast<SecurityLevel>(securityLevel);
- auto devices = initializeKeymasters();
- return devices[secLevel];
+ static std::mutex mutex;
+ static sp<Keymaster> teeDevice;
+ static sp<Keymaster> sbDevice;
+ std::lock_guard<std::mutex> lock(mutex);
+ if (!teeDevice) {
+ auto devices = initializeKeymasters();
+ teeDevice = devices[V4_0::SecurityLevel::TRUSTED_ENVIRONMENT];
+ sbDevice = devices[V4_0::SecurityLevel::STRONGBOX];
+ }
+ switch (securityLevel) {
+ case KeyMintSecurityLevel::TRUSTED_ENVIRONMENT:
+ return teeDevice;
+ case KeyMintSecurityLevel::STRONGBOX:
+ return sbDevice;
+ default:
+ return {};
+ }
}
std::shared_ptr<KeyMintDevice>
KeyMintDevice::createKeyMintDevice(KeyMintSecurityLevel securityLevel) {
- static std::mutex mutex;
- std::lock_guard<std::mutex> lock(mutex);
- static std::shared_ptr<KeyMintDevice> device_ptr;
- if (!device_ptr) {
- auto secLevel = static_cast<SecurityLevel>(securityLevel);
- auto devices = initializeKeymasters();
- auto device = devices[secLevel];
- if (!device) {
- return {};
- }
- device_ptr = ndk::SharedRefBase::make<KeyMintDevice>(std::move(device), securityLevel);
+ if (auto dev = getDevice(securityLevel)) {
+ return ndk::SharedRefBase::make<KeyMintDevice>(std::move(dev), securityLevel);
}
- return device_ptr;
+ return {};
}
std::shared_ptr<SharedSecret> SharedSecret::createSharedSecret(KeyMintSecurityLevel securityLevel) {
@@ -961,14 +953,16 @@
ScopedAStatus
KeystoreCompatService::getKeyMintDevice(KeyMintSecurityLevel in_securityLevel,
std::shared_ptr<IKeyMintDevice>* _aidl_return) {
- if (mDeviceCache.find(in_securityLevel) == mDeviceCache.end()) {
+ auto i = mDeviceCache.find(in_securityLevel);
+ if (i == mDeviceCache.end()) {
auto device = KeyMintDevice::createKeyMintDevice(in_securityLevel);
if (!device) {
return ScopedAStatus::fromStatus(STATUS_NAME_NOT_FOUND);
}
- mDeviceCache[in_securityLevel] = std::move(device);
+ bool inserted = false;
+ std::tie(i, inserted) = mDeviceCache.insert({in_securityLevel, std::move(device)});
}
- *_aidl_return = mDeviceCache[in_securityLevel];
+ *_aidl_return = i->second;
return ScopedAStatus::ok();
}
diff --git a/keystore2/src/km_compat/km_compat.h b/keystore2/src/km_compat/km_compat.h
index 64ad0ba..481481a 100644
--- a/keystore2/src/km_compat/km_compat.h
+++ b/keystore2/src/km_compat/km_compat.h
@@ -38,7 +38,6 @@
using ::aidl::android::hardware::security::keymint::KeyParameter;
using ::aidl::android::hardware::security::keymint::KeyParameterArray;
using ::aidl::android::hardware::security::keymint::KeyPurpose;
-using ::aidl::android::hardware::security::keymint::VerificationToken;
using KeyMintSecurityLevel = ::aidl::android::hardware::security::keymint::SecurityLevel;
using V4_0_ErrorCode = ::android::hardware::keymaster::V4_0::ErrorCode;
using ::aidl::android::hardware::security::keymint::IKeyMintDevice;
@@ -87,8 +86,6 @@
static std::shared_ptr<KeyMintDevice> createKeyMintDevice(KeyMintSecurityLevel securityLevel);
ScopedAStatus getHardwareInfo(KeyMintHardwareInfo* _aidl_return) override;
- ScopedAStatus verifyAuthorization(int64_t in_challenge, const HardwareAuthToken& in_token,
- VerificationToken* _aidl_return) override;
ScopedAStatus addRngEntropy(const std::vector<uint8_t>& in_data) override;
ScopedAStatus generateKey(const std::vector<KeyParameter>& in_keyParams,
KeyCreationResult* out_creationResult) override;
@@ -141,14 +138,14 @@
ScopedAStatus update(const std::optional<KeyParameterArray>& in_inParams,
const std::optional<std::vector<uint8_t>>& in_input,
const std::optional<HardwareAuthToken>& in_inAuthToken,
- const std::optional<VerificationToken>& in_inVerificationToken,
+ const std::optional<TimeStampToken>& in_inTimestampToken,
std::optional<KeyParameterArray>* out_outParams,
std::optional<ByteArray>* out_output, int32_t* _aidl_return);
ScopedAStatus finish(const std::optional<KeyParameterArray>& in_inParams,
const std::optional<std::vector<uint8_t>>& in_input,
const std::optional<std::vector<uint8_t>>& in_inSignature,
const std::optional<HardwareAuthToken>& in_authToken,
- const std::optional<VerificationToken>& in_inVerificationToken,
+ const std::optional<TimeStampToken>& in_inTimestampToken,
std::optional<KeyParameterArray>* out_outParams,
std::vector<uint8_t>* _aidl_return);
ScopedAStatus abort();
diff --git a/keystore2/src/operation.rs b/keystore2/src/operation.rs
index f306df4..8e4f800 100644
--- a/keystore2/src/operation.rs
+++ b/keystore2/src/operation.rs
@@ -134,7 +134,10 @@
ByteArray::ByteArray, HardwareAuthToken::HardwareAuthToken,
IKeyMintOperation::IKeyMintOperation, KeyParameter::KeyParameter as KmParam,
KeyParameterArray::KeyParameterArray, KeyParameterValue::KeyParameterValue as KmParamValue,
- Tag::Tag, VerificationToken::VerificationToken,
+ Tag::Tag,
+};
+use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
+ TimeStampToken::TimeStampToken,
};
use android_system_keystore2::aidl::android::system::keystore2::{
IKeystoreOperation::BnKeystoreOperation, IKeystoreOperation::IKeystoreOperation,
@@ -356,7 +359,7 @@
None,
// TODO Get auth token from enforcement module if required.
None,
- // TODO Get verification token from enforcement module if required.
+ // TODO Get timestamp token from enforcement module if required.
None,
&mut out_params,
&mut output,
@@ -369,14 +372,14 @@
/// Based on the authorization information stored in the operation during create_operation(),
/// and any previous calls to update(), this function returns appropriate auth token and
- /// verification token to be passed to keymint.
+ /// timestamp token to be passed to keymint.
/// Note that the call to the global enforcement object happens only during the first call to
/// update or if finish() is called right after create_opertation.
fn handle_authorization<'a>(
auth_token_handler: &'a mut AuthTokenHandler,
key_params: Option<&Vec<KeyParameter>>,
op_challenge: Option<&OperationChallenge>,
- ) -> Result<(Option<&'a HardwareAuthToken>, Option<&'a VerificationToken>)> {
+ ) -> Result<(Option<&'a HardwareAuthToken>, Option<&'a TimeStampToken>)> {
// keystore performs authorization only if key parameters have been loaded during
// create_operation()
if let Some(key_parameters) = key_params {
@@ -395,7 +398,7 @@
// this variant is found in every subsequent call to update/finish,
// unless the authorization is not required for the key
AuthTokenHandler::Token(_, _) => {
- auth_token_handler.retrieve_auth_and_verification_tokens()
+ auth_token_handler.retrieve_auth_and_timestamp_tokens()
}
_ => Ok((None, None))
}
@@ -418,7 +421,7 @@
self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
let mut auth_handler = self.auth_token_handler.lock().unwrap();
- let (auth_token_for_km, verification_token_for_km) = Self::handle_authorization(
+ let (auth_token_for_km, timestamp_token_for_km) = Self::handle_authorization(
&mut auth_handler,
self.key_params.as_ref(),
self.op_challenge.as_ref(),
@@ -431,7 +434,7 @@
None,
Some(input),
auth_token_for_km,
- verification_token_for_km,
+ timestamp_token_for_km,
&mut out_params,
&mut output,
)),
@@ -465,7 +468,7 @@
self.km_op.get_interface().context("In finish: Failed to get KeyMintOperation.")?;
let mut auth_handler = self.auth_token_handler.lock().unwrap();
- let (auth_token_for_km, verification_token_for_km) = Self::handle_authorization(
+ let (auth_token_for_km, timestamp_token_for_km) = Self::handle_authorization(
&mut auth_handler,
self.key_params.as_ref(),
self.op_challenge.as_ref(),
@@ -480,7 +483,7 @@
input,
signature,
auth_token_for_km,
- verification_token_for_km,
+ timestamp_token_for_km,
&mut out_params,
)),
)
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
index 079e92a..7a87e8d 100644
--- a/keystore2/src/security_level.rs
+++ b/keystore2/src/security_level.rs
@@ -281,10 +281,10 @@
Some(OperationChallenge { challenge: begin_result.challenge });
ENFORCEMENTS.insert_to_op_auth_map(begin_result.challenge);
}
- AuthTokenHandler::VerificationRequired(auth_token) => {
- //request a verification token, given the auth token and the challenge
+ AuthTokenHandler::TimestampRequired(auth_token) => {
+ //request a timestamp token, given the auth token and the challenge
auth_token_handler = ENFORCEMENTS
- .request_verification_token(
+ .request_timestamp_token(
auth_token,
OperationChallenge { challenge: begin_result.challenge },
)