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