Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 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 | |
Mark Salyzyn | 66ce3e0 | 2016-09-28 10:07:20 -0700 | [diff] [blame] | 17 | #define LOG_TAG "TrustyKeymaster" |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 18 | |
| 19 | #include <assert.h> |
Dan Albert | 2f8da43 | 2017-10-12 13:32:56 -0700 | [diff] [blame] | 20 | #include <errno.h> |
Mark Salyzyn | 66ce3e0 | 2016-09-28 10:07:20 -0700 | [diff] [blame] | 21 | #include <openssl/evp.h> |
| 22 | #include <openssl/x509.h> |
| 23 | #include <stddef.h> |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 24 | #include <stdio.h> |
| 25 | #include <stdlib.h> |
| 26 | #include <string.h> |
| 27 | #include <time.h> |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 28 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 29 | #include <algorithm> |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 30 | #include <type_traits> |
| 31 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 32 | #include <hardware/keymaster2.h> |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 33 | #include <keymaster/authorization_set.h> |
Mark Salyzyn | 30f991f | 2017-01-10 13:19:54 -0800 | [diff] [blame] | 34 | #include <log/log.h> |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 35 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 36 | #include "keymaster_ipc.h" |
Mark Salyzyn | 66ce3e0 | 2016-09-28 10:07:20 -0700 | [diff] [blame] | 37 | #include "trusty_keymaster_device.h" |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 38 | #include "trusty_keymaster_ipc.h" |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 39 | |
Jocelyn Bohr | b3ed377 | 2017-07-06 16:24:01 -0700 | [diff] [blame] | 40 | // Maximum size of message from Trusty is 8K (for RSA attestation key and chain) |
| 41 | const uint32_t RECV_BUF_SIZE = 2*PAGE_SIZE; |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 42 | const uint32_t SEND_BUF_SIZE = (PAGE_SIZE - sizeof(struct keymaster_message) - 16 /* tipc header */); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 43 | |
Jocelyn Bohr | a256198 | 2017-02-09 17:32:47 -0800 | [diff] [blame] | 44 | const size_t kMaximumAttestationChallengeLength = 128; |
Jocelyn Bohr | e57f3ce | 2017-02-09 17:44:48 -0800 | [diff] [blame] | 45 | const size_t kMaximumFinishInputLength = 2048; |
Jocelyn Bohr | a256198 | 2017-02-09 17:32:47 -0800 | [diff] [blame] | 46 | |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 47 | namespace keymaster { |
| 48 | |
| 49 | static keymaster_error_t translate_error(int err) { |
| 50 | switch (err) { |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 51 | case 0: |
| 52 | return KM_ERROR_OK; |
| 53 | case -EPERM: |
| 54 | case -EACCES: |
| 55 | return KM_ERROR_SECURE_HW_ACCESS_DENIED; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 56 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 57 | case -ECANCELED: |
| 58 | return KM_ERROR_OPERATION_CANCELLED; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 59 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 60 | case -ENODEV: |
| 61 | return KM_ERROR_UNIMPLEMENTED; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 62 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 63 | case -ENOMEM: |
| 64 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 65 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 66 | case -EBUSY: |
| 67 | return KM_ERROR_SECURE_HW_BUSY; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 68 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 69 | case -EIO: |
| 70 | return KM_ERROR_SECURE_HW_COMMUNICATION_FAILED; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 71 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 72 | case -EOVERFLOW: |
| 73 | return KM_ERROR_INVALID_INPUT_LENGTH; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 74 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 75 | default: |
| 76 | return KM_ERROR_UNKNOWN_ERROR; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 77 | } |
| 78 | } |
| 79 | |
| 80 | TrustyKeymasterDevice::TrustyKeymasterDevice(const hw_module_t* module) { |
| 81 | static_assert(std::is_standard_layout<TrustyKeymasterDevice>::value, |
| 82 | "TrustyKeymasterDevice must be standard layout"); |
| 83 | static_assert(offsetof(TrustyKeymasterDevice, device_) == 0, |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 84 | "device_ must be the first member of TrustyKeymasterDevice"); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 85 | static_assert(offsetof(TrustyKeymasterDevice, device_.common) == 0, |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 86 | "common must be the first member of keymaster2_device"); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 87 | |
| 88 | ALOGI("Creating device"); |
| 89 | ALOGD("Device address: %p", this); |
| 90 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 91 | device_ = {}; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 92 | |
| 93 | device_.common.tag = HARDWARE_DEVICE_TAG; |
| 94 | device_.common.version = 1; |
| 95 | device_.common.module = const_cast<hw_module_t*>(module); |
| 96 | device_.common.close = close_device; |
| 97 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 98 | device_.flags = KEYMASTER_SUPPORTS_EC; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 99 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 100 | device_.configure = configure; |
| 101 | device_.add_rng_entropy = add_rng_entropy; |
| 102 | device_.generate_key = generate_key; |
| 103 | device_.get_key_characteristics = get_key_characteristics; |
| 104 | device_.import_key = import_key; |
| 105 | device_.export_key = export_key; |
| 106 | device_.attest_key = attest_key; |
| 107 | device_.upgrade_key = upgrade_key; |
| 108 | device_.delete_key = nullptr; |
| 109 | device_.delete_all_keys = nullptr; |
| 110 | device_.begin = begin; |
| 111 | device_.update = update; |
| 112 | device_.finish = finish; |
| 113 | device_.abort = abort; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 114 | |
| 115 | int rc = trusty_keymaster_connect(); |
| 116 | error_ = translate_error(rc); |
| 117 | if (rc < 0) { |
| 118 | ALOGE("failed to connect to keymaster (%d)", rc); |
| 119 | return; |
| 120 | } |
| 121 | |
| 122 | GetVersionRequest version_request; |
| 123 | GetVersionResponse version_response; |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 124 | error_ = Send(KM_GET_VERSION, version_request, &version_response); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 125 | if (error_ == KM_ERROR_INVALID_ARGUMENT || error_ == KM_ERROR_UNIMPLEMENTED) { |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 126 | ALOGE("\"Bad parameters\" error on GetVersion call. Version 0 is not supported."); |
| 127 | error_ = KM_ERROR_VERSION_MISMATCH; |
| 128 | return; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 129 | } |
| 130 | message_version_ = MessageVersion(version_response.major_ver, version_response.minor_ver, |
| 131 | version_response.subminor_ver); |
| 132 | if (message_version_ < 0) { |
| 133 | // Can't translate version? Keymaster implementation must be newer. |
| 134 | ALOGE("Keymaster version %d.%d.%d not supported.", version_response.major_ver, |
| 135 | version_response.minor_ver, version_response.subminor_ver); |
| 136 | error_ = KM_ERROR_VERSION_MISMATCH; |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | TrustyKeymasterDevice::~TrustyKeymasterDevice() { |
| 141 | trusty_keymaster_disconnect(); |
| 142 | } |
| 143 | |
Jocelyn Bohr | e514dd8 | 2017-02-09 17:16:51 -0800 | [diff] [blame] | 144 | namespace { |
| 145 | |
| 146 | // Allocates a new buffer with malloc and copies the contents of |buffer| to it. Caller takes |
| 147 | // ownership of the returned buffer. |
| 148 | uint8_t* DuplicateBuffer(const uint8_t* buffer, size_t size) { |
| 149 | uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(size)); |
| 150 | if (tmp) { |
| 151 | memcpy(tmp, buffer, size); |
| 152 | } |
| 153 | return tmp; |
| 154 | } |
| 155 | |
Jocelyn Bohr | a02270f | 2017-02-09 17:20:44 -0800 | [diff] [blame] | 156 | template <typename RequestType> |
| 157 | void AddClientAndAppData(const keymaster_blob_t* client_id, const keymaster_blob_t* app_data, |
| 158 | RequestType* request) { |
| 159 | request->additional_params.Clear(); |
| 160 | if (client_id) { |
| 161 | request->additional_params.push_back(TAG_APPLICATION_ID, *client_id); |
| 162 | } |
| 163 | if (app_data) { |
| 164 | request->additional_params.push_back(TAG_APPLICATION_DATA, *app_data); |
| 165 | } |
| 166 | } |
| 167 | |
Jocelyn Bohr | e514dd8 | 2017-02-09 17:16:51 -0800 | [diff] [blame] | 168 | } // unnamed namespace |
| 169 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 170 | keymaster_error_t TrustyKeymasterDevice::configure(const keymaster_key_param_set_t* params) { |
| 171 | ALOGD("Device received configure\n"); |
Jocelyn Bohr | dccc76c | 2017-02-09 17:06:54 -0800 | [diff] [blame] | 172 | |
| 173 | if (error_ != KM_ERROR_OK) { |
| 174 | return error_; |
| 175 | } |
| 176 | if (!params) { |
| 177 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
| 178 | } |
| 179 | |
| 180 | AuthorizationSet params_copy(*params); |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 181 | ConfigureRequest request(message_version_); |
Jocelyn Bohr | dccc76c | 2017-02-09 17:06:54 -0800 | [diff] [blame] | 182 | if (!params_copy.GetTagValue(TAG_OS_VERSION, &request.os_version) || |
| 183 | !params_copy.GetTagValue(TAG_OS_PATCHLEVEL, &request.os_patchlevel)) { |
| 184 | ALOGD("Configuration parameters must contain OS version and patch level"); |
| 185 | return KM_ERROR_INVALID_ARGUMENT; |
| 186 | } |
| 187 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 188 | ConfigureResponse response(message_version_); |
Jocelyn Bohr | dccc76c | 2017-02-09 17:06:54 -0800 | [diff] [blame] | 189 | keymaster_error_t err = Send(KM_CONFIGURE, request, &response); |
| 190 | if (err != KM_ERROR_OK) { |
| 191 | return err; |
| 192 | } |
| 193 | |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 194 | return KM_ERROR_OK; |
| 195 | } |
| 196 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 197 | keymaster_error_t TrustyKeymasterDevice::add_rng_entropy(const uint8_t* data, size_t data_length) { |
| 198 | ALOGD("Device received add_rng_entropy"); |
Jocelyn Bohr | 126402aa | 2017-02-09 17:13:17 -0800 | [diff] [blame] | 199 | |
| 200 | if (error_ != KM_ERROR_OK) { |
| 201 | return error_; |
| 202 | } |
| 203 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 204 | AddEntropyRequest request(message_version_); |
Jocelyn Bohr | 126402aa | 2017-02-09 17:13:17 -0800 | [diff] [blame] | 205 | request.random_data.Reinitialize(data, data_length); |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 206 | AddEntropyResponse response(message_version_); |
Jocelyn Bohr | 126402aa | 2017-02-09 17:13:17 -0800 | [diff] [blame] | 207 | return Send(KM_ADD_RNG_ENTROPY, request, &response); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 208 | } |
| 209 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 210 | keymaster_error_t TrustyKeymasterDevice::generate_key( |
| 211 | const keymaster_key_param_set_t* params, keymaster_key_blob_t* key_blob, |
| 212 | keymaster_key_characteristics_t* characteristics) { |
| 213 | ALOGD("Device received generate_key"); |
Jocelyn Bohr | e514dd8 | 2017-02-09 17:16:51 -0800 | [diff] [blame] | 214 | |
| 215 | if (error_ != KM_ERROR_OK) { |
| 216 | return error_; |
| 217 | } |
| 218 | if (!params) { |
| 219 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
| 220 | } |
| 221 | if (!key_blob) { |
| 222 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 223 | } |
| 224 | |
| 225 | GenerateKeyRequest request(message_version_); |
| 226 | request.key_description.Reinitialize(*params); |
| 227 | request.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL))); |
| 228 | |
| 229 | GenerateKeyResponse response(message_version_); |
| 230 | keymaster_error_t err = Send(KM_GENERATE_KEY, request, &response); |
| 231 | if (err != KM_ERROR_OK) { |
| 232 | return err; |
| 233 | } |
| 234 | |
| 235 | key_blob->key_material_size = response.key_blob.key_material_size; |
| 236 | key_blob->key_material = |
| 237 | DuplicateBuffer(response.key_blob.key_material, response.key_blob.key_material_size); |
| 238 | if (!key_blob->key_material) { |
| 239 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
| 240 | } |
| 241 | |
| 242 | if (characteristics) { |
| 243 | response.enforced.CopyToParamSet(&characteristics->hw_enforced); |
| 244 | response.unenforced.CopyToParamSet(&characteristics->sw_enforced); |
| 245 | } |
| 246 | |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 247 | return KM_ERROR_OK; |
| 248 | } |
| 249 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 250 | keymaster_error_t TrustyKeymasterDevice::get_key_characteristics( |
| 251 | const keymaster_key_blob_t* key_blob, const keymaster_blob_t* client_id, |
| 252 | const keymaster_blob_t* app_data, keymaster_key_characteristics_t* characteristics) { |
| 253 | ALOGD("Device received get_key_characteristics"); |
Jocelyn Bohr | a02270f | 2017-02-09 17:20:44 -0800 | [diff] [blame] | 254 | |
| 255 | if (error_ != KM_ERROR_OK) { |
| 256 | return error_; |
| 257 | } |
| 258 | if (!key_blob || !key_blob->key_material) { |
| 259 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
| 260 | } |
| 261 | if (!characteristics) { |
| 262 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 263 | } |
| 264 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 265 | GetKeyCharacteristicsRequest request(message_version_); |
Jocelyn Bohr | a02270f | 2017-02-09 17:20:44 -0800 | [diff] [blame] | 266 | request.SetKeyMaterial(*key_blob); |
| 267 | AddClientAndAppData(client_id, app_data, &request); |
| 268 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 269 | GetKeyCharacteristicsResponse response(message_version_); |
Jocelyn Bohr | a02270f | 2017-02-09 17:20:44 -0800 | [diff] [blame] | 270 | keymaster_error_t err = Send(KM_GET_KEY_CHARACTERISTICS, request, &response); |
| 271 | if (err != KM_ERROR_OK) { |
| 272 | return err; |
| 273 | } |
| 274 | |
| 275 | response.enforced.CopyToParamSet(&characteristics->hw_enforced); |
| 276 | response.unenforced.CopyToParamSet(&characteristics->sw_enforced); |
| 277 | |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 278 | return KM_ERROR_OK; |
| 279 | } |
| 280 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 281 | keymaster_error_t TrustyKeymasterDevice::import_key( |
| 282 | const keymaster_key_param_set_t* params, keymaster_key_format_t key_format, |
| 283 | const keymaster_blob_t* key_data, keymaster_key_blob_t* key_blob, |
| 284 | keymaster_key_characteristics_t* characteristics) { |
| 285 | ALOGD("Device received import_key"); |
Jocelyn Bohr | 2d76866 | 2017-02-09 17:28:14 -0800 | [diff] [blame] | 286 | |
| 287 | if (error_ != KM_ERROR_OK) { |
| 288 | return error_; |
| 289 | } |
| 290 | if (!params || !key_data) { |
| 291 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
| 292 | } |
| 293 | if (!key_blob) { |
| 294 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 295 | } |
| 296 | |
| 297 | ImportKeyRequest request(message_version_); |
| 298 | request.key_description.Reinitialize(*params); |
| 299 | request.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL))); |
| 300 | |
| 301 | request.key_format = key_format; |
| 302 | request.SetKeyMaterial(key_data->data, key_data->data_length); |
| 303 | |
| 304 | ImportKeyResponse response(message_version_); |
| 305 | keymaster_error_t err = Send(KM_IMPORT_KEY, request, &response); |
| 306 | if (err != KM_ERROR_OK) { |
| 307 | return err; |
| 308 | } |
| 309 | |
| 310 | key_blob->key_material_size = response.key_blob.key_material_size; |
| 311 | key_blob->key_material = |
| 312 | DuplicateBuffer(response.key_blob.key_material, response.key_blob.key_material_size); |
| 313 | if (!key_blob->key_material) { |
| 314 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
| 315 | } |
| 316 | |
| 317 | if (characteristics) { |
| 318 | response.enforced.CopyToParamSet(&characteristics->hw_enforced); |
| 319 | response.unenforced.CopyToParamSet(&characteristics->sw_enforced); |
| 320 | } |
| 321 | |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 322 | return KM_ERROR_OK; |
| 323 | } |
| 324 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 325 | keymaster_error_t TrustyKeymasterDevice::export_key(keymaster_key_format_t export_format, |
| 326 | const keymaster_key_blob_t* key_to_export, |
| 327 | const keymaster_blob_t* client_id, |
| 328 | const keymaster_blob_t* app_data, |
| 329 | keymaster_blob_t* export_data) { |
| 330 | ALOGD("Device received export_key"); |
Jocelyn Bohr | 4cbfa7f | 2017-02-09 17:29:59 -0800 | [diff] [blame] | 331 | |
| 332 | if (error_ != KM_ERROR_OK) { |
| 333 | return error_; |
| 334 | } |
| 335 | if (!key_to_export || !key_to_export->key_material) { |
| 336 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
| 337 | } |
| 338 | if (!export_data) { |
| 339 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 340 | } |
| 341 | |
| 342 | export_data->data = nullptr; |
| 343 | export_data->data_length = 0; |
| 344 | |
| 345 | ExportKeyRequest request(message_version_); |
| 346 | request.key_format = export_format; |
| 347 | request.SetKeyMaterial(*key_to_export); |
| 348 | AddClientAndAppData(client_id, app_data, &request); |
| 349 | |
| 350 | ExportKeyResponse response(message_version_); |
| 351 | keymaster_error_t err = Send(KM_EXPORT_KEY, request, &response); |
| 352 | if (err != KM_ERROR_OK) { |
| 353 | return err; |
| 354 | } |
| 355 | |
| 356 | export_data->data_length = response.key_data_length; |
| 357 | export_data->data = DuplicateBuffer(response.key_data, response.key_data_length); |
| 358 | if (!export_data->data) { |
| 359 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
| 360 | } |
| 361 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 362 | return KM_ERROR_OK; |
| 363 | } |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 364 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 365 | keymaster_error_t TrustyKeymasterDevice::attest_key(const keymaster_key_blob_t* key_to_attest, |
| 366 | const keymaster_key_param_set_t* attest_params, |
| 367 | keymaster_cert_chain_t* cert_chain) { |
| 368 | ALOGD("Device received attest_key"); |
Jocelyn Bohr | a256198 | 2017-02-09 17:32:47 -0800 | [diff] [blame] | 369 | |
| 370 | if (error_ != KM_ERROR_OK) { |
| 371 | return error_; |
| 372 | } |
| 373 | if (!key_to_attest || !attest_params) { |
| 374 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
| 375 | } |
| 376 | if (!cert_chain) { |
| 377 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 378 | } |
| 379 | |
| 380 | cert_chain->entry_count = 0; |
| 381 | cert_chain->entries = nullptr; |
| 382 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 383 | AttestKeyRequest request(message_version_); |
Jocelyn Bohr | a256198 | 2017-02-09 17:32:47 -0800 | [diff] [blame] | 384 | request.SetKeyMaterial(*key_to_attest); |
| 385 | request.attest_params.Reinitialize(*attest_params); |
| 386 | |
| 387 | keymaster_blob_t attestation_challenge = {}; |
| 388 | request.attest_params.GetTagValue(TAG_ATTESTATION_CHALLENGE, &attestation_challenge); |
| 389 | if (attestation_challenge.data_length > kMaximumAttestationChallengeLength) { |
| 390 | ALOGE("%zu-byte attestation challenge; only %zu bytes allowed", |
| 391 | attestation_challenge.data_length, kMaximumAttestationChallengeLength); |
| 392 | return KM_ERROR_INVALID_INPUT_LENGTH; |
| 393 | } |
| 394 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 395 | AttestKeyResponse response(message_version_); |
Jocelyn Bohr | a256198 | 2017-02-09 17:32:47 -0800 | [diff] [blame] | 396 | keymaster_error_t err = Send(KM_ATTEST_KEY, request, &response); |
| 397 | if (err != KM_ERROR_OK) { |
| 398 | return err; |
| 399 | } |
| 400 | |
| 401 | // Allocate and clear storage for cert_chain. |
| 402 | keymaster_cert_chain_t& rsp_chain = response.certificate_chain; |
| 403 | cert_chain->entries = reinterpret_cast<keymaster_blob_t*>( |
| 404 | malloc(rsp_chain.entry_count * sizeof(*cert_chain->entries))); |
| 405 | if (!cert_chain->entries) { |
| 406 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
| 407 | } |
| 408 | cert_chain->entry_count = rsp_chain.entry_count; |
| 409 | for (keymaster_blob_t& entry : array_range(cert_chain->entries, cert_chain->entry_count)) { |
| 410 | entry = {}; |
| 411 | } |
| 412 | |
| 413 | // Copy cert_chain contents |
| 414 | size_t i = 0; |
| 415 | for (keymaster_blob_t& entry : array_range(rsp_chain.entries, rsp_chain.entry_count)) { |
| 416 | cert_chain->entries[i].data = DuplicateBuffer(entry.data, entry.data_length); |
| 417 | if (!cert_chain->entries[i].data) { |
| 418 | keymaster_free_cert_chain(cert_chain); |
| 419 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
| 420 | } |
| 421 | cert_chain->entries[i].data_length = entry.data_length; |
| 422 | ++i; |
| 423 | } |
| 424 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 425 | return KM_ERROR_OK; |
| 426 | } |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 427 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 428 | keymaster_error_t TrustyKeymasterDevice::upgrade_key(const keymaster_key_blob_t* key_to_upgrade, |
| 429 | const keymaster_key_param_set_t* upgrade_params, |
| 430 | keymaster_key_blob_t* upgraded_key) { |
| 431 | ALOGD("Device received upgrade_key"); |
Jocelyn Bohr | 22812e9 | 2017-02-09 17:35:32 -0800 | [diff] [blame] | 432 | |
| 433 | if (error_ != KM_ERROR_OK) { |
| 434 | return error_; |
| 435 | } |
| 436 | if (!key_to_upgrade || !upgrade_params) { |
| 437 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
| 438 | } |
| 439 | if (!upgraded_key) { |
| 440 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 441 | } |
| 442 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 443 | UpgradeKeyRequest request(message_version_); |
Jocelyn Bohr | 22812e9 | 2017-02-09 17:35:32 -0800 | [diff] [blame] | 444 | request.SetKeyMaterial(*key_to_upgrade); |
| 445 | request.upgrade_params.Reinitialize(*upgrade_params); |
| 446 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 447 | UpgradeKeyResponse response(message_version_); |
Jocelyn Bohr | 22812e9 | 2017-02-09 17:35:32 -0800 | [diff] [blame] | 448 | keymaster_error_t err = Send(KM_UPGRADE_KEY, request, &response); |
| 449 | if (err != KM_ERROR_OK) { |
| 450 | return err; |
| 451 | } |
| 452 | |
| 453 | upgraded_key->key_material_size = response.upgraded_key.key_material_size; |
| 454 | upgraded_key->key_material = DuplicateBuffer(response.upgraded_key.key_material, |
| 455 | response.upgraded_key.key_material_size); |
| 456 | if (!upgraded_key->key_material) { |
| 457 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
| 458 | } |
| 459 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 460 | return KM_ERROR_OK; |
| 461 | } |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 462 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 463 | keymaster_error_t TrustyKeymasterDevice::begin(keymaster_purpose_t purpose, |
| 464 | const keymaster_key_blob_t* key, |
| 465 | const keymaster_key_param_set_t* in_params, |
| 466 | keymaster_key_param_set_t* out_params, |
| 467 | keymaster_operation_handle_t* operation_handle) { |
| 468 | ALOGD("Device received begin"); |
Jocelyn Bohr | d7da42c | 2017-02-09 17:40:47 -0800 | [diff] [blame] | 469 | |
| 470 | if (error_ != KM_ERROR_OK) { |
| 471 | return error_; |
| 472 | } |
| 473 | if (!key || !key->key_material) { |
| 474 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
| 475 | } |
| 476 | if (!operation_handle) { |
| 477 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 478 | } |
| 479 | |
| 480 | if (out_params) { |
| 481 | *out_params = {}; |
| 482 | } |
| 483 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 484 | BeginOperationRequest request(message_version_); |
Jocelyn Bohr | d7da42c | 2017-02-09 17:40:47 -0800 | [diff] [blame] | 485 | request.purpose = purpose; |
| 486 | request.SetKeyMaterial(*key); |
| 487 | request.additional_params.Reinitialize(*in_params); |
| 488 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 489 | BeginOperationResponse response(message_version_); |
Jocelyn Bohr | d7da42c | 2017-02-09 17:40:47 -0800 | [diff] [blame] | 490 | keymaster_error_t err = Send(KM_BEGIN_OPERATION, request, &response); |
| 491 | if (err != KM_ERROR_OK) { |
| 492 | return err; |
| 493 | } |
| 494 | |
| 495 | if (response.output_params.size() > 0) { |
| 496 | if (out_params) { |
| 497 | response.output_params.CopyToParamSet(out_params); |
| 498 | } else { |
| 499 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 500 | } |
| 501 | } |
| 502 | *operation_handle = response.op_handle; |
| 503 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 504 | return KM_ERROR_OK; |
| 505 | } |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 506 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 507 | keymaster_error_t TrustyKeymasterDevice::update(keymaster_operation_handle_t operation_handle, |
| 508 | const keymaster_key_param_set_t* in_params, |
| 509 | const keymaster_blob_t* input, |
| 510 | size_t* input_consumed, |
| 511 | keymaster_key_param_set_t* out_params, |
| 512 | keymaster_blob_t* output) { |
| 513 | ALOGD("Device received update"); |
Jocelyn Bohr | 86eb966 | 2017-02-09 17:42:15 -0800 | [diff] [blame] | 514 | |
| 515 | if (error_ != KM_ERROR_OK) { |
| 516 | return error_; |
| 517 | } |
| 518 | if (!input) { |
| 519 | return KM_ERROR_UNEXPECTED_NULL_POINTER; |
| 520 | } |
| 521 | if (!input_consumed) { |
| 522 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 523 | } |
| 524 | |
| 525 | if (out_params) { |
| 526 | *out_params = {}; |
| 527 | } |
| 528 | if (output) { |
| 529 | *output = {}; |
| 530 | } |
| 531 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 532 | UpdateOperationRequest request(message_version_); |
Jocelyn Bohr | 86eb966 | 2017-02-09 17:42:15 -0800 | [diff] [blame] | 533 | request.op_handle = operation_handle; |
| 534 | if (in_params) { |
| 535 | request.additional_params.Reinitialize(*in_params); |
| 536 | } |
| 537 | if (input && input->data_length > 0) { |
| 538 | size_t max_input_size = SEND_BUF_SIZE - request.SerializedSize(); |
| 539 | request.input.Reinitialize(input->data, std::min(input->data_length, max_input_size)); |
| 540 | } |
| 541 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 542 | UpdateOperationResponse response(message_version_); |
Jocelyn Bohr | 86eb966 | 2017-02-09 17:42:15 -0800 | [diff] [blame] | 543 | keymaster_error_t err = Send(KM_UPDATE_OPERATION, request, &response); |
| 544 | if (err != KM_ERROR_OK) { |
| 545 | return err; |
| 546 | } |
| 547 | |
| 548 | if (response.output_params.size() > 0) { |
| 549 | if (out_params) { |
| 550 | response.output_params.CopyToParamSet(out_params); |
| 551 | } else { |
| 552 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 553 | } |
| 554 | } |
| 555 | *input_consumed = response.input_consumed; |
| 556 | if (output) { |
| 557 | output->data_length = response.output.available_read(); |
| 558 | output->data = DuplicateBuffer(response.output.peek_read(), output->data_length); |
| 559 | if (!output->data) { |
| 560 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
| 561 | } |
| 562 | } else if (response.output.available_read() > 0) { |
| 563 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 564 | } |
| 565 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 566 | return KM_ERROR_OK; |
| 567 | } |
| 568 | |
| 569 | keymaster_error_t TrustyKeymasterDevice::finish(keymaster_operation_handle_t operation_handle, |
| 570 | const keymaster_key_param_set_t* in_params, |
| 571 | const keymaster_blob_t* input, |
| 572 | const keymaster_blob_t* signature, |
| 573 | keymaster_key_param_set_t* out_params, |
| 574 | keymaster_blob_t* output) { |
| 575 | ALOGD("Device received finish"); |
Jocelyn Bohr | e57f3ce | 2017-02-09 17:44:48 -0800 | [diff] [blame] | 576 | |
| 577 | if (error_ != KM_ERROR_OK) { |
| 578 | return error_; |
| 579 | } |
| 580 | if (input && input->data_length > kMaximumFinishInputLength) { |
Jocelyn Bohr | f1e5edf | 2017-08-03 13:59:10 -0700 | [diff] [blame] | 581 | ALOGE("%zu-byte input to finish; only %zu bytes allowed", |
| 582 | input->data_length, kMaximumFinishInputLength); |
| 583 | return KM_ERROR_INVALID_INPUT_LENGTH; |
Jocelyn Bohr | e57f3ce | 2017-02-09 17:44:48 -0800 | [diff] [blame] | 584 | } |
| 585 | |
| 586 | if (out_params) { |
| 587 | *out_params = {}; |
| 588 | } |
| 589 | if (output) { |
| 590 | *output = {}; |
| 591 | } |
| 592 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 593 | FinishOperationRequest request(message_version_); |
Jocelyn Bohr | e57f3ce | 2017-02-09 17:44:48 -0800 | [diff] [blame] | 594 | request.op_handle = operation_handle; |
| 595 | if (signature && signature->data && signature->data_length > 0) { |
| 596 | request.signature.Reinitialize(signature->data, signature->data_length); |
| 597 | } |
| 598 | if (input && input->data && input->data_length) { |
| 599 | request.input.Reinitialize(input->data, input->data_length); |
| 600 | } |
| 601 | if (in_params) { |
| 602 | request.additional_params.Reinitialize(*in_params); |
| 603 | } |
| 604 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 605 | FinishOperationResponse response(message_version_); |
Jocelyn Bohr | e57f3ce | 2017-02-09 17:44:48 -0800 | [diff] [blame] | 606 | keymaster_error_t err = Send(KM_FINISH_OPERATION, request, &response); |
| 607 | if (err != KM_ERROR_OK) { |
| 608 | return err; |
| 609 | } |
| 610 | |
| 611 | if (response.output_params.size() > 0) { |
| 612 | if (out_params) { |
| 613 | response.output_params.CopyToParamSet(out_params); |
| 614 | } else { |
| 615 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 616 | } |
| 617 | } |
| 618 | if (output) { |
| 619 | output->data_length = response.output.available_read(); |
| 620 | output->data = DuplicateBuffer(response.output.peek_read(), output->data_length); |
| 621 | if (!output->data) { |
| 622 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
| 623 | } |
| 624 | } else if (response.output.available_read() > 0) { |
| 625 | return KM_ERROR_OUTPUT_PARAMETER_NULL; |
| 626 | } |
| 627 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 628 | return KM_ERROR_OK; |
| 629 | } |
| 630 | |
| 631 | keymaster_error_t TrustyKeymasterDevice::abort(keymaster_operation_handle_t operation_handle) { |
| 632 | ALOGD("Device received abort"); |
Jocelyn Bohr | 465615e | 2017-02-09 17:46:49 -0800 | [diff] [blame] | 633 | |
| 634 | if (error_ != KM_ERROR_OK) { |
| 635 | return error_; |
| 636 | } |
| 637 | |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 638 | AbortOperationRequest request(message_version_); |
Jocelyn Bohr | 465615e | 2017-02-09 17:46:49 -0800 | [diff] [blame] | 639 | request.op_handle = operation_handle; |
Jocelyn Bohr | 38b9b49 | 2017-08-11 18:06:12 -0700 | [diff] [blame] | 640 | AbortOperationResponse response(message_version_); |
Jocelyn Bohr | 465615e | 2017-02-09 17:46:49 -0800 | [diff] [blame] | 641 | return Send(KM_ABORT_OPERATION, request, &response); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 642 | } |
| 643 | |
| 644 | hw_device_t* TrustyKeymasterDevice::hw_device() { |
| 645 | return &device_.common; |
| 646 | } |
| 647 | |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 648 | static inline TrustyKeymasterDevice* convert_device(const keymaster2_device_t* dev) { |
| 649 | return reinterpret_cast<TrustyKeymasterDevice*>(const_cast<keymaster2_device_t*>(dev)); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 650 | } |
| 651 | |
| 652 | /* static */ |
| 653 | int TrustyKeymasterDevice::close_device(hw_device_t* dev) { |
| 654 | delete reinterpret_cast<TrustyKeymasterDevice*>(dev); |
| 655 | return 0; |
| 656 | } |
| 657 | |
| 658 | /* static */ |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 659 | keymaster_error_t TrustyKeymasterDevice::configure(const keymaster2_device_t* dev, |
| 660 | const keymaster_key_param_set_t* params) { |
| 661 | return convert_device(dev)->configure(params); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 662 | } |
| 663 | |
| 664 | /* static */ |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 665 | keymaster_error_t TrustyKeymasterDevice::add_rng_entropy(const keymaster2_device_t* dev, |
| 666 | const uint8_t* data, size_t data_length) { |
| 667 | return convert_device(dev)->add_rng_entropy(data, data_length); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 668 | } |
| 669 | |
| 670 | /* static */ |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 671 | keymaster_error_t TrustyKeymasterDevice::generate_key( |
| 672 | const keymaster2_device_t* dev, const keymaster_key_param_set_t* params, |
| 673 | keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics) { |
| 674 | return convert_device(dev)->generate_key(params, key_blob, characteristics); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 675 | } |
| 676 | |
| 677 | /* static */ |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 678 | keymaster_error_t TrustyKeymasterDevice::get_key_characteristics( |
| 679 | const keymaster2_device_t* dev, const keymaster_key_blob_t* key_blob, |
| 680 | const keymaster_blob_t* client_id, const keymaster_blob_t* app_data, |
| 681 | keymaster_key_characteristics_t* characteristics) { |
| 682 | return convert_device(dev)->get_key_characteristics(key_blob, client_id, app_data, |
| 683 | characteristics); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 684 | } |
| 685 | |
| 686 | /* static */ |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 687 | keymaster_error_t TrustyKeymasterDevice::import_key( |
| 688 | const keymaster2_device_t* dev, const keymaster_key_param_set_t* params, |
| 689 | keymaster_key_format_t key_format, const keymaster_blob_t* key_data, |
| 690 | keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics) { |
| 691 | return convert_device(dev)->import_key(params, key_format, key_data, key_blob, characteristics); |
| 692 | } |
| 693 | |
| 694 | /* static */ |
| 695 | keymaster_error_t TrustyKeymasterDevice::export_key(const keymaster2_device_t* dev, |
| 696 | keymaster_key_format_t export_format, |
| 697 | const keymaster_key_blob_t* key_to_export, |
| 698 | const keymaster_blob_t* client_id, |
| 699 | const keymaster_blob_t* app_data, |
| 700 | keymaster_blob_t* export_data) { |
| 701 | return convert_device(dev)->export_key(export_format, key_to_export, client_id, app_data, |
| 702 | export_data); |
| 703 | } |
| 704 | |
| 705 | /* static */ |
| 706 | keymaster_error_t TrustyKeymasterDevice::attest_key(const keymaster2_device_t* dev, |
| 707 | const keymaster_key_blob_t* key_to_attest, |
| 708 | const keymaster_key_param_set_t* attest_params, |
| 709 | keymaster_cert_chain_t* cert_chain) { |
| 710 | return convert_device(dev)->attest_key(key_to_attest, attest_params, cert_chain); |
| 711 | } |
| 712 | |
| 713 | /* static */ |
| 714 | keymaster_error_t TrustyKeymasterDevice::upgrade_key(const keymaster2_device_t* dev, |
| 715 | const keymaster_key_blob_t* key_to_upgrade, |
| 716 | const keymaster_key_param_set_t* upgrade_params, |
| 717 | keymaster_key_blob_t* upgraded_key) { |
| 718 | return convert_device(dev)->upgrade_key(key_to_upgrade, upgrade_params, upgraded_key); |
| 719 | } |
| 720 | |
| 721 | /* static */ |
| 722 | keymaster_error_t TrustyKeymasterDevice::begin(const keymaster2_device_t* dev, |
| 723 | keymaster_purpose_t purpose, |
| 724 | const keymaster_key_blob_t* key, |
| 725 | const keymaster_key_param_set_t* in_params, |
| 726 | keymaster_key_param_set_t* out_params, |
| 727 | keymaster_operation_handle_t* operation_handle) { |
| 728 | return convert_device(dev)->begin(purpose, key, in_params, out_params, operation_handle); |
| 729 | } |
| 730 | |
| 731 | /* static */ |
| 732 | keymaster_error_t TrustyKeymasterDevice::update( |
| 733 | const keymaster2_device_t* dev, keymaster_operation_handle_t operation_handle, |
| 734 | const keymaster_key_param_set_t* in_params, const keymaster_blob_t* input, |
| 735 | size_t* input_consumed, keymaster_key_param_set_t* out_params, keymaster_blob_t* output) { |
| 736 | return convert_device(dev)->update(operation_handle, in_params, input, input_consumed, |
| 737 | out_params, output); |
| 738 | } |
| 739 | |
| 740 | /* static */ |
| 741 | keymaster_error_t TrustyKeymasterDevice::finish(const keymaster2_device_t* dev, |
| 742 | keymaster_operation_handle_t operation_handle, |
| 743 | const keymaster_key_param_set_t* in_params, |
| 744 | const keymaster_blob_t* input, |
| 745 | const keymaster_blob_t* signature, |
| 746 | keymaster_key_param_set_t* out_params, |
| 747 | keymaster_blob_t* output) { |
| 748 | return convert_device(dev)->finish(operation_handle, in_params, input, signature, out_params, |
| 749 | output); |
| 750 | } |
| 751 | |
| 752 | /* static */ |
| 753 | keymaster_error_t TrustyKeymasterDevice::abort(const keymaster2_device_t* dev, |
| 754 | keymaster_operation_handle_t operation_handle) { |
| 755 | return convert_device(dev)->abort(operation_handle); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 756 | } |
| 757 | |
| 758 | keymaster_error_t TrustyKeymasterDevice::Send(uint32_t command, const Serializable& req, |
| 759 | KeymasterResponse* rsp) { |
| 760 | uint32_t req_size = req.SerializedSize(); |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 761 | if (req_size > SEND_BUF_SIZE) { |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 762 | return KM_ERROR_MEMORY_ALLOCATION_FAILED; |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 763 | } |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 764 | uint8_t send_buf[SEND_BUF_SIZE]; |
| 765 | Eraser send_buf_eraser(send_buf, SEND_BUF_SIZE); |
| 766 | req.Serialize(send_buf, send_buf + req_size); |
| 767 | |
| 768 | // Send it |
| 769 | uint8_t recv_buf[RECV_BUF_SIZE]; |
| 770 | Eraser recv_buf_eraser(recv_buf, RECV_BUF_SIZE); |
| 771 | uint32_t rsp_size = RECV_BUF_SIZE; |
Jocelyn Bohr | e194e27 | 2017-02-09 16:58:41 -0800 | [diff] [blame] | 772 | ALOGV("Sending %d byte request\n", (int)req.SerializedSize()); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 773 | int rc = trusty_keymaster_call(command, send_buf, req_size, recv_buf, &rsp_size); |
| 774 | if (rc < 0) { |
Jocelyn Bohr | b3ed377 | 2017-07-06 16:24:01 -0700 | [diff] [blame] | 775 | // Reset the connection on tipc error |
| 776 | trusty_keymaster_disconnect(); |
| 777 | trusty_keymaster_connect(); |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 778 | ALOGE("tipc error: %d\n", rc); |
| 779 | // TODO(swillden): Distinguish permanent from transient errors and set error_ appropriately. |
| 780 | return translate_error(rc); |
| 781 | } else { |
| 782 | ALOGV("Received %d byte response\n", rsp_size); |
| 783 | } |
| 784 | |
Jocelyn Bohr | b3ed377 | 2017-07-06 16:24:01 -0700 | [diff] [blame] | 785 | const uint8_t* p = recv_buf; |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 786 | if (!rsp->Deserialize(&p, p + rsp_size)) { |
| 787 | ALOGE("Error deserializing response of size %d\n", (int)rsp_size); |
| 788 | return KM_ERROR_UNKNOWN_ERROR; |
| 789 | } else if (rsp->error != KM_ERROR_OK) { |
| 790 | ALOGE("Response of size %d contained error code %d\n", (int)rsp_size, (int)rsp->error); |
| 791 | return rsp->error; |
| 792 | } |
| 793 | return rsp->error; |
| 794 | } |
| 795 | |
Andres Morales | b33c9b8 | 2015-09-08 17:56:07 -0700 | [diff] [blame] | 796 | } // namespace keymaster |