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 <cstdio> 16 #include <memory> 17 #include <string> 18 #include <vector> 19 20 #include "base/command_line.h" 21 #include "base/files/file_util.h" 22 #include "keymaster/authorization_set.h" 23 #include "keymaster/keymaster_tags.h" 24 #include "keystore/keystore_client_impl.h" 25 26 using base::CommandLine; 27 using keymaster::AuthorizationSet; 28 using keymaster::AuthorizationSetBuilder; 29 using keystore::KeystoreClient; 30 31 namespace { 32 33 struct TestCase { 34 std::string name; 35 bool required_for_brillo_pts; 36 AuthorizationSet parameters; 37 }; 38 39 void PrintUsageAndExit() { 40 printf("Usage: keystore_client_v2 <command> [options]\n"); 41 printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>]\n" 42 " list-brillo-tests\n" 43 " add-entropy --input=<entropy>\n" 44 " generate --name=<key_name>\n" 45 " get-chars --name=<key_name>\n" 46 " export --name=<key_name>\n" 47 " delete --name=<key_name>\n" 48 " delete-all\n" 49 " exists --name=<key_name>\n" 50 " list [--prefix=<key_name_prefix>]\n" 51 " sign-verify --name=<key_name>\n" 52 " [en|de]crypt --name=<key_name> --in=<file> --out=<file>\n"); 53 exit(1); 54 } 55 56 std::unique_ptr<KeystoreClient> CreateKeystoreInstance() { 57 return std::unique_ptr<KeystoreClient>(new keystore::KeystoreClientImpl); 58 } 59 60 #ifndef KEYMASTER_NAME_TAGS 61 #erro KEYMASTER_NAME_TAGS must be defined 62 #endif 63 64 void PrintTags(const AuthorizationSet& parameters) { 65 const keymaster_key_param_t* iter = nullptr; 66 for (iter = parameters.begin(); iter != parameters.end(); ++iter) { 67 printf(" %s\n", keymaster::StringifyTag(iter->tag)); 68 } 69 } 70 71 void PrintKeyCharacteristics(const AuthorizationSet& hardware_enforced_characteristics, 72 const AuthorizationSet& software_enforced_characteristics) { 73 printf("Hardware:\n"); 74 PrintTags(hardware_enforced_characteristics); 75 printf("Software:\n"); 76 PrintTags(software_enforced_characteristics); 77 } 78 79 bool TestKey(const std::string& name, bool required, const AuthorizationSet& parameters) { 80 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 81 AuthorizationSet hardware_enforced_characteristics; 82 AuthorizationSet software_enforced_characteristics; 83 int32_t result = keystore->generateKey("tmp", parameters, &hardware_enforced_characteristics, 84 &software_enforced_characteristics); 85 if (result != KM_ERROR_OK) { 86 LOG(ERROR) << "Failed to generate key: " << result; 87 printf("%s Result: ABORT\n", name.c_str()); 88 return false; 89 } 90 result = keystore->deleteKey("tmp"); 91 if (result != KM_ERROR_OK) { 92 LOG(ERROR) << "Failed to delete key: " << result; 93 printf("%s Result: ABORT\n", name.c_str()); 94 return false; 95 } 96 printf("===============================================================\n"); 97 printf("%s Key Characteristics:\n", name.c_str()); 98 PrintKeyCharacteristics(hardware_enforced_characteristics, software_enforced_characteristics); 99 bool hardware_backed = (hardware_enforced_characteristics.size() > 0); 100 if (software_enforced_characteristics.GetTagCount(KM_TAG_PURPOSE) > 0 || 101 software_enforced_characteristics.GetTagCount(KM_TAG_ALGORITHM) > 0 || 102 software_enforced_characteristics.GetTagCount(KM_TAG_KEY_SIZE) > 0 || 103 software_enforced_characteristics.GetTagCount(KM_TAG_RSA_PUBLIC_EXPONENT) > 0 || 104 software_enforced_characteristics.GetTagCount(KM_TAG_DIGEST) > 0 || 105 software_enforced_characteristics.GetTagCount(KM_TAG_PADDING) > 0 || 106 software_enforced_characteristics.GetTagCount(KM_TAG_BLOCK_MODE) > 0) { 107 VLOG(1) << "Hardware-backed key but required characteristics enforced in software."; 108 hardware_backed = false; 109 } 110 const char kBoldRedFail[] = "\033[1;31mFAIL\033[0m"; 111 const char kBoldGreenPass[] = "\033[1;32mPASS\033[0m"; 112 const char kBoldYellowWarn[] = "\033[1;33mWARN\033[0m"; 113 printf("[%s] %s\n", 114 hardware_backed ? kBoldGreenPass : (required ? kBoldRedFail : kBoldYellowWarn), 115 name.c_str()); 116 117 return (hardware_backed || !required); 118 } 119 120 AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) { 121 AuthorizationSetBuilder parameters; 122 parameters.RsaSigningKey(key_size, 65537) 123 .Digest(KM_DIGEST_SHA_2_256) 124 .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN) 125 .Padding(KM_PAD_RSA_PSS) 126 .Authorization(keymaster::TAG_NO_AUTH_REQUIRED); 127 if (!sha256_only) { 128 parameters.Digest(KM_DIGEST_SHA_2_224) 129 .Digest(KM_DIGEST_SHA_2_384) 130 .Digest(KM_DIGEST_SHA_2_512); 131 } 132 return parameters.build(); 133 } 134 135 AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) { 136 AuthorizationSetBuilder parameters; 137 parameters.RsaEncryptionKey(key_size, 65537) 138 .Padding(KM_PAD_RSA_PKCS1_1_5_ENCRYPT) 139 .Padding(KM_PAD_RSA_OAEP) 140 .Authorization(keymaster::TAG_NO_AUTH_REQUIRED); 141 return parameters.build(); 142 } 143 144 AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) { 145 AuthorizationSetBuilder parameters; 146 parameters.EcdsaSigningKey(key_size) 147 .Digest(KM_DIGEST_SHA_2_256) 148 .Authorization(keymaster::TAG_NO_AUTH_REQUIRED); 149 if (!sha256_only) { 150 parameters.Digest(KM_DIGEST_SHA_2_224) 151 .Digest(KM_DIGEST_SHA_2_384) 152 .Digest(KM_DIGEST_SHA_2_512); 153 } 154 return parameters.build(); 155 } 156 157 AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) { 158 AuthorizationSetBuilder parameters; 159 parameters.AesEncryptionKey(key_size).Authorization(keymaster::TAG_NO_AUTH_REQUIRED); 160 if (with_gcm_mode) { 161 parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM) 162 .Authorization(keymaster::TAG_MIN_MAC_LENGTH, 128); 163 } else { 164 parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_ECB); 165 parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CBC); 166 parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CTR); 167 } 168 return parameters.build(); 169 } 170 171 AuthorizationSet GetHMACParameters(uint32_t key_size, keymaster_digest_t digest) { 172 AuthorizationSetBuilder parameters; 173 parameters.HmacKey(key_size) 174 .Digest(digest) 175 .Authorization(keymaster::TAG_MIN_MAC_LENGTH, 224) 176 .Authorization(keymaster::TAG_NO_AUTH_REQUIRED); 177 return parameters.build(); 178 } 179 180 std::vector<TestCase> GetTestCases() { 181 TestCase test_cases[] = { 182 {"RSA-2048 Sign", true, GetRSASignParameters(2048, true)}, 183 {"RSA-2048 Sign (more digests)", false, GetRSASignParameters(2048, false)}, 184 {"RSA-3072 Sign", false, GetRSASignParameters(3072, false)}, 185 {"RSA-4096 Sign", false, GetRSASignParameters(4096, false)}, 186 {"RSA-2048 Encrypt", true, GetRSAEncryptParameters(2048)}, 187 {"RSA-3072 Encrypt", false, GetRSAEncryptParameters(3072)}, 188 {"RSA-4096 Encrypt", false, GetRSAEncryptParameters(4096)}, 189 {"ECDSA-P256 Sign", true, GetECDSAParameters(256, true)}, 190 {"ECDSA-P256 Sign (more digests)", false, GetECDSAParameters(256, false)}, 191 {"ECDSA-P224 Sign", false, GetECDSAParameters(224, false)}, 192 {"ECDSA-P384 Sign", false, GetECDSAParameters(384, false)}, 193 {"ECDSA-P521 Sign", false, GetECDSAParameters(521, false)}, 194 {"AES-128", true, GetAESParameters(128, false)}, 195 {"AES-256", true, GetAESParameters(256, false)}, 196 {"AES-128-GCM", false, GetAESParameters(128, true)}, 197 {"AES-256-GCM", false, GetAESParameters(256, true)}, 198 {"HMAC-SHA256-16", true, GetHMACParameters(16, KM_DIGEST_SHA_2_256)}, 199 {"HMAC-SHA256-32", true, GetHMACParameters(32, KM_DIGEST_SHA_2_256)}, 200 {"HMAC-SHA256-64", false, GetHMACParameters(64, KM_DIGEST_SHA_2_256)}, 201 {"HMAC-SHA224-32", false, GetHMACParameters(32, KM_DIGEST_SHA_2_224)}, 202 {"HMAC-SHA384-32", false, GetHMACParameters(32, KM_DIGEST_SHA_2_384)}, 203 {"HMAC-SHA512-32", false, GetHMACParameters(32, KM_DIGEST_SHA_2_512)}, 204 }; 205 return std::vector<TestCase>(&test_cases[0], &test_cases[arraysize(test_cases)]); 206 } 207 208 int BrilloPlatformTest(const std::string& prefix) { 209 int test_count = 0; 210 int fail_count = 0; 211 std::vector<TestCase> test_cases = GetTestCases(); 212 for (const auto& test_case : test_cases) { 213 if (!prefix.empty() && test_case.name.find(prefix) != 0) { 214 continue; 215 } 216 ++test_count; 217 if (!TestKey(test_case.name, test_case.required_for_brillo_pts, test_case.parameters)) { 218 VLOG(1) << "Test failed: " << test_case.name; 219 ++fail_count; 220 } 221 } 222 return fail_count; 223 } 224 225 int ListTestCases() { 226 const char kBoldGreenRequired[] = "\033[1;32mREQUIRED\033[0m"; 227 const char kBoldYellowRecommended[] = "\033[1;33mRECOMMENDED\033[0m"; 228 std::vector<TestCase> test_cases = GetTestCases(); 229 for (const auto& test_case : test_cases) { 230 printf("%s : %s\n", test_case.name.c_str(), 231 test_case.required_for_brillo_pts ? kBoldGreenRequired : kBoldYellowRecommended); 232 } 233 return 0; 234 } 235 236 std::string ReadFile(const std::string& filename) { 237 std::string content; 238 base::FilePath path(filename); 239 if (!base::ReadFileToString(path, &content)) { 240 printf("Failed to read file: %s\n", filename.c_str()); 241 exit(1); 242 } 243 return content; 244 } 245 246 void WriteFile(const std::string& filename, const std::string& content) { 247 base::FilePath path(filename); 248 int size = content.size(); 249 if (base::WriteFile(path, content.data(), size) != size) { 250 printf("Failed to write file: %s\n", filename.c_str()); 251 exit(1); 252 } 253 } 254 255 int AddEntropy(const std::string& input) { 256 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 257 int32_t result = keystore->addRandomNumberGeneratorEntropy(input); 258 printf("AddEntropy: %d\n", result); 259 return result; 260 } 261 262 int GenerateKey(const std::string& name) { 263 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 264 AuthorizationSetBuilder params; 265 params.RsaSigningKey(2048, 65537) 266 .Digest(KM_DIGEST_SHA_2_224) 267 .Digest(KM_DIGEST_SHA_2_256) 268 .Digest(KM_DIGEST_SHA_2_384) 269 .Digest(KM_DIGEST_SHA_2_512) 270 .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN) 271 .Padding(KM_PAD_RSA_PSS) 272 .Authorization(keymaster::TAG_NO_AUTH_REQUIRED); 273 AuthorizationSet hardware_enforced_characteristics; 274 AuthorizationSet software_enforced_characteristics; 275 int32_t result = keystore->generateKey(name, params.build(), &hardware_enforced_characteristics, 276 &software_enforced_characteristics); 277 printf("GenerateKey: %d\n", result); 278 if (result == KM_ERROR_OK) { 279 PrintKeyCharacteristics(hardware_enforced_characteristics, 280 software_enforced_characteristics); 281 } 282 return result; 283 } 284 285 int GetCharacteristics(const std::string& name) { 286 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 287 AuthorizationSet hardware_enforced_characteristics; 288 AuthorizationSet software_enforced_characteristics; 289 int32_t result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics, 290 &software_enforced_characteristics); 291 printf("GetCharacteristics: %d\n", result); 292 if (result == KM_ERROR_OK) { 293 PrintKeyCharacteristics(hardware_enforced_characteristics, 294 software_enforced_characteristics); 295 } 296 return result; 297 } 298 299 int ExportKey(const std::string& name) { 300 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 301 std::string data; 302 int32_t result = keystore->exportKey(KM_KEY_FORMAT_X509, name, &data); 303 printf("ExportKey: %d (%zu)\n", result, data.size()); 304 return result; 305 } 306 307 int DeleteKey(const std::string& name) { 308 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 309 int32_t result = keystore->deleteKey(name); 310 printf("DeleteKey: %d\n", result); 311 return result; 312 } 313 314 int DeleteAllKeys() { 315 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 316 int32_t result = keystore->deleteAllKeys(); 317 printf("DeleteAllKeys: %d\n", result); 318 return result; 319 } 320 321 int DoesKeyExist(const std::string& name) { 322 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 323 printf("DoesKeyExist: %s\n", keystore->doesKeyExist(name) ? "yes" : "no"); 324 return 0; 325 } 326 327 int List(const std::string& prefix) { 328 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 329 std::vector<std::string> key_list; 330 if (!keystore->listKeys(prefix, &key_list)) { 331 printf("ListKeys failed.\n"); 332 return 1; 333 } 334 printf("Keys:\n"); 335 for (const auto& key_name : key_list) { 336 printf(" %s\n", key_name.c_str()); 337 } 338 return 0; 339 } 340 341 int SignAndVerify(const std::string& name) { 342 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 343 AuthorizationSetBuilder sign_params; 344 sign_params.Padding(KM_PAD_RSA_PKCS1_1_5_SIGN); 345 sign_params.Digest(KM_DIGEST_SHA_2_256); 346 AuthorizationSet output_params; 347 keymaster_operation_handle_t handle; 348 int32_t result = keystore->beginOperation(KM_PURPOSE_SIGN, name, sign_params.build(), 349 &output_params, &handle); 350 if (result != KM_ERROR_OK) { 351 printf("Sign: BeginOperation failed: %d\n", result); 352 return result; 353 } 354 AuthorizationSet empty_params; 355 size_t num_input_bytes_consumed; 356 std::string output_data; 357 result = keystore->updateOperation(handle, empty_params, "data_to_sign", 358 &num_input_bytes_consumed, &output_params, &output_data); 359 if (result != KM_ERROR_OK) { 360 printf("Sign: UpdateOperation failed: %d\n", result); 361 return result; 362 } 363 result = keystore->finishOperation(handle, empty_params, std::string() /*signature_to_verify*/, 364 &output_params, &output_data); 365 if (result != KM_ERROR_OK) { 366 printf("Sign: FinishOperation failed: %d\n", result); 367 return result; 368 } 369 printf("Sign: %zu bytes.\n", output_data.size()); 370 // We have a signature, now verify it. 371 std::string signature_to_verify = output_data; 372 output_data.clear(); 373 result = keystore->beginOperation(KM_PURPOSE_VERIFY, name, sign_params.build(), &output_params, 374 &handle); 375 if (result != KM_ERROR_OK) { 376 printf("Verify: BeginOperation failed: %d\n", result); 377 return result; 378 } 379 result = keystore->updateOperation(handle, empty_params, "data_to_sign", 380 &num_input_bytes_consumed, &output_params, &output_data); 381 if (result != KM_ERROR_OK) { 382 printf("Verify: UpdateOperation failed: %d\n", result); 383 return result; 384 } 385 result = keystore->finishOperation(handle, empty_params, signature_to_verify, &output_params, 386 &output_data); 387 if (result == KM_ERROR_VERIFICATION_FAILED) { 388 printf("Verify: Failed to verify signature.\n"); 389 return result; 390 } 391 if (result != KM_ERROR_OK) { 392 printf("Verify: FinishOperation failed: %d\n", result); 393 return result; 394 } 395 printf("Verify: OK\n"); 396 return 0; 397 } 398 399 int Encrypt(const std::string& key_name, const std::string& input_filename, 400 const std::string& output_filename) { 401 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 402 std::string input = ReadFile(input_filename); 403 std::string output; 404 if (!keystore->encryptWithAuthentication(key_name, input, &output)) { 405 printf("EncryptWithAuthentication failed.\n"); 406 return 1; 407 } 408 WriteFile(output_filename, output); 409 return 0; 410 } 411 412 int Decrypt(const std::string& key_name, const std::string& input_filename, 413 const std::string& output_filename) { 414 std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance(); 415 std::string input = ReadFile(input_filename); 416 std::string output; 417 if (!keystore->decryptWithAuthentication(key_name, input, &output)) { 418 printf("DecryptWithAuthentication failed.\n"); 419 return 1; 420 } 421 WriteFile(output_filename, output); 422 return 0; 423 } 424 425 } // namespace 426 427 int main(int argc, char** argv) { 428 CommandLine::Init(argc, argv); 429 CommandLine* command_line = CommandLine::ForCurrentProcess(); 430 CommandLine::StringVector args = command_line->GetArgs(); 431 if (args.empty()) { 432 PrintUsageAndExit(); 433 } 434 if (args[0] == "brillo-platform-test") { 435 return BrilloPlatformTest(command_line->GetSwitchValueASCII("prefix")); 436 } else if (args[0] == "list-brillo-tests") { 437 return ListTestCases(); 438 } else if (args[0] == "add-entropy") { 439 return AddEntropy(command_line->GetSwitchValueASCII("input")); 440 } else if (args[0] == "generate") { 441 return GenerateKey(command_line->GetSwitchValueASCII("name")); 442 } else if (args[0] == "get-chars") { 443 return GetCharacteristics(command_line->GetSwitchValueASCII("name")); 444 } else if (args[0] == "export") { 445 return ExportKey(command_line->GetSwitchValueASCII("name")); 446 } else if (args[0] == "delete") { 447 return DeleteKey(command_line->GetSwitchValueASCII("name")); 448 } else if (args[0] == "delete-all") { 449 return DeleteAllKeys(); 450 } else if (args[0] == "exists") { 451 return DoesKeyExist(command_line->GetSwitchValueASCII("name")); 452 } else if (args[0] == "list") { 453 return List(command_line->GetSwitchValueASCII("prefix")); 454 } else if (args[0] == "sign-verify") { 455 return SignAndVerify(command_line->GetSwitchValueASCII("name")); 456 } else if (args[0] == "encrypt") { 457 return Encrypt(command_line->GetSwitchValueASCII("name"), 458 command_line->GetSwitchValueASCII("in"), 459 command_line->GetSwitchValueASCII("out")); 460 } else if (args[0] == "decrypt") { 461 return Decrypt(command_line->GetSwitchValueASCII("name"), 462 command_line->GetSwitchValueASCII("in"), 463 command_line->GetSwitchValueASCII("out")); 464 } else { 465 PrintUsageAndExit(); 466 } 467 return 0; 468 } 469