Model KeyStore security level in keymaster worker

On certain device configurations the security level reported by the
Keymaster HAL differs from the security level understood in KeyStore.
Namely, on devices with only a software Keymaster, KeyStore will set it
in the TEE slot, and create a new in-process legacy Keymaster for the
software slot.

This change introduces a field to keymaster worker to represent the
security level that KeyStore understands this worker to operate on.

Bug: 167412989
Test: atest CtsKeystoreTestCases
Change-Id: Ifeaa4782913be45d89cdd175a02302c7dc318719
This commit is contained in:
Edman Anjos 2020-09-02 17:34:54 +02:00
parent ca543112cd
commit ba9b7d32a7
3 changed files with 24 additions and 10 deletions

View file

@ -60,8 +60,8 @@ KeyStore::KeyStore(const KeymasterDevices& kmDevices,
"KmasterDevices and KeymasterWorkers must have the same size");
for (size_t i = 0; i < kmDevices.size(); ++i) {
if (kmDevices[SecurityLevel(i)]) {
mKmDevices[SecurityLevel(i)] =
std::make_shared<KeymasterWorker>(kmDevices[SecurityLevel(i)], this);
mKmDevices[SecurityLevel(i)] = std::make_shared<KeymasterWorker>(
kmDevices[SecurityLevel(i)], this, SecurityLevel(i));
}
}
}

View file

@ -83,8 +83,10 @@ void Worker::addRequest(WorkerTask request) {
}
}
KeymasterWorker::KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore)
: keymasterDevice_(std::move(keymasterDevice)), operationMap_(keyStore), keyStore_(keyStore) {
KeymasterWorker::KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore,
SecurityLevel internalSecurityLevel)
: keymasterDevice_(std::move(keymasterDevice)), operationMap_(keyStore), keyStore_(keyStore),
internalSecurityLevel_(internalSecurityLevel) {
// make sure that hal version is cached.
if (keymasterDevice_) keymasterDevice_->halVersion();
}
@ -821,7 +823,7 @@ void KeymasterWorker::generateKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyPa
outCharacteristics = keyCharacteristics;
Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
keyBlob.setSecurityLevel(securityLevel);
keyBlob.setSecurityLevel(internalSecurityLevel_);
keyBlob.setCriticalToDeviceEncryption(flags &
KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
if (isAuthenticationBound(keyParams) && !keyBlob.isCriticalToDeviceEncryption()) {
@ -929,7 +931,7 @@ void KeymasterWorker::importKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyPara
outCharacteristics = keyCharacteristics;
Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
keyBlob.setSecurityLevel(securityLevel);
keyBlob.setSecurityLevel(internalSecurityLevel_);
keyBlob.setCriticalToDeviceEncryption(flags &
KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
if (isAuthenticationBound(keyParams) && !keyBlob.isCriticalToDeviceEncryption()) {
@ -1004,8 +1006,6 @@ void KeymasterWorker::importWrappedKey(LockedKeyBlobEntry wrappingLockedEntry,
CAPTURE_MOVE(worker_cb)]() mutable {
auto hidlWrappingKey = blob2hidlVec(wrappingBlob);
SecurityLevel securityLevel = keymasterDevice_->halVersion().securityLevel;
KeyCharacteristics outCharacteristics;
KeyStoreServiceReturnCode error;
@ -1019,7 +1019,7 @@ void KeymasterWorker::importWrappedKey(LockedKeyBlobEntry wrappingLockedEntry,
outCharacteristics = keyCharacteristics;
Blob keyBlob(hidlKeyBlob.data(), hidlKeyBlob.size(), nullptr, 0, ::TYPE_KEYMASTER_10);
keyBlob.setSecurityLevel(securityLevel);
keyBlob.setSecurityLevel(internalSecurityLevel_);
if (isAuthenticationBound(keyCharacteristics.hardwareEnforced)) {
keyBlob.setSuperEncrypted(true);
}

View file

@ -135,6 +135,19 @@ class KeymasterWorker : protected Worker {
OperationMap operationMap_;
KeyStore* keyStore_;
/**
* Models the security level of this worker internal to KeyStore.
*
* When the device has only a software Keymaster, KeyStore will set it on the TEE slot and
* instantiate a new in-process software Keymaster. In that case there is a mismatch between the
* security level used by KeyStore and what is reported from the HAL. This represents the level
* used internally by KeyStore.
*
* This value is used to associate blobs to the corresponding Keymaster backend. It does not
* indicate an actual Keymaster HAL security level and should never be exposed to users.
*/
SecurityLevel internalSecurityLevel_;
template <typename KMFn, typename ErrorType, typename... Args, size_t... I>
void unwrap_tuple(KMFn kmfn, std::function<void(ErrorType)> cb,
const std::tuple<Args...>& tuple, std::index_sequence<I...>) {
@ -200,7 +213,8 @@ class KeymasterWorker : protected Worker {
hidl_vec<KeyParameter>* params);
public:
KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore);
KeymasterWorker(sp<Keymaster> keymasterDevice, KeyStore* keyStore,
SecurityLevel internalSecurityLevel);
void logIfKeymasterVendorError(ErrorCode ec) const;