blob: 5dd0f762adaa1f0107bd4ac0b92cdad04920a964
1 | /* |
2 | * Copyright 2014 The Android Open Source Project |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #ifndef SYSTEM_KEYMASTER_ANDROID_KEYMASTER_TEST_UTILS_H_ |
18 | #define SYSTEM_KEYMASTER_ANDROID_KEYMASTER_TEST_UTILS_H_ |
19 | |
20 | /* |
21 | * Utilities used to help with testing. Not used in production code. |
22 | */ |
23 | |
24 | #include <stdarg.h> |
25 | |
26 | #include <algorithm> |
27 | #include <memory> |
28 | #include <ostream> |
29 | #include <string> |
30 | #include <vector> |
31 | |
32 | #include <gtest/gtest.h> |
33 | |
34 | #include <hardware/keymaster0.h> |
35 | #include <hardware/keymaster1.h> |
36 | #include <hardware/keymaster2.h> |
37 | #include <hardware/keymaster_defs.h> |
38 | |
39 | #include <keymaster/android_keymaster_utils.h> |
40 | #include <keymaster/authorization_set.h> |
41 | #include <keymaster/keymaster_context.h> |
42 | #include <keymaster/logger.h> |
43 | |
44 | std::ostream& operator<<(std::ostream& os, const keymaster_key_param_t& param); |
45 | bool operator==(const keymaster_key_param_t& a, const keymaster_key_param_t& b); |
46 | std::string hex2str(std::string); |
47 | |
48 | namespace keymaster { |
49 | |
50 | bool operator==(const AuthorizationSet& a, const AuthorizationSet& b); |
51 | bool operator!=(const AuthorizationSet& a, const AuthorizationSet& b); |
52 | |
53 | std::ostream& operator<<(std::ostream& os, const AuthorizationSet& set); |
54 | |
55 | namespace test { |
56 | |
57 | template <keymaster_tag_t Tag, typename KeymasterEnum> |
58 | bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM, Tag, KeymasterEnum> tag, |
59 | KeymasterEnum val) { |
60 | int pos = set.find(tag); |
61 | return pos != -1 && static_cast<KeymasterEnum>(set[pos].enumerated) == val; |
62 | } |
63 | |
64 | template <keymaster_tag_t Tag, typename KeymasterEnum> |
65 | bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM_REP, Tag, KeymasterEnum> tag, |
66 | KeymasterEnum val) { |
67 | int pos = -1; |
68 | while ((pos = set.find(tag, pos)) != -1) |
69 | if (static_cast<KeymasterEnum>(set[pos].enumerated) == val) |
70 | return true; |
71 | return false; |
72 | } |
73 | |
74 | template <keymaster_tag_t Tag> |
75 | bool contains(const AuthorizationSet& set, TypedTag<KM_UINT, Tag> tag, uint32_t val) { |
76 | int pos = set.find(tag); |
77 | return pos != -1 && set[pos].integer == val; |
78 | } |
79 | |
80 | template <keymaster_tag_t Tag> |
81 | bool contains(const AuthorizationSet& set, TypedTag<KM_UINT_REP, Tag> tag, uint32_t val) { |
82 | int pos = -1; |
83 | while ((pos = set.find(tag, pos)) != -1) |
84 | if (set[pos].integer == val) |
85 | return true; |
86 | return false; |
87 | } |
88 | |
89 | template <keymaster_tag_t Tag> |
90 | bool contains(const AuthorizationSet& set, TypedTag<KM_ULONG, Tag> tag, uint64_t val) { |
91 | int pos = set.find(tag); |
92 | return pos != -1 && set[pos].long_integer == val; |
93 | } |
94 | |
95 | template <keymaster_tag_t Tag> |
96 | bool contains(const AuthorizationSet& set, TypedTag<KM_BYTES, Tag> tag, const std::string& val) { |
97 | int pos = set.find(tag); |
98 | return pos != -1 && |
99 | std::string(reinterpret_cast<const char*>(set[pos].blob.data), |
100 | set[pos].blob.data_length) == val; |
101 | } |
102 | |
103 | template <keymaster_tag_t Tag> |
104 | bool contains(const AuthorizationSet& set, TypedTag<KM_BIGNUM, Tag> tag, const std::string& val) { |
105 | int pos = set.find(tag); |
106 | return pos != -1 && |
107 | std::string(reinterpret_cast<const char*>(set[pos].blob.data), |
108 | set[pos].blob.data_length) == val; |
109 | } |
110 | |
111 | inline bool contains(const AuthorizationSet& set, keymaster_tag_t tag) { |
112 | return set.find(tag) != -1; |
113 | } |
114 | |
115 | class StdoutLogger : public Logger { |
116 | public: |
117 | StdoutLogger() { set_instance(this); } |
118 | |
119 | int log_msg(LogLevel level, const char* fmt, va_list args) const { |
120 | int output_len = 0; |
121 | switch (level) { |
122 | case DEBUG_LVL: |
123 | output_len = printf("DEBUG: "); |
124 | break; |
125 | case INFO_LVL: |
126 | output_len = printf("INFO: "); |
127 | break; |
128 | case WARNING_LVL: |
129 | output_len = printf("WARNING: "); |
130 | break; |
131 | case ERROR_LVL: |
132 | output_len = printf("ERROR: "); |
133 | break; |
134 | case SEVERE_LVL: |
135 | output_len = printf("SEVERE: "); |
136 | break; |
137 | } |
138 | |
139 | output_len += vprintf(fmt, args); |
140 | output_len += printf("\n"); |
141 | return output_len; |
142 | } |
143 | }; |
144 | |
145 | inline std::string make_string(const uint8_t* data, size_t length) { |
146 | return std::string(reinterpret_cast<const char*>(data), length); |
147 | } |
148 | |
149 | template <size_t N> std::string make_string(const uint8_t (&a)[N]) { |
150 | return make_string(a, N); |
151 | } |
152 | |
153 | /** |
154 | * Keymaster2TestInstance is used to parameterize Keymaster2Tests. Its main function is to create a |
155 | * keymaster2_device_t to which test calls can be directed. It also provides a place to specify |
156 | * various bits of alternative behavior, in cases where different devices are expected to behave |
157 | * differently (any such cases are a potential bug, but sometimes they may make sense). |
158 | */ |
159 | class Keymaster2TestInstanceCreator { |
160 | public: |
161 | virtual ~Keymaster2TestInstanceCreator(){}; |
162 | virtual keymaster2_device_t* CreateDevice() const = 0; |
163 | |
164 | virtual bool algorithm_in_km0_hardware(keymaster_algorithm_t algorithm) const = 0; |
165 | virtual int keymaster0_calls() const = 0; |
166 | virtual int minimal_digest_set() const { return false; } |
167 | virtual bool is_keymaster1_hw() const = 0; |
168 | virtual KeymasterContext* keymaster_context() const = 0; |
169 | }; |
170 | |
171 | // Use a shared_ptr because it's copyable. |
172 | typedef std::shared_ptr<Keymaster2TestInstanceCreator> InstanceCreatorPtr; |
173 | |
174 | const uint64_t OP_HANDLE_SENTINEL = 0xFFFFFFFFFFFFFFFF; |
175 | class Keymaster2Test : public testing::TestWithParam<InstanceCreatorPtr> { |
176 | protected: |
177 | Keymaster2Test(); |
178 | ~Keymaster2Test(); |
179 | |
180 | keymaster2_device_t* device(); |
181 | |
182 | keymaster_error_t GenerateKey(const AuthorizationSetBuilder& builder); |
183 | |
184 | keymaster_error_t DeleteKey(); |
185 | |
186 | keymaster_error_t ImportKey(const AuthorizationSetBuilder& builder, |
187 | keymaster_key_format_t format, const std::string& key_material); |
188 | |
189 | keymaster_error_t ExportKey(keymaster_key_format_t format, std::string* export_data); |
190 | |
191 | keymaster_error_t GetCharacteristics(); |
192 | |
193 | keymaster_error_t BeginOperation(keymaster_purpose_t purpose); |
194 | keymaster_error_t BeginOperation(keymaster_purpose_t purpose, const AuthorizationSet& input_set, |
195 | AuthorizationSet* output_set = NULL); |
196 | |
197 | keymaster_error_t UpdateOperation(const std::string& message, std::string* output, |
198 | size_t* input_consumed); |
199 | keymaster_error_t UpdateOperation(const AuthorizationSet& additional_params, |
200 | const std::string& message, AuthorizationSet* output_params, |
201 | std::string* output, size_t* input_consumed); |
202 | |
203 | keymaster_error_t FinishOperation(std::string* output); |
204 | keymaster_error_t FinishOperation(const std::string& signature, std::string* output); |
205 | keymaster_error_t FinishOperation(const AuthorizationSet& additional_params, |
206 | const std::string& signature, std::string* output) { |
207 | return FinishOperation(additional_params, signature, nullptr /* output_params */, output); |
208 | } |
209 | keymaster_error_t FinishOperation(const AuthorizationSet& additional_params, |
210 | const std::string& signature, AuthorizationSet* output_params, |
211 | std::string* output); |
212 | |
213 | keymaster_error_t AbortOperation(); |
214 | |
215 | keymaster_error_t AttestKey(const std::string& attest_challenge, keymaster_cert_chain_t* chain); |
216 | |
217 | keymaster_error_t UpgradeKey(const AuthorizationSet& upgrade_params); |
218 | |
219 | keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor); |
220 | |
221 | std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message); |
222 | std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message, |
223 | const AuthorizationSet& begin_params, |
224 | const AuthorizationSet& update_params, |
225 | AuthorizationSet* output_params = NULL); |
226 | std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message, |
227 | const std::string& signature, const AuthorizationSet& begin_params, |
228 | const AuthorizationSet& update_params, |
229 | AuthorizationSet* output_params = NULL); |
230 | std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message, |
231 | const std::string& signature); |
232 | |
233 | void SignMessage(const std::string& message, std::string* signature, keymaster_digest_t digest); |
234 | void SignMessage(const std::string& message, std::string* signature, keymaster_digest_t digest, |
235 | keymaster_padding_t padding); |
236 | void MacMessage(const std::string& message, std::string* signature, size_t mac_length); |
237 | |
238 | void VerifyMessage(const std::string& message, const std::string& signature, |
239 | keymaster_digest_t digest); |
240 | void VerifyMessage(const std::string& message, const std::string& signature, |
241 | keymaster_digest_t digest, keymaster_padding_t padding); |
242 | void VerifyMac(const std::string& message, const std::string& signature); |
243 | |
244 | std::string EncryptMessage(const std::string& message, keymaster_padding_t padding, |
245 | std::string* generated_nonce = NULL); |
246 | std::string EncryptMessage(const std::string& message, keymaster_digest_t digest, |
247 | keymaster_padding_t padding, std::string* generated_nonce = NULL); |
248 | std::string EncryptMessage(const std::string& message, keymaster_block_mode_t block_mode, |
249 | keymaster_padding_t padding, std::string* generated_nonce = NULL); |
250 | std::string EncryptMessage(const AuthorizationSet& update_params, const std::string& message, |
251 | keymaster_digest_t digest, keymaster_padding_t padding, |
252 | std::string* generated_nonce = NULL); |
253 | std::string EncryptMessage(const AuthorizationSet& update_params, const std::string& message, |
254 | keymaster_block_mode_t block_mode, keymaster_padding_t padding, |
255 | std::string* generated_nonce = NULL); |
256 | std::string EncryptMessageWithParams(const std::string& message, |
257 | const AuthorizationSet& begin_params, |
258 | const AuthorizationSet& update_params, |
259 | AuthorizationSet* output_params); |
260 | |
261 | std::string DecryptMessage(const std::string& ciphertext, keymaster_padding_t padding); |
262 | std::string DecryptMessage(const std::string& ciphertext, keymaster_digest_t digest, |
263 | keymaster_padding_t padding); |
264 | std::string DecryptMessage(const std::string& ciphertext, keymaster_block_mode_t block_mode, |
265 | keymaster_padding_t padding); |
266 | std::string DecryptMessage(const std::string& ciphertext, keymaster_digest_t digest, |
267 | keymaster_padding_t padding, const std::string& nonce); |
268 | std::string DecryptMessage(const std::string& ciphertext, keymaster_block_mode_t block_mode, |
269 | keymaster_padding_t padding, const std::string& nonce); |
270 | std::string DecryptMessage(const AuthorizationSet& update_params, const std::string& ciphertext, |
271 | keymaster_digest_t digest, keymaster_padding_t padding, |
272 | const std::string& nonce); |
273 | std::string DecryptMessage(const AuthorizationSet& update_params, const std::string& ciphertext, |
274 | keymaster_block_mode_t block_mode, keymaster_padding_t padding, |
275 | const std::string& nonce); |
276 | |
277 | void CheckHmacTestVector(const std::string& key, const std::string& message, keymaster_digest_t digest, |
278 | std::string expected_mac); |
279 | void CheckAesOcbTestVector(const std::string& key, const std::string& nonce, |
280 | const std::string& associated_data, const std::string& message, |
281 | const std::string& expected_ciphertext); |
282 | void CheckAesCtrTestVector(const std::string& key, const std::string& nonce, |
283 | const std::string& message, const std::string& expected_ciphertext); |
284 | AuthorizationSet UserAuthParams(); |
285 | AuthorizationSet ClientParams(); |
286 | |
287 | template <typename T> |
288 | bool ResponseContains(const std::vector<T>& expected, const T* values, size_t len) { |
289 | return expected.size() == len && |
290 | std::is_permutation(values, values + len, expected.begin()); |
291 | } |
292 | |
293 | template <typename T> bool ResponseContains(T expected, const T* values, size_t len) { |
294 | return (len == 1 && *values == expected); |
295 | } |
296 | |
297 | AuthorizationSet hw_enforced(); |
298 | AuthorizationSet sw_enforced(); |
299 | |
300 | void FreeCharacteristics(); |
301 | void FreeKeyBlob(); |
302 | |
303 | void corrupt_key_blob(); |
304 | |
305 | void set_key_blob(const uint8_t* key, size_t key_length) { |
306 | FreeKeyBlob(); |
307 | blob_.key_material = key; |
308 | blob_.key_material_size = key_length; |
309 | } |
310 | |
311 | AuthorizationSet client_params() { |
312 | return AuthorizationSet(client_params_, sizeof(client_params_) / sizeof(client_params_[0])); |
313 | } |
314 | |
315 | private: |
316 | keymaster2_device_t* device_; |
317 | keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"), |
318 | .data_length = 6}; |
319 | keymaster_key_param_t client_params_[1] = { |
320 | Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)}; |
321 | |
322 | uint64_t op_handle_; |
323 | |
324 | keymaster_key_blob_t blob_; |
325 | keymaster_key_characteristics_t characteristics_; |
326 | }; |
327 | |
328 | struct Keymaster0CountingWrapper : public keymaster0_device_t { |
329 | explicit Keymaster0CountingWrapper(keymaster0_device_t* device) : device_(device), counter_(0) { |
330 | common = device_->common; |
331 | common.close = counting_close_device; |
332 | client_version = device_->client_version; |
333 | flags = device_->flags; |
334 | context = this; |
335 | |
336 | generate_keypair = counting_generate_keypair; |
337 | import_keypair = counting_import_keypair; |
338 | get_keypair_public = counting_get_keypair_public; |
339 | delete_keypair = counting_delete_keypair; |
340 | delete_all = counting_delete_all; |
341 | sign_data = counting_sign_data; |
342 | verify_data = counting_verify_data; |
343 | } |
344 | |
345 | int count() { return counter_; } |
346 | |
347 | // The blobs generated by the underlying softkeymaster start with "PK#8". Tweak the prefix so |
348 | // they don't get identified as softkeymaster blobs. |
349 | static void munge_blob(uint8_t* blob, size_t blob_length) { |
350 | if (blob && blob_length > 0 && *blob == 'P') |
351 | *blob = 'Q'; // Mind your Ps and Qs! |
352 | } |
353 | |
354 | // Copy and un-modfy the blob. The caller must clean up the return value. |
355 | static uint8_t* unmunge_blob(const uint8_t* blob, size_t blob_length) { |
356 | uint8_t* dup_blob = dup_buffer(blob, blob_length); |
357 | if (dup_blob && blob_length > 0 && *dup_blob == 'Q') |
358 | *dup_blob = 'P'; |
359 | return dup_blob; |
360 | } |
361 | |
362 | static keymaster0_device_t* device(const keymaster0_device_t* dev) { |
363 | Keymaster0CountingWrapper* wrapper = |
364 | reinterpret_cast<Keymaster0CountingWrapper*>(dev->context); |
365 | return wrapper->device_; |
366 | } |
367 | |
368 | static void increment(const keymaster0_device_t* dev) { |
369 | Keymaster0CountingWrapper* wrapper = |
370 | reinterpret_cast<Keymaster0CountingWrapper*>(dev->context); |
371 | wrapper->counter_++; |
372 | } |
373 | |
374 | static int counting_close_device(hw_device_t* dev) { |
375 | keymaster0_device_t* k0_dev = reinterpret_cast<keymaster0_device_t*>(dev); |
376 | increment(k0_dev); |
377 | Keymaster0CountingWrapper* wrapper = |
378 | reinterpret_cast<Keymaster0CountingWrapper*>(k0_dev->context); |
379 | int retval = |
380 | wrapper->device_->common.close(reinterpret_cast<hw_device_t*>(wrapper->device_)); |
381 | delete wrapper; |
382 | return retval; |
383 | } |
384 | |
385 | static int counting_generate_keypair(const struct keymaster0_device* dev, |
386 | const keymaster_keypair_t key_type, const void* key_params, |
387 | uint8_t** key_blob, size_t* key_blob_length) { |
388 | increment(dev); |
389 | int result = device(dev)->generate_keypair(device(dev), key_type, key_params, key_blob, |
390 | key_blob_length); |
391 | if (result == 0) |
392 | munge_blob(*key_blob, *key_blob_length); |
393 | return result; |
394 | } |
395 | |
396 | static int counting_import_keypair(const struct keymaster0_device* dev, const uint8_t* key, |
397 | const size_t key_length, uint8_t** key_blob, |
398 | size_t* key_blob_length) { |
399 | increment(dev); |
400 | int result = |
401 | device(dev)->import_keypair(device(dev), key, key_length, key_blob, key_blob_length); |
402 | if (result == 0) |
403 | munge_blob(*key_blob, *key_blob_length); |
404 | return result; |
405 | } |
406 | |
407 | static int counting_get_keypair_public(const struct keymaster0_device* dev, |
408 | const uint8_t* key_blob, const size_t key_blob_length, |
409 | uint8_t** x509_data, size_t* x509_data_length) { |
410 | increment(dev); |
411 | std::unique_ptr<uint8_t[]> dup_blob(unmunge_blob(key_blob, key_blob_length)); |
412 | return device(dev)->get_keypair_public(device(dev), dup_blob.get(), key_blob_length, |
413 | x509_data, x509_data_length); |
414 | } |
415 | |
416 | static int counting_delete_keypair(const struct keymaster0_device* dev, const uint8_t* key_blob, |
417 | const size_t key_blob_length) { |
418 | increment(dev); |
419 | if (key_blob && key_blob_length > 0) |
420 | EXPECT_EQ('Q', *key_blob); |
421 | if (device(dev)->delete_keypair) { |
422 | std::unique_ptr<uint8_t[]> dup_blob(unmunge_blob(key_blob, key_blob_length)); |
423 | return device(dev)->delete_keypair(device(dev), dup_blob.get(), key_blob_length); |
424 | } |
425 | return 0; |
426 | } |
427 | |
428 | static int counting_delete_all(const struct keymaster0_device* dev) { |
429 | increment(dev); |
430 | if (device(dev)->delete_all) |
431 | return device(dev)->delete_all(device(dev)); |
432 | return 0; |
433 | } |
434 | |
435 | static int counting_sign_data(const struct keymaster0_device* dev, const void* signing_params, |
436 | const uint8_t* key_blob, const size_t key_blob_length, |
437 | const uint8_t* data, const size_t data_length, |
438 | uint8_t** signed_data, size_t* signed_data_length) { |
439 | increment(dev); |
440 | std::unique_ptr<uint8_t[]> dup_blob(unmunge_blob(key_blob, key_blob_length)); |
441 | return device(dev)->sign_data(device(dev), signing_params, dup_blob.get(), key_blob_length, |
442 | data, data_length, signed_data, signed_data_length); |
443 | } |
444 | |
445 | static int counting_verify_data(const struct keymaster0_device* dev, const void* signing_params, |
446 | const uint8_t* key_blob, const size_t key_blob_length, |
447 | const uint8_t* signed_data, const size_t signed_data_length, |
448 | const uint8_t* signature, const size_t signature_length) { |
449 | increment(dev); |
450 | std::unique_ptr<uint8_t[]> dup_blob(unmunge_blob(key_blob, key_blob_length)); |
451 | return device(dev)->verify_data(device(dev), signing_params, dup_blob.get(), |
452 | key_blob_length, signed_data, signed_data_length, signature, |
453 | signature_length); |
454 | } |
455 | |
456 | private: |
457 | keymaster0_device_t* device_; |
458 | int counter_; |
459 | }; |
460 | |
461 | /** |
462 | * This function takes a keymaster1_device_t and wraps it in an adapter that supports only |
463 | * KM_DIGEST_SHA_2_256. |
464 | */ |
465 | keymaster1_device_t* make_device_sha256_only(keymaster1_device_t* device); |
466 | |
467 | } // namespace test |
468 | } // namespace keymaster |
469 | |
470 | #endif // SYSTEM_KEYMASTER_ANDROID_KEYMASTER_TEST_UTILS_H_ |
471 |