xref: /aosp_15_r20/system/security/keystore/keystore_cli_v2.cpp (revision e1997b9af69e3155ead6e072d106a0077849ffba)
1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <chrono>
16 #include <cstdio>
17 #include <future>
18 #include <iomanip>
19 #include <iostream>
20 #include <memory>
21 #include <string>
22 #include <variant>
23 #include <vector>
24 
25 #include <android-base/strings.h>
26 
27 #include <base/command_line.h>
28 #include <base/files/file_util.h>
29 #include <base/strings/string_number_conversions.h>
30 #include <base/strings/string_split.h>
31 
32 #include <aidl/android/security/apc/BnConfirmationCallback.h>
33 #include <aidl/android/security/apc/IProtectedConfirmation.h>
34 #include <aidl/android/system/keystore2/IKeystoreService.h>
35 #include <aidl/android/system/keystore2/ResponseCode.h>
36 #include <android/binder_manager.h>
37 #include <android/binder_process.h>
38 #include <keymint_support/authorization_set.h>
39 
40 #include <openssl/evp.h>
41 #include <openssl/mem.h>
42 #include <openssl/x509.h>
43 
44 #include "keystore_client.pb.h"
45 
46 namespace apc = ::aidl::android::security::apc;
47 namespace keymint = ::aidl::android::hardware::security::keymint;
48 namespace ks2 = ::aidl::android::system::keystore2;
49 
50 using base::CommandLine;
51 using keystore::EncryptedData;
52 
53 namespace {
54 
55 struct TestCase {
56     std::string name;
57     bool required_for_brillo_pts;
58     keymint::AuthorizationSet parameters;
59 };
60 
61 constexpr const char keystore2_service_name[] = "android.system.keystore2.IKeystoreService/default";
62 
string_replace_all(std::string str,const std::string & from,const std::string & to)63 std::string string_replace_all(std::string str, const std::string& from,
64                                       const std::string& to) {
65     size_t start = 0;
66     while ((start = str.find(from, start)) != std::string::npos) {
67         str.replace(start, from.length(), to);
68         start += to.length();
69     }
70     return str;
71 }
72 
unwrapError(const ndk::ScopedAStatus & status)73 int unwrapError(const ndk::ScopedAStatus& status) {
74     if (status.isOk()) return 0;
75     if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) {
76         return status.getServiceSpecificError();
77     } else {
78         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
79     }
80 }
81 
keyDescriptor(const std::string & alias)82 ks2::KeyDescriptor keyDescriptor(const std::string& alias) {
83     return {
84         .domain = ks2::Domain::APP,
85         .nspace = -1,  // ignored - should be -1.
86         .alias = alias,
87         .blob = {},
88     };
89 }
90 
PrintUsageAndExit()91 void PrintUsageAndExit() {
92     printf("Usage: keystore_client_v2 <command> [options]\n");
93     printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>] [--test_for_0_3]\n"
94            "          list-brillo-tests\n"
95            "          add-entropy --input=<entropy> [--seclevel=software|strongbox|tee(default)]\n"
96            "          generate --name=<key_name> [--seclevel=software|strongbox|tee(default)]\n"
97            "          get-chars --name=<key_name>\n"
98            "          export --name=<key_name>\n"
99            "          delete --name=<key_name>\n"
100            "          delete-all\n"
101            "          exists --name=<key_name>\n"
102            "          list [--prefix=<key_name_prefix>]\n"
103            "          list-apps-with-keys\n"
104            "          sign-verify --name=<key_name>\n"
105            "          [en|de]crypt --name=<key_name> --in=<file> --out=<file>\n"
106            "                       [--seclevel=software|strongbox|tee(default)]\n"
107            "          confirmation --prompt_text=<PromptText> --extra_data=<hex>\n"
108            "                       --locale=<locale> [--ui_options=<list_of_ints>]\n"
109            "                       --cancel_after=<seconds>\n");
110     exit(1);
111 }
112 
CreateKeystoreInstance()113 std::shared_ptr<ks2::IKeystoreService> CreateKeystoreInstance() {
114     ::ndk::SpAIBinder keystoreBinder(AServiceManager_checkService(keystore2_service_name));
115     auto result = ks2::IKeystoreService::fromBinder(keystoreBinder);
116     if (result) return result;
117     std::cerr << "Unable to connect to Keystore.";
118     exit(-1);
119 }
120 
121 std::shared_ptr<ks2::IKeystoreSecurityLevel>
GetSecurityLevelInterface(std::shared_ptr<ks2::IKeystoreService> keystore,keymint::SecurityLevel securitylevel)122 GetSecurityLevelInterface(std::shared_ptr<ks2::IKeystoreService> keystore,
123                           keymint::SecurityLevel securitylevel) {
124     std::shared_ptr<ks2::IKeystoreSecurityLevel> sec_level;
125     auto rc = keystore->getSecurityLevel(securitylevel, &sec_level);
126     if (rc.isOk()) return sec_level;
127     std::cerr << "Unable to get security level interface from Keystore: " << rc.getDescription();
128     exit(-1);
129 }
130 
isHardwareEnforced(const ks2::Authorization & a)131 bool isHardwareEnforced(const ks2::Authorization& a) {
132     return !(a.securityLevel == keymint::SecurityLevel::SOFTWARE ||
133              a.securityLevel == keymint::SecurityLevel::KEYSTORE);
134 }
135 
PrintTags(const std::vector<ks2::Authorization> & characteristics,bool printHardwareEnforced)136 void PrintTags(const std::vector<ks2::Authorization>& characteristics, bool printHardwareEnforced) {
137     for (const auto& a : characteristics) {
138         if (isHardwareEnforced(a) == printHardwareEnforced) {
139             std::cout << toString(a.keyParameter.tag) << "\n";
140         }
141     }
142 }
143 
PrintKeyCharacteristics(const std::vector<ks2::Authorization> & characteristics)144 void PrintKeyCharacteristics(const std::vector<ks2::Authorization>& characteristics) {
145     printf("Hardware:\n");
146     PrintTags(characteristics, true /* printHardwareEnforced */);
147     printf("Software:\n");
148     PrintTags(characteristics, false /* printHardwareEnforced */);
149 }
150 
151 const char kEncryptSuffix[] = "_ENC";
152 const char kAuthenticateSuffix[] = "_AUTH";
153 constexpr uint32_t kAESKeySize = 256;      // bits
154 constexpr uint32_t kHMACKeySize = 256;     // bits
155 constexpr uint32_t kHMACOutputSize = 256;  // bits
156 
verifyEncryptionKeyAttributes(const std::vector<ks2::Authorization> authorizations)157 bool verifyEncryptionKeyAttributes(const std::vector<ks2::Authorization> authorizations) {
158     bool verified = true;
159     verified =
160         verified &&
161         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
162             return a.keyParameter.tag == keymint::Tag::ALGORITHM &&
163                    a.keyParameter.value ==
164                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::algorithm>(
165                            keymint::Algorithm::AES);
166         });
167 
168     verified =
169         verified &&
170         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
171             return a.keyParameter.tag == keymint::Tag::KEY_SIZE &&
172                    a.keyParameter.value ==
173                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
174                            kAESKeySize);
175         });
176 
177     verified =
178         verified &&
179         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
180             return a.keyParameter.tag == keymint::Tag::BLOCK_MODE &&
181                    a.keyParameter.value ==
182                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::blockMode>(
183                            keymint::BlockMode::CBC);
184         });
185 
186     verified =
187         verified &&
188         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
189             return a.keyParameter.tag == keymint::Tag::PADDING &&
190                    a.keyParameter.value ==
191                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::paddingMode>(
192                            keymint::PaddingMode::PKCS7);
193         });
194 
195     return verified;
196 }
197 
verifyAuthenticationKeyAttributes(const std::vector<ks2::Authorization> authorizations)198 bool verifyAuthenticationKeyAttributes(const std::vector<ks2::Authorization> authorizations) {
199     bool verified = true;
200     verified =
201         verified &&
202         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
203             return a.keyParameter.tag == keymint::Tag::ALGORITHM &&
204                    a.keyParameter.value ==
205                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::algorithm>(
206                            keymint::Algorithm::HMAC);
207         });
208 
209     verified =
210         verified &&
211         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
212             return a.keyParameter.tag == keymint::Tag::KEY_SIZE &&
213                    a.keyParameter.value ==
214                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
215                            kHMACKeySize);
216         });
217 
218     verified =
219         verified &&
220         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
221             return a.keyParameter.tag == keymint::Tag::MIN_MAC_LENGTH &&
222                    a.keyParameter.value ==
223                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::integer>(
224                            kHMACOutputSize);
225         });
226 
227     verified =
228         verified &&
229         std::any_of(authorizations.begin(), authorizations.end(), [&](const ks2::Authorization& a) {
230             return a.keyParameter.tag == keymint::Tag::DIGEST &&
231                    a.keyParameter.value ==
232                        keymint::KeyParameterValue::make<keymint::KeyParameterValue::digest>(
233                            keymint::Digest::SHA_2_256);
234         });
235     return verified;
236 }
237 
238 std::variant<int, ks2::KeyEntryResponse>
loadOrCreateAndVerifyEncryptionKey(const std::string & name,keymint::SecurityLevel securityLevel,bool create)239 loadOrCreateAndVerifyEncryptionKey(const std::string& name, keymint::SecurityLevel securityLevel,
240                                    bool create) {
241     auto keystore = CreateKeystoreInstance();
242 
243     ks2::KeyEntryResponse keyEntryResponse;
244 
245     bool foundKey = true;
246     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
247     if (!rc.isOk()) {
248         auto error = unwrapError(rc);
249         if (ks2::ResponseCode(error) == ks2::ResponseCode::KEY_NOT_FOUND && create) {
250             foundKey = false;
251         } else {
252             std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
253             return error;
254         }
255     }
256 
257     if (!foundKey) {
258         auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
259         auto params = keymint::AuthorizationSetBuilder()
260                           .AesEncryptionKey(kAESKeySize)
261                           .Padding(keymint::PaddingMode::PKCS7)
262                           .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC)
263                           .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
264 
265         ks2::KeyMetadata keyMetadata;
266 
267         rc = sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */,
268                                     params.vector_data(), 0 /* flags */, {} /* entropy */,
269                                     &keyMetadata);
270         if (!rc.isOk()) {
271             std::cerr << "Failed to generate key: " << rc.getDescription() << std::endl;
272             return unwrapError(rc);
273         }
274 
275         rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
276         if (!rc.isOk()) {
277             std::cerr << "Failed to get key entry (second try): " << rc.getDescription()
278                       << std::endl;
279             return unwrapError(rc);
280         }
281     }
282 
283     if (!verifyEncryptionKeyAttributes(keyEntryResponse.metadata.authorizations)) {
284         std::cerr << "Key has wrong set of parameters." << std::endl;
285         return static_cast<int>(ks2::ResponseCode::INVALID_ARGUMENT);
286     }
287 
288     return keyEntryResponse;
289 }
290 
291 std::variant<int, ks2::KeyEntryResponse>
loadOrCreateAndVerifyAuthenticationKey(const std::string & name,keymint::SecurityLevel securityLevel,bool create)292 loadOrCreateAndVerifyAuthenticationKey(const std::string& name,
293                                        keymint::SecurityLevel securityLevel, bool create) {
294     auto keystore = CreateKeystoreInstance();
295 
296     ks2::KeyEntryResponse keyEntryResponse;
297 
298     bool foundKey = true;
299     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
300     if (!rc.isOk()) {
301         auto error = unwrapError(rc);
302         if (ks2::ResponseCode(error) == ks2::ResponseCode::KEY_NOT_FOUND && create) {
303             foundKey = false;
304         } else {
305             std::cerr << "Failed to get HMAC key entry: " << rc.getDescription() << std::endl;
306             return error;
307         }
308     }
309 
310     if (!foundKey) {
311         auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
312         auto params = keymint::AuthorizationSetBuilder()
313                           .HmacKey(kHMACKeySize)
314                           .Digest(keymint::Digest::SHA_2_256)
315                           .Authorization(keymint::TAG_MIN_MAC_LENGTH, kHMACOutputSize)
316                           .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
317 
318         ks2::KeyMetadata keyMetadata;
319 
320         rc = sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */,
321                                     params.vector_data(), 0 /* flags */, {} /* entropy */,
322                                     &keyMetadata);
323         if (!rc.isOk()) {
324             std::cerr << "Failed to generate HMAC key: " << rc.getDescription() << std::endl;
325             return unwrapError(rc);
326         }
327 
328         rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
329         if (!rc.isOk()) {
330             std::cerr << "Failed to get HMAC key entry (second try): " << rc.getDescription()
331                       << std::endl;
332             return unwrapError(rc);
333         }
334     }
335 
336     if (!verifyAuthenticationKeyAttributes(keyEntryResponse.metadata.authorizations)) {
337         std::cerr << "Key has wrong set of parameters." << std::endl;
338         return static_cast<int>(ks2::ResponseCode::INVALID_ARGUMENT);
339     }
340 
341     return keyEntryResponse;
342 }
343 
344 std::variant<int, std::vector<uint8_t>>
encryptWithAuthentication(const std::string & name,const std::vector<uint8_t> & data,keymint::SecurityLevel securityLevel)345 encryptWithAuthentication(const std::string& name, const std::vector<uint8_t>& data,
346                           keymint::SecurityLevel securityLevel) {
347     // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
348     // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
349     // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
350     // because hardware support for GCM is not mandatory for all Brillo devices.
351     std::string encryption_key_name = name + kEncryptSuffix;
352     auto encryption_key_result =
353         loadOrCreateAndVerifyEncryptionKey(encryption_key_name, securityLevel, true /* create */);
354     if (auto error = std::get_if<int>(&encryption_key_result)) {
355         return *error;
356     }
357     auto encryption_key = std::get<ks2::KeyEntryResponse>(encryption_key_result);
358 
359     std::string authentication_key_name = name + kAuthenticateSuffix;
360     auto authentication_key_result = loadOrCreateAndVerifyAuthenticationKey(
361         authentication_key_name, securityLevel, true /* create */);
362     if (auto error = std::get_if<int>(&authentication_key_result)) {
363         return *error;
364     }
365     auto authentication_key = std::get<ks2::KeyEntryResponse>(authentication_key_result);
366 
367     ks2::CreateOperationResponse encOperationResponse;
368     auto encrypt_params = keymint::AuthorizationSetBuilder()
369                               .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::ENCRYPT)
370                               .Padding(keymint::PaddingMode::PKCS7)
371                               .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
372 
373     auto rc = encryption_key.iSecurityLevel->createOperation(
374         encryption_key.metadata.key, encrypt_params.vector_data(), false /* forced */,
375         &encOperationResponse);
376     if (!rc.isOk()) {
377         std::cerr << "Failed to begin encryption operation: " << rc.getDescription() << std::endl;
378         return unwrapError(rc);
379     }
380 
381     std::optional<std::vector<uint8_t>> optCiphertext;
382 
383     rc = encOperationResponse.iOperation->finish(data, {}, &optCiphertext);
384     if (!rc.isOk()) {
385         std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
386         return unwrapError(rc);
387     }
388 
389     std::vector<uint8_t> initVector;
390     if (auto params = encOperationResponse.parameters) {
391         for (auto& p : params->keyParameter) {
392             if (auto iv = keymint::authorizationValue(keymint::TAG_NONCE, p)) {
393                 initVector = std::move(iv->get());
394                 break;
395             }
396         }
397         if (initVector.empty()) {
398             std::cerr << "Encryption operation did not return an IV." << std::endl;
399             return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
400         }
401     }
402 
403     if (!optCiphertext) {
404         std::cerr << "Encryption succeeded but no ciphertext returned." << std::endl;
405         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
406     }
407 
408     auto ciphertext = std::move(*optCiphertext);
409     auto toBeSigned = initVector;
410     toBeSigned.insert(toBeSigned.end(), ciphertext.begin(), ciphertext.end());
411 
412     ks2::CreateOperationResponse signOperationResponse;
413     auto sign_params = keymint::AuthorizationSetBuilder()
414                            .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::SIGN)
415                            .Digest(keymint::Digest::SHA_2_256)
416                            .Authorization(keymint::TAG_MAC_LENGTH, kHMACOutputSize);
417 
418     rc = authentication_key.iSecurityLevel->createOperation(
419         authentication_key.metadata.key, sign_params.vector_data(), false /* forced */,
420         &signOperationResponse);
421     if (!rc.isOk()) {
422         std::cerr << "Failed to begin signing operation: " << rc.getDescription() << std::endl;
423         return unwrapError(rc);
424     }
425 
426     std::optional<std::vector<uint8_t>> optMac;
427 
428     rc = signOperationResponse.iOperation->finish(toBeSigned, {}, &optMac);
429     if (!rc.isOk()) {
430         std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
431         return unwrapError(rc);
432     }
433 
434     if (!optMac) {
435         std::cerr << "Signing succeeded but no MAC returned." << std::endl;
436         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
437     }
438 
439     auto mac = std::move(*optMac);
440 
441     EncryptedData protobuf;
442     protobuf.set_init_vector(initVector.data(), initVector.size());
443     protobuf.set_authentication_data(mac.data(), mac.size());
444     protobuf.set_encrypted_data(ciphertext.data(), ciphertext.size());
445     std::string resultString;
446     if (!protobuf.SerializeToString(&resultString)) {
447         std::cerr << "Encrypt: Failed to serialize EncryptedData protobuf.";
448         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
449     }
450 
451     std::vector<uint8_t> result(reinterpret_cast<const uint8_t*>(resultString.data()),
452                                 reinterpret_cast<const uint8_t*>(resultString.data()) +
453                                     resultString.size());
454     return result;
455 }
456 
457 std::variant<int, std::vector<uint8_t>>
decryptWithAuthentication(const std::string & name,const std::vector<uint8_t> & data)458 decryptWithAuthentication(const std::string& name, const std::vector<uint8_t>& data) {
459 
460     // Decode encrypted data
461     EncryptedData protobuf;
462     if (!protobuf.ParseFromArray(data.data(), data.size())) {
463         std::cerr << "Decrypt: Failed to parse EncryptedData protobuf." << std::endl;
464         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
465     }
466 
467     // Load encryption and authentication keys.
468     std::string encryption_key_name = name + kEncryptSuffix;
469     auto encryption_key_result = loadOrCreateAndVerifyEncryptionKey(
470         encryption_key_name, keymint::SecurityLevel::KEYSTORE /* ignored */, false /* create */);
471     if (auto error = std::get_if<int>(&encryption_key_result)) {
472         return *error;
473     }
474     auto encryption_key = std::get<ks2::KeyEntryResponse>(encryption_key_result);
475 
476     std::string authentication_key_name = name + kAuthenticateSuffix;
477     auto authentication_key_result = loadOrCreateAndVerifyAuthenticationKey(
478         authentication_key_name, keymint::SecurityLevel::KEYSTORE /* ignored */,
479         false /* create */);
480     if (auto error = std::get_if<int>(&authentication_key_result)) {
481         return *error;
482     }
483     auto authentication_key = std::get<ks2::KeyEntryResponse>(authentication_key_result);
484 
485     // Begin authentication operation
486     ks2::CreateOperationResponse signOperationResponse;
487     auto sign_params = keymint::AuthorizationSetBuilder()
488                            .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::VERIFY)
489                            .Digest(keymint::Digest::SHA_2_256)
490                            .Authorization(keymint::TAG_MAC_LENGTH, kHMACOutputSize);
491 
492     auto rc = authentication_key.iSecurityLevel->createOperation(
493         authentication_key.metadata.key, sign_params.vector_data(), false /* forced */,
494         &signOperationResponse);
495     if (!rc.isOk()) {
496         std::cerr << "Failed to begin verify operation: " << rc.getDescription() << std::endl;
497         return unwrapError(rc);
498     }
499 
500     const uint8_t* p = reinterpret_cast<const uint8_t*>(protobuf.init_vector().data());
501     std::vector<uint8_t> toBeVerified(p, p + protobuf.init_vector().size());
502 
503     p = reinterpret_cast<const uint8_t*>(protobuf.encrypted_data().data());
504     toBeVerified.insert(toBeVerified.end(), p, p + protobuf.encrypted_data().size());
505 
506     p = reinterpret_cast<const uint8_t*>(protobuf.authentication_data().data());
507     std::vector<uint8_t> signature(p, p + protobuf.authentication_data().size());
508 
509     std::optional<std::vector<uint8_t>> optOut;
510     rc = signOperationResponse.iOperation->finish(toBeVerified, signature, &optOut);
511     if (!rc.isOk()) {
512         std::cerr << "Decrypt: HMAC verification failed: " << rc.getDescription() << std::endl;
513         return unwrapError(rc);
514     }
515 
516     // Begin decryption operation
517     ks2::CreateOperationResponse encOperationResponse;
518     auto encrypt_params = keymint::AuthorizationSetBuilder()
519                               .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::DECRYPT)
520                               .Authorization(keymint::TAG_NONCE, protobuf.init_vector().data(),
521                                              protobuf.init_vector().size())
522                               .Padding(keymint::PaddingMode::PKCS7)
523                               .Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
524 
525     rc = encryption_key.iSecurityLevel->createOperation(encryption_key.metadata.key,
526                                                         encrypt_params.vector_data(),
527                                                         false /* forced */, &encOperationResponse);
528     if (!rc.isOk()) {
529         std::cerr << "Failed to begin encryption operation: " << rc.getDescription() << std::endl;
530         return unwrapError(rc);
531     }
532 
533     std::optional<std::vector<uint8_t>> optPlaintext;
534 
535     p = reinterpret_cast<const uint8_t*>(protobuf.encrypted_data().data());
536     std::vector<uint8_t> cyphertext(p, p + protobuf.encrypted_data().size());
537 
538     rc = encOperationResponse.iOperation->finish(cyphertext, {}, &optPlaintext);
539     if (!rc.isOk()) {
540         std::cerr << "Failed to finish encryption operation: " << rc.getDescription() << std::endl;
541         return unwrapError(rc);
542     }
543 
544     if (!optPlaintext) {
545         std::cerr << "Decryption succeeded but no plaintext returned." << std::endl;
546         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
547     }
548 
549     return *optPlaintext;
550 }
551 
TestKey(const std::string & name,bool required,const std::vector<keymint::KeyParameter> & parameters)552 bool TestKey(const std::string& name, bool required,
553              const std::vector<keymint::KeyParameter>& parameters) {
554     auto keystore = CreateKeystoreInstance();
555     auto sec_level =
556         GetSecurityLevelInterface(keystore, keymint::SecurityLevel::TRUSTED_ENVIRONMENT);
557 
558     ks2::KeyDescriptor keyDescriptor = {
559         .domain = ks2::Domain::APP,
560         .nspace = -1,
561         .alias = "tmp",
562         .blob = {},
563     };
564 
565     ks2::KeyMetadata keyMetadata;
566 
567     auto rc = sec_level->generateKey(keyDescriptor, {} /* attestationKey */, parameters,
568                                      0 /* flags */, {} /* entropy */, &keyMetadata);
569     const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
570     if (!rc.isOk()) {
571         LOG(ERROR) << "Failed to generate key: " << rc.getDescription();
572         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
573         return false;
574     }
575 
576     rc = keystore->deleteKey(keyDescriptor);
577     if (!rc.isOk()) {
578         LOG(ERROR) << "Failed to delete key: " << rc.getDescription();
579         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
580         return false;
581     }
582     printf("===============================================================\n");
583     printf("%s Key Characteristics:\n", name.c_str());
584     PrintKeyCharacteristics(keyMetadata.authorizations);
585     bool hardware_backed = std::any_of(keyMetadata.authorizations.begin(),
586                                        keyMetadata.authorizations.end(), isHardwareEnforced);
587     if (std::any_of(keyMetadata.authorizations.begin(), keyMetadata.authorizations.end(),
588                     [&](const auto& a) {
589                         return !isHardwareEnforced(a) &&
590                                (a.keyParameter.tag == keymint::Tag::ALGORITHM ||
591                                 a.keyParameter.tag == keymint::Tag::KEY_SIZE ||
592                                 a.keyParameter.tag == keymint::Tag::RSA_PUBLIC_EXPONENT);
593                     })) {
594         VLOG(1) << "Hardware-backed key but required characteristics enforced in software.";
595         hardware_backed = false;
596     }
597     const char kBoldRedFail[] = "\033[1;31mFAIL\033[0m";
598     const char kBoldGreenPass[] = "\033[1;32mPASS\033[0m";
599     const char kBoldYellowWarn[] = "\033[1;33mWARN\033[0m";
600     printf("[%s] %s\n",
601            hardware_backed ? kBoldGreenPass : (required ? kBoldRedFail : kBoldYellowWarn),
602            name.c_str());
603 
604     return (hardware_backed || !required);
605 }
606 
GetRSASignParameters(uint32_t key_size,bool sha256_only)607 keymint::AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
608     keymint::AuthorizationSetBuilder parameters;
609     parameters.RsaSigningKey(key_size, 65537)
610         .Digest(keymint::Digest::SHA_2_256)
611         .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
612         .Padding(keymint::PaddingMode::RSA_PSS)
613         .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
614     if (!sha256_only) {
615         parameters.Digest(keymint::Digest::SHA_2_224)
616             .Digest(keymint::Digest::SHA_2_384)
617             .Digest(keymint::Digest::SHA_2_512);
618     }
619     return std::move(parameters);
620 }
621 
GetRSAEncryptParameters(uint32_t key_size)622 keymint::AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
623     keymint::AuthorizationSetBuilder parameters;
624     parameters.RsaEncryptionKey(key_size, 65537)
625         .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
626         .Padding(keymint::PaddingMode::RSA_OAEP)
627         .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
628     return std::move(parameters);
629 }
630 
GetECDSAParameters(keymint::EcCurve curve,bool sha256_only)631 keymint::AuthorizationSet GetECDSAParameters(keymint::EcCurve curve, bool sha256_only) {
632     keymint::AuthorizationSetBuilder parameters;
633     parameters.EcdsaSigningKey(curve)
634         .Digest(keymint::Digest::SHA_2_256)
635         .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
636     if (!sha256_only) {
637         parameters.Digest(keymint::Digest::SHA_2_224)
638             .Digest(keymint::Digest::SHA_2_384)
639             .Digest(keymint::Digest::SHA_2_512);
640     }
641     return std::move(parameters);
642 }
643 
GetAESParameters(uint32_t key_size,bool with_gcm_mode)644 keymint::AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
645     keymint::AuthorizationSetBuilder parameters;
646     parameters.AesEncryptionKey(key_size).Authorization(keymint::TAG_NO_AUTH_REQUIRED);
647     if (with_gcm_mode) {
648         parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::GCM)
649             .Authorization(keymint::TAG_MIN_MAC_LENGTH, 128);
650     } else {
651         parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::ECB);
652         parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CBC);
653         parameters.Authorization(keymint::TAG_BLOCK_MODE, keymint::BlockMode::CTR);
654         parameters.Padding(keymint::PaddingMode::NONE);
655     }
656     return std::move(parameters);
657 }
658 
GetHMACParameters(uint32_t key_size,keymint::Digest digest)659 keymint::AuthorizationSet GetHMACParameters(uint32_t key_size, keymint::Digest digest) {
660     keymint::AuthorizationSetBuilder parameters;
661     parameters.HmacKey(key_size)
662         .Digest(digest)
663         .Authorization(keymint::TAG_MIN_MAC_LENGTH, 224)
664         .Authorization(keymint::TAG_NO_AUTH_REQUIRED);
665     return std::move(parameters);
666 }
667 
GetTestCases()668 std::vector<TestCase> GetTestCases() {
669     TestCase test_cases[] = {
670         {"RSA-2048 Sign", true, GetRSASignParameters(2048, true)},
671         {"RSA-2048 Sign (more digests)", false, GetRSASignParameters(2048, false)},
672         {"RSA-3072 Sign", false, GetRSASignParameters(3072, false)},
673         {"RSA-4096 Sign", false, GetRSASignParameters(4096, false)},
674         {"RSA-2048 Encrypt", true, GetRSAEncryptParameters(2048)},
675         {"RSA-3072 Encrypt", false, GetRSAEncryptParameters(3072)},
676         {"RSA-4096 Encrypt", false, GetRSAEncryptParameters(4096)},
677         {"ECDSA-P256 Sign", true, GetECDSAParameters(keymint::EcCurve::P_256, true)},
678         {"ECDSA-P256 Sign (more digests)", false,
679          GetECDSAParameters(keymint::EcCurve::P_256, false)},
680         {"ECDSA-P224 Sign", false, GetECDSAParameters(keymint::EcCurve::P_224, false)},
681         {"ECDSA-P384 Sign", false, GetECDSAParameters(keymint::EcCurve::P_384, false)},
682         {"ECDSA-P521 Sign", false, GetECDSAParameters(keymint::EcCurve::P_521, false)},
683         {"AES-128", true, GetAESParameters(128, false)},
684         {"AES-256", true, GetAESParameters(256, false)},
685         {"AES-128-GCM", false, GetAESParameters(128, true)},
686         {"AES-256-GCM", false, GetAESParameters(256, true)},
687         {"HMAC-SHA256-16", true, GetHMACParameters(16, keymint::Digest::SHA_2_256)},
688         {"HMAC-SHA256-32", true, GetHMACParameters(32, keymint::Digest::SHA_2_256)},
689         {"HMAC-SHA256-64", false, GetHMACParameters(64, keymint::Digest::SHA_2_256)},
690         {"HMAC-SHA224-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_224)},
691         {"HMAC-SHA384-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_384)},
692         {"HMAC-SHA512-32", false, GetHMACParameters(32, keymint::Digest::SHA_2_512)},
693     };
694     return std::vector<TestCase>(&test_cases[0], &test_cases[arraysize(test_cases)]);
695 }
696 
BrilloPlatformTest(const std::string & prefix,bool test_for_0_3)697 int BrilloPlatformTest(const std::string& prefix, bool test_for_0_3) {
698     const char kBoldYellowWarning[] = "\033[1;33mWARNING\033[0m";
699     if (test_for_0_3) {
700         printf("%s: Testing for keymaster v0.3. "
701                "This does not meet Brillo requirements.\n",
702                kBoldYellowWarning);
703     }
704     int test_count = 0;
705     int fail_count = 0;
706     std::vector<TestCase> test_cases = GetTestCases();
707     for (const auto& test_case : test_cases) {
708         if (!prefix.empty() &&
709             !android::base::StartsWith(test_case.name, prefix)) {
710             continue;
711         }
712         if (test_for_0_3 &&
713             (android::base::StartsWith(test_case.name, "AES") ||
714              android::base::StartsWith(test_case.name, "HMAC"))) {
715             continue;
716         }
717         ++test_count;
718         if (!TestKey(test_case.name, test_case.required_for_brillo_pts,
719                      test_case.parameters.vector_data())) {
720             VLOG(1) << "Test failed: " << test_case.name;
721             ++fail_count;
722         }
723     }
724     return fail_count;
725 }
726 
ListTestCases()727 int ListTestCases() {
728     const char kBoldGreenRequired[] = "\033[1;32mREQUIRED\033[0m";
729     const char kBoldYellowRecommended[] = "\033[1;33mRECOMMENDED\033[0m";
730     std::vector<TestCase> test_cases = GetTestCases();
731     for (const auto& test_case : test_cases) {
732         printf("%s : %s\n", test_case.name.c_str(),
733                test_case.required_for_brillo_pts ? kBoldGreenRequired : kBoldYellowRecommended);
734     }
735     return 0;
736 }
737 
ReadFile(const std::string & filename)738 std::vector<uint8_t> ReadFile(const std::string& filename) {
739     std::string content;
740     base::FilePath path(filename);
741     if (!base::ReadFileToString(path, &content)) {
742         printf("Failed to read file: %s\n", filename.c_str());
743         exit(1);
744     }
745     std::vector<uint8_t> buffer(reinterpret_cast<const uint8_t*>(content.data()),
746                                 reinterpret_cast<const uint8_t*>(content.data()) + content.size());
747     return buffer;
748 }
749 
WriteFile(const std::string & filename,const std::vector<uint8_t> & content)750 void WriteFile(const std::string& filename, const std::vector<uint8_t>& content) {
751     base::FilePath path(filename);
752     int size = content.size();
753     if (base::WriteFile(path, reinterpret_cast<const char*>(content.data()), size) != size) {
754         printf("Failed to write file: %s\n", filename.c_str());
755         exit(1);
756     }
757 }
758 
759 // Note: auth_bound keys created with this tool will not be usable.
GenerateKey(const std::string & name,keymint::SecurityLevel securityLevel,bool auth_bound)760 int GenerateKey(const std::string& name, keymint::SecurityLevel securityLevel, bool auth_bound) {
761     auto keystore = CreateKeystoreInstance();
762     auto sec_level = GetSecurityLevelInterface(keystore, securityLevel);
763     keymint::AuthorizationSetBuilder params;
764     params.RsaSigningKey(2048, 65537)
765         .Digest(keymint::Digest::SHA_2_224)
766         .Digest(keymint::Digest::SHA_2_256)
767         .Digest(keymint::Digest::SHA_2_384)
768         .Digest(keymint::Digest::SHA_2_512)
769         .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
770         .Padding(keymint::PaddingMode::RSA_PSS);
771     if (auth_bound) {
772         // Gatekeeper normally generates the secure user id.
773         // Using zero allows the key to be created, but it will not be usuable.
774         params.Authorization(keymint::TAG_USER_SECURE_ID, 0);
775     } else {
776         params.Authorization(keymint::TAG_NO_AUTH_REQUIRED);
777     }
778 
779     ks2::KeyMetadata keyMetadata;
780 
781     auto rc =
782         sec_level->generateKey(keyDescriptor(name), {} /* attestationKey */, params.vector_data(),
783                                0 /* flags */, {} /* entropy */, &keyMetadata);
784 
785     if (!rc.isOk()) {
786         std::cerr << "GenerateKey failed: " << rc.getDescription() << std::endl;
787         return unwrapError(rc);
788     }
789     std::cout << "GenerateKey: success" << std::endl;
790     PrintKeyCharacteristics(keyMetadata.authorizations);
791     return 0;
792 }
793 
GetCharacteristics(const std::string & name)794 int GetCharacteristics(const std::string& name) {
795     auto keystore = CreateKeystoreInstance();
796 
797     ks2::KeyEntryResponse keyEntryResponse;
798 
799     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
800     if (!rc.isOk()) {
801         std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
802         return unwrapError(rc);
803     }
804 
805     std::cout << "GetCharacteristics: success" << std::endl;
806     PrintKeyCharacteristics(keyEntryResponse.metadata.authorizations);
807     return 0;
808 }
809 
ExportKey(const std::string & name)810 int ExportKey(const std::string& name) {
811     auto keystore = CreateKeystoreInstance();
812 
813     ks2::KeyEntryResponse keyEntryResponse;
814 
815     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
816     if (!rc.isOk()) {
817         std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
818         return unwrapError(rc);
819     }
820 
821     if (auto cert = keyEntryResponse.metadata.certificate) {
822         std::cout << "ExportKey: Got certificate of length (" << cert->size() << ")" << std::endl;
823     } else {
824         std::cout << "ExportKey: Key entry does not have a public component.\n";
825         std::cout << "Possibly a symmetric key?" << std::endl;
826     }
827     return 0;
828 }
829 
DeleteKey(const std::string & name)830 int DeleteKey(const std::string& name) {
831     auto keystore = CreateKeystoreInstance();
832 
833     auto rc = keystore->deleteKey(keyDescriptor(name));
834     if (!rc.isOk()) {
835         std::cerr << "Failed to delete key: " << rc.getDescription();
836         return unwrapError(rc);
837     }
838     std::cout << "Successfully deleted key." << std::endl;
839     return 0;
840 }
841 
DoesKeyExist(const std::string & name)842 int DoesKeyExist(const std::string& name) {
843     auto keystore = CreateKeystoreInstance();
844     ks2::KeyEntryResponse keyEntryResponse;
845 
846     bool keyExists = true;
847     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
848     if (!rc.isOk()) {
849         auto responseCode = unwrapError(rc);
850         if (ks2::ResponseCode(responseCode) == ks2::ResponseCode::KEY_NOT_FOUND) {
851             keyExists = false;
852         } else {
853             std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
854             return unwrapError(rc);
855         }
856     }
857     std::cout << "DoesKeyExists: " << (keyExists ? "yes" : "no") << std::endl;
858     return 0;
859 }
860 
List()861 int List() {
862     auto keystore = CreateKeystoreInstance();
863     std::vector<ks2::KeyDescriptor> key_list;
864     auto rc = keystore->listEntries(ks2::Domain::APP, -1 /* nspace ignored */, &key_list);
865     if (!rc.isOk()) {
866         std::cerr << "ListKeys failed: " << rc.getDescription() << std::endl;
867         return unwrapError(rc);
868     }
869     std::cout << "Keys:\n";
870     for (const auto& key : key_list) {
871         std::cout << "  "
872                   << (key.alias ? *key.alias : "Whoopsi - no alias, this should not happen.")
873                   << std::endl;
874     }
875     return 0;
876 }
877 
SignAndVerify(const std::string & name)878 int SignAndVerify(const std::string& name) {
879     auto keystore = CreateKeystoreInstance();
880     auto sign_params = keymint::AuthorizationSetBuilder()
881                            .Authorization(keymint::TAG_PURPOSE, keymint::KeyPurpose::SIGN)
882                            .Padding(keymint::PaddingMode::RSA_PKCS1_1_5_SIGN)
883                            .Digest(keymint::Digest::SHA_2_256);
884 
885     keymint::AuthorizationSet output_params;
886 
887     ks2::KeyEntryResponse keyEntryResponse;
888 
889     auto rc = keystore->getKeyEntry(keyDescriptor(name), &keyEntryResponse);
890     if (!rc.isOk()) {
891         std::cerr << "Failed to get key entry: " << rc.getDescription() << std::endl;
892         return unwrapError(rc);
893     }
894 
895     ks2::CreateOperationResponse operationResponse;
896 
897     rc = keyEntryResponse.iSecurityLevel->createOperation(keyEntryResponse.metadata.key,
898                                                           sign_params.vector_data(),
899                                                           false /* forced */, &operationResponse);
900     if (!rc.isOk()) {
901         std::cerr << "Failed to create operation: " << rc.getDescription() << std::endl;
902         return unwrapError(rc);
903     }
904 
905     const std::vector<uint8_t> data_to_sign{0x64, 0x61, 0x74, 0x61, 0x5f, 0x74,
906                                             0x6f, 0x5f, 0x73, 0x69, 0x67, 0x6e};
907     std::optional<std::vector<uint8_t>> output_data;
908     rc = operationResponse.iOperation->finish(data_to_sign, {}, &output_data);
909     if (!rc.isOk()) {
910         std::cerr << "Failed to finalize operation: " << rc.getDescription() << std::endl;
911         return unwrapError(rc);
912     }
913 
914     if (!output_data) {
915         std::cerr << "Odd signing succeeded but no signature was returned." << std::endl;
916         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
917     }
918     auto signature = std::move(*output_data);
919 
920     std::cout << "Sign: " << signature.size() << " bytes." << std::endl;
921 
922     if (auto cert = keyEntryResponse.metadata.certificate) {
923         const uint8_t* p = cert->data();
924         bssl::UniquePtr<X509> decoded_cert(d2i_X509(nullptr, &p, (long)cert->size()));
925         bssl::UniquePtr<EVP_PKEY> decoded_pkey(X509_get_pubkey(decoded_cert.get()));
926         bssl::UniquePtr<EVP_MD_CTX> ctx(EVP_MD_CTX_new());
927         if (!ctx) {
928             std::cerr << "Failed to created EVP_MD context. << std::endl";
929             return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
930         }
931 
932         if (!EVP_DigestVerifyInit(ctx.get(), nullptr, EVP_sha256(), nullptr, decoded_pkey.get()) ||
933             !EVP_DigestVerifyUpdate(ctx.get(), data_to_sign.data(), data_to_sign.size()) ||
934             EVP_DigestVerifyFinal(ctx.get(), signature.data(), signature.size()) != 1) {
935             std::cerr << "Failed to verify signature." << std::endl;
936             return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
937         }
938     } else {
939         std::cerr << "No public key to check signature against." << std::endl;
940         return static_cast<int>(ks2::ResponseCode::SYSTEM_ERROR);
941     }
942 
943     std::cout << "Verify: OK" << std::endl;
944     return 0;
945 }
946 
Encrypt(const std::string & key_name,const std::string & input_filename,const std::string & output_filename,keymint::SecurityLevel securityLevel)947 int Encrypt(const std::string& key_name, const std::string& input_filename,
948             const std::string& output_filename, keymint::SecurityLevel securityLevel) {
949     auto input = ReadFile(input_filename);
950     auto result = encryptWithAuthentication(key_name, input, securityLevel);
951     if (auto error = std::get_if<int>(&result)) {
952         std::cerr << "EncryptWithAuthentication failed." << std::endl;
953         return *error;
954     }
955     WriteFile(output_filename, std::get<std::vector<uint8_t>>(result));
956     return 0;
957 }
958 
Decrypt(const std::string & key_name,const std::string & input_filename,const std::string & output_filename)959 int Decrypt(const std::string& key_name, const std::string& input_filename,
960             const std::string& output_filename) {
961     auto input = ReadFile(input_filename);
962     auto result = decryptWithAuthentication(key_name, input);
963     if (auto error = std::get_if<int>(&result)) {
964         std::cerr << "DecryptWithAuthentication failed." << std::endl;
965         return *error;
966     }
967     WriteFile(output_filename, std::get<std::vector<uint8_t>>(result));
968     return 0;
969 }
970 
securityLevelOption2SecurlityLevel(const CommandLine & cmd)971 keymint::SecurityLevel securityLevelOption2SecurlityLevel(const CommandLine& cmd) {
972     if (cmd.HasSwitch("seclevel")) {
973         auto str = cmd.GetSwitchValueASCII("seclevel");
974         if (str == "strongbox") {
975             return keymint::SecurityLevel::STRONGBOX;
976         } else if (str == "tee") {
977             return keymint::SecurityLevel::TRUSTED_ENVIRONMENT;
978         }
979         std::cerr << "Unknown Security level: " << str << std::endl;
980         std::cerr << "Supported security levels: \"strongbox\" or \"tee\" (default)" << std::endl;
981     }
982     return keymint::SecurityLevel::TRUSTED_ENVIRONMENT;
983 }
984 
985 class ConfirmationListener
986     : public apc::BnConfirmationCallback,
987       public std::promise<std::tuple<apc::ResponseCode, std::optional<std::vector<uint8_t>>>> {
988   public:
ConfirmationListener()989     ConfirmationListener() {}
990 
991     virtual ::ndk::ScopedAStatus
onCompleted(::aidl::android::security::apc::ResponseCode result,const std::optional<std::vector<uint8_t>> & dataConfirmed)992     onCompleted(::aidl::android::security::apc::ResponseCode result,
993                 const std::optional<std::vector<uint8_t>>& dataConfirmed) override {
994         this->set_value({result, dataConfirmed});
995         return ::ndk::ScopedAStatus::ok();
996     };
997 };
998 
Confirmation(const std::string & promptText,const std::string & extraDataHex,const std::string & locale,const std::string & uiOptionsStr,const std::string & cancelAfter)999 int Confirmation(const std::string& promptText, const std::string& extraDataHex,
1000                  const std::string& locale, const std::string& uiOptionsStr,
1001                  const std::string& cancelAfter) {
1002     ::ndk::SpAIBinder apcBinder(AServiceManager_getService("android.security.apc"));
1003     auto apcService = apc::IProtectedConfirmation::fromBinder(apcBinder);
1004     if (!apcService) {
1005         std::cerr << "Error: could not connect to apc service." << std::endl;
1006         return 1;
1007     }
1008 
1009     if (promptText.size() == 0) {
1010         printf("The --prompt_text parameter cannot be empty.\n");
1011         return 1;
1012     }
1013 
1014     std::vector<uint8_t> extraData;
1015     if (!base::HexStringToBytes(extraDataHex, &extraData)) {
1016         printf("The --extra_data parameter does not appear to be valid hexadecimal.\n");
1017         return 1;
1018     }
1019 
1020     std::vector<std::string> pieces = android::base::Tokenize(uiOptionsStr, ",");
1021     int uiOptionsAsFlags = 0;
1022     for (auto& p : pieces) {
1023         int value;
1024         if (!base::StringToInt(p, &value)) {
1025             printf("Error parsing %s in --ui_options parameter as a number.\n", p.c_str());
1026             return 1;
1027         }
1028         uiOptionsAsFlags |= (1 << value);
1029     }
1030 
1031     double cancelAfterValue = 0.0;
1032 
1033     if (cancelAfter.size() > 0 && !base::StringToDouble(cancelAfter, &cancelAfterValue)) {
1034         printf("Error parsing %s in --cancel_after parameter as a double.\n", cancelAfter.c_str());
1035         return 1;
1036     }
1037 
1038     auto listener = ndk::SharedRefBase::make<ConfirmationListener>();
1039 
1040     auto future = listener->get_future();
1041     auto rc = apcService->presentPrompt(listener, string_replace_all(promptText, "\\n", "\n"),
1042                                         extraData, locale, uiOptionsAsFlags);
1043 
1044     if (!rc.isOk()) {
1045         std::cerr << "Presenting confirmation prompt failed: " << rc.getDescription() << std::endl;
1046         return 1;
1047     }
1048 
1049     std::cerr << "Waiting for prompt to complete - use Ctrl+C to abort..." << std::endl;
1050 
1051     if (cancelAfterValue > 0.0) {
1052         std::cerr << "Sleeping " << cancelAfterValue << " seconds before canceling prompt..."
1053                   << std::endl;
1054         auto fstatus =
1055             future.wait_for(std::chrono::milliseconds(uint64_t(cancelAfterValue * 1000)));
1056         if (fstatus == std::future_status::timeout) {
1057             rc = apcService->cancelPrompt(listener);
1058             if (!rc.isOk()) {
1059                 std::cerr << "Canceling confirmation prompt failed: " << rc.getDescription()
1060                           << std::endl;
1061                 return 1;
1062             }
1063         }
1064     }
1065 
1066     future.wait();
1067 
1068     auto [responseCode, dataThatWasConfirmed] = future.get();
1069 
1070     std::cerr << "Confirmation prompt completed\n"
1071               << "responseCode = " << toString(responseCode);
1072     size_t newLineCountDown = 16;
1073     bool hasPrinted = false;
1074     if (dataThatWasConfirmed) {
1075         std::cerr << "dataThatWasConfirmed[" << dataThatWasConfirmed->size() << "] = {";
1076         for (uint8_t element : *dataThatWasConfirmed) {
1077             if (hasPrinted) {
1078                 std::cerr << ", ";
1079             }
1080             if (newLineCountDown == 0) {
1081                 std::cerr << "\n  ";
1082                 newLineCountDown = 32;
1083             }
1084             std::cerr << "0x" << std::hex << std::setw(2) << std::setfill('0') << (unsigned)element;
1085 
1086             hasPrinted = true;
1087         }
1088     }
1089     std::cerr << std::endl;
1090     return 0;
1091 }
1092 
1093 }  // namespace
1094 
main(int argc,char ** argv)1095 int main(int argc, char** argv) {
1096     CommandLine::Init(argc, argv);
1097     CommandLine* command_line = CommandLine::ForCurrentProcess();
1098     CommandLine::StringVector args = command_line->GetArgs();
1099 
1100     ABinderProcess_startThreadPool();
1101 
1102     if (args.empty()) {
1103         PrintUsageAndExit();
1104     }
1105     if (args[0] == "brillo-platform-test") {
1106         return BrilloPlatformTest(command_line->GetSwitchValueASCII("prefix"),
1107                                   command_line->HasSwitch("test_for_0_3"));
1108     } else if (args[0] == "list-brillo-tests") {
1109         return ListTestCases();
1110     } else if (args[0] == "generate") {
1111         return GenerateKey(command_line->GetSwitchValueASCII("name"),
1112                            securityLevelOption2SecurlityLevel(*command_line),
1113                            command_line->HasSwitch("auth_bound"));
1114     } else if (args[0] == "get-chars") {
1115         return GetCharacteristics(command_line->GetSwitchValueASCII("name"));
1116     } else if (args[0] == "export") {
1117         return ExportKey(command_line->GetSwitchValueASCII("name"));
1118     } else if (args[0] == "delete") {
1119         return DeleteKey(command_line->GetSwitchValueASCII("name"));
1120     } else if (args[0] == "exists") {
1121         return DoesKeyExist(command_line->GetSwitchValueASCII("name"));
1122     } else if (args[0] == "list") {
1123         return List();
1124     } else if (args[0] == "sign-verify") {
1125         return SignAndVerify(command_line->GetSwitchValueASCII("name"));
1126     } else if (args[0] == "encrypt") {
1127         return Encrypt(command_line->GetSwitchValueASCII("name"),
1128                        command_line->GetSwitchValueASCII("in"),
1129                        command_line->GetSwitchValueASCII("out"),
1130                        securityLevelOption2SecurlityLevel(*command_line));
1131     } else if (args[0] == "decrypt") {
1132         return Decrypt(command_line->GetSwitchValueASCII("name"),
1133                        command_line->GetSwitchValueASCII("in"),
1134                        command_line->GetSwitchValueASCII("out"));
1135     } else if (args[0] == "confirmation") {
1136         return Confirmation(command_line->GetSwitchValueNative("prompt_text"),
1137                             command_line->GetSwitchValueASCII("extra_data"),
1138                             command_line->GetSwitchValueASCII("locale"),
1139                             command_line->GetSwitchValueASCII("ui_options"),
1140                             command_line->GetSwitchValueASCII("cancel_after"));
1141     } else {
1142         PrintUsageAndExit();
1143     }
1144     return 0;
1145 }
1146