blob: 0981f1eb0a3b8b3f12e3d6193c5c092f96a3dfff [file] [log] [blame]
Darren Krahn69a3dbc2015-09-22 16:21:04 -07001// 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 <cstdio>
16#include <memory>
17#include <string>
18#include <vector>
19
Shawn Willdenbb22a6c2017-12-06 19:35:28 -070020#include <base/command_line.h>
21#include <base/files/file_util.h>
David Zeuthenc6eb7cd2017-11-27 11:33:55 -050022#include <base/strings/string_number_conversions.h>
23#include <base/strings/string_split.h>
Shawn Willdenbb22a6c2017-12-06 19:35:28 -070024#include <base/strings/string_util.h>
David Zeuthenc6eb7cd2017-11-27 11:33:55 -050025#include <base/strings/utf_string_conversions.h>
26#include <base/threading/platform_thread.h>
Shawn Willdenbb22a6c2017-12-06 19:35:28 -070027#include <keystore/keymaster_types.h>
28#include <keystore/keystore_client_impl.h>
Darren Krahn69a3dbc2015-09-22 16:21:04 -070029
David Zeuthenc6eb7cd2017-11-27 11:33:55 -050030#include <android/hardware/confirmationui/1.0/types.h>
31#include <android/security/BnConfirmationPromptCallback.h>
Rob Barnesbb6cabd2018-10-04 17:10:37 -060032#include <android/security/keystore/IKeystoreService.h>
David Zeuthenc6eb7cd2017-11-27 11:33:55 -050033
34#include <binder/IPCThreadState.h>
35#include <binder/IServiceManager.h>
36
37//#include <keystore/keystore.h>
38
Darren Krahn69a3dbc2015-09-22 16:21:04 -070039using base::CommandLine;
Darren Krahn69a3dbc2015-09-22 16:21:04 -070040using keystore::KeystoreClient;
41
David Zeuthenc6eb7cd2017-11-27 11:33:55 -050042using android::sp;
43using android::String16;
Rob Barnesbb6cabd2018-10-04 17:10:37 -060044using android::security::keystore::IKeystoreService;
David Zeuthenc6eb7cd2017-11-27 11:33:55 -050045using base::CommandLine;
46using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;
47
Darren Krahn69a3dbc2015-09-22 16:21:04 -070048namespace {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010049using namespace keystore;
Darren Krahn69a3dbc2015-09-22 16:21:04 -070050
Darren Krahna9474ab2015-11-03 14:38:53 -080051struct TestCase {
52 std::string name;
53 bool required_for_brillo_pts;
54 AuthorizationSet parameters;
55};
56
Darren Krahn69a3dbc2015-09-22 16:21:04 -070057void PrintUsageAndExit() {
58 printf("Usage: keystore_client_v2 <command> [options]\n");
Darren Krahn82f4f5b2016-03-03 16:21:07 -080059 printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>] [--test_for_0_3]\n"
Darren Krahna9474ab2015-11-03 14:38:53 -080060 " list-brillo-tests\n"
Janis Danisevskisc1460142017-12-18 16:48:46 -080061 " add-entropy --input=<entropy> [--seclevel=software|strongbox|tee(default)]\n"
62 " generate --name=<key_name> [--seclevel=software|strongbox|tee(default)]\n"
Darren Krahn69a3dbc2015-09-22 16:21:04 -070063 " get-chars --name=<key_name>\n"
64 " export --name=<key_name>\n"
65 " delete --name=<key_name>\n"
66 " delete-all\n"
67 " exists --name=<key_name>\n"
68 " list [--prefix=<key_name_prefix>]\n"
Darren Krahn251cb282015-09-28 08:51:18 -070069 " sign-verify --name=<key_name>\n"
Janis Danisevskisc1460142017-12-18 16:48:46 -080070 " [en|de]crypt --name=<key_name> --in=<file> --out=<file>\n"
David Zeuthenc6eb7cd2017-11-27 11:33:55 -050071 " [--seclevel=software|strongbox|tee(default)]\n"
72 " confirmation --prompt_text=<PromptText> --extra_data=<hex>\n"
73 " --locale=<locale> [--ui_options=<list_of_ints>]\n"
74 " --cancel_after=<seconds>\n");
Darren Krahn69a3dbc2015-09-22 16:21:04 -070075 exit(1);
76}
77
78std::unique_ptr<KeystoreClient> CreateKeystoreInstance() {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010079 return std::unique_ptr<KeystoreClient>(
Shawn Willdenbb22a6c2017-12-06 19:35:28 -070080 static_cast<KeystoreClient*>(new keystore::KeystoreClientImpl));
Darren Krahn69a3dbc2015-09-22 16:21:04 -070081}
82
Darren Krahna9474ab2015-11-03 14:38:53 -080083void PrintTags(const AuthorizationSet& parameters) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010084 for (auto iter = parameters.begin(); iter != parameters.end(); ++iter) {
Shawn Willdenbb22a6c2017-12-06 19:35:28 -070085 auto tag_str = toString(iter->tag);
86 printf(" %s\n", tag_str.c_str());
Darren Krahna9474ab2015-11-03 14:38:53 -080087 }
88}
89
90void PrintKeyCharacteristics(const AuthorizationSet& hardware_enforced_characteristics,
91 const AuthorizationSet& software_enforced_characteristics) {
92 printf("Hardware:\n");
93 PrintTags(hardware_enforced_characteristics);
94 printf("Software:\n");
95 PrintTags(software_enforced_characteristics);
96}
97
98bool TestKey(const std::string& name, bool required, const AuthorizationSet& parameters) {
99 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
100 AuthorizationSet hardware_enforced_characteristics;
101 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc1460142017-12-18 16:48:46 -0800102 auto result =
103 keystore->generateKey("tmp", parameters, 0 /*flags*/, &hardware_enforced_characteristics,
104 &software_enforced_characteristics);
Darren Krahn82f4f5b2016-03-03 16:21:07 -0800105 const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100106 if (!result.isOk()) {
Darren Krahna9474ab2015-11-03 14:38:53 -0800107 LOG(ERROR) << "Failed to generate key: " << result;
Darren Krahn82f4f5b2016-03-03 16:21:07 -0800108 printf("[%s] %s\n", kBoldRedAbort, name.c_str());
Darren Krahna9474ab2015-11-03 14:38:53 -0800109 return false;
110 }
111 result = keystore->deleteKey("tmp");
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100112 if (!result.isOk()) {
Darren Krahna9474ab2015-11-03 14:38:53 -0800113 LOG(ERROR) << "Failed to delete key: " << result;
Darren Krahn82f4f5b2016-03-03 16:21:07 -0800114 printf("[%s] %s\n", kBoldRedAbort, name.c_str());
Darren Krahna9474ab2015-11-03 14:38:53 -0800115 return false;
116 }
117 printf("===============================================================\n");
118 printf("%s Key Characteristics:\n", name.c_str());
119 PrintKeyCharacteristics(hardware_enforced_characteristics, software_enforced_characteristics);
120 bool hardware_backed = (hardware_enforced_characteristics.size() > 0);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100121 if (software_enforced_characteristics.GetTagCount(TAG_ALGORITHM) > 0 ||
122 software_enforced_characteristics.GetTagCount(TAG_KEY_SIZE) > 0 ||
123 software_enforced_characteristics.GetTagCount(TAG_RSA_PUBLIC_EXPONENT) > 0) {
Darren Krahna9474ab2015-11-03 14:38:53 -0800124 VLOG(1) << "Hardware-backed key but required characteristics enforced in software.";
125 hardware_backed = false;
126 }
127 const char kBoldRedFail[] = "\033[1;31mFAIL\033[0m";
128 const char kBoldGreenPass[] = "\033[1;32mPASS\033[0m";
129 const char kBoldYellowWarn[] = "\033[1;33mWARN\033[0m";
130 printf("[%s] %s\n",
131 hardware_backed ? kBoldGreenPass : (required ? kBoldRedFail : kBoldYellowWarn),
132 name.c_str());
133
134 return (hardware_backed || !required);
135}
136
137AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
138 AuthorizationSetBuilder parameters;
139 parameters.RsaSigningKey(key_size, 65537)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100140 .Digest(Digest::SHA_2_256)
141 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
142 .Padding(PaddingMode::RSA_PSS)
143 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahna9474ab2015-11-03 14:38:53 -0800144 if (!sha256_only) {
Shawn Willdenbb22a6c2017-12-06 19:35:28 -0700145 parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
Darren Krahna9474ab2015-11-03 14:38:53 -0800146 }
Yi Kong53b02f72018-07-26 17:13:50 -0700147 return std::move(parameters);
Darren Krahna9474ab2015-11-03 14:38:53 -0800148}
149
150AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
151 AuthorizationSetBuilder parameters;
152 parameters.RsaEncryptionKey(key_size, 65537)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100153 .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
154 .Padding(PaddingMode::RSA_OAEP)
155 .Authorization(TAG_NO_AUTH_REQUIRED);
Yi Kong53b02f72018-07-26 17:13:50 -0700156 return std::move(parameters);
Darren Krahna9474ab2015-11-03 14:38:53 -0800157}
158
159AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
160 AuthorizationSetBuilder parameters;
161 parameters.EcdsaSigningKey(key_size)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100162 .Digest(Digest::SHA_2_256)
163 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahna9474ab2015-11-03 14:38:53 -0800164 if (!sha256_only) {
Shawn Willdenbb22a6c2017-12-06 19:35:28 -0700165 parameters.Digest(Digest::SHA_2_224).Digest(Digest::SHA_2_384).Digest(Digest::SHA_2_512);
Darren Krahna9474ab2015-11-03 14:38:53 -0800166 }
Yi Kong53b02f72018-07-26 17:13:50 -0700167 return std::move(parameters);
Darren Krahna9474ab2015-11-03 14:38:53 -0800168}
169
170AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
171 AuthorizationSetBuilder parameters;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100172 parameters.AesEncryptionKey(key_size).Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahna9474ab2015-11-03 14:38:53 -0800173 if (with_gcm_mode) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100174 parameters.Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
175 .Authorization(TAG_MIN_MAC_LENGTH, 128);
Darren Krahna9474ab2015-11-03 14:38:53 -0800176 } else {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100177 parameters.Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
178 parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
179 parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CTR);
180 parameters.Padding(PaddingMode::NONE);
Darren Krahna9474ab2015-11-03 14:38:53 -0800181 }
Yi Kong53b02f72018-07-26 17:13:50 -0700182 return std::move(parameters);
Darren Krahna9474ab2015-11-03 14:38:53 -0800183}
184
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100185AuthorizationSet GetHMACParameters(uint32_t key_size, Digest digest) {
Darren Krahna9474ab2015-11-03 14:38:53 -0800186 AuthorizationSetBuilder parameters;
187 parameters.HmacKey(key_size)
188 .Digest(digest)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100189 .Authorization(TAG_MIN_MAC_LENGTH, 224)
190 .Authorization(TAG_NO_AUTH_REQUIRED);
Yi Kong53b02f72018-07-26 17:13:50 -0700191 return std::move(parameters);
Darren Krahna9474ab2015-11-03 14:38:53 -0800192}
193
194std::vector<TestCase> GetTestCases() {
195 TestCase test_cases[] = {
196 {"RSA-2048 Sign", true, GetRSASignParameters(2048, true)},
197 {"RSA-2048 Sign (more digests)", false, GetRSASignParameters(2048, false)},
198 {"RSA-3072 Sign", false, GetRSASignParameters(3072, false)},
199 {"RSA-4096 Sign", false, GetRSASignParameters(4096, false)},
200 {"RSA-2048 Encrypt", true, GetRSAEncryptParameters(2048)},
201 {"RSA-3072 Encrypt", false, GetRSAEncryptParameters(3072)},
202 {"RSA-4096 Encrypt", false, GetRSAEncryptParameters(4096)},
203 {"ECDSA-P256 Sign", true, GetECDSAParameters(256, true)},
204 {"ECDSA-P256 Sign (more digests)", false, GetECDSAParameters(256, false)},
205 {"ECDSA-P224 Sign", false, GetECDSAParameters(224, false)},
206 {"ECDSA-P384 Sign", false, GetECDSAParameters(384, false)},
207 {"ECDSA-P521 Sign", false, GetECDSAParameters(521, false)},
208 {"AES-128", true, GetAESParameters(128, false)},
209 {"AES-256", true, GetAESParameters(256, false)},
210 {"AES-128-GCM", false, GetAESParameters(128, true)},
211 {"AES-256-GCM", false, GetAESParameters(256, true)},
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100212 {"HMAC-SHA256-16", true, GetHMACParameters(16, Digest::SHA_2_256)},
213 {"HMAC-SHA256-32", true, GetHMACParameters(32, Digest::SHA_2_256)},
214 {"HMAC-SHA256-64", false, GetHMACParameters(64, Digest::SHA_2_256)},
215 {"HMAC-SHA224-32", false, GetHMACParameters(32, Digest::SHA_2_224)},
216 {"HMAC-SHA384-32", false, GetHMACParameters(32, Digest::SHA_2_384)},
217 {"HMAC-SHA512-32", false, GetHMACParameters(32, Digest::SHA_2_512)},
Darren Krahna9474ab2015-11-03 14:38:53 -0800218 };
219 return std::vector<TestCase>(&test_cases[0], &test_cases[arraysize(test_cases)]);
220}
221
Darren Krahn82f4f5b2016-03-03 16:21:07 -0800222int BrilloPlatformTest(const std::string& prefix, bool test_for_0_3) {
223 const char kBoldYellowWarning[] = "\033[1;33mWARNING\033[0m";
224 if (test_for_0_3) {
225 printf("%s: Testing for keymaster v0.3. "
Shawn Willdenbb22a6c2017-12-06 19:35:28 -0700226 "This does not meet Brillo requirements.\n",
227 kBoldYellowWarning);
Darren Krahn82f4f5b2016-03-03 16:21:07 -0800228 }
Darren Krahna9474ab2015-11-03 14:38:53 -0800229 int test_count = 0;
230 int fail_count = 0;
231 std::vector<TestCase> test_cases = GetTestCases();
232 for (const auto& test_case : test_cases) {
Darren Krahn82f4f5b2016-03-03 16:21:07 -0800233 if (!prefix.empty() &&
234 !base::StartsWith(test_case.name, prefix, base::CompareCase::SENSITIVE)) {
235 continue;
236 }
237 if (test_for_0_3 &&
238 (base::StartsWith(test_case.name, "AES", base::CompareCase::SENSITIVE) ||
239 base::StartsWith(test_case.name, "HMAC", base::CompareCase::SENSITIVE))) {
Darren Krahna9474ab2015-11-03 14:38:53 -0800240 continue;
241 }
242 ++test_count;
243 if (!TestKey(test_case.name, test_case.required_for_brillo_pts, test_case.parameters)) {
244 VLOG(1) << "Test failed: " << test_case.name;
245 ++fail_count;
246 }
247 }
248 return fail_count;
249}
250
251int ListTestCases() {
252 const char kBoldGreenRequired[] = "\033[1;32mREQUIRED\033[0m";
253 const char kBoldYellowRecommended[] = "\033[1;33mRECOMMENDED\033[0m";
254 std::vector<TestCase> test_cases = GetTestCases();
255 for (const auto& test_case : test_cases) {
256 printf("%s : %s\n", test_case.name.c_str(),
257 test_case.required_for_brillo_pts ? kBoldGreenRequired : kBoldYellowRecommended);
258 }
259 return 0;
260}
261
Darren Krahn251cb282015-09-28 08:51:18 -0700262std::string ReadFile(const std::string& filename) {
263 std::string content;
264 base::FilePath path(filename);
265 if (!base::ReadFileToString(path, &content)) {
266 printf("Failed to read file: %s\n", filename.c_str());
267 exit(1);
268 }
269 return content;
270}
271
272void WriteFile(const std::string& filename, const std::string& content) {
273 base::FilePath path(filename);
274 int size = content.size();
275 if (base::WriteFile(path, content.data(), size) != size) {
276 printf("Failed to write file: %s\n", filename.c_str());
277 exit(1);
278 }
279}
280
Janis Danisevskisc1460142017-12-18 16:48:46 -0800281int AddEntropy(const std::string& input, int32_t flags) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700282 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
Janis Danisevskisc1460142017-12-18 16:48:46 -0800283 int32_t result = keystore->addRandomNumberGeneratorEntropy(input, flags);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700284 printf("AddEntropy: %d\n", result);
285 return result;
286}
287
Janis Danisevskisc1460142017-12-18 16:48:46 -0800288int GenerateKey(const std::string& name, int32_t flags) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700289 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
290 AuthorizationSetBuilder params;
291 params.RsaSigningKey(2048, 65537)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100292 .Digest(Digest::SHA_2_224)
293 .Digest(Digest::SHA_2_256)
294 .Digest(Digest::SHA_2_384)
295 .Digest(Digest::SHA_2_512)
296 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
297 .Padding(PaddingMode::RSA_PSS)
298 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700299 AuthorizationSet hardware_enforced_characteristics;
300 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc1460142017-12-18 16:48:46 -0800301 auto result = keystore->generateKey(name, params, flags, &hardware_enforced_characteristics,
Shawn Willdenbb22a6c2017-12-06 19:35:28 -0700302 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100303 printf("GenerateKey: %d\n", int32_t(result));
304 if (result.isOk()) {
Darren Krahna9474ab2015-11-03 14:38:53 -0800305 PrintKeyCharacteristics(hardware_enforced_characteristics,
306 software_enforced_characteristics);
307 }
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700308 return result;
309}
310
311int GetCharacteristics(const std::string& name) {
312 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
313 AuthorizationSet hardware_enforced_characteristics;
314 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100315 auto result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
Shawn Willdenbb22a6c2017-12-06 19:35:28 -0700316 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100317 printf("GetCharacteristics: %d\n", int32_t(result));
318 if (result.isOk()) {
Darren Krahna9474ab2015-11-03 14:38:53 -0800319 PrintKeyCharacteristics(hardware_enforced_characteristics,
320 software_enforced_characteristics);
321 }
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700322 return result;
323}
324
325int ExportKey(const std::string& name) {
326 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
327 std::string data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100328 int32_t result = keystore->exportKey(KeyFormat::X509, name, &data);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700329 printf("ExportKey: %d (%zu)\n", result, data.size());
330 return result;
331}
332
333int DeleteKey(const std::string& name) {
334 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
335 int32_t result = keystore->deleteKey(name);
336 printf("DeleteKey: %d\n", result);
337 return result;
338}
339
340int DeleteAllKeys() {
341 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
342 int32_t result = keystore->deleteAllKeys();
343 printf("DeleteAllKeys: %d\n", result);
344 return result;
345}
346
347int DoesKeyExist(const std::string& name) {
348 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
349 printf("DoesKeyExist: %s\n", keystore->doesKeyExist(name) ? "yes" : "no");
350 return 0;
351}
352
353int List(const std::string& prefix) {
354 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
355 std::vector<std::string> key_list;
356 if (!keystore->listKeys(prefix, &key_list)) {
357 printf("ListKeys failed.\n");
358 return 1;
359 }
360 printf("Keys:\n");
361 for (const auto& key_name : key_list) {
362 printf(" %s\n", key_name.c_str());
363 }
364 return 0;
365}
366
367int SignAndVerify(const std::string& name) {
368 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
369 AuthorizationSetBuilder sign_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100370 sign_params.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
371 sign_params.Digest(Digest::SHA_2_256);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700372 AuthorizationSet output_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100373 uint64_t handle;
Shawn Willdenbb22a6c2017-12-06 19:35:28 -0700374 auto result =
375 keystore->beginOperation(KeyPurpose::SIGN, name, sign_params, &output_params, &handle);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100376 if (!result.isOk()) {
377 printf("Sign: BeginOperation failed: %d\n", int32_t(result));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700378 return result;
379 }
380 AuthorizationSet empty_params;
381 size_t num_input_bytes_consumed;
382 std::string output_data;
383 result = keystore->updateOperation(handle, empty_params, "data_to_sign",
384 &num_input_bytes_consumed, &output_params, &output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100385 if (!result.isOk()) {
386 printf("Sign: UpdateOperation failed: %d\n", int32_t(result));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700387 return result;
388 }
389 result = keystore->finishOperation(handle, empty_params, std::string() /*signature_to_verify*/,
390 &output_params, &output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100391 if (!result.isOk()) {
392 printf("Sign: FinishOperation failed: %d\n", int32_t(result));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700393 return result;
394 }
395 printf("Sign: %zu bytes.\n", output_data.size());
396 // We have a signature, now verify it.
397 std::string signature_to_verify = output_data;
Darren Krahn251cb282015-09-28 08:51:18 -0700398 output_data.clear();
Shawn Willdenbb22a6c2017-12-06 19:35:28 -0700399 result =
400 keystore->beginOperation(KeyPurpose::VERIFY, name, sign_params, &output_params, &handle);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100401 if (!result.isOk()) {
402 printf("Verify: BeginOperation failed: %d\n", int32_t(result));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700403 return result;
404 }
405 result = keystore->updateOperation(handle, empty_params, "data_to_sign",
406 &num_input_bytes_consumed, &output_params, &output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100407 if (!result.isOk()) {
408 printf("Verify: UpdateOperation failed: %d\n", int32_t(result));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700409 return result;
410 }
411 result = keystore->finishOperation(handle, empty_params, signature_to_verify, &output_params,
412 &output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100413 if (result == ErrorCode::VERIFICATION_FAILED) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700414 printf("Verify: Failed to verify signature.\n");
415 return result;
416 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100417 if (!result.isOk()) {
418 printf("Verify: FinishOperation failed: %d\n", int32_t(result));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700419 return result;
420 }
421 printf("Verify: OK\n");
422 return 0;
423}
424
Darren Krahn251cb282015-09-28 08:51:18 -0700425int Encrypt(const std::string& key_name, const std::string& input_filename,
Janis Danisevskisc1460142017-12-18 16:48:46 -0800426 const std::string& output_filename, int32_t flags) {
Darren Krahn251cb282015-09-28 08:51:18 -0700427 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
428 std::string input = ReadFile(input_filename);
429 std::string output;
Janis Danisevskisc1460142017-12-18 16:48:46 -0800430 if (!keystore->encryptWithAuthentication(key_name, input, flags, &output)) {
Darren Krahn251cb282015-09-28 08:51:18 -0700431 printf("EncryptWithAuthentication failed.\n");
432 return 1;
433 }
434 WriteFile(output_filename, output);
435 return 0;
436}
437
438int Decrypt(const std::string& key_name, const std::string& input_filename,
439 const std::string& output_filename) {
440 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
441 std::string input = ReadFile(input_filename);
442 std::string output;
443 if (!keystore->decryptWithAuthentication(key_name, input, &output)) {
444 printf("DecryptWithAuthentication failed.\n");
445 return 1;
446 }
447 WriteFile(output_filename, output);
448 return 0;
449}
450
Janis Danisevskisc1460142017-12-18 16:48:46 -0800451uint32_t securityLevelOption2Flags(const CommandLine& cmd) {
452 if (cmd.HasSwitch("seclevel")) {
453 auto str = cmd.GetSwitchValueASCII("seclevel");
454 if (str == "strongbox") {
455 return KEYSTORE_FLAG_STRONGBOX;
456 } else if (str == "software") {
457 return KEYSTORE_FLAG_FALLBACK;
458 }
459 }
460 return KEYSTORE_FLAG_NONE;
461}
462
David Zeuthenc6eb7cd2017-11-27 11:33:55 -0500463class ConfirmationListener : public android::security::BnConfirmationPromptCallback {
464 public:
465 ConfirmationListener() {}
466
467 virtual ::android::binder::Status
468 onConfirmationPromptCompleted(int32_t result,
469 const ::std::vector<uint8_t>& dataThatWasConfirmed) override {
470 ConfirmationResponseCode responseCode = static_cast<ConfirmationResponseCode>(result);
471 printf("Confirmation prompt completed\n"
472 "responseCode = %d\n",
473 responseCode);
474 printf("dataThatWasConfirmed[%zd] = {", dataThatWasConfirmed.size());
475 size_t newLineCountDown = 16;
476 bool hasPrinted = false;
477 for (uint8_t element : dataThatWasConfirmed) {
478 if (hasPrinted) {
479 printf(", ");
480 }
481 if (newLineCountDown == 0) {
482 printf("\n ");
483 newLineCountDown = 32;
484 }
485 printf("0x%02x", element);
486 hasPrinted = true;
487 }
488 printf("}\n");
489 exit(0);
490 }
491};
492
493int Confirmation(const std::string& promptText, const std::string& extraDataHex,
494 const std::string& locale, const std::string& uiOptionsStr,
495 const std::string& cancelAfter) {
496 sp<android::IServiceManager> sm = android::defaultServiceManager();
497 sp<android::IBinder> binder = sm->getService(String16("android.security.keystore"));
498 sp<IKeystoreService> service = android::interface_cast<IKeystoreService>(binder);
Yi Konge353f252018-07-30 01:38:39 -0700499 if (service == nullptr) {
David Zeuthenc6eb7cd2017-11-27 11:33:55 -0500500 printf("error: could not connect to keystore service.\n");
501 return 1;
502 }
503
504 if (promptText.size() == 0) {
Janis Danisevskis1a8d5802018-03-14 13:38:07 -0700505 printf("The --prompt_text parameter cannot be empty.\n");
David Zeuthenc6eb7cd2017-11-27 11:33:55 -0500506 return 1;
507 }
508
509 std::vector<uint8_t> extraData;
510 if (!base::HexStringToBytes(extraDataHex, &extraData)) {
511 printf("The --extra_data parameter does not appear to be valid hexadecimal.\n");
512 return 1;
513 }
514
515 std::vector<std::string> pieces =
516 base::SplitString(uiOptionsStr, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
517 int uiOptionsAsFlags = 0;
518 for (auto& p : pieces) {
519 int value;
520 if (!base::StringToInt(p, &value)) {
521 printf("Error parsing %s in --ui_options parameter as a number.\n", p.c_str());
522 return 1;
523 }
524 uiOptionsAsFlags |= (1 << value);
525 }
526
527 double cancelAfterValue = 0.0;
528
529 if (cancelAfter.size() > 0 && !base::StringToDouble(cancelAfter, &cancelAfterValue)) {
530 printf("Error parsing %s in --cancel_after parameter as a double.\n", cancelAfter.c_str());
531 return 1;
532 }
533
534 String16 promptText16(promptText.data(), promptText.size());
535 String16 locale16(locale.data(), locale.size());
536
537 sp<ConfirmationListener> listener = new ConfirmationListener();
538
539 int32_t aidl_return;
540 android::binder::Status status = service->presentConfirmationPrompt(
541 listener, promptText16, extraData, locale16, uiOptionsAsFlags, &aidl_return);
542 if (!status.isOk()) {
543 printf("Presenting confirmation prompt failed with binder status '%s'.\n",
544 status.toString8().c_str());
545 return 1;
546 }
547 ConfirmationResponseCode responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
548 if (responseCode != ConfirmationResponseCode::OK) {
549 printf("Presenting confirmation prompt failed with response code %d.\n", responseCode);
550 return 1;
551 }
552
553 if (cancelAfterValue > 0.0) {
554 printf("Sleeping %.1f seconds before canceling prompt...\n", cancelAfterValue);
555 base::PlatformThread::Sleep(base::TimeDelta::FromSecondsD(cancelAfterValue));
556 status = service->cancelConfirmationPrompt(listener, &aidl_return);
557 if (!status.isOk()) {
558 printf("Canceling confirmation prompt failed with binder status '%s'.\n",
559 status.toString8().c_str());
560 return 1;
561 }
562 responseCode = static_cast<ConfirmationResponseCode>(aidl_return);
563 if (responseCode != ConfirmationResponseCode::OK) {
564 printf("Canceling confirmation prompt failed with response code %d.\n", responseCode);
565 return 1;
566 }
567 }
568
569 printf("Waiting for prompt to complete - use Ctrl+C to abort...\n");
570 // Use the main thread to process Binder transactions.
571 android::IPCThreadState::self()->joinThreadPool();
572 return 0;
573}
574
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700575} // namespace
576
577int main(int argc, char** argv) {
578 CommandLine::Init(argc, argv);
579 CommandLine* command_line = CommandLine::ForCurrentProcess();
580 CommandLine::StringVector args = command_line->GetArgs();
581 if (args.empty()) {
582 PrintUsageAndExit();
583 }
Darren Krahna9474ab2015-11-03 14:38:53 -0800584 if (args[0] == "brillo-platform-test") {
Darren Krahn82f4f5b2016-03-03 16:21:07 -0800585 return BrilloPlatformTest(command_line->GetSwitchValueASCII("prefix"),
586 command_line->HasSwitch("test_for_0_3"));
Darren Krahna9474ab2015-11-03 14:38:53 -0800587 } else if (args[0] == "list-brillo-tests") {
588 return ListTestCases();
589 } else if (args[0] == "add-entropy") {
Janis Danisevskisc1460142017-12-18 16:48:46 -0800590 return AddEntropy(command_line->GetSwitchValueASCII("input"),
591 securityLevelOption2Flags(*command_line));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700592 } else if (args[0] == "generate") {
Janis Danisevskisc1460142017-12-18 16:48:46 -0800593 return GenerateKey(command_line->GetSwitchValueASCII("name"),
594 securityLevelOption2Flags(*command_line));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700595 } else if (args[0] == "get-chars") {
596 return GetCharacteristics(command_line->GetSwitchValueASCII("name"));
597 } else if (args[0] == "export") {
598 return ExportKey(command_line->GetSwitchValueASCII("name"));
599 } else if (args[0] == "delete") {
600 return DeleteKey(command_line->GetSwitchValueASCII("name"));
601 } else if (args[0] == "delete-all") {
602 return DeleteAllKeys();
603 } else if (args[0] == "exists") {
604 return DoesKeyExist(command_line->GetSwitchValueASCII("name"));
605 } else if (args[0] == "list") {
606 return List(command_line->GetSwitchValueASCII("prefix"));
607 } else if (args[0] == "sign-verify") {
608 return SignAndVerify(command_line->GetSwitchValueASCII("name"));
Darren Krahn251cb282015-09-28 08:51:18 -0700609 } else if (args[0] == "encrypt") {
Janis Danisevskisc1460142017-12-18 16:48:46 -0800610 return Encrypt(
611 command_line->GetSwitchValueASCII("name"), command_line->GetSwitchValueASCII("in"),
612 command_line->GetSwitchValueASCII("out"), securityLevelOption2Flags(*command_line));
Darren Krahn251cb282015-09-28 08:51:18 -0700613 } else if (args[0] == "decrypt") {
614 return Decrypt(command_line->GetSwitchValueASCII("name"),
615 command_line->GetSwitchValueASCII("in"),
616 command_line->GetSwitchValueASCII("out"));
David Zeuthenc6eb7cd2017-11-27 11:33:55 -0500617 } else if (args[0] == "confirmation") {
Janis Danisevskis1a8d5802018-03-14 13:38:07 -0700618 return Confirmation(command_line->GetSwitchValueNative("prompt_text"),
David Zeuthenc6eb7cd2017-11-27 11:33:55 -0500619 command_line->GetSwitchValueASCII("extra_data"),
620 command_line->GetSwitchValueASCII("locale"),
621 command_line->GetSwitchValueASCII("ui_options"),
622 command_line->GetSwitchValueASCII("cancel_after"));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700623 } else {
624 PrintUsageAndExit();
625 }
626 return 0;
627}