• 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 <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 
PrintUsageAndExit()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 
CreateKeystoreInstance()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 
PrintTags(const AuthorizationSet & parameters)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 
PrintKeyCharacteristics(const AuthorizationSet & hardware_enforced_characteristics,const AuthorizationSet & software_enforced_characteristics)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 
TestKey(const std::string & name,bool required,const AuthorizationSet & parameters)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 
GetRSASignParameters(uint32_t key_size,bool sha256_only)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 
GetRSAEncryptParameters(uint32_t key_size)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 
GetECDSAParameters(uint32_t key_size,bool sha256_only)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 
GetAESParameters(uint32_t key_size,bool with_gcm_mode)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 
GetHMACParameters(uint32_t key_size,keymaster_digest_t digest)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 
GetTestCases()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 
BrilloPlatformTest(const std::string & prefix)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 
ListTestCases()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 
ReadFile(const std::string & filename)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 
WriteFile(const std::string & filename,const std::string & content)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 
AddEntropy(const std::string & input)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 
GenerateKey(const std::string & name)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 
GetCharacteristics(const std::string & name)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 
ExportKey(const std::string & name)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 
DeleteKey(const std::string & name)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 
DeleteAllKeys()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 
DoesKeyExist(const std::string & name)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 
List(const std::string & prefix)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 
SignAndVerify(const std::string & name)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 
Encrypt(const std::string & key_name,const std::string & input_filename,const std::string & output_filename)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 
Decrypt(const std::string & key_name,const std::string & input_filename,const std::string & output_filename)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 
main(int argc,char ** argv)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