/* * 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. */ #include "KeyMintAidlTestBase.h" #include #include #include #include #include namespace android::hardware::security::keymint { using namespace std::literals::chrono_literals; using std::endl; using std::optional; ::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set) { if (set.size() == 0) os << "(Empty)" << ::std::endl; else { os << "\n"; for (size_t i = 0; i < set.size(); ++i) os << set[i] << ::std::endl; } return os; } namespace test { ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(Status result) { if (result.isOk()) return ErrorCode::OK; if (result.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC) { return static_cast(result.serviceSpecificErrorCode()); } return ErrorCode::UNKNOWN_ERROR; } void KeyMintAidlTestBase::InitializeKeyMint(sp keyMint) { ASSERT_NE(keyMint, nullptr); keymint_ = keyMint; KeyMintHardwareInfo info; ASSERT_TRUE(keymint_->getHardwareInfo(&info).isOk()); securityLevel_ = info.securityLevel; name_.assign(info.keyMintName.begin(), info.keyMintName.end()); author_.assign(info.keyMintAuthorName.begin(), info.keyMintAuthorName.end()); os_version_ = getOsVersion(); os_patch_level_ = getOsPatchlevel(); } void KeyMintAidlTestBase::SetUp() { InitializeKeyMint( android::waitForDeclaredService(String16(GetParam().c_str()))); } ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc, vector* keyBlob, KeyCharacteristics* keyChar) { EXPECT_NE(keyBlob, nullptr) << "Key blob pointer must not be null. Test bug"; EXPECT_NE(keyChar, 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; result = keymint_->generateKey(key_desc.vector_data(), &blob, keyChar, &certChain_); // 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; } return GetReturnErrorCode(result); } ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc) { return GenerateKey(key_desc, &key_blob_, &key_characteristics_); } ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format, const string& key_material, vector* key_blob, KeyCharacteristics* key_characteristics) { Status result; certChain_.clear(); key_characteristics->softwareEnforced.clear(); key_characteristics->hardwareEnforced.clear(); key_blob->clear(); ByteArray blob; result = keymint_->importKey(key_desc.vector_data(), format, vector(key_material.begin(), key_material.end()), &blob, key_characteristics, &certChain_); 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; } return GetReturnErrorCode(result); } ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format, const string& key_material) { return ImportKey(key_desc, format, key_material, &key_blob_, &key_characteristics_); } ErrorCode KeyMintAidlTestBase::ImportWrappedKey(string wrapped_key, string wrapping_key, 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(); result = keymint_->importWrappedKey(vector(wrapped_key.begin(), wrapped_key.end()), key_blob_, vector(masking_key.begin(), masking_key.end()), unwrapping_params.vector_data(), 0 /* passwordSid */, 0 /* biometricSid */, &outBlob, &key_characteristics_); 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); } return GetReturnErrorCode(result); } ErrorCode KeyMintAidlTestBase::DeleteKey(vector* key_blob, bool keep_key_blob) { Status result = keymint_->deleteKey(*key_blob); if (!keep_key_blob) { *key_blob = vector(); } EXPECT_TRUE(result.isOk()) << result.serviceSpecificErrorCode() << endl; return GetReturnErrorCode(result); } ErrorCode KeyMintAidlTestBase::DeleteKey(bool keep_key_blob) { return DeleteKey(&key_blob_, keep_key_blob); } ErrorCode KeyMintAidlTestBase::DeleteAllKeys() { Status result = keymint_->deleteAllKeys(); EXPECT_TRUE(result.isOk()) << result.serviceSpecificErrorCode() << endl; return GetReturnErrorCode(result); } void KeyMintAidlTestBase::CheckedDeleteKey(vector* key_blob, bool keep_key_blob) { ErrorCode result = DeleteKey(key_blob, keep_key_blob); EXPECT_TRUE(result == ErrorCode::OK || result == ErrorCode::UNIMPLEMENTED) << result << endl; } void KeyMintAidlTestBase::CheckedDeleteKey() { CheckedDeleteKey(&key_blob_); } ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector& key_blob, const AuthorizationSet& in_params, AuthorizationSet* out_params, sp& op) { SCOPED_TRACE("Begin"); Status result; BeginResult out; result = keymint_->begin(purpose, key_blob, in_params.vector_data(), HardwareAuthToken(), &out); if (result.isOk()) { *out_params = out.params; challenge_ = out.challenge; op = out.operation; } return GetReturnErrorCode(result); } ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector& key_blob, const AuthorizationSet& in_params, AuthorizationSet* out_params) { SCOPED_TRACE("Begin"); Status result; BeginResult out; result = keymint_->begin(purpose, key_blob, in_params.vector_data(), HardwareAuthToken(), &out); if (result.isOk()) { *out_params = out.params; challenge_ = out.challenge; op_ = out.operation; } return GetReturnErrorCode(result); } ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const AuthorizationSet& in_params, AuthorizationSet* out_params) { SCOPED_TRACE("Begin"); EXPECT_EQ(nullptr, op_); return Begin(purpose, key_blob_, in_params, out_params); } ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const AuthorizationSet& in_params) { SCOPED_TRACE("Begin"); AuthorizationSet out_params; ErrorCode result = Begin(purpose, in_params, &out_params); EXPECT_TRUE(out_params.empty()); return result; } ErrorCode KeyMintAidlTestBase::Update(const AuthorizationSet& in_params, const string& input, AuthorizationSet* out_params, string* output, int32_t* input_consumed) { SCOPED_TRACE("Update"); Status result; EXPECT_NE(op_, nullptr); if (!op_) { return ErrorCode::UNEXPECTED_NULL_POINTER; } KeyParameterArray key_params; key_params.params = in_params.vector_data(); KeyParameterArray in_keyParams; in_keyParams.params = in_params.vector_data(); optional out_keyParams; optional o_put; result = op_->update(in_keyParams, vector(input.begin(), input.end()), {}, {}, &out_keyParams, &o_put, input_consumed); if (result.isOk()) { if (o_put) { output->append(o_put->data.begin(), o_put->data.end()); } if (out_keyParams) { out_params->push_back(AuthorizationSet(out_keyParams->params)); } } return GetReturnErrorCode(result); } ErrorCode KeyMintAidlTestBase::Update(const string& input, string* out, int32_t* input_consumed) { SCOPED_TRACE("Update"); AuthorizationSet out_params; ErrorCode result = Update(AuthorizationSet() /* in_params */, input, &out_params, out, input_consumed); EXPECT_TRUE(out_params.empty()); return result; } ErrorCode KeyMintAidlTestBase::Finish(const AuthorizationSet& in_params, const string& input, const string& signature, AuthorizationSet* out_params, string* output) { SCOPED_TRACE("Finish"); Status result; EXPECT_NE(op_, nullptr); if (!op_) { return ErrorCode::UNEXPECTED_NULL_POINTER; } KeyParameterArray key_params; key_params.params = in_params.vector_data(); KeyParameterArray in_keyParams; in_keyParams.params = in_params.vector_data(); optional out_keyParams; optional> o_put; vector oPut; result = op_->finish(in_keyParams, vector(input.begin(), input.end()), vector(signature.begin(), signature.end()), {}, {}, &out_keyParams, &oPut); if (result.isOk()) { if (out_keyParams) { out_params->push_back(AuthorizationSet(out_keyParams->params)); } output->append(oPut.begin(), oPut.end()); } op_.clear(); // So dtor doesn't Abort(). return GetReturnErrorCode(result); } ErrorCode KeyMintAidlTestBase::Finish(const string& message, string* output) { SCOPED_TRACE("Finish"); AuthorizationSet out_params; string finish_output; ErrorCode result = Finish(AuthorizationSet() /* in_params */, message, "" /* signature */, &out_params, output); if (result != ErrorCode::OK) { return result; } EXPECT_EQ(0U, out_params.size()); return result; } ErrorCode KeyMintAidlTestBase::Finish(const string& message, const string& signature, string* output) { SCOPED_TRACE("Finish"); AuthorizationSet out_params; ErrorCode result = Finish(AuthorizationSet() /* in_params */, message, signature, &out_params, output); if (result != ErrorCode::OK) { return result; } EXPECT_EQ(0U, out_params.size()); return result; } ErrorCode KeyMintAidlTestBase::Abort(const sp& op) { SCOPED_TRACE("Abort"); EXPECT_NE(op, nullptr); if (!op) { return ErrorCode::UNEXPECTED_NULL_POINTER; } Status retval = op->abort(); EXPECT_TRUE(retval.isOk()); return static_cast(retval.serviceSpecificErrorCode()); } ErrorCode KeyMintAidlTestBase::Abort() { SCOPED_TRACE("Abort"); EXPECT_NE(op_, nullptr); if (!op_) { return ErrorCode::UNEXPECTED_NULL_POINTER; } Status retval = op_->abort(); return static_cast(retval.serviceSpecificErrorCode()); } void KeyMintAidlTestBase::AbortIfNeeded() { SCOPED_TRACE("AbortIfNeeded"); if (op_) { EXPECT_EQ(ErrorCode::OK, Abort()); op_.clear(); } } string KeyMintAidlTestBase::ProcessMessage(const vector& key_blob, KeyPurpose operation, const string& message, const AuthorizationSet& in_params, AuthorizationSet* out_params) { SCOPED_TRACE("ProcessMessage"); AuthorizationSet begin_out_params; ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params); EXPECT_EQ(ErrorCode::OK, result); if (result != ErrorCode::OK) { return ""; } string output; int32_t consumed = 0; AuthorizationSet update_params; AuthorizationSet update_out_params; result = Update(update_params, message, &update_out_params, &output, &consumed); EXPECT_EQ(ErrorCode::OK, result); if (result != ErrorCode::OK) { return ""; } string unused; AuthorizationSet finish_params; AuthorizationSet finish_out_params; EXPECT_EQ(ErrorCode::OK, Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output)); out_params->push_back(begin_out_params); out_params->push_back(finish_out_params); return output; } string KeyMintAidlTestBase::SignMessage(const vector& key_blob, const string& message, const AuthorizationSet& params) { SCOPED_TRACE("SignMessage"); AuthorizationSet out_params; string signature = ProcessMessage(key_blob, KeyPurpose::SIGN, message, params, &out_params); EXPECT_TRUE(out_params.empty()); return signature; } string KeyMintAidlTestBase::SignMessage(const string& message, const AuthorizationSet& params) { SCOPED_TRACE("SignMessage"); return SignMessage(key_blob_, message, params); } string KeyMintAidlTestBase::MacMessage(const string& message, Digest digest, size_t mac_length) { SCOPED_TRACE("MacMessage"); return SignMessage( key_blob_, message, AuthorizationSetBuilder().Digest(digest).Authorization(TAG_MAC_LENGTH, mac_length)); } void KeyMintAidlTestBase::CheckHmacTestVector(const string& key, const string& message, Digest digest, const string& expected_mac) { SCOPED_TRACE("CheckHmacTestVector"); ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .HmacKey(key.size() * 8) .Authorization(TAG_MIN_MAC_LENGTH, expected_mac.size() * 8) .Digest(digest), KeyFormat::RAW, key)); string signature = MacMessage(message, digest, expected_mac.size() * 8); EXPECT_EQ(expected_mac, signature) << "Test vector didn't match for key of size " << key.size() << " message of size " << message.size() << " and digest " << digest; CheckedDeleteKey(); } void KeyMintAidlTestBase::CheckAesCtrTestVector(const string& key, const string& nonce, const string& message, const string& expected_ciphertext) { SCOPED_TRACE("CheckAesCtrTestVector"); ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .AesEncryptionKey(key.size() * 8) .BlockMode(BlockMode::CTR) .Authorization(TAG_CALLER_NONCE) .Padding(PaddingMode::NONE), KeyFormat::RAW, key)); auto params = AuthorizationSetBuilder() .Authorization(TAG_NONCE, nonce.data(), nonce.size()) .BlockMode(BlockMode::CTR) .Padding(PaddingMode::NONE); AuthorizationSet out_params; string ciphertext = EncryptMessage(key_blob_, message, params, &out_params); EXPECT_EQ(expected_ciphertext, ciphertext); } void KeyMintAidlTestBase::CheckTripleDesTestVector(KeyPurpose purpose, BlockMode block_mode, PaddingMode padding_mode, const string& key, const string& iv, const string& input, const string& expected_output) { auto authset = AuthorizationSetBuilder() .TripleDesEncryptionKey(key.size() * 7) .BlockMode(block_mode) .Authorization(TAG_NO_AUTH_REQUIRED) .Padding(padding_mode); if (iv.size()) authset.Authorization(TAG_CALLER_NONCE); ASSERT_EQ(ErrorCode::OK, ImportKey(authset, KeyFormat::RAW, key)); ASSERT_GT(key_blob_.size(), 0U); auto begin_params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding_mode); if (iv.size()) begin_params.Authorization(TAG_NONCE, iv.data(), iv.size()); AuthorizationSet output_params; string output = ProcessMessage(key_blob_, purpose, input, begin_params, &output_params); EXPECT_EQ(expected_output, output); } void KeyMintAidlTestBase::VerifyMessage(const vector& key_blob, const string& message, const string& signature, const AuthorizationSet& params) { SCOPED_TRACE("VerifyMessage"); AuthorizationSet begin_out_params; ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::VERIFY, key_blob, params, &begin_out_params)); string output; AuthorizationSet update_params; AuthorizationSet update_out_params; int32_t consumed; ASSERT_EQ(ErrorCode::OK, Update(update_params, message, &update_out_params, &output, &consumed)); EXPECT_TRUE(output.empty()); EXPECT_GT(consumed, 0U); string unused; AuthorizationSet finish_params; AuthorizationSet finish_out_params; EXPECT_EQ(ErrorCode::OK, Finish(finish_params, message.substr(consumed), signature, &finish_out_params, &output)); op_.clear(); EXPECT_TRUE(output.empty()); } void KeyMintAidlTestBase::VerifyMessage(const string& message, const string& signature, const AuthorizationSet& params) { SCOPED_TRACE("VerifyMessage"); VerifyMessage(key_blob_, message, signature, params); } string KeyMintAidlTestBase::EncryptMessage(const vector& key_blob, const string& message, const AuthorizationSet& in_params, AuthorizationSet* out_params) { SCOPED_TRACE("EncryptMessage"); return ProcessMessage(key_blob, KeyPurpose::ENCRYPT, message, in_params, out_params); } string KeyMintAidlTestBase::EncryptMessage(const string& message, const AuthorizationSet& params, AuthorizationSet* out_params) { SCOPED_TRACE("EncryptMessage"); return EncryptMessage(key_blob_, message, params, out_params); } string KeyMintAidlTestBase::EncryptMessage(const string& message, const AuthorizationSet& params) { SCOPED_TRACE("EncryptMessage"); AuthorizationSet out_params; string ciphertext = EncryptMessage(message, params, &out_params); EXPECT_TRUE(out_params.empty()) << "Output params should be empty. Contained: " << out_params; return ciphertext; } string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding) { SCOPED_TRACE("EncryptMessage"); auto params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding); AuthorizationSet out_params; string ciphertext = EncryptMessage(message, params, &out_params); EXPECT_TRUE(out_params.empty()) << "Output params should be empty. Contained: " << out_params; return ciphertext; } string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding, vector* iv_out) { SCOPED_TRACE("EncryptMessage"); auto params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding); AuthorizationSet out_params; string ciphertext = EncryptMessage(message, params, &out_params); EXPECT_EQ(1U, out_params.size()); auto ivVal = out_params.GetTagValue(TAG_NONCE); EXPECT_TRUE(ivVal.isOk()); if (ivVal.isOk()) *iv_out = ivVal.value(); return ciphertext; } string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding, const vector& iv_in) { SCOPED_TRACE("EncryptMessage"); auto params = AuthorizationSetBuilder() .BlockMode(block_mode) .Padding(padding) .Authorization(TAG_NONCE, iv_in); AuthorizationSet out_params; string ciphertext = EncryptMessage(message, params, &out_params); return ciphertext; } string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding, uint8_t mac_length_bits, const vector& iv_in) { SCOPED_TRACE("EncryptMessage"); auto params = AuthorizationSetBuilder() .BlockMode(block_mode) .Padding(padding) .Authorization(TAG_MAC_LENGTH, mac_length_bits) .Authorization(TAG_NONCE, iv_in); AuthorizationSet out_params; string ciphertext = EncryptMessage(message, params, &out_params); return ciphertext; } string KeyMintAidlTestBase::DecryptMessage(const vector& key_blob, const string& ciphertext, const AuthorizationSet& params) { SCOPED_TRACE("DecryptMessage"); AuthorizationSet out_params; string plaintext = ProcessMessage(key_blob, KeyPurpose::DECRYPT, ciphertext, params, &out_params); EXPECT_TRUE(out_params.empty()); return plaintext; } string KeyMintAidlTestBase::DecryptMessage(const string& ciphertext, const AuthorizationSet& params) { SCOPED_TRACE("DecryptMessage"); return DecryptMessage(key_blob_, ciphertext, params); } string KeyMintAidlTestBase::DecryptMessage(const string& ciphertext, BlockMode block_mode, PaddingMode padding_mode, const vector& iv) { SCOPED_TRACE("DecryptMessage"); auto params = AuthorizationSetBuilder() .BlockMode(block_mode) .Padding(padding_mode) .Authorization(TAG_NONCE, iv); return DecryptMessage(key_blob_, ciphertext, params); } std::pair> KeyMintAidlTestBase::UpgradeKey( const vector& key_blob) { std::pair> retval; vector outKeyBlob; Status result = keymint_->upgradeKey(key_blob, vector(), &outKeyBlob); ErrorCode errorcode = GetReturnErrorCode(result); retval = std::tie(errorcode, outKeyBlob); return retval; } vector KeyMintAidlTestBase::ValidKeySizes(Algorithm algorithm) { switch (algorithm) { case Algorithm::RSA: switch (SecLevel()) { case SecurityLevel::SOFTWARE: case SecurityLevel::TRUSTED_ENVIRONMENT: return {2048, 3072, 4096}; case SecurityLevel::STRONGBOX: return {2048}; default: ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel()); break; } break; case Algorithm::EC: switch (SecLevel()) { case SecurityLevel::SOFTWARE: case SecurityLevel::TRUSTED_ENVIRONMENT: return {224, 256, 384, 521}; case SecurityLevel::STRONGBOX: return {256}; default: ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel()); break; } break; case Algorithm::AES: return {128, 256}; case Algorithm::TRIPLE_DES: return {168}; case Algorithm::HMAC: { vector retval((512 - 64) / 8 + 1); uint32_t size = 64 - 8; std::generate(retval.begin(), retval.end(), [&]() { return (size += 8); }); return retval; } default: ADD_FAILURE() << "Invalid Algorithm: " << algorithm; return {}; } ADD_FAILURE() << "Should be impossible to get here"; return {}; } vector KeyMintAidlTestBase::InvalidKeySizes(Algorithm algorithm) { if (SecLevel() == SecurityLevel::STRONGBOX) { switch (algorithm) { case Algorithm::RSA: return {3072, 4096}; case Algorithm::EC: return {224, 384, 521}; case Algorithm::AES: return {192}; default: return {}; } } return {}; } vector KeyMintAidlTestBase::ValidCurves() { if (securityLevel_ == SecurityLevel::STRONGBOX) { return {EcCurve::P_256}; } else { return {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521}; } } vector KeyMintAidlTestBase::InvalidCurves() { if (SecLevel() == SecurityLevel::TRUSTED_ENVIRONMENT) return {}; CHECK(SecLevel() == SecurityLevel::STRONGBOX); return {EcCurve::P_224, EcCurve::P_384, EcCurve::P_521}; } vector KeyMintAidlTestBase::ValidDigests(bool withNone, bool withMD5) { switch (SecLevel()) { case SecurityLevel::SOFTWARE: case SecurityLevel::TRUSTED_ENVIRONMENT: if (withNone) { if (withMD5) return {Digest::NONE, Digest::MD5, Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512}; else return {Digest::NONE, Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512}; } else { if (withMD5) return {Digest::MD5, Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512}; else return {Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512}; } break; case SecurityLevel::STRONGBOX: if (withNone) return {Digest::NONE, Digest::SHA_2_256}; else return {Digest::SHA_2_256}; break; default: ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel()); break; } ADD_FAILURE() << "Should be impossible to get here"; return {}; } } // namespace test } // namespace android::hardware::security::keymint