diff options
author | David Drysdale <drysdale@google.com> | 2021-04-01 12:17:35 +0100 |
---|---|---|
committer | David Drysdale <drysdale@google.com> | 2021-04-12 14:48:31 +0100 |
commit | 4dc010739d287542518ba65701e5f2ac7a400a2e (patch) | |
tree | b523a7a6940a4d56ea015b0da94edb00be272024 /security/keymint/aidl/vts/functional/KeyMintTest.cpp | |
parent | 303991b322f7e47c5106efd651f59536e5719d96 (diff) |
Check that KeyMint provides IRemotelyProvisionedComponent
Move helper utilities across into KeyMintAidlTestBase to allow re-use.
Test: VtsHalRemotelyProvisionedComponentTargetTest, VtsAidlKeyMintTargetTest
Change-Id: Ib9e55a7d72fd197016ae1a1f073dadedafa09c25
Diffstat (limited to 'security/keymint/aidl/vts/functional/KeyMintTest.cpp')
-rw-r--r-- | security/keymint/aidl/vts/functional/KeyMintTest.cpp | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 7ecfa3723f..d5308dc9a4 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -27,6 +27,9 @@ #include <cutils/properties.h> +#include <android/binder_manager.h> + +#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h> #include <aidl/android/hardware/security/keymint/KeyFormat.h> #include <keymint_support/key_param_output.h> @@ -209,6 +212,32 @@ class AidlBuf : public vector<uint8_t> { string to_string() const { return string(reinterpret_cast<const char*>(data()), size()); } }; +string device_suffix(const string& name) { + size_t pos = name.find('/'); + if (pos == string::npos) { + return name; + } + return name.substr(pos + 1); +} + +bool matching_rp_instance(const string& km_name, + std::shared_ptr<IRemotelyProvisionedComponent>* rp) { + string km_suffix = device_suffix(km_name); + + vector<string> rp_names = + ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor); + for (const string& rp_name : rp_names) { + // If the suffix of the RemotelyProvisionedComponent instance equals the suffix of the + // KeyMint instance, assume they match. + if (device_suffix(rp_name) == km_suffix && AServiceManager_isDeclared(rp_name.c_str())) { + ::ndk::SpAIBinder binder(AServiceManager_waitForService(rp_name.c_str())); + *rp = IRemotelyProvisionedComponent::fromBinder(binder); + return true; + } + } + return false; +} + } // namespace class NewKeyGenerationTest : public KeyMintAidlTestBase { @@ -322,6 +351,77 @@ TEST_P(NewKeyGenerationTest, RsaWithAttestation) { } /* + * NewKeyGenerationTest.RsaWithRpkAttestation + * + * Verifies that keymint can generate all required RSA key sizes, using an attestation key + * that has been generated using an associate IRemotelyProvisionedComponent. + */ +TEST_P(NewKeyGenerationTest, RsaWithRpkAttestation) { + // There should be an IRemotelyProvisionedComponent instance associated with the KeyMint + // instance. + std::shared_ptr<IRemotelyProvisionedComponent> rp; + ASSERT_TRUE(matching_rp_instance(GetParam(), &rp)) + << "No IRemotelyProvisionedComponent found that matches KeyMint device " << GetParam(); + + // Generate a P-256 keypair to use as an attestation key. + MacedPublicKey macedPubKey; + std::vector<uint8_t> privateKeyBlob; + auto status = + rp->generateEcdsaP256KeyPair(/* testMode= */ false, &macedPubKey, &privateKeyBlob); + ASSERT_TRUE(status.isOk()); + vector<uint8_t> coseKeyData; + check_maced_pubkey(macedPubKey, /* testMode= */ false, &coseKeyData); + + AttestationKey attestation_key; + attestation_key.keyBlob = std::move(privateKeyBlob); + attestation_key.issuerSubjectName = make_name_from_str("Android Keystore Key"); + + for (auto key_size : ValidKeySizes(Algorithm::RSA)) { + auto challenge = "hello"; + auto app_id = "foo"; + + 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) + .AttestationChallenge(challenge) + .AttestationApplicationId(app_id) + .Authorization(TAG_NO_AUTH_REQUIRED) + .SetDefaultValidity(), + attestation_key, &key_blob, &key_characteristics, &cert_chain_)); + + 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)); + + // Attestation by itself is not valid (last entry is not self-signed). + EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_)); + + // The signature over the attested key should correspond to the P256 public key. + X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate)); + ASSERT_TRUE(key_cert.get()); + EVP_PKEY_Ptr signing_pubkey; + p256_pub_key(coseKeyData, &signing_pubkey); + ASSERT_TRUE(signing_pubkey.get()); + + ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get())) + << "Verification of attested certificate failed " + << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL); + + CheckedDeleteKey(&key_blob); + } +} + +/* * NewKeyGenerationTest.LimitedUsageRsa * * Verifies that KeyMint can generate all required RSA key sizes with limited usage, and that the |