/* * Copyright (C) 2019 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. */ #define LOG_TAG "keymaster_benchmark" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace android { namespace hardware { namespace keymaster { namespace V4_0 { namespace test { // libutils: using android::OK; using android::sp; using android::status_t; // libhidl: using android::hardware::hidl_vec; using android::hardware::Return; using android::hardware::Void; // IKeymaster: using android::IServiceManager; using android::hardware::hidl_string; using android::hardware::keymaster::V4_0::AuthorizationSet; using android::hardware::keymaster::V4_0::AuthorizationSetBuilder; using android::hardware::keymaster::V4_0::BlockMode; using android::hardware::keymaster::V4_0::ErrorCode; using android::hardware::keymaster::V4_0::IKeymasterDevice; using android::hardware::keymaster::V4_0::KeyCharacteristics; using android::hardware::keymaster::V4_0::SecurityLevel; // Standard library: using std::cerr; using std::cout; using std::endl; using std::optional; using std::string; using std::unique_ptr; using std::vector; class HidlBuf : public hidl_vec { typedef hidl_vec super; public: HidlBuf() {} HidlBuf(const super& other) : super(other) {} HidlBuf(super&& other) : super(std::move(other)) {} explicit HidlBuf(const std::string& other) : HidlBuf() { *this = other; } HidlBuf& operator=(const super& other) { super::operator=(other); return *this; } HidlBuf& operator=(super&& other) { super::operator=(std::move(other)); return *this; } HidlBuf& operator=(const string& other) { resize(other.size()); std::copy(other.begin(), other.end(), begin()); return *this; } string to_string() const { return string(reinterpret_cast(data()), size()); } }; #define SMALL_MESSAGE_SIZE 64 #define MEDIUM_MESSAGE_SIZE 1024 #define LARGE_MESSAGE_SIZE 131072 class KeymasterWrapper { private: sp keymaster_; SecurityLevel securityLevel_; hidl_string name_; hidl_string author_; HidlBuf key_blob_; KeyCharacteristics key_characteristics_; ErrorCode error_; string key_transform_; string keymaster_name_; uint32_t os_version_; uint32_t os_patch_level_; std::vector message_cache_; bool GenerateKey(const AuthorizationSet& authSet) { return (keymaster_ ->generateKey( authSet.hidl_data(), [&](ErrorCode hidl_error, const hidl_vec& hidl_key_blob, const KeyCharacteristics& hidl_key_characteristics) { error_ = hidl_error; key_blob_ = hidl_key_blob; key_characteristics_ = std::move(hidl_key_characteristics); }) .isOk() && error_ == ErrorCode::OK); } bool GenerateKey(Algorithm algorithm, int keySize, Digest digest = Digest::NONE, PaddingMode padding = PaddingMode::NONE, optional blockMode = {}) { AuthorizationSetBuilder authSet = AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT) .Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT) .Authorization(TAG_PURPOSE, KeyPurpose::SIGN) .Authorization(TAG_PURPOSE, KeyPurpose::VERIFY) .Authorization(TAG_KEY_SIZE, keySize) .Authorization(TAG_ALGORITHM, algorithm) .Digest(digest) .Authorization(TAG_MIN_MAC_LENGTH, 128) .Padding(padding); if (blockMode) { authSet.BlockMode(*blockMode); } if (algorithm == Algorithm::RSA) { authSet.Authorization(TAG_RSA_PUBLIC_EXPONENT, 65537U); } return GenerateKey(authSet); } KeymasterWrapper(const sp keymaster) { os_version_ = ::keymaster::GetOsVersion(); os_patch_level_ = ::keymaster::GetOsPatchlevel(); keymaster_ = keymaster; keymaster_->getHardwareInfo([&](SecurityLevel securityLevel, const hidl_string& name, const hidl_string& author) { securityLevel_ = securityLevel; name_ = name; author_ = author; }); message_cache_.push_back(string(SMALL_MESSAGE_SIZE, 'x')); message_cache_.push_back(string(MEDIUM_MESSAGE_SIZE, 'x')); message_cache_.push_back(string(LARGE_MESSAGE_SIZE, 'x')); } public: static KeymasterWrapper* newInstance(const std::string& keymaster_name) { auto keymaster = IKeymasterDevice::getService(keymaster_name); if (!keymaster) { std::cerr << "Error: unable to find keymaster service named " << keymaster_name << std::endl; return nullptr; } return new KeymasterWrapper(keymaster); } bool GenerateKey(string transform, int keySize, bool sign = false) { if (transform == key_transform_) { return true; } else if (key_transform_ != "") { // Deleting old key first if (!DeleteKey()) { return false; } } optional algorithm = getAlgorithm(transform); if (!algorithm) { cerr << "Error: invalid algorithm " << transform << endl; return false; } key_transform_ = transform; return GenerateKey(*algorithm, keySize, getDigest(transform), getPadding(transform, sign), getBlockMode(transform)); } bool DeleteKey() { key_blob_ = HidlBuf(); key_transform_ = ""; return keymaster_->deleteKey(key_blob_).isOk(); } AuthorizationSet getOperationParams(string transform, bool sign = false) { AuthorizationSetBuilder builder = AuthorizationSetBuilder() .Padding(getPadding(transform, sign)) .Authorization(TAG_MAC_LENGTH, 128) .Digest(getDigest(transform)); optional blockMode = getBlockMode(transform); if (blockMode) { builder.BlockMode(*blockMode); } return std::move(builder); } optional EncryptBegin(AuthorizationSet& in_params, AuthorizationSet* out_params = new AuthorizationSet) { return Begin(KeyPurpose::ENCRYPT, in_params, out_params); } optional DecryptBegin(AuthorizationSet& in_params, AuthorizationSet* out_params = new AuthorizationSet) { return Begin(KeyPurpose::DECRYPT, in_params, out_params); } optional SignBegin(AuthorizationSet& in_params, AuthorizationSet* out_params = new AuthorizationSet) { return Begin(KeyPurpose::SIGN, in_params, out_params); } optional VerifyBegin(AuthorizationSet& in_params, AuthorizationSet* out_params = new AuthorizationSet) { return Begin(KeyPurpose::VERIFY, in_params, out_params); } optional Begin(KeyPurpose operation, const AuthorizationSet& in_params, AuthorizationSet* out_params) { OperationHandle op_handle; if (!keymaster_ ->begin(operation, key_blob_, in_params.hidl_data(), HardwareAuthToken(), [&](ErrorCode hidl_error, const hidl_vec& hidl_out_params, uint64_t hidl_op_handle) { error_ = hidl_error; out_params->push_back(AuthorizationSet(hidl_out_params)); op_handle = hidl_op_handle; }) .isOk() || error_ != ErrorCode::OK) { keymaster_->abort(op_handle); return {}; } return op_handle; } optional ProcessMessage(const OperationHandle& op_handle, const string& message, const AuthorizationSet& in_params, AuthorizationSet* out_params = new AuthorizationSet, const string& signature = "") { static const int HIDL_BUFFER_LIMIT = 1 << 14; // 16KB string output; size_t input_consumed = 0; while (message.length() - input_consumed > 0) { if (!keymaster_ ->update(op_handle, in_params.hidl_data(), HidlBuf(message.substr(input_consumed, HIDL_BUFFER_LIMIT)), HardwareAuthToken(), VerificationToken(), [&](ErrorCode hidl_error, uint32_t hidl_input_consumed, const hidl_vec& hidl_out_params, const HidlBuf& hidl_output) { error_ = hidl_error; out_params->push_back(AuthorizationSet(hidl_out_params)); output.append(hidl_output.to_string()); input_consumed += hidl_input_consumed; }) .isOk() || error_ != ErrorCode::OK) { keymaster_->abort(op_handle); return {}; } } if (!keymaster_ ->finish(op_handle, in_params.hidl_data(), HidlBuf(message.substr(input_consumed)), HidlBuf(signature), HardwareAuthToken(), VerificationToken(), [&](ErrorCode hidl_error, const hidl_vec& hidl_out_params, const HidlBuf& hidl_output) { error_ = hidl_error; out_params->push_back(AuthorizationSet(hidl_out_params)); output.append(hidl_output.to_string()); }) .isOk() || error_ != ErrorCode::OK) { keymaster_->abort(op_handle); return {}; } return output; } int getError() { return static_cast(error_); } const string getHardwareName() { return name_; } SecurityLevel getSecurityLevel() { return securityLevel_; } const string& GenerateMessage(int size) { for (const string& message : message_cache_) { if (message.size() == size) { return message; } } string message = string(size, 'x'); message_cache_.push_back(message); return std::move(message); } optional getBlockMode(string transform) { if (transform.find("/ECB") != string::npos) { return BlockMode::ECB; } else if (transform.find("/CBC") != string::npos) { return BlockMode::CBC; } else if (transform.find("/CTR") != string::npos) { return BlockMode::CTR; } else if (transform.find("/GCM") != string::npos) { return BlockMode::GCM; } return {}; } PaddingMode getPadding(string transform, bool sign) { if (transform.find("/PKCS7") != string::npos) { return PaddingMode::PKCS7; } else if (transform.find("/PSS") != string::npos) { return PaddingMode::RSA_PSS; } else if (transform.find("/OAEP") != string::npos) { return PaddingMode::RSA_OAEP; } else if (transform.find("/PKCS1") != string::npos) { return sign ? PaddingMode::RSA_PKCS1_1_5_SIGN : PaddingMode::RSA_PKCS1_1_5_ENCRYPT; } else if (sign && transform.find("RSA") != string::npos) { // RSA defaults to PKCS1 for sign return PaddingMode::RSA_PKCS1_1_5_SIGN; } return PaddingMode::NONE; } optional getAlgorithm(string transform) { if (transform.find("AES") != string::npos) { return Algorithm::AES; } else if (transform.find("Hmac") != string::npos) { return Algorithm::HMAC; } else if (transform.find("DESede") != string::npos) { return Algorithm::TRIPLE_DES; } else if (transform.find("RSA") != string::npos) { return Algorithm::RSA; } else if (transform.find("EC") != string::npos) { return Algorithm::EC; } cerr << "Can't find algorithm for " << transform << endl; return {}; } Digest getDigest(string transform) { if (transform.find("MD5") != string::npos) { return Digest::MD5; } else if (transform.find("SHA1") != string::npos || transform.find("SHA-1") != string::npos) { return Digest::SHA1; } else if (transform.find("SHA224") != string::npos) { return Digest::SHA_2_224; } else if (transform.find("SHA256") != string::npos) { return Digest::SHA_2_256; } else if (transform.find("SHA384") != string::npos) { return Digest::SHA_2_384; } else if (transform.find("SHA512") != string::npos) { return Digest::SHA_2_512; } else if (transform.find("RSA") != string::npos && transform.find("OAEP") != string::npos) { return Digest::SHA1; } return Digest::NONE; } }; KeymasterWrapper* keymaster; static void settings(benchmark::internal::Benchmark* benchmark) { benchmark->Unit(benchmark::kMillisecond); } static void addDefaultLabel(benchmark::State& state) { string secLevel; switch (keymaster->getSecurityLevel()) { case SecurityLevel::STRONGBOX: secLevel = "STRONGBOX"; break; case SecurityLevel::SOFTWARE: secLevel = "SOFTWARE"; break; case SecurityLevel::TRUSTED_ENVIRONMENT: secLevel = "TEE"; break; } state.SetLabel("hardware_name:" + keymaster->getHardwareName() + " sec_level:" + secLevel); } // clang-format off #define BENCHMARK_KM(func, transform, keySize) \ BENCHMARK_CAPTURE(func, transform/keySize, #transform "/" #keySize, keySize)->Apply(settings); #define BENCHMARK_KM_MSG(func, transform, keySize, msgSize) \ BENCHMARK_CAPTURE(func, transform/keySize/msgSize, #transform "/" #keySize "/" #msgSize, \ keySize, msgSize) \ ->Apply(settings); #define BENCHMARK_KM_ALL_MSGS(func, transform, keySize) \ BENCHMARK_KM_MSG(func, transform, keySize, SMALL_MESSAGE_SIZE) \ BENCHMARK_KM_MSG(func, transform, keySize, MEDIUM_MESSAGE_SIZE) \ BENCHMARK_KM_MSG(func, transform, keySize, LARGE_MESSAGE_SIZE) #define BENCHMARK_KM_CIPHER(transform, keySize, msgSize) \ BENCHMARK_KM_MSG(encrypt, transform, keySize, msgSize) \ BENCHMARK_KM_MSG(decrypt, transform, keySize, msgSize) #define BENCHMARK_KM_CIPHER_ALL_MSGS(transform, keySize) \ BENCHMARK_KM_ALL_MSGS(encrypt, transform, keySize) \ BENCHMARK_KM_ALL_MSGS(decrypt, transform, keySize) #define BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, keySize) \ BENCHMARK_KM_ALL_MSGS(sign, transform, keySize) \ BENCHMARK_KM_ALL_MSGS(verify, transform, keySize) // clang-format on /* * ============= KeyGen TESTS ================== */ static void keygen(benchmark::State& state, string transform, int keySize) { addDefaultLabel(state); for (auto _ : state) { keymaster->GenerateKey(transform, keySize); state.PauseTiming(); keymaster->DeleteKey(); state.ResumeTiming(); } } BENCHMARK_KM(keygen, AES, 128); BENCHMARK_KM(keygen, AES, 256); BENCHMARK_KM(keygen, RSA, 2048); BENCHMARK_KM(keygen, RSA, 3072); BENCHMARK_KM(keygen, RSA, 4096); BENCHMARK_KM(keygen, EC, 224); BENCHMARK_KM(keygen, EC, 256); BENCHMARK_KM(keygen, EC, 384); BENCHMARK_KM(keygen, EC, 521); BENCHMARK_KM(keygen, DESede, 168); BENCHMARK_KM(keygen, Hmac, 64); BENCHMARK_KM(keygen, Hmac, 128); BENCHMARK_KM(keygen, Hmac, 256); BENCHMARK_KM(keygen, Hmac, 512); BENCHMARK_KM(keygen, Hmac, 1024); BENCHMARK_KM(keygen, Hmac, 2048); BENCHMARK_KM(keygen, Hmac, 4096); BENCHMARK_KM(keygen, Hmac, 8192); /* * ============= SIGNATURE TESTS ================== */ static void sign(benchmark::State& state, string transform, int keySize, int msgSize) { addDefaultLabel(state); if (!keymaster->GenerateKey(transform, keySize, true)) { state.SkipWithError( ("Key generation error, " + std::to_string(keymaster->getError())).c_str()); return; } auto params = keymaster->getOperationParams(transform, true); string message = keymaster->GenerateMessage(msgSize); for (auto _ : state) { state.PauseTiming(); auto opHandle = keymaster->SignBegin(params); if (!opHandle) { state.SkipWithError( ("Error beginning sign, " + std::to_string(keymaster->getError())).c_str()); return; } state.ResumeTiming(); if (!keymaster->ProcessMessage(*opHandle, message, params)) { state.SkipWithError(("Sign error, " + std::to_string(keymaster->getError())).c_str()); break; } } } static void verify(benchmark::State& state, string transform, int keySize, int msgSize) { addDefaultLabel(state); if (!keymaster->GenerateKey(transform, keySize, true)) { state.SkipWithError( ("Key generation error, " + std::to_string(keymaster->getError())).c_str()); return; } AuthorizationSet out_params; AuthorizationSet in_params = keymaster->getOperationParams(transform, true); string message = keymaster->GenerateMessage(msgSize); auto opHandle = keymaster->SignBegin(in_params, &out_params); if (!opHandle) { state.SkipWithError( ("Error beginning sign, " + std::to_string(keymaster->getError())).c_str()); return; } optional signature = keymaster->ProcessMessage(*opHandle, message, in_params, &out_params); if (!signature) { state.SkipWithError(("Sign error, " + std::to_string(keymaster->getError())).c_str()); return; } in_params.push_back(out_params); for (auto _ : state) { state.PauseTiming(); opHandle = keymaster->VerifyBegin(in_params); if (!opHandle) { state.SkipWithError( ("Verify begin error, " + std::to_string(keymaster->getError())).c_str()); return; } state.ResumeTiming(); if (!keymaster->ProcessMessage(*opHandle, message, in_params, &out_params, *signature)) { state.SkipWithError(("Verify error, " + std::to_string(keymaster->getError())).c_str()); break; } } } // clang-format off #define BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(transform) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 64) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 128) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 512) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 1024) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2024) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 8192) BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA1) BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA256) BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA224) BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA256) BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA384) BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA512) #define BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(transform) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 224) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 384) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 521) BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(NONEwithECDSA); BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA1withECDSA); BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA224withECDSA); BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA256withECDSA); BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA384withECDSA); BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA512withECDSA); #define BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(transform) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2048) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 3072) \ BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096) BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA); BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA); BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA); BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA); BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA); BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA/PSS); BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA/PSS); BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA/PSS); BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA/PSS); BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA/PSS); // clang-format on /* * ============= CIPHER TESTS ================== */ static void encrypt(benchmark::State& state, string transform, int keySize, int msgSize) { addDefaultLabel(state); if (!keymaster->GenerateKey(transform, keySize)) { state.SkipWithError( ("Key generation error, " + std::to_string(keymaster->getError())).c_str()); return; } auto params = keymaster->getOperationParams(transform); string message = keymaster->GenerateMessage(msgSize); for (auto _ : state) { state.PauseTiming(); auto opHandle = keymaster->EncryptBegin(params); if (!opHandle) { state.SkipWithError( ("Encryption begin error, " + std::to_string(keymaster->getError())).c_str()); return; } state.ResumeTiming(); if (!keymaster->ProcessMessage(*opHandle, message, params)) { state.SkipWithError( ("Encryption error, " + std::to_string(keymaster->getError())).c_str()); break; } } } static void decrypt(benchmark::State& state, string transform, int keySize, int msgSize) { addDefaultLabel(state); if (!keymaster->GenerateKey(transform, keySize)) { state.SkipWithError( ("Key generation error, " + std::to_string(keymaster->getError())).c_str()); return; } AuthorizationSet out_params; AuthorizationSet in_params = keymaster->getOperationParams(transform); string message = keymaster->GenerateMessage(msgSize); auto opHandle = keymaster->EncryptBegin(in_params, &out_params); if (!opHandle) { state.SkipWithError( ("Encryption begin error, " + std::to_string(keymaster->getError())).c_str()); return; } auto encryptedMessage = keymaster->ProcessMessage(*opHandle, message, in_params, &out_params); if (!encryptedMessage) { state.SkipWithError(("Encryption error, " + std::to_string(keymaster->getError())).c_str()); return; } in_params.push_back(out_params); for (auto _ : state) { state.PauseTiming(); opHandle = keymaster->DecryptBegin(in_params); if (!opHandle) { state.SkipWithError( ("Decryption begin error, " + std::to_string(keymaster->getError())).c_str()); return; } state.ResumeTiming(); if (!keymaster->ProcessMessage(*opHandle, *encryptedMessage, in_params)) { state.SkipWithError( ("Decryption error, " + std::to_string(keymaster->getError())).c_str()); break; } } } // clang-format off // AES #define BENCHMARK_KM_CIPHER_ALL_AES_KEYS(transform) \ BENCHMARK_KM_CIPHER_ALL_MSGS(transform, 128) \ BENCHMARK_KM_CIPHER_ALL_MSGS(transform, 256) BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CBC/NoPadding); BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CBC/PKCS7Padding); BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CTR/NoPadding); BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/ECB/NoPadding); BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/ECB/PKCS7Padding); BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/GCM/NoPadding); // Triple DES BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/CBC/NoPadding, 168); BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/CBC/PKCS7Padding, 168); BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/NoPadding, 168); BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/PKCS7Padding, 168); #define BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(transform, msgSize) \ BENCHMARK_KM_CIPHER(transform, 2048, msgSize) \ BENCHMARK_KM_CIPHER(transform, 3072, msgSize) \ BENCHMARK_KM_CIPHER(transform, 4096, msgSize) BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/NoPadding, SMALL_MESSAGE_SIZE); BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/PKCS1Padding, SMALL_MESSAGE_SIZE); BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/OAEPPadding, SMALL_MESSAGE_SIZE); // clang-format on } // namespace test } // namespace V4_0 } // namespace keymaster } // namespace hardware } // namespace android int main(int argc, char** argv) { ::benchmark::Initialize(&argc, argv); base::CommandLine::Init(argc, argv); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); auto service_name = command_line->GetSwitchValueASCII("service_name"); if (service_name.empty()) { service_name = "default"; } android::hardware::keymaster::V4_0::test::keymaster = android::hardware::keymaster::V4_0::test::KeymasterWrapper::newInstance(service_name); if (!android::hardware::keymaster::V4_0::test::keymaster) { return 1; } ::benchmark::RunSpecifiedBenchmarks(); }