/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace aidl::android::hardware::security::keymint { ::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set); inline bool operator==(const keymint::AuthorizationSet& a, const keymint::AuthorizationSet& b) { return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); } namespace test { using ::android::sp; using Status = ::ndk::ScopedAStatus; using ::std::optional; using ::std::shared_ptr; using ::std::string; using ::std::vector; constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF; class KeyMintAidlTestBase : public ::testing::TestWithParam { public: struct KeyData { vector blob; vector characteristics; }; static bool arm_deleteAllKeys; static bool dump_Attestations; void SetUp() override; void TearDown() override { if (key_blob_.size()) { CheckedDeleteKey(); } AbortIfNeeded(); } void InitializeKeyMint(std::shared_ptr keyMint); IKeyMintDevice& keyMint() { return *keymint_; } uint32_t os_version() { return os_version_; } uint32_t os_patch_level() { return os_patch_level_; } uint32_t vendor_patch_level() { return vendor_patch_level_; } uint32_t boot_patch_level(const vector& key_characteristics); uint32_t boot_patch_level(); ErrorCode GetReturnErrorCode(const Status& result); ErrorCode GenerateKey(const AuthorizationSet& key_desc, vector* key_blob, vector* key_characteristics) { return GenerateKey(key_desc, std::nullopt /* attest_key */, key_blob, key_characteristics, &cert_chain_); } ErrorCode GenerateKey(const AuthorizationSet& key_desc, const optional& attest_key, vector* key_blob, vector* key_characteristics, vector* cert_chain); ErrorCode GenerateKey(const AuthorizationSet& key_desc, const optional& attest_key = std::nullopt); ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format, const string& key_material, vector* key_blob, vector* key_characteristics); ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format, const string& key_material); ErrorCode ImportWrappedKey(string wrapped_key, string wrapping_key, const AuthorizationSet& wrapping_key_desc, string masking_key, const AuthorizationSet& unwrapping_params, int64_t password_sid, int64_t biometric_sid); ErrorCode ImportWrappedKey(string wrapped_key, string wrapping_key, const AuthorizationSet& wrapping_key_desc, string masking_key, const AuthorizationSet& unwrapping_params) { return ImportWrappedKey(wrapped_key, wrapping_key, wrapping_key_desc, masking_key, unwrapping_params, 0 /* password_sid */, 0 /* biometric_sid */); } ErrorCode GetCharacteristics(const vector& key_blob, const vector& app_id, const vector& app_data, vector* key_characteristics); ErrorCode GetCharacteristics(const vector& key_blob, vector* key_characteristics); void CheckCharacteristics(const vector& key_blob, const vector& generate_characteristics); void CheckAppIdCharacteristics(const vector& key_blob, std::string_view app_id_string, std::string_view app_data_string, const vector& generate_characteristics); ErrorCode DeleteKey(vector* key_blob, bool keep_key_blob = false); ErrorCode DeleteKey(bool keep_key_blob = false); ErrorCode DeleteAllKeys(); ErrorCode DestroyAttestationIds(); void CheckedDeleteKey(vector* key_blob, bool keep_key_blob = false); void CheckedDeleteKey(); ErrorCode Begin(KeyPurpose purpose, const vector& key_blob, const AuthorizationSet& in_params, AuthorizationSet* out_params, std::shared_ptr& op); ErrorCode Begin(KeyPurpose purpose, const vector& key_blob, const AuthorizationSet& in_params, AuthorizationSet* out_params); ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params, AuthorizationSet* out_params); ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params); ErrorCode UpdateAad(const string& input); ErrorCode Update(const string& input, string* output); ErrorCode Finish(const string& message, const string& signature, string* output); ErrorCode Finish(const string& message, string* output) { return Finish(message, {} /* signature */, output); } ErrorCode Finish(string* output) { return Finish({} /* message */, output); } ErrorCode Abort(); ErrorCode Abort(const shared_ptr& op); void AbortIfNeeded(); string ProcessMessage(const vector& key_blob, KeyPurpose operation, const string& message, const AuthorizationSet& in_params, AuthorizationSet* out_params); std::tuple ProcessMessage( const vector& key_blob, KeyPurpose operation, const std::string& message, const AuthorizationSet& in_params); string SignMessage(const vector& key_blob, const string& message, const AuthorizationSet& params); string SignMessage(const string& message, const AuthorizationSet& params); string MacMessage(const string& message, Digest digest, size_t mac_length); void CheckHmacTestVector(const string& key, const string& message, Digest digest, const string& expected_mac); void CheckAesCtrTestVector(const string& key, const string& nonce, const string& message, const string& expected_ciphertext); void CheckTripleDesTestVector(KeyPurpose purpose, BlockMode block_mode, PaddingMode padding_mode, const string& key, const string& iv, const string& input, const string& expected_output); void VerifyMessage(const vector& key_blob, const string& message, const string& signature, const AuthorizationSet& params); void VerifyMessage(const string& message, const string& signature, const AuthorizationSet& params); void LocalVerifyMessage(const string& message, const string& signature, const AuthorizationSet& params); string LocalRsaEncryptMessage(const string& message, const AuthorizationSet& params); string EncryptMessage(const vector& key_blob, const string& message, const AuthorizationSet& in_params, AuthorizationSet* out_params); string EncryptMessage(const string& message, const AuthorizationSet& params, AuthorizationSet* out_params); string EncryptMessage(const string& message, const AuthorizationSet& params); string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding); string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding, vector* iv_out); string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding, const vector& iv_in); string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding, uint8_t mac_length_bits, const vector& iv_in); string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding, uint8_t mac_length_bits); string DecryptMessage(const vector& key_blob, const string& ciphertext, const AuthorizationSet& params); string DecryptMessage(const string& ciphertext, const AuthorizationSet& params); string DecryptMessage(const string& ciphertext, BlockMode block_mode, PaddingMode padding_mode, const vector& iv); std::pair> UpgradeKey(const vector& key_blob); template std::tuple CreateTestKeys( TagType tagToTest, ErrorCode expectedReturn, std::function tagModifier = [](AuthorizationSetBuilder*) {}) { /* AES */ KeyData aesKeyData; AuthorizationSetBuilder aesBuilder = AuthorizationSetBuilder() .AesEncryptionKey(128) .Authorization(tagToTest) .BlockMode(BlockMode::ECB) .Padding(PaddingMode::NONE) .Authorization(TAG_NO_AUTH_REQUIRED); tagModifier(&aesBuilder); ErrorCode errorCode = GenerateKey(aesBuilder, &aesKeyData.blob, &aesKeyData.characteristics); EXPECT_EQ(expectedReturn, errorCode); /* HMAC */ KeyData hmacKeyData; AuthorizationSetBuilder hmacBuilder = AuthorizationSetBuilder() .HmacKey(128) .Authorization(tagToTest) .Digest(Digest::SHA_2_256) .Authorization(TAG_MIN_MAC_LENGTH, 128) .Authorization(TAG_NO_AUTH_REQUIRED); tagModifier(&hmacBuilder); errorCode = GenerateKey(hmacBuilder, &hmacKeyData.blob, &hmacKeyData.characteristics); EXPECT_EQ(expectedReturn, errorCode); /* RSA */ KeyData rsaKeyData; AuthorizationSetBuilder rsaBuilder = AuthorizationSetBuilder() .RsaSigningKey(2048, 65537) .Authorization(tagToTest) .Digest(Digest::NONE) .Padding(PaddingMode::NONE) .Authorization(TAG_NO_AUTH_REQUIRED) .SetDefaultValidity(); tagModifier(&rsaBuilder); errorCode = GenerateKey(rsaBuilder, &rsaKeyData.blob, &rsaKeyData.characteristics); EXPECT_EQ(expectedReturn, errorCode); /* ECDSA */ KeyData ecdsaKeyData; AuthorizationSetBuilder ecdsaBuilder = AuthorizationSetBuilder() .EcdsaSigningKey(EcCurve::P_256) .Authorization(tagToTest) .Digest(Digest::SHA_2_256) .Authorization(TAG_NO_AUTH_REQUIRED) .SetDefaultValidity(); tagModifier(&ecdsaBuilder); errorCode = GenerateKey(ecdsaBuilder, &ecdsaKeyData.blob, &ecdsaKeyData.characteristics); EXPECT_EQ(expectedReturn, errorCode); return {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}; } bool IsSecure() const { return securityLevel_ != SecurityLevel::SOFTWARE; } SecurityLevel SecLevel() const { return securityLevel_; } vector ValidKeySizes(Algorithm algorithm); vector InvalidKeySizes(Algorithm algorithm); vector ValidBlockModes(Algorithm algorithm); vector ValidPaddingModes(Algorithm algorithm, BlockMode blockMode); vector InvalidPaddingModes(Algorithm algorithm, BlockMode blockMode); vector ValidCurves(); vector InvalidCurves(); vector ValidDigests(bool withNone, bool withMD5); static vector build_params() { auto params = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor); return params; } std::shared_ptr op_; vector cert_chain_; vector key_blob_; vector key_characteristics_; const vector& SecLevelAuthorizations( const vector& key_characteristics); inline const vector& SecLevelAuthorizations() { return SecLevelAuthorizations(key_characteristics_); } const vector& SecLevelAuthorizations( const vector& key_characteristics, SecurityLevel securityLevel); ErrorCode UseAesKey(const vector& aesKeyBlob); ErrorCode UseHmacKey(const vector& hmacKeyBlob); ErrorCode UseRsaKey(const vector& rsaKeyBlob); ErrorCode UseEcdsaKey(const vector& ecdsaKeyBlob); protected: std::shared_ptr keymint_; uint32_t os_version_; uint32_t os_patch_level_; uint32_t vendor_patch_level_; bool timestamp_token_required_; SecurityLevel securityLevel_; string name_; string author_; long challenge_; }; // If the given property is available, add it to the tag set under the given tag ID. template void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag ttag, const char* prop) { std::string prop_value = ::android::base::GetProperty(prop, /* default= */ ""); if (!prop_value.empty()) { tags->Authorization(ttag, prop_value.data(), prop_value.size()); } } vector build_serial_blob(const uint64_t serial_int); void verify_subject(const X509* cert, const string& subject, bool self_signed); void verify_serial(X509* cert, const uint64_t expected_serial); void verify_subject_and_serial(const Certificate& certificate, // const uint64_t expected_serial, // const string& subject, bool self_signed); bool verify_attestation_record(const string& challenge, // const string& app_id, // AuthorizationSet expected_sw_enforced, // AuthorizationSet expected_hw_enforced, // SecurityLevel security_level, const vector& attestation_cert, vector* unique_id = nullptr); string bin2hex(const vector& data); X509_Ptr parse_cert_blob(const vector& blob); vector make_name_from_str(const string& name); void check_maced_pubkey(const MacedPublicKey& macedPubKey, bool testMode, vector* payload_value); void p256_pub_key(const vector& coseKeyData, EVP_PKEY_Ptr* signingKey); AuthorizationSet HwEnforcedAuthorizations(const vector& key_characteristics); AuthorizationSet SwEnforcedAuthorizations(const vector& key_characteristics); ::testing::AssertionResult ChainSignaturesAreValid(const vector& chain, bool strict_issuer_check = true); #define INSTANTIATE_KEYMINT_AIDL_TEST(name) \ INSTANTIATE_TEST_SUITE_P(PerInstance, name, \ testing::ValuesIn(KeyMintAidlTestBase::build_params()), \ ::android::PrintInstanceNameToString); \ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); } // namespace test } // namespace aidl::android::hardware::security::keymint