blob: 7a8c785e20624ebc0a43543c3f9cabf4e9175972
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 | #define LOG_TAG "AmlKeymaster" |
18 | |
19 | #include <assert.h> |
20 | #include <openssl/evp.h> |
21 | #include <openssl/x509.h> |
22 | #include <openssl/sha.h> |
23 | #include <stddef.h> |
24 | #include <stdio.h> |
25 | #include <stdlib.h> |
26 | #include <string.h> |
27 | #include <time.h> |
28 | #include <fstream> |
29 | #include <iostream> |
30 | #include <inttypes.h> |
31 | |
32 | #include <algorithm> |
33 | #include <type_traits> |
34 | |
35 | #include <hardware/keymaster2.h> |
36 | #include <keymaster/authorization_set.h> |
37 | #include <log/log.h> |
38 | #include <utils/String8.h> |
39 | |
40 | #include "keymaster_ipc.h" |
41 | #include "aml_keymaster_device.h" |
42 | #include "aml_keymaster_ipc.h" |
43 | |
44 | #ifndef KEYMASTER_TEMP_FAILURE_RETRY |
45 | #define KEYMASTER_TEMP_FAILURE_RETRY(exp, retry) \ |
46 | ({ \ |
47 | __typeof__(exp) _rc; \ |
48 | int count = 0; \ |
49 | do { \ |
50 | _rc = (exp); \ |
51 | count ++; \ |
52 | } while (_rc != TEEC_SUCCESS && count < retry); \ |
53 | _rc; \ |
54 | }) |
55 | #endif |
56 | |
57 | const uint32_t RECV_BUF_SIZE = 66 * 1024; |
58 | const uint32_t SEND_BUF_SIZE = (66 * 1024 - sizeof(struct keymaster_message) - 16 /* tipc header */); |
59 | |
60 | const size_t kMaximumAttestationChallengeLength = 128; |
61 | const size_t kMaximumFinishInputLength = 64 * 1024; |
62 | |
63 | namespace keymaster { |
64 | |
65 | static keymaster_error_t translate_error(TEEC_Result err) { |
66 | switch (err) { |
67 | case TEEC_SUCCESS: |
68 | return KM_ERROR_OK; |
69 | case TEEC_ERROR_ACCESS_DENIED: |
70 | return KM_ERROR_SECURE_HW_ACCESS_DENIED; |
71 | |
72 | case TEEC_ERROR_CANCEL: |
73 | return KM_ERROR_OPERATION_CANCELLED; |
74 | |
75 | case TEEC_ERROR_NOT_IMPLEMENTED: |
76 | return KM_ERROR_UNIMPLEMENTED; |
77 | |
78 | case TEEC_ERROR_OUT_OF_MEMORY: |
79 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
80 | |
81 | case TEEC_ERROR_BUSY: |
82 | return KM_ERROR_SECURE_HW_BUSY; |
83 | |
84 | case TEEC_ERROR_COMMUNICATION: |
85 | return KM_ERROR_SECURE_HW_COMMUNICATION_FAILED; |
86 | |
87 | case TEEC_ERROR_SHORT_BUFFER: |
88 | return KM_ERROR_INVALID_INPUT_LENGTH; |
89 | |
90 | default: |
91 | return KM_ERROR_UNKNOWN_ERROR; |
92 | } |
93 | } |
94 | |
95 | AmlKeymasterDevice::AmlKeymasterDevice(const hw_module_t* module) { |
96 | static_assert(std::is_standard_layout<AmlKeymasterDevice>::value, |
97 | "AmlKeymasterDevice must be standard layout"); |
98 | static_assert(offsetof(AmlKeymasterDevice, device_) == 0, |
99 | "device_ must be the first member of AmlKeymasterDevice"); |
100 | static_assert(offsetof(AmlKeymasterDevice, device_.common) == 0, |
101 | "common must be the first member of keymaster2_device"); |
102 | |
103 | ALOGI("Creating device"); |
104 | ALOGD("Device address: %p", this); |
105 | |
106 | device_ = {}; |
107 | |
108 | device_.common.tag = HARDWARE_DEVICE_TAG; |
109 | device_.common.version = 1; |
110 | device_.common.module = const_cast<hw_module_t*>(module); |
111 | device_.common.close = close_device; |
112 | |
113 | device_.flags = KEYMASTER_SUPPORTS_EC; |
114 | |
115 | device_.configure = configure; |
116 | device_.add_rng_entropy = add_rng_entropy; |
117 | device_.generate_key = generate_key; |
118 | device_.get_key_characteristics = get_key_characteristics; |
119 | device_.import_key = import_key; |
120 | device_.export_key = export_key; |
121 | device_.attest_key = attest_key; |
122 | device_.upgrade_key = upgrade_key; |
123 | device_.delete_key = delete_key; |
124 | device_.delete_all_keys = nullptr; |
125 | device_.begin = begin; |
126 | device_.update = update; |
127 | device_.finish = finish; |
128 | device_.abort = abort; |
129 | |
130 | KM_context.fd = 0; |
131 | KM_session.ctx = NULL; |
132 | KM_session.session_id = 0; |
133 | |
134 | |
135 | TEEC_Result rc = KEYMASTER_TEMP_FAILURE_RETRY(aml_keymaster_connect(&KM_context, &KM_session), 100); |
136 | error_ = translate_error(rc); |
137 | if (rc != TEEC_SUCCESS) { |
138 | ALOGE("failed to connect to keymaster (0x%x)", rc); |
139 | error_ = KM_ERROR_SECURE_HW_COMMUNICATION_FAILED; |
140 | return; |
141 | } |
142 | |
143 | GetVersionRequest version_request; |
144 | GetVersionResponse version_response; |
145 | error_ = Send(KM_GET_VERSION, version_request, &version_response); |
146 | if (error_ == KM_ERROR_INVALID_ARGUMENT || error_ == KM_ERROR_UNIMPLEMENTED) { |
147 | ALOGE("\"Bad parameters\" error on GetVersion call. Version 0 is not supported."); |
148 | error_ = KM_ERROR_VERSION_MISMATCH; |
149 | return; |
150 | } |
151 | message_version_ = MessageVersion(version_response.major_ver, version_response.minor_ver, |
152 | version_response.subminor_ver); |
153 | if (message_version_ < 0) { |
154 | // Can't translate version? Keymaster implementation must be newer. |
155 | ALOGE("Keymaster version %d.%d.%d not supported.", version_response.major_ver, |
156 | version_response.minor_ver, version_response.subminor_ver); |
157 | error_ = KM_ERROR_VERSION_MISMATCH; |
158 | } |
159 | } |
160 | |
161 | AmlKeymasterDevice::~AmlKeymasterDevice() { |
162 | if (KM_session.ctx != NULL) |
163 | aml_keymaster_disconnect(&KM_context, &KM_session); |
164 | } |
165 | |
166 | namespace { |
167 | |
168 | // Allocates a new buffer with malloc and copies the contents of |buffer| to it. Caller takes |
169 | // ownership of the returned buffer. |
170 | uint8_t* DuplicateBuffer(const uint8_t* buffer, size_t size) { |
171 | uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(size)); |
172 | if (tmp) { |
173 | memcpy(tmp, buffer, size); |
174 | } |
175 | return tmp; |
176 | } |
177 | |
178 | template <typename RequestType> |
179 | void AddClientAndAppData(const keymaster_blob_t* client_id, const keymaster_blob_t* app_data, |
180 | RequestType* request) { |
181 | request->additional_params.Clear(); |
182 | if (client_id) { |
183 | request->additional_params.push_back(TAG_APPLICATION_ID, *client_id); |
184 | } |
185 | if (app_data) { |
186 | request->additional_params.push_back(TAG_APPLICATION_DATA, *app_data); |
187 | } |
188 | } |
189 | |
190 | } // unnamed namespace |
191 | |
192 | struct tag_table_entry { |
193 | const char *name; |
194 | keymaster_tag_t tag; |
195 | }; |
196 | |
197 | static struct tag_table_entry tag_table[] = |
198 | { |
199 | {"KM_TAG_PURPOSE", KM_TAG_PURPOSE}, |
200 | {"KM_TAG_ALGORITHM", KM_TAG_ALGORITHM}, |
201 | {"KM_TAG_KEY_SIZE", KM_TAG_KEY_SIZE}, |
202 | {"KM_TAG_BLOCK_MODE", KM_TAG_BLOCK_MODE}, |
203 | {"KM_TAG_DIGEST", KM_TAG_DIGEST}, |
204 | {"KM_TAG_PADDING", KM_TAG_PADDING}, |
205 | {"KM_TAG_CALLER_NONCE", KM_TAG_CALLER_NONCE}, |
206 | {"KM_TAG_MIN_MAC_LENGTH", KM_TAG_MIN_MAC_LENGTH}, |
207 | {"KM_TAG_RSA_PUBLIC_EXPONENT", KM_TAG_RSA_PUBLIC_EXPONENT}, |
208 | {"KM_TAG_BLOB_USAGE_REQUIREMENTS", KM_TAG_BLOB_USAGE_REQUIREMENTS}, |
209 | {"KM_TAG_BOOTLOADER_ONLY", KM_TAG_BOOTLOADER_ONLY}, |
210 | {"KM_TAG_ACTIVE_DATETIME", KM_TAG_ACTIVE_DATETIME}, |
211 | {"KM_TAG_ORIGINATION_EXPIRE_DATETIME", KM_TAG_ORIGINATION_EXPIRE_DATETIME}, |
212 | {"KM_TAG_USAGE_EXPIRE_DATETIME",KM_TAG_USAGE_EXPIRE_DATETIME}, |
213 | {"KM_TAG_MIN_SECONDS_BETWEEN_OPS",KM_TAG_MIN_SECONDS_BETWEEN_OPS}, |
214 | {"KM_TAG_MAX_USES_PER_BOOT",KM_TAG_MAX_USES_PER_BOOT}, |
215 | {"KM_TAG_ALL_USERS", KM_TAG_ALL_USERS}, |
216 | {"KM_TAG_USER_ID", KM_TAG_USER_ID}, |
217 | {"KM_TAG_USER_SECURE_ID",KM_TAG_USER_SECURE_ID}, |
218 | {"KM_TAG_NO_AUTH_REQUIRED",KM_TAG_NO_AUTH_REQUIRED}, |
219 | {"KM_TAG_USER_AUTH_TYPE ", KM_TAG_USER_AUTH_TYPE}, |
220 | {"KM_TAG_AUTH_TIMEOUT ",KM_TAG_AUTH_TIMEOUT }, |
221 | {"KM_TAG_ALL_APPLICATIONS ", KM_TAG_ALL_APPLICATIONS }, |
222 | {"KM_TAG_APPLICATION_ID", KM_TAG_APPLICATION_ID}, |
223 | {"KM_TAG_APPLICATION_DATA ",KM_TAG_APPLICATION_DATA }, |
224 | {"KM_TAG_CREATION_DATETIME ",KM_TAG_CREATION_DATETIME }, |
225 | {"KM_TAG_ORIGIN ", KM_TAG_ORIGIN }, |
226 | {"KM_TAG_ROLLBACK_RESISTANT ", KM_TAG_ROLLBACK_RESISTANT }, |
227 | {"KM_TAG_ROOT_OF_TRUST", KM_TAG_ROOT_OF_TRUST}, |
228 | {"KM_TAG_ASSOCIATED_DATA ",KM_TAG_ASSOCIATED_DATA}, |
229 | {"KM_TAG_NONCE", KM_TAG_NONCE}, |
230 | {"KM_TAG_AUTH_TOKEN",KM_TAG_AUTH_TOKEN}, |
231 | {"KM_TAG_MAC_LENGTH", KM_TAG_MAC_LENGTH}, |
232 | }; |
233 | |
234 | const size_t tag_table_size = sizeof(tag_table)/sizeof(struct tag_table_entry); |
235 | |
236 | void AmlKeymasterDevice::dump_tag_item_value(const char *name, const keymaster_key_param_t* item) |
237 | { |
238 | keymaster_tag_type_t type = KM_INVALID; |
239 | |
240 | if (item) { |
241 | type = keymaster_tag_get_type(item->tag); |
242 | switch (type) { |
243 | case KM_ULONG: |
244 | case KM_ULONG_REP: |
245 | ALOGI("%s: %" PRIx64 "\n", name, item->long_integer); |
246 | //printf("%s: %" PRIx64 "\n", name, item->long_integer); |
247 | break; |
248 | case KM_DATE: |
249 | ALOGI("%s: %" PRIx64 "\n", name, item->date_time); |
250 | //printf("%s: %" PRIx64 "\n", name, item->date_time); |
251 | break; |
252 | case KM_BYTES: |
253 | case KM_BIGNUM: |
254 | ALOGI("%s: blob data: %p, len: 0x%zx\n", name, item->blob.data, item->blob.data_length); |
255 | //printf("%s: blob data: %p, len: 0x%zx\n", name, item->blob.data, item->blob.data_length); |
256 | break; |
257 | case KM_ENUM: |
258 | case KM_ENUM_REP: |
259 | ALOGI("%s: 0x%x\n", name, item->enumerated); |
260 | //printf("%s: 0x%x\n", name, item->enumerated); |
261 | break; |
262 | case KM_BOOL: |
263 | ALOGI("%s: 0x%x\n", name, item->boolean); |
264 | //printf("%s: 0x%x\n", name, item->boolean); |
265 | break; |
266 | case KM_UINT: |
267 | case KM_UINT_REP: |
268 | ALOGI("%s: 0x%x\n", name, item->integer); |
269 | //printf("%s: 0x%x\n", name, item->integer); |
270 | break; |
271 | default: |
272 | ALOGI("%s: invalid type: %d\n", name, type); |
273 | //printf("%s: invalid type: %d\n", name, type); |
274 | break; |
275 | } |
276 | } |
277 | } |
278 | |
279 | void AmlKeymasterDevice::dump_tags(const char *name, const keymaster_key_param_set_t *params) |
280 | { |
281 | size_t i = 0, j =0; |
282 | keymaster_key_param_t* item = params->params; |
283 | |
284 | ALOGI("==== start dump %s, length (%zu)\n", name, params->length); |
285 | //printf("==== start dump %s, length (%zu)\n", name, params->length); |
286 | for (i = 0; i < params->length; i++) { |
287 | for (j = 0; j < tag_table_size; j++) { |
288 | if (tag_table[j].tag == item[i].tag) { |
289 | dump_tag_item_value(tag_table[j].name, &item[i]); |
290 | break; |
291 | } |
292 | } |
293 | } |
294 | ALOGI("==== end dump %s\n", name); |
295 | //printf("==== end dump %s\n", name); |
296 | } |
297 | |
298 | keymaster_error_t AmlKeymasterDevice::configure(const keymaster_key_param_set_t* params) { |
299 | ALOGD("Device received configure\n"); |
300 | |
301 | if (error_ != KM_ERROR_OK) { |
302 | return error_; |
303 | } |
304 | if (!params) { |
305 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
306 | } |
307 | |
308 | AuthorizationSet params_copy(*params); |
309 | ConfigureRequest request; |
310 | if (!params_copy.GetTagValue(TAG_OS_VERSION, &request.os_version) || |
311 | !params_copy.GetTagValue(TAG_OS_PATCHLEVEL, &request.os_patchlevel)) { |
312 | ALOGD("Configuration parameters must contain OS version and patch level"); |
313 | return KM_ERROR_INVALID_ARGUMENT; |
314 | } |
315 | |
316 | ConfigureResponse response; |
317 | keymaster_error_t err = Send(KM_CONFIGURE, request, &response); |
318 | if (err != KM_ERROR_OK) { |
319 | return err; |
320 | } |
321 | |
322 | return KM_ERROR_OK; |
323 | } |
324 | |
325 | keymaster_error_t AmlKeymasterDevice::add_rng_entropy(const uint8_t* data, size_t data_length) { |
326 | ALOGD("Device received add_rng_entropy"); |
327 | |
328 | if (error_ != KM_ERROR_OK) { |
329 | return error_; |
330 | } |
331 | |
332 | AddEntropyRequest request; |
333 | request.random_data.Reinitialize(data, data_length); |
334 | AddEntropyResponse response; |
335 | return Send(KM_ADD_RNG_ENTROPY, request, &response); |
336 | } |
337 | |
338 | keymaster_error_t AmlKeymasterDevice::simple_bin2ascii(uint8_t *data, size_t data_length, char *out) { |
339 | for (size_t i = 0; i < data_length; i++) { |
340 | if (((data[i] & 0xf0) >> 4) < 0xa) |
341 | out[i * 2] = ((data[i] & 0xf0) >> 4) + 48; |
342 | else |
343 | out[i * 2] = ((data[i] & 0xf0) >> 4) + 87; |
344 | if ((data[i] & 0xf) < 0xa) |
345 | out[i * 2 + 1] = (data[i] & 0xf) + 48; |
346 | else |
347 | out[i * 2 + 1] = (data[i] & 0xf) + 87; |
348 | } |
349 | |
350 | return KM_ERROR_OK; |
351 | } |
352 | |
353 | keymaster_error_t AmlKeymasterDevice::store_encrypted_key(keymaster_key_blob_t* key_blob) { |
354 | SHA256_CTX sha256_ctx; |
355 | UniquePtr<uint8_t[]> hash_buf(new (std::nothrow) uint8_t[SHA256_DIGEST_LENGTH + 1]); |
356 | UniquePtr<char[]> name_buf(new (std::nothrow) char [SHA256_DIGEST_LENGTH * 2 + 1]); |
357 | std::ofstream out; |
358 | char name[256]; |
359 | |
360 | // Hash key data to create filename. |
361 | Eraser sha256_ctx_eraser(sha256_ctx); |
362 | memset(name_buf.get(), 0, SHA256_DIGEST_LENGTH * 2 + 1); |
363 | SHA256_Init(&sha256_ctx); |
364 | SHA256_Update(&sha256_ctx, key_blob->key_material, key_blob->key_material_size); |
365 | SHA256_Final(hash_buf.get(), &sha256_ctx); |
366 | |
367 | simple_bin2ascii(hash_buf.get(), SHA256_DIGEST_LENGTH, name_buf.get()); |
368 | name_buf[SHA256_DIGEST_LENGTH * 2] = '\0'; |
369 | sprintf(name, "/data/tee/%s", name_buf.get()); |
370 | out.open(name, std::ofstream::out | std::ofstream::binary); |
371 | if (out.is_open()) { |
372 | out.write((const char *)key_blob->key_material, key_blob->key_material_size); |
373 | out.close(); |
374 | } else { |
375 | ALOGE("error opening key files\n"); |
376 | } |
377 | |
378 | return KM_ERROR_OK; |
379 | } |
380 | |
381 | keymaster_error_t AmlKeymasterDevice::delete_encrypted_key(const keymaster_key_blob_t* key_blob) { |
382 | SHA256_CTX sha256_ctx; |
383 | UniquePtr<uint8_t[]> hash_buf(new (std::nothrow) uint8_t[SHA256_DIGEST_LENGTH + 1]); |
384 | UniquePtr<char[]> name_buf(new (std::nothrow) char [SHA256_DIGEST_LENGTH * 2 + 1]); |
385 | std::ofstream out; |
386 | char name[256]; |
387 | int result = -1; |
388 | |
389 | // Hash key data to get filename. |
390 | Eraser sha256_ctx_eraser(sha256_ctx); |
391 | memset(name_buf.get(), 0, SHA256_DIGEST_LENGTH * 2 + 1); |
392 | SHA256_Init(&sha256_ctx); |
393 | SHA256_Update(&sha256_ctx, key_blob->key_material, key_blob->key_material_size); |
394 | SHA256_Final(hash_buf.get(), &sha256_ctx); |
395 | |
396 | simple_bin2ascii(hash_buf.get(), SHA256_DIGEST_LENGTH, name_buf.get()); |
397 | name_buf[SHA256_DIGEST_LENGTH * 2] = '\0'; |
398 | sprintf(name, "/data/tee/%s", name_buf.get()); |
399 | out.open(name, std::ofstream::out | std::ofstream::binary); |
400 | result = unlink(name); |
401 | |
402 | if (!result) { |
403 | return KM_ERROR_OK; |
404 | } else { |
405 | ALOGE("cannot locate %s\n", name); |
406 | return KM_ERROR_INVALID_OPERATION_HANDLE; |
407 | } |
408 | } |
409 | |
410 | keymaster_error_t AmlKeymasterDevice::generate_key( |
411 | const keymaster_key_param_set_t* params, keymaster_key_blob_t* key_blob, |
412 | keymaster_key_characteristics_t* characteristics) { |
413 | ALOGD("Device received generate_key"); |
414 | |
415 | if (error_ != KM_ERROR_OK) { |
416 | return error_; |
417 | } |
418 | if (!params) { |
419 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
420 | } |
421 | if (!key_blob) { |
422 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
423 | } |
424 | |
425 | GenerateKeyRequest request(message_version_); |
426 | request.key_description.Reinitialize(*params); |
427 | request.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL))); |
428 | |
429 | GenerateKeyResponse response(message_version_); |
430 | keymaster_error_t err = Send(KM_GENERATE_KEY, request, &response); |
431 | if (err != KM_ERROR_OK) { |
432 | return err; |
433 | } |
434 | |
435 | key_blob->key_material_size = response.key_blob.key_material_size; |
436 | key_blob->key_material = |
437 | DuplicateBuffer(response.key_blob.key_material, response.key_blob.key_material_size); |
438 | if (!key_blob->key_material) { |
439 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
440 | } |
441 | |
442 | if (characteristics) { |
443 | response.enforced.CopyToParamSet(&characteristics->hw_enforced); |
444 | response.unenforced.CopyToParamSet(&characteristics->sw_enforced); |
445 | } |
446 | |
447 | return KM_ERROR_OK; |
448 | } |
449 | |
450 | keymaster_error_t AmlKeymasterDevice::get_key_characteristics( |
451 | const keymaster_key_blob_t* key_blob, const keymaster_blob_t* client_id, |
452 | const keymaster_blob_t* app_data, keymaster_key_characteristics_t* characteristics) { |
453 | ALOGD("Device received get_key_characteristics"); |
454 | |
455 | if (error_ != KM_ERROR_OK) { |
456 | return error_; |
457 | } |
458 | if (!key_blob || !key_blob->key_material) { |
459 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
460 | } |
461 | if (!characteristics) { |
462 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
463 | } |
464 | |
465 | GetKeyCharacteristicsRequest request; |
466 | request.SetKeyMaterial(*key_blob); |
467 | AddClientAndAppData(client_id, app_data, &request); |
468 | |
469 | GetKeyCharacteristicsResponse response; |
470 | keymaster_error_t err = Send(KM_GET_KEY_CHARACTERISTICS, request, &response); |
471 | if (err != KM_ERROR_OK) { |
472 | return err; |
473 | } |
474 | |
475 | response.enforced.CopyToParamSet(&characteristics->hw_enforced); |
476 | response.unenforced.CopyToParamSet(&characteristics->sw_enforced); |
477 | |
478 | return KM_ERROR_OK; |
479 | } |
480 | |
481 | keymaster_error_t AmlKeymasterDevice::import_key( |
482 | const keymaster_key_param_set_t* params, keymaster_key_format_t key_format, |
483 | const keymaster_blob_t* key_data, keymaster_key_blob_t* key_blob, |
484 | keymaster_key_characteristics_t* characteristics) { |
485 | ALOGD("Device received import_key"); |
486 | |
487 | if (error_ != KM_ERROR_OK) { |
488 | return error_; |
489 | } |
490 | if (!params || !key_data) { |
491 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
492 | } |
493 | if (!key_blob) { |
494 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
495 | } |
496 | |
497 | ImportKeyRequest request(message_version_); |
498 | request.key_description.Reinitialize(*params); |
499 | request.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL))); |
500 | |
501 | dump_tags("import", &request.key_description); |
502 | request.key_format = key_format; |
503 | request.SetKeyMaterial(key_data->data, key_data->data_length); |
504 | |
505 | ImportKeyResponse response(message_version_); |
506 | keymaster_error_t err = Send(KM_IMPORT_KEY, request, &response); |
507 | if (err != KM_ERROR_OK) { |
508 | return err; |
509 | } |
510 | |
511 | key_blob->key_material_size = response.key_blob.key_material_size; |
512 | key_blob->key_material = |
513 | DuplicateBuffer(response.key_blob.key_material, response.key_blob.key_material_size); |
514 | if (!key_blob->key_material) { |
515 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
516 | } |
517 | |
518 | dump_tags("hw", &response.enforced); |
519 | dump_tags("sw", &response.unenforced); |
520 | if (characteristics) { |
521 | response.enforced.CopyToParamSet(&characteristics->hw_enforced); |
522 | response.unenforced.CopyToParamSet(&characteristics->sw_enforced); |
523 | } |
524 | |
525 | return KM_ERROR_OK; |
526 | } |
527 | |
528 | keymaster_error_t AmlKeymasterDevice::export_key(keymaster_key_format_t export_format, |
529 | const keymaster_key_blob_t* key_to_export, |
530 | const keymaster_blob_t* client_id, |
531 | const keymaster_blob_t* app_data, |
532 | keymaster_blob_t* export_data) { |
533 | ALOGD("Device received export_key"); |
534 | |
535 | if (error_ != KM_ERROR_OK) { |
536 | return error_; |
537 | } |
538 | if (!key_to_export || !key_to_export->key_material) { |
539 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
540 | } |
541 | if (!export_data) { |
542 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
543 | } |
544 | |
545 | export_data->data = nullptr; |
546 | export_data->data_length = 0; |
547 | |
548 | ExportKeyRequest request(message_version_); |
549 | request.key_format = export_format; |
550 | request.SetKeyMaterial(*key_to_export); |
551 | AddClientAndAppData(client_id, app_data, &request); |
552 | |
553 | ExportKeyResponse response(message_version_); |
554 | keymaster_error_t err = Send(KM_EXPORT_KEY, request, &response); |
555 | if (err != KM_ERROR_OK) { |
556 | return err; |
557 | } |
558 | |
559 | export_data->data_length = response.key_data_length; |
560 | export_data->data = DuplicateBuffer(response.key_data, response.key_data_length); |
561 | if (!export_data->data) { |
562 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
563 | } |
564 | |
565 | return KM_ERROR_OK; |
566 | } |
567 | |
568 | keymaster_error_t AmlKeymasterDevice::attest_key(const keymaster_key_blob_t* key_to_attest, |
569 | const keymaster_key_param_set_t* attest_params, |
570 | keymaster_cert_chain_t* cert_chain) { |
571 | ALOGD("Device received attest_key"); |
572 | |
573 | if (error_ != KM_ERROR_OK) { |
574 | return error_; |
575 | } |
576 | if (!key_to_attest || !attest_params) { |
577 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
578 | } |
579 | if (!cert_chain) { |
580 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
581 | } |
582 | |
583 | cert_chain->entry_count = 0; |
584 | cert_chain->entries = nullptr; |
585 | |
586 | AttestKeyRequest request; |
587 | request.SetKeyMaterial(*key_to_attest); |
588 | request.attest_params.Reinitialize(*attest_params); |
589 | |
590 | keymaster_blob_t attestation_challenge = {}; |
591 | request.attest_params.GetTagValue(TAG_ATTESTATION_CHALLENGE, &attestation_challenge); |
592 | if (attestation_challenge.data_length > kMaximumAttestationChallengeLength) { |
593 | ALOGE("%zu-byte attestation challenge; only %zu bytes allowed", |
594 | attestation_challenge.data_length, kMaximumAttestationChallengeLength); |
595 | return KM_ERROR_INVALID_INPUT_LENGTH; |
596 | } |
597 | |
598 | AttestKeyResponse response; |
599 | keymaster_error_t err = Send(KM_ATTEST_KEY, request, &response); |
600 | if (err != KM_ERROR_OK) { |
601 | return err; |
602 | } |
603 | |
604 | // Allocate and clear storage for cert_chain. |
605 | keymaster_cert_chain_t& rsp_chain = response.certificate_chain; |
606 | cert_chain->entries = reinterpret_cast<keymaster_blob_t*>( |
607 | malloc(rsp_chain.entry_count * sizeof(*cert_chain->entries))); |
608 | if (!cert_chain->entries) { |
609 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
610 | } |
611 | cert_chain->entry_count = rsp_chain.entry_count; |
612 | for (keymaster_blob_t& entry : array_range(cert_chain->entries, cert_chain->entry_count)) { |
613 | entry = {}; |
614 | } |
615 | |
616 | // Copy cert_chain contents |
617 | size_t i = 0; |
618 | for (keymaster_blob_t& entry : array_range(rsp_chain.entries, rsp_chain.entry_count)) { |
619 | cert_chain->entries[i].data = DuplicateBuffer(entry.data, entry.data_length); |
620 | if (!cert_chain->entries[i].data) { |
621 | keymaster_free_cert_chain(cert_chain); |
622 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
623 | } |
624 | cert_chain->entries[i].data_length = entry.data_length; |
625 | ++i; |
626 | } |
627 | |
628 | return KM_ERROR_OK; |
629 | } |
630 | |
631 | keymaster_error_t AmlKeymasterDevice::upgrade_key(const keymaster_key_blob_t* key_to_upgrade, |
632 | const keymaster_key_param_set_t* upgrade_params, |
633 | keymaster_key_blob_t* upgraded_key) { |
634 | ALOGD("Device received upgrade_key"); |
635 | |
636 | if (error_ != KM_ERROR_OK) { |
637 | return error_; |
638 | } |
639 | if (!key_to_upgrade || !upgrade_params) { |
640 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
641 | } |
642 | if (!upgraded_key) { |
643 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
644 | } |
645 | |
646 | UpgradeKeyRequest request; |
647 | request.SetKeyMaterial(*key_to_upgrade); |
648 | request.upgrade_params.Reinitialize(*upgrade_params); |
649 | |
650 | UpgradeKeyResponse response; |
651 | keymaster_error_t err = Send(KM_UPGRADE_KEY, request, &response); |
652 | if (err != KM_ERROR_OK) { |
653 | return err; |
654 | } |
655 | |
656 | upgraded_key->key_material_size = response.upgraded_key.key_material_size; |
657 | upgraded_key->key_material = DuplicateBuffer(response.upgraded_key.key_material, |
658 | response.upgraded_key.key_material_size); |
659 | if (!upgraded_key->key_material) { |
660 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
661 | } |
662 | |
663 | return KM_ERROR_OK; |
664 | } |
665 | |
666 | keymaster_error_t AmlKeymasterDevice::delete_key(const keymaster_key_blob_t* key) { |
667 | (void)key; |
668 | return KM_ERROR_OK; |
669 | } |
670 | |
671 | keymaster_error_t AmlKeymasterDevice::begin(keymaster_purpose_t purpose, |
672 | const keymaster_key_blob_t* key, |
673 | const keymaster_key_param_set_t* in_params, |
674 | keymaster_key_param_set_t* out_params, |
675 | keymaster_operation_handle_t* operation_handle) { |
676 | ALOGD("Device received begin"); |
677 | |
678 | if (error_ != KM_ERROR_OK) { |
679 | return error_; |
680 | } |
681 | if (!key || !key->key_material) { |
682 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
683 | } |
684 | if (!operation_handle) { |
685 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
686 | } |
687 | |
688 | if (out_params) { |
689 | *out_params = {}; |
690 | } |
691 | |
692 | BeginOperationRequest request; |
693 | request.purpose = purpose; |
694 | request.SetKeyMaterial(*key); |
695 | request.additional_params.Reinitialize(*in_params); |
696 | |
697 | BeginOperationResponse response; |
698 | keymaster_error_t err = Send(KM_BEGIN_OPERATION, request, &response); |
699 | if (err != KM_ERROR_OK) { |
700 | return err; |
701 | } |
702 | |
703 | if (response.output_params.size() > 0) { |
704 | if (out_params) { |
705 | response.output_params.CopyToParamSet(out_params); |
706 | } else { |
707 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
708 | } |
709 | } |
710 | *operation_handle = response.op_handle; |
711 | |
712 | return KM_ERROR_OK; |
713 | } |
714 | |
715 | keymaster_error_t AmlKeymasterDevice::update(keymaster_operation_handle_t operation_handle, |
716 | const keymaster_key_param_set_t* in_params, |
717 | const keymaster_blob_t* input, |
718 | size_t* input_consumed, |
719 | keymaster_key_param_set_t* out_params, |
720 | keymaster_blob_t* output) { |
721 | ALOGD("Device received update"); |
722 | |
723 | if (error_ != KM_ERROR_OK) { |
724 | return error_; |
725 | } |
726 | if (!input) { |
727 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
728 | } |
729 | if (!input_consumed) { |
730 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
731 | } |
732 | |
733 | if (out_params) { |
734 | *out_params = {}; |
735 | } |
736 | if (output) { |
737 | *output = {}; |
738 | } |
739 | |
740 | UpdateOperationRequest request; |
741 | request.op_handle = operation_handle; |
742 | if (in_params) { |
743 | request.additional_params.Reinitialize(*in_params); |
744 | } |
745 | if (input && input->data_length > 0) { |
746 | size_t max_input_size = SEND_BUF_SIZE - request.SerializedSize(); |
747 | request.input.Reinitialize(input->data, std::min(input->data_length, max_input_size)); |
748 | } |
749 | |
750 | UpdateOperationResponse response; |
751 | keymaster_error_t err = Send(KM_UPDATE_OPERATION, request, &response); |
752 | if (err != KM_ERROR_OK) { |
753 | return err; |
754 | } |
755 | |
756 | if (response.output_params.size() > 0) { |
757 | if (out_params) { |
758 | response.output_params.CopyToParamSet(out_params); |
759 | } else { |
760 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
761 | } |
762 | } |
763 | *input_consumed = response.input_consumed; |
764 | if (output) { |
765 | output->data_length = response.output.available_read(); |
766 | output->data = DuplicateBuffer(response.output.peek_read(), output->data_length); |
767 | if (!output->data) { |
768 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
769 | } |
770 | } else if (response.output.available_read() > 0) { |
771 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
772 | } |
773 | |
774 | return KM_ERROR_OK; |
775 | } |
776 | |
777 | keymaster_error_t AmlKeymasterDevice::finish(keymaster_operation_handle_t operation_handle, |
778 | const keymaster_key_param_set_t* in_params, |
779 | const keymaster_blob_t* input, |
780 | const keymaster_blob_t* signature, |
781 | keymaster_key_param_set_t* out_params, |
782 | keymaster_blob_t* output) { |
783 | ALOGD("Device received finish"); |
784 | |
785 | bool size_exceeded = false; |
786 | if (error_ != KM_ERROR_OK) { |
787 | return error_; |
788 | } |
789 | if (input && input->data_length > kMaximumFinishInputLength) { |
790 | ALOGE("%zu-byte input to finish; only %zu bytes allowed", |
791 | input->data_length, kMaximumFinishInputLength); |
792 | size_exceeded = true; |
793 | } |
794 | |
795 | if (out_params) { |
796 | *out_params = {}; |
797 | } |
798 | if (output) { |
799 | *output = {}; |
800 | } |
801 | |
802 | FinishOperationRequest request; |
803 | request.op_handle = operation_handle; |
804 | if (signature && signature->data && signature->data_length > 0) { |
805 | request.signature.Reinitialize(signature->data, signature->data_length); |
806 | } |
807 | if (input && input->data && input->data_length) { |
808 | /* sending fake request to close operation handle */ |
809 | if (size_exceeded) |
810 | request.input.Reinitialize(input->data, 1); |
811 | else |
812 | request.input.Reinitialize(input->data, input->data_length); |
813 | } |
814 | if (in_params) { |
815 | request.additional_params.Reinitialize(*in_params); |
816 | } |
817 | |
818 | FinishOperationResponse response; |
819 | keymaster_error_t err = Send(KM_FINISH_OPERATION, request, &response); |
820 | /* drop result in case of fake request */ |
821 | if (size_exceeded) |
822 | return KM_ERROR_INVALID_INPUT_LENGTH; |
823 | if (err != KM_ERROR_OK) { |
824 | return err; |
825 | } |
826 | |
827 | if (response.output_params.size() > 0) { |
828 | if (out_params) { |
829 | response.output_params.CopyToParamSet(out_params); |
830 | } else { |
831 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
832 | } |
833 | } |
834 | if (output) { |
835 | output->data_length = response.output.available_read(); |
836 | output->data = DuplicateBuffer(response.output.peek_read(), output->data_length); |
837 | if (!output->data) { |
838 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
839 | } |
840 | } else if (response.output.available_read() > 0) { |
841 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
842 | } |
843 | |
844 | return KM_ERROR_OK; |
845 | } |
846 | |
847 | keymaster_error_t AmlKeymasterDevice::abort(keymaster_operation_handle_t operation_handle) { |
848 | ALOGD("Device received abort"); |
849 | |
850 | if (error_ != KM_ERROR_OK) { |
851 | return error_; |
852 | } |
853 | |
854 | AbortOperationRequest request; |
855 | request.op_handle = operation_handle; |
856 | AbortOperationResponse response; |
857 | return Send(KM_ABORT_OPERATION, request, &response); |
858 | } |
859 | |
860 | hw_device_t* AmlKeymasterDevice::hw_device() { |
861 | return &device_.common; |
862 | } |
863 | |
864 | static inline AmlKeymasterDevice* convert_device(const keymaster2_device_t* dev) { |
865 | return reinterpret_cast<AmlKeymasterDevice*>(const_cast<keymaster2_device_t*>(dev)); |
866 | } |
867 | |
868 | /* static */ |
869 | int AmlKeymasterDevice::close_device(hw_device_t* dev) { |
870 | delete reinterpret_cast<AmlKeymasterDevice*>(dev); |
871 | return 0; |
872 | } |
873 | |
874 | /* static */ |
875 | keymaster_error_t AmlKeymasterDevice::configure(const keymaster2_device_t* dev, |
876 | const keymaster_key_param_set_t* params) { |
877 | return convert_device(dev)->configure(params); |
878 | } |
879 | |
880 | /* static */ |
881 | keymaster_error_t AmlKeymasterDevice::add_rng_entropy(const keymaster2_device_t* dev, |
882 | const uint8_t* data, size_t data_length) { |
883 | return convert_device(dev)->add_rng_entropy(data, data_length); |
884 | } |
885 | |
886 | /* static */ |
887 | keymaster_error_t AmlKeymasterDevice::generate_key( |
888 | const keymaster2_device_t* dev, const keymaster_key_param_set_t* params, |
889 | keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics) { |
890 | return convert_device(dev)->generate_key(params, key_blob, characteristics); |
891 | } |
892 | |
893 | /* static */ |
894 | keymaster_error_t AmlKeymasterDevice::get_key_characteristics( |
895 | const keymaster2_device_t* dev, const keymaster_key_blob_t* key_blob, |
896 | const keymaster_blob_t* client_id, const keymaster_blob_t* app_data, |
897 | keymaster_key_characteristics_t* characteristics) { |
898 | return convert_device(dev)->get_key_characteristics(key_blob, client_id, app_data, |
899 | characteristics); |
900 | } |
901 | |
902 | /* static */ |
903 | keymaster_error_t AmlKeymasterDevice::import_key( |
904 | const keymaster2_device_t* dev, const keymaster_key_param_set_t* params, |
905 | keymaster_key_format_t key_format, const keymaster_blob_t* key_data, |
906 | keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics) { |
907 | return convert_device(dev)->import_key(params, key_format, key_data, key_blob, characteristics); |
908 | } |
909 | |
910 | /* static */ |
911 | keymaster_error_t AmlKeymasterDevice::export_key(const keymaster2_device_t* dev, |
912 | keymaster_key_format_t export_format, |
913 | const keymaster_key_blob_t* key_to_export, |
914 | const keymaster_blob_t* client_id, |
915 | const keymaster_blob_t* app_data, |
916 | keymaster_blob_t* export_data) { |
917 | return convert_device(dev)->export_key(export_format, key_to_export, client_id, app_data, |
918 | export_data); |
919 | } |
920 | |
921 | /* static */ |
922 | keymaster_error_t AmlKeymasterDevice::attest_key(const keymaster2_device_t* dev, |
923 | const keymaster_key_blob_t* key_to_attest, |
924 | const keymaster_key_param_set_t* attest_params, |
925 | keymaster_cert_chain_t* cert_chain) { |
926 | return convert_device(dev)->attest_key(key_to_attest, attest_params, cert_chain); |
927 | } |
928 | |
929 | /* static */ |
930 | keymaster_error_t AmlKeymasterDevice::upgrade_key(const keymaster2_device_t* dev, |
931 | const keymaster_key_blob_t* key_to_upgrade, |
932 | const keymaster_key_param_set_t* upgrade_params, |
933 | keymaster_key_blob_t* upgraded_key) { |
934 | return convert_device(dev)->upgrade_key(key_to_upgrade, upgrade_params, upgraded_key); |
935 | } |
936 | |
937 | /* static */ |
938 | keymaster_error_t AmlKeymasterDevice::delete_key(const keymaster2_device_t* dev, |
939 | const keymaster_key_blob_t* key_blob) { |
940 | return convert_device(dev)->delete_key(key_blob); |
941 | } |
942 | |
943 | /* static */ |
944 | keymaster_error_t AmlKeymasterDevice::begin(const keymaster2_device_t* dev, |
945 | keymaster_purpose_t purpose, |
946 | const keymaster_key_blob_t* key, |
947 | const keymaster_key_param_set_t* in_params, |
948 | keymaster_key_param_set_t* out_params, |
949 | keymaster_operation_handle_t* operation_handle) { |
950 | return convert_device(dev)->begin(purpose, key, in_params, out_params, operation_handle); |
951 | } |
952 | |
953 | /* static */ |
954 | keymaster_error_t AmlKeymasterDevice::update( |
955 | const keymaster2_device_t* dev, keymaster_operation_handle_t operation_handle, |
956 | const keymaster_key_param_set_t* in_params, const keymaster_blob_t* input, |
957 | size_t* input_consumed, keymaster_key_param_set_t* out_params, keymaster_blob_t* output) { |
958 | return convert_device(dev)->update(operation_handle, in_params, input, input_consumed, |
959 | out_params, output); |
960 | } |
961 | |
962 | /* static */ |
963 | keymaster_error_t AmlKeymasterDevice::finish(const keymaster2_device_t* dev, |
964 | keymaster_operation_handle_t operation_handle, |
965 | const keymaster_key_param_set_t* in_params, |
966 | const keymaster_blob_t* input, |
967 | const keymaster_blob_t* signature, |
968 | keymaster_key_param_set_t* out_params, |
969 | keymaster_blob_t* output) { |
970 | return convert_device(dev)->finish(operation_handle, in_params, input, signature, out_params, |
971 | output); |
972 | } |
973 | |
974 | /* static */ |
975 | keymaster_error_t AmlKeymasterDevice::abort(const keymaster2_device_t* dev, |
976 | keymaster_operation_handle_t operation_handle) { |
977 | return convert_device(dev)->abort(operation_handle); |
978 | } |
979 | |
980 | keymaster_error_t AmlKeymasterDevice::Send(uint32_t command, const Serializable& req, |
981 | KeymasterResponse* rsp) { |
982 | uint32_t req_size = req.SerializedSize(); |
983 | |
984 | if (req_size > SEND_BUF_SIZE) { |
985 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
986 | } |
987 | //uint8_t send_buf[SEND_BUF_SIZE]; |
988 | UniquePtr<uint8_t[]> send_buf (new (std::nothrow) uint8_t[SEND_BUF_SIZE]); |
989 | if (!send_buf.get()) |
990 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
991 | Eraser send_buf_eraser(send_buf.get(), SEND_BUF_SIZE); |
992 | req.Serialize(send_buf.get(), send_buf.get() + req_size); |
993 | |
994 | // Send it |
995 | //uint8_t recv_buf[RECV_BUF_SIZE]; |
996 | UniquePtr<uint8_t[]> recv_buf (new (std::nothrow) uint8_t[RECV_BUF_SIZE]); |
997 | if (!recv_buf.get()) |
998 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
999 | Eraser recv_buf_eraser(recv_buf.get(), RECV_BUF_SIZE); |
1000 | uint32_t rsp_size = RECV_BUF_SIZE; |
1001 | ALOGD("Sending cmd: %u with %d byte request\n", command, (int)req.SerializedSize()); |
1002 | TEEC_Result rc = aml_keymaster_call(&KM_session, command, send_buf.get(), req_size, recv_buf.get(), &rsp_size); |
1003 | if (rc != TEEC_SUCCESS) { |
1004 | return translate_error(rc); |
1005 | } else { |
1006 | ALOGD("Received %d byte response\n", rsp_size); |
1007 | } |
1008 | |
1009 | const keymaster_message* msg = (keymaster_message*)recv_buf.get(); |
1010 | const uint8_t* p = msg->payload; |
1011 | if (!rsp->Deserialize(&p, p + rsp_size)) { |
1012 | ALOGE("Error deserializing response of size %d\n", (int)rsp_size); |
1013 | return KM_ERROR_UNKNOWN_ERROR; |
1014 | } else if (rsp->error != KM_ERROR_OK) { |
1015 | ALOGE("Response of size %d contained error code %d\n", (int)rsp_size, (int)rsp->error); |
1016 | return rsp->error; |
1017 | } |
1018 | return rsp->error; |
1019 | } |
1020 | |
1021 | } // namespace keymaster |
1022 |