diff options
author | Shawn Willden <swillden@google.com> | 2021-01-10 18:06:50 -0700 |
---|---|---|
committer | Shawn Willden <swillden@google.com> | 2021-01-12 22:15:21 -0700 |
commit | 7f42437ebb2be7fdfe872aff49b47e576b7b77d5 (patch) | |
tree | c00b1183ee0ff23038fbcf3f564abaa6b388e10b /security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp | |
parent | 46f91823cf4a04c22b6d13b1f4704f8a81a2d352 (diff) |
Change KeyCharacteristics
Support key characteristics with three security levels, do not store
unenforced authorizations with keys or bind them to keys.
Bug: 163606833
Test: atest VtsAidlKeyMintTargetTest
Change-Id: Idbc523f16d8ef66ec38e0d503ad579a93c49e7b4
Diffstat (limited to 'security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp')
-rw-r--r-- | security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp | 126 |
1 files changed, 80 insertions, 46 deletions
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 94bc199ca7..93a216f27e 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -17,6 +17,7 @@ #include "KeyMintAidlTestBase.h" #include <chrono> +#include <unordered_set> #include <vector> #include <android-base/logging.h> @@ -43,6 +44,34 @@ using std::optional; namespace test { +namespace { + +// Predicate for testing basic characteristics validity in generation or import. +bool KeyCharacteristicsBasicallyValid(SecurityLevel secLevel, + const vector<KeyCharacteristics>& key_characteristics) { + if (key_characteristics.empty()) return false; + + std::unordered_set<SecurityLevel> levels_seen; + for (auto& entry : key_characteristics) { + if (entry.authorizations.empty()) return false; + + if (levels_seen.find(entry.securityLevel) != levels_seen.end()) return false; + levels_seen.insert(entry.securityLevel); + + // Generally, we should only have one entry, at the same security level as the KM + // instance. There is an exception: StrongBox KM can have some authorizations that are + // enforced by the TEE. + bool isExpectedSecurityLevel = secLevel == entry.securityLevel || + (secLevel == SecurityLevel::STRONGBOX && + entry.securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT); + + if (!isExpectedSecurityLevel) return false; + } + return true; +} + +} // namespace + ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(const Status& result) { if (result.isOk()) return ErrorCode::OK; @@ -78,35 +107,30 @@ void KeyMintAidlTestBase::SetUp() { } ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc, - vector<uint8_t>* keyBlob, KeyCharacteristics* keyChar) { - EXPECT_NE(keyBlob, nullptr) << "Key blob pointer must not be null. Test bug"; - EXPECT_NE(keyChar, nullptr) + vector<uint8_t>* key_blob, + vector<KeyCharacteristics>* key_characteristics) { + EXPECT_NE(key_blob, nullptr) << "Key blob pointer must not be null. Test bug"; + EXPECT_NE(key_characteristics, nullptr) << "Previous characteristics not deleted before generating key. Test bug."; // Aidl does not clear these output parameters if the function returns // error. This is different from hal where output parameter is always // cleared due to hal returning void. So now we need to do our own clearing // of the output variables prior to calling keyMint aidl libraries. - keyBlob->clear(); - keyChar->softwareEnforced.clear(); - keyChar->hardwareEnforced.clear(); - certChain_.clear(); - - Status result; - ByteArray blob; + key_blob->clear(); + key_characteristics->clear(); + cert_chain_.clear(); - result = keymint_->generateKey(key_desc.vector_data(), &blob, keyChar, &certChain_); + KeyCreationResult creationResult; + Status result = keymint_->generateKey(key_desc.vector_data(), &creationResult); - // On result, blob & characteristics should be empty. if (result.isOk()) { - if (SecLevel() != SecurityLevel::SOFTWARE) { - EXPECT_GT(keyChar->hardwareEnforced.size(), 0); - } - EXPECT_GT(keyChar->softwareEnforced.size(), 0); - // TODO(seleneh) in a later version where we return @nullable - // single Certificate, check non-null single certificate is always - // non-empty. - *keyBlob = blob.data; + EXPECT_PRED2(KeyCharacteristicsBasicallyValid, SecLevel(), + creationResult.keyCharacteristics); + EXPECT_GT(creationResult.keyBlob.size(), 0); + *key_blob = std::move(creationResult.keyBlob); + *key_characteristics = std::move(creationResult.keyCharacteristics); + cert_chain_ = std::move(creationResult.certificateChain); } return GetReturnErrorCode(result); @@ -118,25 +142,26 @@ ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc) { ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format, const string& key_material, vector<uint8_t>* key_blob, - KeyCharacteristics* key_characteristics) { + vector<KeyCharacteristics>* key_characteristics) { Status result; - certChain_.clear(); - key_characteristics->softwareEnforced.clear(); - key_characteristics->hardwareEnforced.clear(); + cert_chain_.clear(); + key_characteristics->clear(); key_blob->clear(); - ByteArray blob; + KeyCreationResult creationResult; result = keymint_->importKey(key_desc.vector_data(), format, - vector<uint8_t>(key_material.begin(), key_material.end()), &blob, - key_characteristics, &certChain_); + vector<uint8_t>(key_material.begin(), key_material.end()), + &creationResult); if (result.isOk()) { - if (SecLevel() != SecurityLevel::SOFTWARE) { - EXPECT_GT(key_characteristics->hardwareEnforced.size(), 0); - } - EXPECT_GT(key_characteristics->softwareEnforced.size(), 0); - *key_blob = blob.data; + EXPECT_PRED2(KeyCharacteristicsBasicallyValid, SecLevel(), + creationResult.keyCharacteristics); + EXPECT_GT(creationResult.keyBlob.size(), 0); + + *key_blob = std::move(creationResult.keyBlob); + *key_characteristics = std::move(creationResult.keyCharacteristics); + cert_chain_ = std::move(creationResult.certificateChain); } return GetReturnErrorCode(result); @@ -151,25 +176,25 @@ ErrorCode KeyMintAidlTestBase::ImportWrappedKey(string wrapped_key, string wrapp const AuthorizationSet& wrapping_key_desc, string masking_key, const AuthorizationSet& unwrapping_params) { - Status result; EXPECT_EQ(ErrorCode::OK, ImportKey(wrapping_key_desc, KeyFormat::PKCS8, wrapping_key)); - ByteArray outBlob; - key_characteristics_.softwareEnforced.clear(); - key_characteristics_.hardwareEnforced.clear(); + key_characteristics_.clear(); - result = keymint_->importWrappedKey(vector<uint8_t>(wrapped_key.begin(), wrapped_key.end()), - key_blob_, - vector<uint8_t>(masking_key.begin(), masking_key.end()), - unwrapping_params.vector_data(), 0 /* passwordSid */, - 0 /* biometricSid */, &outBlob, &key_characteristics_); + KeyCreationResult creationResult; + Status result = keymint_->importWrappedKey( + vector<uint8_t>(wrapped_key.begin(), wrapped_key.end()), key_blob_, + vector<uint8_t>(masking_key.begin(), masking_key.end()), + unwrapping_params.vector_data(), 0 /* passwordSid */, 0 /* biometricSid */, + &creationResult); if (result.isOk()) { - key_blob_ = outBlob.data; - if (SecLevel() != SecurityLevel::SOFTWARE) { - EXPECT_GT(key_characteristics_.hardwareEnforced.size(), 0); - } - EXPECT_GT(key_characteristics_.softwareEnforced.size(), 0); + EXPECT_PRED2(KeyCharacteristicsBasicallyValid, SecLevel(), + creationResult.keyCharacteristics); + EXPECT_GT(creationResult.keyBlob.size(), 0); + + key_blob_ = std::move(creationResult.keyBlob); + key_characteristics_ = std::move(creationResult.keyCharacteristics); + cert_chain_ = std::move(creationResult.certificateChain); } return GetReturnErrorCode(result); @@ -754,6 +779,15 @@ vector<Digest> KeyMintAidlTestBase::ValidDigests(bool withNone, bool withMD5) { return {}; } +static const vector<KeyParameter> kEmptyAuthList{}; + +const vector<KeyParameter>& KeyMintAidlTestBase::SecLevelAuthorizations( + const vector<KeyCharacteristics>& key_characteristics) { + auto found = std::find_if(key_characteristics.begin(), key_characteristics.end(), + [this](auto& entry) { return entry.securityLevel == SecLevel(); }); + return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations; +} + } // namespace test } // namespace aidl::android::hardware::security::keymint |