1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "keymaster_benchmark"
18 
19 #include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
20 #include <android/hardware/keymaster/4.0/types.h>
21 #include <keymaster/keymaster_configuration.h>
22 #include <keymasterV4_0/authorization_set.h>
23 
24 #include <android/hidl/manager/1.0/IServiceManager.h>
25 #include <binder/IServiceManager.h>
26 
27 #include <sys/types.h>
28 #include <sys/wait.h>
29 #include <unistd.h>
30 
31 #include <iostream>
32 
33 #include <log/log.h>
34 #include <utils/StrongPointer.h>
35 
36 #include <benchmark/benchmark.h>
37 #include <hidl/Status.h>
38 
39 #include <base/command_line.h>
40 
41 namespace android {
42 namespace hardware {
43 namespace keymaster {
44 namespace V4_0 {
45 namespace test {
46 
47 // libutils:
48 using android::OK;
49 using android::sp;
50 using android::status_t;
51 
52 // libhidl:
53 using android::hardware::hidl_vec;
54 using android::hardware::Return;
55 using android::hardware::Void;
56 
57 // IKeymaster:
58 using android::IServiceManager;
59 using android::hardware::hidl_string;
60 using android::hardware::keymaster::V4_0::AuthorizationSet;
61 using android::hardware::keymaster::V4_0::AuthorizationSetBuilder;
62 using android::hardware::keymaster::V4_0::BlockMode;
63 using android::hardware::keymaster::V4_0::ErrorCode;
64 using android::hardware::keymaster::V4_0::IKeymasterDevice;
65 using android::hardware::keymaster::V4_0::KeyCharacteristics;
66 using android::hardware::keymaster::V4_0::SecurityLevel;
67 
68 // Standard library:
69 using std::cerr;
70 using std::cout;
71 using std::endl;
72 using std::optional;
73 using std::string;
74 using std::unique_ptr;
75 using std::vector;
76 
77 class HidlBuf : public hidl_vec<uint8_t> {
78     typedef hidl_vec<uint8_t> super;
79 
80   public:
HidlBuf()81     HidlBuf() {}
HidlBuf(const super & other)82     HidlBuf(const super& other) : super(other) {}
HidlBuf(super && other)83     HidlBuf(super&& other) : super(std::move(other)) {}
HidlBuf(const std::string & other)84     explicit HidlBuf(const std::string& other) : HidlBuf() { *this = other; }
85 
operator =(const super & other)86     HidlBuf& operator=(const super& other) {
87         super::operator=(other);
88         return *this;
89     }
90 
operator =(super && other)91     HidlBuf& operator=(super&& other) {
92         super::operator=(std::move(other));
93         return *this;
94     }
95 
operator =(const string & other)96     HidlBuf& operator=(const string& other) {
97         resize(other.size());
98         std::copy(other.begin(), other.end(), begin());
99         return *this;
100     }
101 
to_string() const102     string to_string() const { return string(reinterpret_cast<const char*>(data()), size()); }
103 };
104 
105 #define SMALL_MESSAGE_SIZE 64
106 #define MEDIUM_MESSAGE_SIZE 1024
107 #define LARGE_MESSAGE_SIZE 131072
108 
109 class KeymasterWrapper {
110   private:
111     sp<IKeymasterDevice> keymaster_;
112     SecurityLevel securityLevel_;
113     hidl_string name_;
114     hidl_string author_;
115     HidlBuf key_blob_;
116     KeyCharacteristics key_characteristics_;
117     ErrorCode error_;
118     string key_transform_;
119     string keymaster_name_;
120     uint32_t os_version_;
121     uint32_t os_patch_level_;
122     std::vector<string> message_cache_;
123 
GenerateKey(const AuthorizationSet & authSet)124     bool GenerateKey(const AuthorizationSet& authSet) {
125         return (keymaster_
126                         ->generateKey(
127                                 authSet.hidl_data(),
128                                 [&](ErrorCode hidl_error, const hidl_vec<uint8_t>& hidl_key_blob,
129                                     const KeyCharacteristics& hidl_key_characteristics) {
130                                     error_ = hidl_error;
131                                     key_blob_ = hidl_key_blob;
132                                     key_characteristics_ = std::move(hidl_key_characteristics);
133                                 })
134                         .isOk() &&
135                 error_ == ErrorCode::OK);
136     }
137 
GenerateKey(Algorithm algorithm,int keySize,Digest digest=Digest::NONE,PaddingMode padding=PaddingMode::NONE,optional<BlockMode> blockMode={})138     bool GenerateKey(Algorithm algorithm, int keySize, Digest digest = Digest::NONE,
139                      PaddingMode padding = PaddingMode::NONE, optional<BlockMode> blockMode = {}) {
140         AuthorizationSetBuilder authSet = AuthorizationSetBuilder()
141                                                   .Authorization(TAG_NO_AUTH_REQUIRED)
142                                                   .Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT)
143                                                   .Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT)
144                                                   .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
145                                                   .Authorization(TAG_PURPOSE, KeyPurpose::VERIFY)
146                                                   .Authorization(TAG_KEY_SIZE, keySize)
147                                                   .Authorization(TAG_ALGORITHM, algorithm)
148                                                   .Digest(digest)
149                                                   .Authorization(TAG_MIN_MAC_LENGTH, 128)
150                                                   .Padding(padding);
151         if (blockMode) {
152             authSet.BlockMode(*blockMode);
153         }
154         if (algorithm == Algorithm::RSA) {
155             authSet.Authorization(TAG_RSA_PUBLIC_EXPONENT, 65537U);
156         }
157         return GenerateKey(authSet);
158     }
159 
KeymasterWrapper(const sp<IKeymasterDevice> keymaster)160     KeymasterWrapper(const sp<IKeymasterDevice> keymaster) {
161         os_version_ = ::keymaster::GetOsVersion();
162         os_patch_level_ = ::keymaster::GetOsPatchlevel();
163         keymaster_ = keymaster;
164         keymaster_->getHardwareInfo([&](SecurityLevel securityLevel, const hidl_string& name,
165                                         const hidl_string& author) {
166             securityLevel_ = securityLevel;
167             name_ = name;
168             author_ = author;
169         });
170 
171         message_cache_.push_back(string(SMALL_MESSAGE_SIZE, 'x'));
172         message_cache_.push_back(string(MEDIUM_MESSAGE_SIZE, 'x'));
173         message_cache_.push_back(string(LARGE_MESSAGE_SIZE, 'x'));
174     }
175 
176   public:
newInstance(const std::string & keymaster_name)177     static KeymasterWrapper* newInstance(const std::string& keymaster_name) {
178         auto keymaster = IKeymasterDevice::getService(keymaster_name);
179         if (!keymaster) {
180             std::cerr << "Error: unable to find keymaster service named " << keymaster_name
181                       << std::endl;
182             return nullptr;
183         }
184         return new KeymasterWrapper(keymaster);
185     }
186 
GenerateKey(string transform,int keySize,bool sign=false)187     bool GenerateKey(string transform, int keySize, bool sign = false) {
188         if (transform == key_transform_) {
189             return true;
190         } else if (key_transform_ != "") {
191             // Deleting old key first
192             if (!DeleteKey()) {
193                 return false;
194             }
195         }
196         optional<Algorithm> algorithm = getAlgorithm(transform);
197         if (!algorithm) {
198             cerr << "Error: invalid algorithm " << transform << endl;
199             return false;
200         }
201         key_transform_ = transform;
202         return GenerateKey(*algorithm, keySize, getDigest(transform), getPadding(transform, sign),
203                            getBlockMode(transform));
204     }
205 
DeleteKey()206     bool DeleteKey() {
207         key_blob_ = HidlBuf();
208         key_transform_ = "";
209         return keymaster_->deleteKey(key_blob_).isOk();
210     }
211 
getOperationParams(string transform,bool sign=false)212     AuthorizationSet getOperationParams(string transform, bool sign = false) {
213         AuthorizationSetBuilder builder = AuthorizationSetBuilder()
214                                                   .Padding(getPadding(transform, sign))
215                                                   .Authorization(TAG_MAC_LENGTH, 128)
216                                                   .Digest(getDigest(transform));
217         optional<BlockMode> blockMode = getBlockMode(transform);
218         if (blockMode) {
219             builder.BlockMode(*blockMode);
220         }
221         return std::move(builder);
222     }
223 
EncryptBegin(AuthorizationSet & in_params,AuthorizationSet * out_params=new AuthorizationSet)224     optional<OperationHandle> EncryptBegin(AuthorizationSet& in_params,
225                                            AuthorizationSet* out_params = new AuthorizationSet) {
226         return Begin(KeyPurpose::ENCRYPT, in_params, out_params);
227     }
228 
DecryptBegin(AuthorizationSet & in_params,AuthorizationSet * out_params=new AuthorizationSet)229     optional<OperationHandle> DecryptBegin(AuthorizationSet& in_params,
230                                            AuthorizationSet* out_params = new AuthorizationSet) {
231         return Begin(KeyPurpose::DECRYPT, in_params, out_params);
232     }
233 
SignBegin(AuthorizationSet & in_params,AuthorizationSet * out_params=new AuthorizationSet)234     optional<OperationHandle> SignBegin(AuthorizationSet& in_params,
235                                         AuthorizationSet* out_params = new AuthorizationSet) {
236         return Begin(KeyPurpose::SIGN, in_params, out_params);
237     }
238 
VerifyBegin(AuthorizationSet & in_params,AuthorizationSet * out_params=new AuthorizationSet)239     optional<OperationHandle> VerifyBegin(AuthorizationSet& in_params,
240                                           AuthorizationSet* out_params = new AuthorizationSet) {
241         return Begin(KeyPurpose::VERIFY, in_params, out_params);
242     }
243 
Begin(KeyPurpose operation,const AuthorizationSet & in_params,AuthorizationSet * out_params)244     optional<OperationHandle> Begin(KeyPurpose operation, const AuthorizationSet& in_params,
245                                     AuthorizationSet* out_params) {
246         OperationHandle op_handle;
247         if (!keymaster_
248                      ->begin(operation, key_blob_, in_params.hidl_data(), HardwareAuthToken(),
249                              [&](ErrorCode hidl_error,
250                                  const hidl_vec<KeyParameter>& hidl_out_params,
251                                  uint64_t hidl_op_handle) {
252                                  error_ = hidl_error;
253                                  out_params->push_back(AuthorizationSet(hidl_out_params));
254                                  op_handle = hidl_op_handle;
255                              })
256                      .isOk() ||
257             error_ != ErrorCode::OK) {
258             keymaster_->abort(op_handle);
259             return {};
260         }
261         return op_handle;
262     }
263 
ProcessMessage(const OperationHandle & op_handle,const string & message,const AuthorizationSet & in_params,AuthorizationSet * out_params=new AuthorizationSet,const string & signature="")264     optional<string> ProcessMessage(const OperationHandle& op_handle, const string& message,
265                                     const AuthorizationSet& in_params,
266                                     AuthorizationSet* out_params = new AuthorizationSet,
267                                     const string& signature = "") {
268         static const int HIDL_BUFFER_LIMIT = 1 << 14;  // 16KB
269 
270         string output;
271         size_t input_consumed = 0;
272         while (message.length() - input_consumed > 0) {
273             if (!keymaster_
274                          ->update(op_handle, in_params.hidl_data(),
275                                   HidlBuf(message.substr(input_consumed, HIDL_BUFFER_LIMIT)),
276                                   HardwareAuthToken(), VerificationToken(),
277                                   [&](ErrorCode hidl_error, uint32_t hidl_input_consumed,
278                                       const hidl_vec<KeyParameter>& hidl_out_params,
279                                       const HidlBuf& hidl_output) {
280                                       error_ = hidl_error;
281                                       out_params->push_back(AuthorizationSet(hidl_out_params));
282                                       output.append(hidl_output.to_string());
283                                       input_consumed += hidl_input_consumed;
284                                   })
285                          .isOk() ||
286                 error_ != ErrorCode::OK) {
287                 keymaster_->abort(op_handle);
288                 return {};
289             }
290         }
291 
292         if (!keymaster_
293                      ->finish(op_handle, in_params.hidl_data(),
294                               HidlBuf(message.substr(input_consumed)), HidlBuf(signature),
295                               HardwareAuthToken(), VerificationToken(),
296                               [&](ErrorCode hidl_error,
297                                   const hidl_vec<KeyParameter>& hidl_out_params,
298                                   const HidlBuf& hidl_output) {
299                                   error_ = hidl_error;
300                                   out_params->push_back(AuthorizationSet(hidl_out_params));
301                                   output.append(hidl_output.to_string());
302                               })
303                      .isOk() ||
304             error_ != ErrorCode::OK) {
305             keymaster_->abort(op_handle);
306             return {};
307         }
308 
309         return output;
310     }
311 
getError()312     int getError() { return static_cast<int>(error_); }
313 
getHardwareName()314     const string getHardwareName() { return name_; }
315 
getSecurityLevel()316     SecurityLevel getSecurityLevel() { return securityLevel_; }
317 
GenerateMessage(int size)318     const string& GenerateMessage(int size) {
319         for (const string& message : message_cache_) {
320             if (message.size() == size) {
321                 return message;
322             }
323         }
324         string message = string(size, 'x');
325         message_cache_.push_back(message);
326         return std::move(message);
327     }
328 
getBlockMode(string transform)329     optional<BlockMode> getBlockMode(string transform) {
330         if (transform.find("/ECB") != string::npos) {
331             return BlockMode::ECB;
332         } else if (transform.find("/CBC") != string::npos) {
333             return BlockMode::CBC;
334         } else if (transform.find("/CTR") != string::npos) {
335             return BlockMode::CTR;
336         } else if (transform.find("/GCM") != string::npos) {
337             return BlockMode::GCM;
338         }
339         return {};
340     }
341 
getPadding(string transform,bool sign)342     PaddingMode getPadding(string transform, bool sign) {
343         if (transform.find("/PKCS7") != string::npos) {
344             return PaddingMode::PKCS7;
345         } else if (transform.find("/PSS") != string::npos) {
346             return PaddingMode::RSA_PSS;
347         } else if (transform.find("/OAEP") != string::npos) {
348             return PaddingMode::RSA_OAEP;
349         } else if (transform.find("/PKCS1") != string::npos) {
350             return sign ? PaddingMode::RSA_PKCS1_1_5_SIGN : PaddingMode::RSA_PKCS1_1_5_ENCRYPT;
351         } else if (sign && transform.find("RSA") != string::npos) {
352             // RSA defaults to PKCS1 for sign
353             return PaddingMode::RSA_PKCS1_1_5_SIGN;
354         }
355         return PaddingMode::NONE;
356     }
357 
getAlgorithm(string transform)358     optional<Algorithm> getAlgorithm(string transform) {
359         if (transform.find("AES") != string::npos) {
360             return Algorithm::AES;
361         } else if (transform.find("Hmac") != string::npos) {
362             return Algorithm::HMAC;
363         } else if (transform.find("DESede") != string::npos) {
364             return Algorithm::TRIPLE_DES;
365         } else if (transform.find("RSA") != string::npos) {
366             return Algorithm::RSA;
367         } else if (transform.find("EC") != string::npos) {
368             return Algorithm::EC;
369         }
370         cerr << "Can't find algorithm for " << transform << endl;
371         return {};
372     }
373 
getDigest(string transform)374     Digest getDigest(string transform) {
375         if (transform.find("MD5") != string::npos) {
376             return Digest::MD5;
377         } else if (transform.find("SHA1") != string::npos ||
378                    transform.find("SHA-1") != string::npos) {
379             return Digest::SHA1;
380         } else if (transform.find("SHA224") != string::npos) {
381             return Digest::SHA_2_224;
382         } else if (transform.find("SHA256") != string::npos) {
383             return Digest::SHA_2_256;
384         } else if (transform.find("SHA384") != string::npos) {
385             return Digest::SHA_2_384;
386         } else if (transform.find("SHA512") != string::npos) {
387             return Digest::SHA_2_512;
388         } else if (transform.find("RSA") != string::npos &&
389                    transform.find("OAEP") != string::npos) {
390             return Digest::SHA1;
391         }
392         return Digest::NONE;
393     }
394 };
395 
396 KeymasterWrapper* keymaster;
397 
settings(benchmark::internal::Benchmark * benchmark)398 static void settings(benchmark::internal::Benchmark* benchmark) {
399     benchmark->Unit(benchmark::kMillisecond);
400 }
401 
addDefaultLabel(benchmark::State & state)402 static void addDefaultLabel(benchmark::State& state) {
403     string secLevel;
404     switch (keymaster->getSecurityLevel()) {
405         case SecurityLevel::STRONGBOX:
406             secLevel = "STRONGBOX";
407             break;
408         case SecurityLevel::SOFTWARE:
409             secLevel = "SOFTWARE";
410             break;
411         case SecurityLevel::TRUSTED_ENVIRONMENT:
412             secLevel = "TEE";
413             break;
414     }
415     state.SetLabel("hardware_name:" + keymaster->getHardwareName() + " sec_level:" + secLevel);
416 }
417 
418 // clang-format off
419 #define BENCHMARK_KM(func, transform, keySize) \
420     BENCHMARK_CAPTURE(func, transform/keySize, #transform "/" #keySize, keySize)->Apply(settings);
421 #define BENCHMARK_KM_MSG(func, transform, keySize, msgSize)                                      \
422     BENCHMARK_CAPTURE(func, transform/keySize/msgSize, #transform "/" #keySize "/" #msgSize, \
423                       keySize, msgSize)                                                          \
424             ->Apply(settings);
425 
426 #define BENCHMARK_KM_ALL_MSGS(func, transform, keySize)             \
427     BENCHMARK_KM_MSG(func, transform, keySize, SMALL_MESSAGE_SIZE)  \
428     BENCHMARK_KM_MSG(func, transform, keySize, MEDIUM_MESSAGE_SIZE) \
429     BENCHMARK_KM_MSG(func, transform, keySize, LARGE_MESSAGE_SIZE)
430 
431 #define BENCHMARK_KM_CIPHER(transform, keySize, msgSize)   \
432     BENCHMARK_KM_MSG(encrypt, transform, keySize, msgSize) \
433     BENCHMARK_KM_MSG(decrypt, transform, keySize, msgSize)
434 
435 #define BENCHMARK_KM_CIPHER_ALL_MSGS(transform, keySize) \
436     BENCHMARK_KM_ALL_MSGS(encrypt, transform, keySize)   \
437     BENCHMARK_KM_ALL_MSGS(decrypt, transform, keySize)
438 
439 #define BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, keySize) \
440     BENCHMARK_KM_ALL_MSGS(sign, transform, keySize)         \
441     BENCHMARK_KM_ALL_MSGS(verify, transform, keySize)
442 // clang-format on
443 
444 /*
445  * ============= KeyGen TESTS ==================
446  */
keygen(benchmark::State & state,string transform,int keySize)447 static void keygen(benchmark::State& state, string transform, int keySize) {
448     addDefaultLabel(state);
449     for (auto _ : state) {
450         keymaster->GenerateKey(transform, keySize);
451         state.PauseTiming();
452         keymaster->DeleteKey();
453         state.ResumeTiming();
454     }
455 }
456 
457 BENCHMARK_KM(keygen, AES, 128);
458 BENCHMARK_KM(keygen, AES, 256);
459 
460 BENCHMARK_KM(keygen, RSA, 2048);
461 BENCHMARK_KM(keygen, RSA, 3072);
462 BENCHMARK_KM(keygen, RSA, 4096);
463 
464 BENCHMARK_KM(keygen, EC, 224);
465 BENCHMARK_KM(keygen, EC, 256);
466 BENCHMARK_KM(keygen, EC, 384);
467 BENCHMARK_KM(keygen, EC, 521);
468 
469 BENCHMARK_KM(keygen, DESede, 168);
470 
471 BENCHMARK_KM(keygen, Hmac, 64);
472 BENCHMARK_KM(keygen, Hmac, 128);
473 BENCHMARK_KM(keygen, Hmac, 256);
474 BENCHMARK_KM(keygen, Hmac, 512);
475 BENCHMARK_KM(keygen, Hmac, 1024);
476 BENCHMARK_KM(keygen, Hmac, 2048);
477 BENCHMARK_KM(keygen, Hmac, 4096);
478 BENCHMARK_KM(keygen, Hmac, 8192);
479 
480 /*
481  * ============= SIGNATURE TESTS ==================
482  */
483 
sign(benchmark::State & state,string transform,int keySize,int msgSize)484 static void sign(benchmark::State& state, string transform, int keySize, int msgSize) {
485     addDefaultLabel(state);
486     if (!keymaster->GenerateKey(transform, keySize, true)) {
487         state.SkipWithError(
488                 ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
489         return;
490     }
491     auto params = keymaster->getOperationParams(transform, true);
492     string message = keymaster->GenerateMessage(msgSize);
493 
494     for (auto _ : state) {
495         state.PauseTiming();
496         auto opHandle = keymaster->SignBegin(params);
497         if (!opHandle) {
498             state.SkipWithError(
499                     ("Error beginning sign, " + std::to_string(keymaster->getError())).c_str());
500             return;
501         }
502         state.ResumeTiming();
503         if (!keymaster->ProcessMessage(*opHandle, message, params)) {
504             state.SkipWithError(("Sign error, " + std::to_string(keymaster->getError())).c_str());
505             break;
506         }
507     }
508 }
509 
verify(benchmark::State & state,string transform,int keySize,int msgSize)510 static void verify(benchmark::State& state, string transform, int keySize, int msgSize) {
511     addDefaultLabel(state);
512     if (!keymaster->GenerateKey(transform, keySize, true)) {
513         state.SkipWithError(
514                 ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
515         return;
516     }
517     AuthorizationSet out_params;
518     AuthorizationSet in_params = keymaster->getOperationParams(transform, true);
519     string message = keymaster->GenerateMessage(msgSize);
520     auto opHandle = keymaster->SignBegin(in_params, &out_params);
521     if (!opHandle) {
522         state.SkipWithError(
523                 ("Error beginning sign, " + std::to_string(keymaster->getError())).c_str());
524         return;
525     }
526     optional<string> signature =
527             keymaster->ProcessMessage(*opHandle, message, in_params, &out_params);
528     if (!signature) {
529         state.SkipWithError(("Sign error, " + std::to_string(keymaster->getError())).c_str());
530         return;
531     }
532     in_params.push_back(out_params);
533     for (auto _ : state) {
534         state.PauseTiming();
535         opHandle = keymaster->VerifyBegin(in_params);
536         if (!opHandle) {
537             state.SkipWithError(
538                     ("Verify begin error, " + std::to_string(keymaster->getError())).c_str());
539             return;
540         }
541         state.ResumeTiming();
542         if (!keymaster->ProcessMessage(*opHandle, message, in_params, &out_params, *signature)) {
543             state.SkipWithError(("Verify error, " + std::to_string(keymaster->getError())).c_str());
544             break;
545         }
546     }
547 }
548 
549 // clang-format off
550 #define BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(transform) \
551     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 64)      \
552     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 128)     \
553     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256)     \
554     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 512)     \
555     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 1024)    \
556     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2024)    \
557     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096)    \
558     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 8192)
559 
560 BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA1)
561 BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA256)
562 BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA224)
563 BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA256)
564 BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA384)
565 BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA512)
566 
567 #define BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(transform) \
568     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 224)      \
569     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256)      \
570     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 384)      \
571     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 521)
572 
573 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(NONEwithECDSA);
574 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA1withECDSA);
575 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA224withECDSA);
576 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA256withECDSA);
577 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA384withECDSA);
578 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA512withECDSA);
579 
580 #define BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(transform) \
581     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2048)   \
582     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 3072)   \
583     BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096)
584 
585 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA);
586 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA);
587 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA);
588 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA);
589 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA);
590 
591 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA/PSS);
592 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA/PSS);
593 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA/PSS);
594 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA/PSS);
595 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA/PSS);
596 // clang-format on
597 
598 /*
599  * ============= CIPHER TESTS ==================
600  */
601 
encrypt(benchmark::State & state,string transform,int keySize,int msgSize)602 static void encrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
603     addDefaultLabel(state);
604     if (!keymaster->GenerateKey(transform, keySize)) {
605         state.SkipWithError(
606                 ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
607         return;
608     }
609     auto params = keymaster->getOperationParams(transform);
610     string message = keymaster->GenerateMessage(msgSize);
611 
612     for (auto _ : state) {
613         state.PauseTiming();
614         auto opHandle = keymaster->EncryptBegin(params);
615         if (!opHandle) {
616             state.SkipWithError(
617                     ("Encryption begin error, " + std::to_string(keymaster->getError())).c_str());
618             return;
619         }
620         state.ResumeTiming();
621         if (!keymaster->ProcessMessage(*opHandle, message, params)) {
622             state.SkipWithError(
623                     ("Encryption error, " + std::to_string(keymaster->getError())).c_str());
624             break;
625         }
626     }
627 }
628 
decrypt(benchmark::State & state,string transform,int keySize,int msgSize)629 static void decrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
630     addDefaultLabel(state);
631     if (!keymaster->GenerateKey(transform, keySize)) {
632         state.SkipWithError(
633                 ("Key generation error, " + std::to_string(keymaster->getError())).c_str());
634         return;
635     }
636     AuthorizationSet out_params;
637     AuthorizationSet in_params = keymaster->getOperationParams(transform);
638     string message = keymaster->GenerateMessage(msgSize);
639     auto opHandle = keymaster->EncryptBegin(in_params, &out_params);
640     if (!opHandle) {
641         state.SkipWithError(
642                 ("Encryption begin error, " + std::to_string(keymaster->getError())).c_str());
643         return;
644     }
645     auto encryptedMessage = keymaster->ProcessMessage(*opHandle, message, in_params, &out_params);
646     if (!encryptedMessage) {
647         state.SkipWithError(("Encryption error, " + std::to_string(keymaster->getError())).c_str());
648         return;
649     }
650     in_params.push_back(out_params);
651     for (auto _ : state) {
652         state.PauseTiming();
653         opHandle = keymaster->DecryptBegin(in_params);
654         if (!opHandle) {
655             state.SkipWithError(
656                     ("Decryption begin error, " + std::to_string(keymaster->getError())).c_str());
657             return;
658         }
659         state.ResumeTiming();
660         if (!keymaster->ProcessMessage(*opHandle, *encryptedMessage, in_params)) {
661             state.SkipWithError(
662                     ("Decryption error, " + std::to_string(keymaster->getError())).c_str());
663             break;
664         }
665     }
666 }
667 
668 // clang-format off
669 // AES
670 #define BENCHMARK_KM_CIPHER_ALL_AES_KEYS(transform) \
671     BENCHMARK_KM_CIPHER_ALL_MSGS(transform, 128)    \
672     BENCHMARK_KM_CIPHER_ALL_MSGS(transform, 256)
673 
674 BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CBC/NoPadding);
675 BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CBC/PKCS7Padding);
676 BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/CTR/NoPadding);
677 BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/ECB/NoPadding);
678 BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/ECB/PKCS7Padding);
679 BENCHMARK_KM_CIPHER_ALL_AES_KEYS(AES/GCM/NoPadding);
680 
681 // Triple DES
682 BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/CBC/NoPadding, 168);
683 BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/CBC/PKCS7Padding, 168);
684 BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/NoPadding, 168);
685 BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/PKCS7Padding, 168);
686 
687 #define BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(transform, msgSize) \
688     BENCHMARK_KM_CIPHER(transform, 2048, msgSize)            \
689     BENCHMARK_KM_CIPHER(transform, 3072, msgSize)            \
690     BENCHMARK_KM_CIPHER(transform, 4096, msgSize)
691 
692 BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/NoPadding, SMALL_MESSAGE_SIZE);
693 BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/PKCS1Padding, SMALL_MESSAGE_SIZE);
694 BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/OAEPPadding, SMALL_MESSAGE_SIZE);
695 // clang-format on
696 
697 }  // namespace test
698 }  // namespace V4_0
699 }  // namespace keymaster
700 }  // namespace hardware
701 }  // namespace android
702 
main(int argc,char ** argv)703 int main(int argc, char** argv) {
704     ::benchmark::Initialize(&argc, argv);
705     base::CommandLine::Init(argc, argv);
706     base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
707     auto service_name = command_line->GetSwitchValueASCII("service_name");
708     if (service_name.empty()) {
709         service_name = "default";
710     }
711     android::hardware::keymaster::V4_0::test::keymaster =
712             android::hardware::keymaster::V4_0::test::KeymasterWrapper::newInstance(service_name);
713     if (!android::hardware::keymaster::V4_0::test::keymaster) {
714         return 1;
715     }
716     ::benchmark::RunSpecifiedBenchmarks();
717 }