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 }