Merge "KeyMint: Add support for key agreement operation and use it for ECDH." am: df543ea006 am: 30f799ff0e am: e5ed85d5ef am: e5dfd6036c am: 3c62e7d7f1
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1544544
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I822685eedbaaf87f0f875e23c9340373fed569d1
diff --git a/drm/1.0/default/Android.bp b/drm/1.0/default/Android.bp
index 93b3278..d5063fb 100644
--- a/drm/1.0/default/Android.bp
+++ b/drm/1.0/default/Android.bp
@@ -46,7 +46,7 @@
android_hardware_drm_1_0_multilib {
name: "android.hardware.drm@1.0-multilib-lib",
- compile_multilib: "32",
+ compile_multilib: "prefer32",
soong_config_variables: {
TARGET_ENABLE_MEDIADRM_64: {
compile_multilib: "both",
@@ -56,7 +56,7 @@
android_hardware_drm_1_0_multilib {
name: "android.hardware.drm@1.0-multilib-exe",
- compile_multilib: "32",
+ compile_multilib: "prefer32",
soong_config_variables: {
TARGET_ENABLE_MEDIADRM_64: {
compile_multilib: "first",
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
index ce12fed..a6be6b1 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
@@ -42,6 +42,7 @@
USAGE_EXPIRE_DATETIME = 1610613138,
MIN_SECONDS_BETWEEN_OPS = 805306771,
MAX_USES_PER_BOOT = 805306772,
+ USAGE_COUNT_LIMIT = 805306773,
USER_ID = 805306869,
USER_SECURE_ID = -1610612234,
NO_AUTH_REQUIRED = 1879048695,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index f92bf00..bc07235 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -333,6 +333,35 @@
MAX_USES_PER_BOOT = (3 << 28) /* TagType:UINT */ | 404,
/**
+ * Tag::USAGE_COUNT_LIMIT specifies the number of times that a key may be used. This can be
+ * used to limit the use of a key.
+ *
+ * The value is a 32-bit integer representing the current number of attempts left.
+ *
+ * When initializing a limited use key, the value of this tag represents the maximum usage
+ * limit for that key. After the key usage is exhausted, the key blob should be invalidated by
+ * finish() call. Any subsequent attempts to use the key must result in a failure with
+ * ErrorCode::INVALID_KEY_BLOB returned by IKeyMintDevice.
+ *
+ * At this point, if the caller specifies count > 1, it is not expected that any TEE will be
+ * able to enforce this feature in the hardware due to limited resources of secure
+ * storage. In this case, the tag with the value of maximum usage must be added to the key
+ * characteristics with SecurityLevel::SOFTWARE by the IKeyMintDevice.
+ *
+ * On the other hand, if the caller specifies count = 1, some TEEs may have the ability
+ * to enforce this feature in the hardware with its secure storage. If the IKeyMintDevice
+ * implementation can enforce this feature, the tag with value = 1 must be added to the key
+ * characteristics with the SecurityLevel of the IKeyMintDevice. If the IKeyMintDevice can't
+ * enforce this feature even when the count = 1, the tag must be added to the key
+ * characteristics with the SecurityLevel::SOFTWARE.
+ *
+ * When the key is attested, this tag with the same value must also be added to the attestation
+ * record. This tag must have the same SecurityLevel as the tag that is added to the key
+ * characteristics.
+ */
+ USAGE_COUNT_LIMIT = (3 << 28) | 405, /* TagType:UINT */
+
+ /**
* Tag::USER_ID specifies the ID of the Android user that is permitted to use the key.
*
* Must not be hardware-enforced.
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 5989cde..c876440 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -562,7 +562,7 @@
}
/*
- * NewKeyGenerationTest.Rsa
+ * NewKeyGenerationTest.RsaWithAttestation
*
* Verifies that keymint can generate all required RSA key sizes, and that the resulting keys
* have correct characteristics.
@@ -607,6 +607,45 @@
}
/*
+ * NewKeyGenerationTest.LimitedUsageRsa
+ *
+ * Verifies that KeyMint can generate all required RSA key sizes with limited usage, and that the
+ * resulting keys have correct characteristics.
+ */
+TEST_P(NewKeyGenerationTest, LimitedUsageRsa) {
+ for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+ vector<uint8_t> key_blob;
+ vector<KeyCharacteristics> key_characteristics;
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_USAGE_COUNT_LIMIT, 1),
+ &key_blob, &key_characteristics));
+
+ ASSERT_GT(key_blob.size(), 0U);
+ CheckBaseParams(key_characteristics);
+
+ AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+ EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA));
+ EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+ << "Key size " << key_size << "missing";
+ EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+
+ // Check the usage count limit tag appears in the authorizations.
+ AuthorizationSet auths;
+ for (auto& entry : key_characteristics) {
+ auths.push_back(AuthorizationSet(entry.authorizations));
+ }
+ EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+ << "key usage count limit " << 1U << " missing";
+
+ CheckedDeleteKey(&key_blob);
+ }
+}
+
+/*
* NewKeyGenerationTest.NoInvalidRsaSizes
*
* Verifies that keymint cannot generate any RSA key sizes that are designated as invalid.
@@ -666,6 +705,43 @@
}
/*
+ * NewKeyGenerationTest.LimitedUsageEcdsa
+ *
+ * Verifies that KeyMint can generate all required EC key sizes with limited usage, and that the
+ * resulting keys have correct characteristics.
+ */
+TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) {
+ for (auto key_size : ValidKeySizes(Algorithm::EC)) {
+ vector<uint8_t> key_blob;
+ vector<KeyCharacteristics> key_characteristics;
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .EcdsaSigningKey(key_size)
+ .Digest(Digest::NONE)
+ .Authorization(TAG_USAGE_COUNT_LIMIT, 1),
+ &key_blob, &key_characteristics));
+
+ ASSERT_GT(key_blob.size(), 0U);
+ CheckBaseParams(key_characteristics);
+
+ AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+ EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
+ EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+ << "Key size " << key_size << "missing";
+
+ // Check the usage count limit tag appears in the authorizations.
+ AuthorizationSet auths;
+ for (auto& entry : key_characteristics) {
+ auths.push_back(AuthorizationSet(entry.authorizations));
+ }
+ EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+ << "key usage count limit " << 1U << " missing";
+
+ CheckedDeleteKey(&key_blob);
+ }
+}
+
+/*
* NewKeyGenerationTest.EcdsaDefaultSize
*
* Verifies that failing to specify a key size for EC key generation returns
@@ -780,6 +856,44 @@
}
/*
+ * NewKeyGenerationTest.LimitedUsageHmac
+ *
+ * Verifies that KeyMint supports all required digests with limited usage Hmac, and that the
+ * resulting keys have correct characteristics.
+ */
+TEST_P(NewKeyGenerationTest, LimitedUsageHmac) {
+ for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) {
+ vector<uint8_t> key_blob;
+ vector<KeyCharacteristics> key_characteristics;
+ constexpr size_t key_size = 128;
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .HmacKey(key_size)
+ .Digest(digest)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)
+ .Authorization(TAG_USAGE_COUNT_LIMIT, 1),
+ &key_blob, &key_characteristics));
+
+ ASSERT_GT(key_blob.size(), 0U);
+ CheckBaseParams(key_characteristics);
+
+ AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+ EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
+ EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+ << "Key size " << key_size << "missing";
+
+ // Check the usage count limit tag appears in the authorizations.
+ AuthorizationSet auths;
+ for (auto& entry : key_characteristics) {
+ auths.push_back(AuthorizationSet(entry.authorizations));
+ }
+ EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+ << "key usage count limit " << 1U << " missing";
+
+ CheckedDeleteKey(&key_blob);
+ }
+}
+
+/*
* NewKeyGenerationTest.HmacCheckKeySizes
*
* Verifies that keymint supports all key sizes, and rejects all invalid key sizes.
@@ -4153,7 +4267,7 @@
}
/*
- * MaxOperationsTest.TestLimitAes
+ * MaxOperationsTest.TestLimitRsa
*
* Verifies that the max uses per boot tag works correctly with RSA keys.
*/
@@ -4180,6 +4294,100 @@
INSTANTIATE_KEYMINT_AIDL_TEST(MaxOperationsTest);
+typedef KeyMintAidlTestBase UsageCountLimitTest;
+
+/*
+ * UsageCountLimitTest.TestLimitAes
+ *
+ * Verifies that the usage count limit tag works correctly with AES keys.
+ */
+TEST_P(UsageCountLimitTest, TestLimitAes) {
+ if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(128)
+ .EcbMode()
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_USAGE_COUNT_LIMIT, 1)));
+
+ // Check the usage count limit tag appears in the authorizations.
+ AuthorizationSet auths;
+ for (auto& entry : key_characteristics_) {
+ auths.push_back(AuthorizationSet(entry.authorizations));
+ }
+ EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+ << "key usage count limit " << 1U << " missing";
+
+ string message = "1234567890123456";
+ auto params = AuthorizationSetBuilder().EcbMode().Padding(PaddingMode::NONE);
+
+ // First usage of AES key should work.
+ EncryptMessage(message, params);
+
+ AuthorizationSet hardware_auths;
+ for (auto& entry : key_characteristics_) {
+ if (entry.securityLevel != SecurityLevel::SOFTWARE) {
+ auths.push_back(AuthorizationSet(entry.authorizations));
+ }
+ }
+ if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) {
+ // Usage count limit tag is enforced by hardware. After using the key, the key blob
+ // must be invalidated from secure storage (such as RPMB partition).
+ EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::ENCRYPT, params));
+ } else {
+ // Usage count limit tag is enforced by software, keymint does nothing.
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
+ }
+}
+
+/*
+ * UsageCountLimitTest.TestLimitRsa
+ *
+ * Verifies that the usage count limit tag works correctly with RSA keys.
+ */
+TEST_P(UsageCountLimitTest, TestLimitRsa) {
+ if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaSigningKey(1024, 65537)
+ .NoDigestOrPadding()
+ .Authorization(TAG_USAGE_COUNT_LIMIT, 1)));
+
+ // Check the usage count limit tag appears in the authorizations.
+ AuthorizationSet auths;
+ for (auto& entry : key_characteristics_) {
+ auths.push_back(AuthorizationSet(entry.authorizations));
+ }
+ EXPECT_TRUE(auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U))
+ << "key usage count limit " << 1U << " missing";
+
+ string message = "1234567890123456";
+ auto params = AuthorizationSetBuilder().NoDigestOrPadding();
+
+ // First usage of RSA key should work.
+ SignMessage(message, params);
+
+ AuthorizationSet hardware_auths;
+ for (auto& entry : key_characteristics_) {
+ if (entry.securityLevel != SecurityLevel::SOFTWARE) {
+ auths.push_back(AuthorizationSet(entry.authorizations));
+ }
+ }
+
+ if (hardware_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U)) {
+ // Usage count limit tag is enforced by hardware. After using the key, the key blob
+ // must be invalidated from secure storage (such as RPMB partition).
+ EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::SIGN, params));
+ } else {
+ // Usage count limit tag is enforced by software, keymint does nothing.
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
+ }
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(UsageCountLimitTest);
+
typedef KeyMintAidlTestBase AddEntropyTest;
/*
diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h
index 76aecb7..8d2fe28 100644
--- a/security/keymint/support/include/keymint_support/keymint_tags.h
+++ b/security/keymint/support/include/keymint_support/keymint_tags.h
@@ -119,6 +119,7 @@
DECLARE_TYPED_TAG(TRUSTED_USER_PRESENCE_REQUIRED);
DECLARE_TYPED_TAG(UNIQUE_ID);
DECLARE_TYPED_TAG(UNLOCKED_DEVICE_REQUIRED);
+DECLARE_TYPED_TAG(USAGE_COUNT_LIMIT);
DECLARE_TYPED_TAG(USAGE_EXPIRE_DATETIME);
DECLARE_TYPED_TAG(USER_AUTH_TYPE);
DECLARE_TYPED_TAG(USER_ID);
@@ -135,15 +136,15 @@
TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t, TAG_MIN_MAC_LENGTH_t,
TAG_RSA_PUBLIC_EXPONENT_t, TAG_INCLUDE_UNIQUE_ID_t, TAG_ACTIVE_DATETIME_t,
TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t,
- TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_USER_ID_t, TAG_USER_SECURE_ID_t,
- TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t, TAG_ALLOW_WHILE_ON_BODY_t,
- TAG_UNLOCKED_DEVICE_REQUIRED_t, TAG_APPLICATION_ID_t, TAG_APPLICATION_DATA_t,
- TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t, TAG_HARDWARE_TYPE_t,
- TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t, TAG_BOOTLOADER_ONLY_t,
- TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t, TAG_ATTESTATION_CHALLENGE_t,
- TAG_ATTESTATION_APPLICATION_ID_t, TAG_ATTESTATION_ID_BRAND_t, TAG_ATTESTATION_ID_DEVICE_t,
- TAG_ATTESTATION_ID_PRODUCT_t, TAG_ATTESTATION_ID_MANUFACTURER_t, TAG_ATTESTATION_ID_MODEL_t,
- TAG_ATTESTATION_ID_SERIAL_t, TAG_ATTESTATION_ID_IMEI_t, TAG_ATTESTATION_ID_MEID_t,
+ TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_USAGE_COUNT_LIMIT_t,
+ TAG_USER_ID_t, TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t,
+ TAG_ALLOW_WHILE_ON_BODY_t, TAG_UNLOCKED_DEVICE_REQUIRED_t, TAG_APPLICATION_ID_t,
+ TAG_APPLICATION_DATA_t, TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t,
+ TAG_HARDWARE_TYPE_t, TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t,
+ TAG_BOOTLOADER_ONLY_t, TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t,
+ TAG_ATTESTATION_CHALLENGE_t, TAG_ATTESTATION_APPLICATION_ID_t, TAG_ATTESTATION_ID_BRAND_t,
+ TAG_ATTESTATION_ID_DEVICE_t, TAG_ATTESTATION_ID_PRODUCT_t,
+ TAG_ATTESTATION_ID_MANUFACTURER_t, TAG_ATTESTATION_ID_MODEL_t,
TAG_RESET_SINCE_ID_ROTATION_t, TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t,
TAG_DIGEST_t, TAG_PADDING_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t,
TAG_BOOT_PATCHLEVEL_t, TAG_VENDOR_PATCHLEVEL_t, TAG_TRUSTED_CONFIRMATION_REQUIRED_t,
diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp
index fbb4a52..414d74c 100644
--- a/wifi/1.5/default/wifi_chip.cpp
+++ b/wifi/1.5/default/wifi_chip.cpp
@@ -1036,7 +1036,6 @@
WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
const std::string& ifname, const std::string& ifInstanceName) {
- legacy_hal::wifi_error legacy_status;
const auto iface = findUsingName(ap_ifaces_, ifname);
if (!iface.get() || ifInstanceName.empty()) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
@@ -1048,13 +1047,13 @@
if (iface == ifInstanceName) {
if (!iface_util_.lock()->removeIfaceFromBridge(it.first,
iface)) {
- LOG(ERROR) << "Failed to remove interface: " << iface
- << " from " << ifname << ", error: "
- << legacyErrorToString(legacy_status);
+ LOG(ERROR)
+ << "Failed to remove interface: " << ifInstanceName
+ << " from " << ifname;
return createWifiStatus(
WifiStatusCode::ERROR_NOT_AVAILABLE);
}
- legacy_status =
+ legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->deleteVirtualInterface(iface);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to del interface: " << iface