Make SW keymaster security level configurable
This CL enables the pure software keymaster implementation to have a
configurable security level, for testing, so we can use it to test
Strongbox features.
Test: VtsHalKeymasterV4_0TargetTest (on emulator)
Change-Id: I017fd81df3dc14ac5c11943241b63ff3291a92e6
Merged-In: I1b012dcd359e294dad7771c7a91e36270d9a0289
Merged-In: I10515d77310b4d2fd2922e1083df19269f199f33
Merged-In: Ibe86062000373bb71244256c4ebd81ad42bfb0da
diff --git a/contexts/pure_soft_keymaster_context.cpp b/contexts/pure_soft_keymaster_context.cpp
index 45930eb..d52fe2e 100644
--- a/contexts/pure_soft_keymaster_context.cpp
+++ b/contexts/pure_soft_keymaster_context.cpp
@@ -50,12 +50,12 @@
namespace keymaster {
-PureSoftKeymasterContext::PureSoftKeymasterContext()
+PureSoftKeymasterContext::PureSoftKeymasterContext(keymaster_security_level_t security_level)
: rsa_factory_(new RsaKeyFactory(this)), ec_factory_(new EcKeyFactory(this)),
aes_factory_(new AesKeyFactory(this, this)),
tdes_factory_(new TripleDesKeyFactory(this, this)),
hmac_factory_(new HmacKeyFactory(this, this)), os_version_(0), os_patchlevel_(0),
- soft_keymaster_enforcement_(64, 64) {}
+ soft_keymaster_enforcement_(64, 64), security_level_(security_level) {}
PureSoftKeymasterContext::~PureSoftKeymasterContext() {}
@@ -106,24 +106,56 @@
}
keymaster_error_t PureSoftKeymasterContext::CreateKeyBlob(const AuthorizationSet& key_description,
- const keymaster_key_origin_t origin,
- const KeymasterKeyBlob& key_material,
- KeymasterKeyBlob* blob,
- AuthorizationSet* hw_enforced,
- AuthorizationSet* sw_enforced) const {
+ const keymaster_key_origin_t origin,
+ const KeymasterKeyBlob& key_material,
+ KeymasterKeyBlob* blob,
+ AuthorizationSet* hw_enforced,
+ AuthorizationSet* sw_enforced) const {
if (key_description.GetTagValue(TAG_ROLLBACK_RESISTANCE)) {
return KM_ERROR_ROLLBACK_RESISTANCE_UNAVAILABLE;
}
+ if (GetSecurityLevel() != KM_SECURITY_LEVEL_SOFTWARE) {
+ // We're pretending to be some sort of secure hardware. Put relevant tags in hw_enforced.
+ for (auto& entry : key_description) {
+ switch (entry.tag) {
+ case KM_TAG_PURPOSE:
+ case KM_TAG_ALGORITHM:
+ case KM_TAG_KEY_SIZE:
+ case KM_TAG_RSA_PUBLIC_EXPONENT:
+ case KM_TAG_BLOB_USAGE_REQUIREMENTS:
+ case KM_TAG_DIGEST:
+ case KM_TAG_PADDING:
+ case KM_TAG_BLOCK_MODE:
+ case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
+ case KM_TAG_MAX_USES_PER_BOOT:
+ case KM_TAG_USER_SECURE_ID:
+ case KM_TAG_NO_AUTH_REQUIRED:
+ case KM_TAG_AUTH_TIMEOUT:
+ case KM_TAG_CALLER_NONCE:
+ case KM_TAG_MIN_MAC_LENGTH:
+ case KM_TAG_KDF:
+ case KM_TAG_EC_CURVE:
+ case KM_TAG_ECIES_SINGLE_HASH_MODE:
+ case KM_TAG_USER_AUTH_TYPE:
+ case KM_TAG_ORIGIN:
+ case KM_TAG_OS_VERSION:
+ case KM_TAG_OS_PATCHLEVEL:
+ hw_enforced->push_back(entry);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
keymaster_error_t error = SetKeyBlobAuthorizations(key_description, origin, os_version_,
os_patchlevel_, hw_enforced, sw_enforced);
- if (error != KM_ERROR_OK)
- return error;
+ if (error != KM_ERROR_OK) return error;
AuthorizationSet hidden;
error = BuildHiddenAuthorizations(key_description, &hidden, softwareRootOfTrust);
- if (error != KM_ERROR_OK)
- return error;
+ if (error != KM_ERROR_OK) return error;
return SerializeIntegrityAssuredBlob(key_material, hidden, *hw_enforced, *sw_enforced, blob);
}
diff --git a/include/keymaster/contexts/pure_soft_keymaster_context.h b/include/keymaster/contexts/pure_soft_keymaster_context.h
index d8532a8..a1951a0 100644
--- a/include/keymaster/contexts/pure_soft_keymaster_context.h
+++ b/include/keymaster/contexts/pure_soft_keymaster_context.h
@@ -43,7 +43,9 @@
AttestationRecordContext,
SoftwareRandomSource {
public:
- explicit PureSoftKeymasterContext();
+ // Security level must only be used for testing.
+ explicit PureSoftKeymasterContext(
+ keymaster_security_level_t security_level = KM_SECURITY_LEVEL_SOFTWARE);
~PureSoftKeymasterContext() override;
/*********************************************************************************************
@@ -99,6 +101,8 @@
keymaster_verified_boot_t* verified_boot_state,
bool* device_locked) const override;
+ keymaster_security_level_t GetSecurityLevel() const override { return security_level_; }
+
protected:
std::unique_ptr<KeyFactory> rsa_factory_;
std::unique_ptr<KeyFactory> ec_factory_;
@@ -108,6 +112,7 @@
uint32_t os_version_;
uint32_t os_patchlevel_;
SoftKeymasterEnforcement soft_keymaster_enforcement_;
+ keymaster_security_level_t security_level_;
};
} // namespace keymaster
diff --git a/key_blob_utils/software_keyblobs.cpp b/key_blob_utils/software_keyblobs.cpp
index c490631..60719bb 100644
--- a/key_blob_utils/software_keyblobs.cpp
+++ b/key_blob_utils/software_keyblobs.cpp
@@ -292,10 +292,16 @@
}
}
- sw_enforced->push_back(TAG_CREATION_DATETIME, java_time(time(nullptr)));
- sw_enforced->push_back(TAG_ORIGIN, origin);
- sw_enforced->push_back(TAG_OS_VERSION, os_version);
- sw_enforced->push_back(TAG_OS_PATCHLEVEL, os_patchlevel);
+ // If hw_enforced is non-empty, we're pretending to be some sort of secure hardware.
+ AuthorizationSet* pseudo_hw_enforced = (hw_enforced->empty()) ? sw_enforced : hw_enforced;
+ pseudo_hw_enforced->push_back(TAG_ORIGIN, origin);
+ pseudo_hw_enforced->push_back(TAG_OS_VERSION, os_version);
+ pseudo_hw_enforced->push_back(TAG_OS_PATCHLEVEL, os_patchlevel);
+
+ // Honor caller creation, if provided.
+ if (!sw_enforced->Contains(TAG_CREATION_DATETIME)) {
+ sw_enforced->push_back(TAG_CREATION_DATETIME, java_time(time(nullptr)));
+ }
return TranslateAuthorizationSetError(sw_enforced->is_valid());
}
diff --git a/ng/AndroidKeymaster4Device.cpp b/ng/AndroidKeymaster4Device.cpp
index 70060d6..b42a19b 100644
--- a/ng/AndroidKeymaster4Device.cpp
+++ b/ng/AndroidKeymaster4Device.cpp
@@ -211,12 +211,14 @@
AndroidKeymaster4Device::AndroidKeymaster4Device(SecurityLevel securityLevel)
: impl_(new ::keymaster::AndroidKeymaster(
- []() -> auto {
- auto context = new PureSoftKeymasterContext();
+ [&]() -> auto {
+ auto context = new PureSoftKeymasterContext(
+ static_cast<keymaster_security_level_t>(securityLevel));
context->SetSystemVersion(GetOsVersion(), GetOsPatchlevel());
return context;
}(),
- kOperationTableSize)), securityLevel_(securityLevel) {}
+ kOperationTableSize)),
+ securityLevel_(securityLevel) {}
AndroidKeymaster4Device::~AndroidKeymaster4Device() {}