blob: 9f3418edd4a504ab71f318587f2eca5152e4c476 [file] [log] [blame]
Shawn Willden5b53c992015-02-02 08:05:25 -07001/*
2 * Copyright 2015 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
Chad Brubaker834d4132015-02-12 10:18:45 -080017#include <keymaster/soft_keymaster_device.h>
Shawn Willden5b53c992015-02-02 08:05:25 -070018
19#include <assert.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <time.h>
24#include <stddef.h>
25
26#include <algorithm>
27
28#include <type_traits>
29
Shawn Willdend7a5c712015-04-09 16:33:52 -060030#include <openssl/x509.h>
31
Shawn Willden30255022015-02-24 14:00:21 -070032#include <hardware/keymaster1.h>
Shawn Willden5b53c992015-02-02 08:05:25 -070033#define LOG_TAG "SoftKeymasterDevice"
34#include <cutils/log.h>
35
Shawn Willden0cb69422015-05-26 08:31:37 -060036#include <keymaster/android_keymaster.h>
Shawn Willden13fbe3e2015-05-23 03:36:30 +000037#include <keymaster/android_keymaster_messages.h>
Shawn Willden0cb69422015-05-26 08:31:37 -060038#include <keymaster/authorization_set.h>
39#include <keymaster/soft_keymaster_context.h>
Chad Brubaker834d4132015-02-12 10:18:45 -080040#include <keymaster/soft_keymaster_logger.h>
Shawn Willden5b53c992015-02-02 08:05:25 -070041
Shawn Willden0cb69422015-05-26 08:31:37 -060042#include "openssl_utils.h"
Shawn Willden5b53c992015-02-02 08:05:25 -070043
Shawn Willden5b53c992015-02-02 08:05:25 -070044struct keystore_module soft_keymaster_device_module = {
45 .common =
46 {
Shawn Willdenf01329d2015-03-11 21:51:38 -060047 .tag = HARDWARE_MODULE_TAG,
48 .module_api_version = KEYMASTER_MODULE_API_VERSION_1_0,
49 .hal_api_version = HARDWARE_HAL_API_VERSION,
50 .id = KEYSTORE_HARDWARE_MODULE_ID,
Shawn Willden2612fb52015-07-27 16:58:30 -060051 .name = "OpenSSL-based SoftKeymaster HAL",
Shawn Willdenf01329d2015-03-11 21:51:38 -060052 .author = "The Android Open Source Project",
53 .methods = NULL,
54 .dso = 0,
55 .reserved = {},
Shawn Willden5b53c992015-02-02 08:05:25 -070056 },
57};
58
59namespace keymaster {
60
Shawn Willden2612fb52015-07-27 16:58:30 -060061const size_t kOperationTableSize = 16;
62
63typedef std::map<std::pair<keymaster_algorithm_t, keymaster_purpose_t>,
64 std::vector<keymaster_digest_t>> DigestMap;
65
66template <typename T> std::vector<T> make_vector(const T* array, size_t len) {
67 return std::vector<T>(array, array + len);
Shawn Willdenada48502015-06-25 06:26:05 -070068}
69
Shawn Willden2612fb52015-07-27 16:58:30 -060070static keymaster_error_t add_digests(keymaster1_device_t* dev, keymaster_algorithm_t algorithm,
71 keymaster_purpose_t purpose, DigestMap* map) {
72 auto key = std::make_pair(algorithm, purpose);
73
74 keymaster_digest_t* digests;
75 size_t digests_length;
76 keymaster_error_t error =
77 dev->get_supported_digests(dev, algorithm, purpose, &digests, &digests_length);
78 if (error != KM_ERROR_OK) {
79 LOG_E("Error %d getting supported digests from keymaster1 device", error);
80 return error;
81 }
82 std::unique_ptr<keymaster_digest_t, Malloc_Delete> digests_deleter(digests);
83
84 (*map)[key] = make_vector(digests, digests_length);
85 return KM_ERROR_OK;
Shawn Willdenada48502015-06-25 06:26:05 -070086}
87
Shawn Willden2612fb52015-07-27 16:58:30 -060088static keymaster_error_t map_digests(keymaster1_device_t* dev, DigestMap* map) {
89 map->clear();
90
91 keymaster_algorithm_t sig_algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_EC};
92 keymaster_purpose_t sig_purposes[] = {KM_PURPOSE_SIGN, KM_PURPOSE_VERIFY};
93 for (auto algorithm : sig_algorithms)
94 for (auto purpose : sig_purposes) {
95 keymaster_error_t error = add_digests(dev, algorithm, purpose, map);
96 if (error != KM_ERROR_OK)
97 return error;
98 }
99
100 keymaster_algorithm_t crypt_algorithms[] = {KM_ALGORITHM_RSA};
101 keymaster_purpose_t crypt_purposes[] = {KM_PURPOSE_ENCRYPT, KM_PURPOSE_DECRYPT};
102 for (auto algorithm : crypt_algorithms)
103 for (auto purpose : crypt_purposes) {
104 keymaster_error_t error = add_digests(dev, algorithm, purpose, map);
105 if (error != KM_ERROR_OK)
106 return error;
107 }
108
109 return KM_ERROR_OK;
110}
111
112SoftKeymasterDevice::SoftKeymasterDevice()
113 : wrapped_km0_device_(nullptr), wrapped_km1_device_(nullptr),
114 context_(new SoftKeymasterContext),
115 impl_(new AndroidKeymaster(context_, kOperationTableSize)) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700116 static_assert(std::is_standard_layout<SoftKeymasterDevice>::value,
117 "SoftKeymasterDevice must be standard layout");
118 static_assert(offsetof(SoftKeymasterDevice, device_) == 0,
Shawn Willden2beb6282015-05-20 16:36:24 -0600119 "device_ must be the first member of SoftKeymasterDevice");
Shawn Willden5b53c992015-02-02 08:05:25 -0700120 static_assert(offsetof(SoftKeymasterDevice, device_.common) == 0,
121 "common must be the first member of keymaster_device");
Shawn Willdenc6096592015-03-17 15:53:14 -0600122 LOG_I("Creating device", 0);
Shawn Willden567a4a02014-12-31 12:14:46 -0700123 LOG_D("Device address: %p", this);
Shawn Willden5b53c992015-02-02 08:05:25 -0700124
Shawn Willden2612fb52015-07-27 16:58:30 -0600125 initialize_device_struct();
126}
127
128SoftKeymasterDevice::SoftKeymasterDevice(SoftKeymasterContext* context)
129 : wrapped_km0_device_(nullptr), wrapped_km1_device_(nullptr), context_(context),
130 impl_(new AndroidKeymaster(context_, kOperationTableSize)) {
131 static_assert(std::is_standard_layout<SoftKeymasterDevice>::value,
132 "SoftKeymasterDevice must be standard layout");
133 static_assert(offsetof(SoftKeymasterDevice, device_) == 0,
134 "device_ must be the first member of SoftKeymasterDevice");
135 static_assert(offsetof(SoftKeymasterDevice, device_.common) == 0,
136 "common must be the first member of keymaster_device");
137 LOG_I("Creating test device", 0);
138 LOG_D("Device address: %p", this);
139
140 initialize_device_struct();
141}
142
143keymaster_error_t SoftKeymasterDevice::SetHardwareDevice(keymaster0_device_t* keymaster0_device) {
144 assert(keymaster0_device);
145 LOG_D("Reinitializing SoftKeymasterDevice to use HW keymaster0", 0);
146
147 if (!context_)
148 return KM_ERROR_UNEXPECTED_NULL_POINTER;
149
150 keymaster_error_t error = context_->SetHardwareDevice(keymaster0_device);
151 if (error != KM_ERROR_OK)
152 return error;
153
154 initialize_device_struct();
155
156 module_name_ = device_.common.module->name;
157 module_name_.append("(Wrapping ");
158 module_name_.append(keymaster0_device->common.module->name);
159 module_name_.append(")");
160
161 updated_module_ = *device_.common.module;
162 updated_module_.name = module_name_.c_str();
163
164 device_.common.module = &updated_module_;
165
166 wrapped_km0_device_ = keymaster0_device;
167 wrapped_km1_device_ = nullptr;
168 return KM_ERROR_OK;
169}
170
171keymaster_error_t SoftKeymasterDevice::SetHardwareDevice(keymaster1_device_t* keymaster1_device) {
172 assert(keymaster1_device);
173 LOG_D("Reinitializing SoftKeymasterDevice to use HW keymaster1", 0);
174
175 if (!context_)
176 return KM_ERROR_UNEXPECTED_NULL_POINTER;
177
178 keymaster_error_t error = map_digests(keymaster1_device, &km1_device_digests_);
179 if (error != KM_ERROR_OK)
180 return error;
181
182 error = context_->SetHardwareDevice(keymaster1_device);
183 if (error != KM_ERROR_OK)
184 return error;
185
186 initialize_device_struct();
187
188 module_name_ = device_.common.module->name;
189 module_name_.append(" (Wrapping ");
190 module_name_.append(keymaster1_device->common.module->name);
191 module_name_.append(")");
192
193 updated_module_ = *device_.common.module;
194 updated_module_.name = module_name_.c_str();
195
196 device_.common.module = &updated_module_;
197
198 wrapped_km0_device_ = nullptr;
199 wrapped_km1_device_ = keymaster1_device;
200 return KM_ERROR_OK;
201}
202
203bool SoftKeymasterDevice::Keymaster1DeviceIsGood() {
204 std::vector<keymaster_digest_t> expected_rsa_digests = {
205 KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
206 KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
207 std::vector<keymaster_digest_t> expected_ec_digests = {
208 KM_DIGEST_NONE, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
209 KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
210
211 for (auto& entry : km1_device_digests_) {
212 if (entry.first.first == KM_ALGORITHM_RSA)
213 if (!std::is_permutation(entry.second.begin(), entry.second.end(),
214 expected_rsa_digests.begin()))
215 return false;
216 if (entry.first.first == KM_ALGORITHM_EC)
217 if (!std::is_permutation(entry.second.begin(), entry.second.end(),
218 expected_ec_digests.begin()))
219 return false;
220 }
221 return true;
222}
223
224void SoftKeymasterDevice::initialize_device_struct() {
Shawn Willden5b53c992015-02-02 08:05:25 -0700225 memset(&device_, 0, sizeof(device_));
226
227 device_.common.tag = HARDWARE_DEVICE_TAG;
228 device_.common.version = 1;
229 device_.common.module = reinterpret_cast<hw_module_t*>(&soft_keymaster_device_module);
230 device_.common.close = &close_device;
231
Chad Brubaker23937572015-06-04 11:35:50 -0700232 device_.flags = KEYMASTER_BLOBS_ARE_STANDALONE | KEYMASTER_SUPPORTS_EC;
Shawn Willden5b53c992015-02-02 08:05:25 -0700233
Shawn Willden2beb6282015-05-20 16:36:24 -0600234 // keymaster0 APIs
Shawn Willden2612fb52015-07-27 16:58:30 -0600235 device_.generate_keypair = nullptr;
236 device_.import_keypair = nullptr;
237 device_.get_keypair_public = nullptr;
238 device_.delete_keypair = nullptr;
239 device_.delete_all = nullptr;
240 device_.sign_data = nullptr;
241 device_.verify_data = nullptr;
Shawn Willden5b53c992015-02-02 08:05:25 -0700242
Shawn Willden2beb6282015-05-20 16:36:24 -0600243 // keymaster1 APIs
Shawn Willden5b53c992015-02-02 08:05:25 -0700244 device_.get_supported_algorithms = get_supported_algorithms;
245 device_.get_supported_block_modes = get_supported_block_modes;
246 device_.get_supported_padding_modes = get_supported_padding_modes;
247 device_.get_supported_digests = get_supported_digests;
248 device_.get_supported_import_formats = get_supported_import_formats;
249 device_.get_supported_export_formats = get_supported_export_formats;
250 device_.add_rng_entropy = add_rng_entropy;
251 device_.generate_key = generate_key;
252 device_.get_key_characteristics = get_key_characteristics;
Shawn Willden5b53c992015-02-02 08:05:25 -0700253 device_.import_key = import_key;
254 device_.export_key = export_key;
Shawn Willden2beb6282015-05-20 16:36:24 -0600255 device_.delete_key = delete_key;
256 device_.delete_all_keys = delete_all_keys;
Shawn Willden5b53c992015-02-02 08:05:25 -0700257 device_.begin = begin;
258 device_.update = update;
259 device_.finish = finish;
260 device_.abort = abort;
261
262 device_.context = NULL;
263}
264
265const uint64_t HUNDRED_YEARS = 1000LL * 60 * 60 * 24 * 365 * 100;
266
267hw_device_t* SoftKeymasterDevice::hw_device() {
268 return &device_.common;
269}
270
Shawn Willden95dda362015-02-27 10:58:37 -0700271keymaster1_device_t* SoftKeymasterDevice::keymaster_device() {
272 return &device_;
273}
274
Shawn Willden5b53c992015-02-02 08:05:25 -0700275static keymaster_key_characteristics_t* BuildCharacteristics(const AuthorizationSet& hw_enforced,
276 const AuthorizationSet& sw_enforced) {
277 keymaster_key_characteristics_t* characteristics =
278 reinterpret_cast<keymaster_key_characteristics_t*>(
279 malloc(sizeof(keymaster_key_characteristics_t)));
280 if (characteristics) {
281 hw_enforced.CopyToParamSet(&characteristics->hw_enforced);
282 sw_enforced.CopyToParamSet(&characteristics->sw_enforced);
283 }
284 return characteristics;
285}
286
287template <typename RequestType>
288static void AddClientAndAppData(const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
289 RequestType* request) {
290 request->additional_params.Clear();
291 if (client_id)
292 request->additional_params.push_back(TAG_APPLICATION_ID, *client_id);
293 if (app_data)
294 request->additional_params.push_back(TAG_APPLICATION_DATA, *app_data);
295}
296
Shawn Willden30255022015-02-24 14:00:21 -0700297static inline SoftKeymasterDevice* convert_device(const keymaster1_device_t* dev) {
298 return reinterpret_cast<SoftKeymasterDevice*>(const_cast<keymaster1_device_t*>(dev));
Shawn Willden5b53c992015-02-02 08:05:25 -0700299}
300
301/* static */
302int SoftKeymasterDevice::close_device(hw_device_t* dev) {
303 delete reinterpret_cast<SoftKeymasterDevice*>(dev);
304 return 0;
305}
306
307/* static */
Shawn Willden30255022015-02-24 14:00:21 -0700308keymaster_error_t SoftKeymasterDevice::get_supported_algorithms(const keymaster1_device_t* dev,
Shawn Willden5b53c992015-02-02 08:05:25 -0700309 keymaster_algorithm_t** algorithms,
310 size_t* algorithms_length) {
Shawn Willdenf01329d2015-03-11 21:51:38 -0600311 if (!dev)
312 return KM_ERROR_UNEXPECTED_NULL_POINTER;
313
Shawn Willden5b53c992015-02-02 08:05:25 -0700314 if (!algorithms || !algorithms_length)
315 return KM_ERROR_OUTPUT_PARAMETER_NULL;
316
Shawn Willden2612fb52015-07-27 16:58:30 -0600317 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
318 if (km1_dev)
319 return km1_dev->get_supported_algorithms(km1_dev, algorithms, algorithms_length);
320
Shawn Willden36d41e22015-06-17 06:39:48 -0600321 SupportedAlgorithmsRequest request;
322 SupportedAlgorithmsResponse response;
323 convert_device(dev)->impl_->SupportedAlgorithms(request, &response);
Shawn Willdenddf2d672015-02-20 16:37:12 -0700324 if (response.error != KM_ERROR_OK) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700325 LOG_E("get_supported_algorithms failed with %d", response.error);
Shawn Willdenddf2d672015-02-20 16:37:12 -0700326
Shawn Willden5b53c992015-02-02 08:05:25 -0700327 return response.error;
Shawn Willdenddf2d672015-02-20 16:37:12 -0700328 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700329
330 *algorithms_length = response.results_length;
331 *algorithms =
332 reinterpret_cast<keymaster_algorithm_t*>(malloc(*algorithms_length * sizeof(**algorithms)));
333 if (!*algorithms)
334 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
335 std::copy(response.results, response.results + response.results_length, *algorithms);
336 return KM_ERROR_OK;
337}
338
339/* static */
Shawn Willden30255022015-02-24 14:00:21 -0700340keymaster_error_t SoftKeymasterDevice::get_supported_block_modes(const keymaster1_device_t* dev,
Shawn Willden5b53c992015-02-02 08:05:25 -0700341 keymaster_algorithm_t algorithm,
342 keymaster_purpose_t purpose,
343 keymaster_block_mode_t** modes,
344 size_t* modes_length) {
Shawn Willdenf01329d2015-03-11 21:51:38 -0600345 if (!dev)
346 return KM_ERROR_UNEXPECTED_NULL_POINTER;
347
Shawn Willden5b53c992015-02-02 08:05:25 -0700348 if (!modes || !modes_length)
349 return KM_ERROR_OUTPUT_PARAMETER_NULL;
350
Shawn Willden2612fb52015-07-27 16:58:30 -0600351 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
352 if (km1_dev)
353 return km1_dev->get_supported_block_modes(km1_dev, algorithm, purpose, modes, modes_length);
354
Shawn Willden36d41e22015-06-17 06:39:48 -0600355 SupportedBlockModesRequest request;
356 request.algorithm = algorithm;
357 request.purpose = purpose;
358 SupportedBlockModesResponse response;
359 convert_device(dev)->impl_->SupportedBlockModes(request, &response);
Shawn Willden5b53c992015-02-02 08:05:25 -0700360
Shawn Willdenddf2d672015-02-20 16:37:12 -0700361 if (response.error != KM_ERROR_OK) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700362 LOG_E("get_supported_block_modes failed with %d", response.error);
Shawn Willdenddf2d672015-02-20 16:37:12 -0700363
Shawn Willden5b53c992015-02-02 08:05:25 -0700364 return response.error;
Shawn Willdenddf2d672015-02-20 16:37:12 -0700365 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700366
367 *modes_length = response.results_length;
368 *modes = reinterpret_cast<keymaster_block_mode_t*>(malloc(*modes_length * sizeof(**modes)));
369 if (!*modes)
370 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
371 std::copy(response.results, response.results + response.results_length, *modes);
372 return KM_ERROR_OK;
373}
374
375/* static */
Shawn Willden30255022015-02-24 14:00:21 -0700376keymaster_error_t SoftKeymasterDevice::get_supported_padding_modes(const keymaster1_device_t* dev,
377 keymaster_algorithm_t algorithm,
378 keymaster_purpose_t purpose,
379 keymaster_padding_t** modes,
380 size_t* modes_length) {
Shawn Willdenf01329d2015-03-11 21:51:38 -0600381 if (!dev)
382 return KM_ERROR_UNEXPECTED_NULL_POINTER;
383
Shawn Willden5b53c992015-02-02 08:05:25 -0700384 if (!modes || !modes_length)
385 return KM_ERROR_OUTPUT_PARAMETER_NULL;
386
Shawn Willden2612fb52015-07-27 16:58:30 -0600387 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
388 if (km1_dev)
389 return km1_dev->get_supported_padding_modes(km1_dev, algorithm, purpose, modes,
390 modes_length);
391
Shawn Willden36d41e22015-06-17 06:39:48 -0600392 SupportedPaddingModesRequest request;
393 request.algorithm = algorithm;
394 request.purpose = purpose;
395 SupportedPaddingModesResponse response;
396 convert_device(dev)->impl_->SupportedPaddingModes(request, &response);
Shawn Willden5b53c992015-02-02 08:05:25 -0700397
Shawn Willdenddf2d672015-02-20 16:37:12 -0700398 if (response.error != KM_ERROR_OK) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700399 LOG_E("get_supported_padding_modes failed with %d", response.error);
Shawn Willden5b53c992015-02-02 08:05:25 -0700400 return response.error;
Shawn Willdenddf2d672015-02-20 16:37:12 -0700401 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700402
403 *modes_length = response.results_length;
404 *modes = reinterpret_cast<keymaster_padding_t*>(malloc(*modes_length * sizeof(**modes)));
405 if (!*modes)
406 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
407 std::copy(response.results, response.results + response.results_length, *modes);
408 return KM_ERROR_OK;
409}
410
411/* static */
Shawn Willden30255022015-02-24 14:00:21 -0700412keymaster_error_t SoftKeymasterDevice::get_supported_digests(const keymaster1_device_t* dev,
Shawn Willden5b53c992015-02-02 08:05:25 -0700413 keymaster_algorithm_t algorithm,
414 keymaster_purpose_t purpose,
415 keymaster_digest_t** digests,
416 size_t* digests_length) {
Shawn Willdenf01329d2015-03-11 21:51:38 -0600417 if (!dev)
418 return KM_ERROR_UNEXPECTED_NULL_POINTER;
419
Shawn Willden5b53c992015-02-02 08:05:25 -0700420 if (!digests || !digests_length)
421 return KM_ERROR_OUTPUT_PARAMETER_NULL;
422
Shawn Willden2612fb52015-07-27 16:58:30 -0600423 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
424 if (km1_dev)
425 return km1_dev->get_supported_digests(km1_dev, algorithm, purpose, digests, digests_length);
426
Shawn Willden36d41e22015-06-17 06:39:48 -0600427 SupportedDigestsRequest request;
428 request.algorithm = algorithm;
429 request.purpose = purpose;
430 SupportedDigestsResponse response;
431 convert_device(dev)->impl_->SupportedDigests(request, &response);
Shawn Willden5b53c992015-02-02 08:05:25 -0700432
Shawn Willdenddf2d672015-02-20 16:37:12 -0700433 if (response.error != KM_ERROR_OK) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700434 LOG_E("get_supported_digests failed with %d", response.error);
Shawn Willden5b53c992015-02-02 08:05:25 -0700435 return response.error;
Shawn Willdenddf2d672015-02-20 16:37:12 -0700436 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700437
438 *digests_length = response.results_length;
439 *digests = reinterpret_cast<keymaster_digest_t*>(malloc(*digests_length * sizeof(**digests)));
440 if (!*digests)
441 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
442 std::copy(response.results, response.results + response.results_length, *digests);
443 return KM_ERROR_OK;
444}
445
446/* static */
447keymaster_error_t SoftKeymasterDevice::get_supported_import_formats(
Shawn Willden30255022015-02-24 14:00:21 -0700448 const keymaster1_device_t* dev, keymaster_algorithm_t algorithm,
Shawn Willden5b53c992015-02-02 08:05:25 -0700449 keymaster_key_format_t** formats, size_t* formats_length) {
Shawn Willdenf01329d2015-03-11 21:51:38 -0600450 if (!dev)
451 return KM_ERROR_UNEXPECTED_NULL_POINTER;
452
Shawn Willden5b53c992015-02-02 08:05:25 -0700453 if (!formats || !formats_length)
454 return KM_ERROR_OUTPUT_PARAMETER_NULL;
455
Shawn Willden2612fb52015-07-27 16:58:30 -0600456 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
457 if (km1_dev)
458 return km1_dev->get_supported_import_formats(km1_dev, algorithm, formats, formats_length);
459
Shawn Willden36d41e22015-06-17 06:39:48 -0600460 SupportedImportFormatsRequest request;
461 request.algorithm = algorithm;
462 SupportedImportFormatsResponse response;
463 convert_device(dev)->impl_->SupportedImportFormats(request, &response);
Shawn Willden5b53c992015-02-02 08:05:25 -0700464
Shawn Willdenddf2d672015-02-20 16:37:12 -0700465 if (response.error != KM_ERROR_OK) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700466 LOG_E("get_supported_import_formats failed with %d", response.error);
Shawn Willden5b53c992015-02-02 08:05:25 -0700467 return response.error;
Shawn Willdenddf2d672015-02-20 16:37:12 -0700468 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700469
470 *formats_length = response.results_length;
471 *formats =
472 reinterpret_cast<keymaster_key_format_t*>(malloc(*formats_length * sizeof(**formats)));
473 if (!*formats)
474 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
475 std::copy(response.results, response.results + response.results_length, *formats);
476 return KM_ERROR_OK;
477}
478
479/* static */
480keymaster_error_t SoftKeymasterDevice::get_supported_export_formats(
Shawn Willden30255022015-02-24 14:00:21 -0700481 const keymaster1_device_t* dev, keymaster_algorithm_t algorithm,
Shawn Willden5b53c992015-02-02 08:05:25 -0700482 keymaster_key_format_t** formats, size_t* formats_length) {
Shawn Willdenf01329d2015-03-11 21:51:38 -0600483 if (!dev)
484 return KM_ERROR_UNEXPECTED_NULL_POINTER;
485
Shawn Willden5b53c992015-02-02 08:05:25 -0700486 if (!formats || !formats_length)
487 return KM_ERROR_OUTPUT_PARAMETER_NULL;
488
Shawn Willden2612fb52015-07-27 16:58:30 -0600489 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
490 if (km1_dev)
491 return km1_dev->get_supported_export_formats(km1_dev, algorithm, formats, formats_length);
492
Shawn Willden36d41e22015-06-17 06:39:48 -0600493 SupportedExportFormatsRequest request;
494 request.algorithm = algorithm;
495 SupportedExportFormatsResponse response;
496 convert_device(dev)->impl_->SupportedExportFormats(request, &response);
Shawn Willden5b53c992015-02-02 08:05:25 -0700497
Shawn Willdenddf2d672015-02-20 16:37:12 -0700498 if (response.error != KM_ERROR_OK) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700499 LOG_E("get_supported_export_formats failed with %d", response.error);
Shawn Willden5b53c992015-02-02 08:05:25 -0700500 return response.error;
Shawn Willdenddf2d672015-02-20 16:37:12 -0700501 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700502
503 *formats_length = response.results_length;
504 *formats =
505 reinterpret_cast<keymaster_key_format_t*>(malloc(*formats_length * sizeof(**formats)));
506 if (!*formats)
507 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
508 std::copy(response.results, response.results + *formats_length, *formats);
509 return KM_ERROR_OK;
510}
511
512/* static */
Shawn Willdencd695822015-01-26 14:06:32 -0700513keymaster_error_t SoftKeymasterDevice::add_rng_entropy(const keymaster1_device_t* dev,
514 const uint8_t* data, size_t data_length) {
Shawn Willdenf01329d2015-03-11 21:51:38 -0600515 if (!dev)
516 return KM_ERROR_UNEXPECTED_NULL_POINTER;
517
Shawn Willden2612fb52015-07-27 16:58:30 -0600518 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
519 if (km1_dev)
520 return km1_dev->add_rng_entropy(km1_dev, data, data_length);
521
Shawn Willdencd695822015-01-26 14:06:32 -0700522 AddEntropyRequest request;
523 request.random_data.Reinitialize(data, data_length);
Shawn Willden36d41e22015-06-17 06:39:48 -0600524 AddEntropyResponse response;
525 convert_device(dev)->impl_->AddRngEntropy(request, &response);
526 if (response.error != KM_ERROR_OK)
527 LOG_E("add_rng_entropy failed with %d", response.error);
528 return response.error;
Shawn Willden5b53c992015-02-02 08:05:25 -0700529}
530
Shawn Willden2612fb52015-07-27 16:58:30 -0600531template <typename Collection, typename Value> bool contains(const Collection& c, const Value& v) {
532 return std::find(c.begin(), c.end(), v) != c.end();
533}
534
535bool SoftKeymasterDevice::FindUnsupportedDigest(keymaster_algorithm_t algorithm,
536 keymaster_purpose_t purpose,
537 const AuthorizationSet& params,
538 keymaster_digest_t* unsupported) const {
539 assert(wrapped_km1_device_);
540
541 auto supported_digests = km1_device_digests_.find(std::make_pair(algorithm, purpose));
542 if (supported_digests == km1_device_digests_.end())
543 // Invalid algorith/purpose pair (e.g. EC encrypt). Let the error be handled by HW module.
544 return false;
545
546 for (auto& entry : params)
547 if (entry.tag == TAG_DIGEST)
548 if (!contains(supported_digests->second, entry.enumerated)) {
549 LOG_I("Digest %d requested but not supported by module %s", entry.enumerated,
550 wrapped_km1_device_->common.module->name);
551 *unsupported = static_cast<keymaster_digest_t>(entry.enumerated);
552 return true;
553 }
554 return false;
555}
556
557bool SoftKeymasterDevice::RequiresSoftwareDigesting(keymaster_algorithm_t algorithm,
558 keymaster_purpose_t purpose,
559 const AuthorizationSet& params) const {
560 assert(wrapped_km1_device_);
561 if (!wrapped_km1_device_)
562 return true;
563
564 switch (algorithm) {
565 case KM_ALGORITHM_AES:
566 case KM_ALGORITHM_HMAC:
567 LOG_D("Not performing software digesting for algorithm %d", algorithm);
568 return false;
569 case KM_ALGORITHM_RSA:
570 case KM_ALGORITHM_EC:
571 break;
572 }
573
574 keymaster_digest_t unsupported;
575 if (!FindUnsupportedDigest(algorithm, purpose, params, &unsupported)) {
576 LOG_D("Requested digest(s) supported for algorithm %d and purpose %d", algorithm, purpose);
577 return false;
578 }
579
580 return true;
581}
582
583bool SoftKeymasterDevice::KeyRequiresSoftwareDigesting(
584 const AuthorizationSet& key_description) const {
585 assert(wrapped_km1_device_);
586 if (!wrapped_km1_device_)
587 return true;
588
589 keymaster_algorithm_t algorithm;
590 if (!key_description.GetTagValue(TAG_ALGORITHM, &algorithm)) {
591 // The hardware module will return an error during keygen.
592 return false;
593 }
594
595 for (auto& entry : key_description)
596 if (entry.tag == TAG_PURPOSE) {
597 keymaster_purpose_t purpose = static_cast<keymaster_purpose_t>(entry.enumerated);
598 if (RequiresSoftwareDigesting(algorithm, purpose, key_description))
599 return true;
600 }
601
602 return false;
603}
604
Shawn Willden5b53c992015-02-02 08:05:25 -0700605/* static */
606keymaster_error_t SoftKeymasterDevice::generate_key(
Shawn Willden0e2ee442015-06-01 14:42:16 -0600607 const keymaster1_device_t* dev, const keymaster_key_param_set_t* params,
Shawn Willden5b53c992015-02-02 08:05:25 -0700608 keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t** characteristics) {
Shawn Willdenf01329d2015-03-11 21:51:38 -0600609 if (!dev || !params)
610 return KM_ERROR_UNEXPECTED_NULL_POINTER;
Shawn Willden5b53c992015-02-02 08:05:25 -0700611
612 if (!key_blob)
613 return KM_ERROR_OUTPUT_PARAMETER_NULL;
614
Shawn Willden2612fb52015-07-27 16:58:30 -0600615 SoftKeymasterDevice* sk_dev = convert_device(dev);
616
Shawn Willden5b53c992015-02-02 08:05:25 -0700617 GenerateKeyRequest request;
Shawn Willden0e2ee442015-06-01 14:42:16 -0600618 request.key_description.Reinitialize(*params);
Shawn Willden5b53c992015-02-02 08:05:25 -0700619
Shawn Willden2612fb52015-07-27 16:58:30 -0600620 keymaster1_device_t* km1_dev = sk_dev->wrapped_km1_device_;
621 if (km1_dev && !sk_dev->KeyRequiresSoftwareDigesting(request.key_description))
622 return km1_dev->generate_key(km1_dev, params, key_blob, characteristics);
623
Shawn Willden5b53c992015-02-02 08:05:25 -0700624 GenerateKeyResponse response;
Shawn Willden2612fb52015-07-27 16:58:30 -0600625 sk_dev->impl_->GenerateKey(request, &response);
Shawn Willden5b53c992015-02-02 08:05:25 -0700626 if (response.error != KM_ERROR_OK)
627 return response.error;
628
629 key_blob->key_material_size = response.key_blob.key_material_size;
630 uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(key_blob->key_material_size));
631 if (!tmp)
632 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
633 memcpy(tmp, response.key_blob.key_material, response.key_blob.key_material_size);
634 key_blob->key_material = tmp;
635
636 if (characteristics) {
637 *characteristics = BuildCharacteristics(response.enforced, response.unenforced);
638 if (!*characteristics)
639 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
640 }
641
642 return KM_ERROR_OK;
643}
644
645/* static */
646keymaster_error_t SoftKeymasterDevice::get_key_characteristics(
Shawn Willden30255022015-02-24 14:00:21 -0700647 const keymaster1_device_t* dev, const keymaster_key_blob_t* key_blob,
Shawn Willden5b53c992015-02-02 08:05:25 -0700648 const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
649 keymaster_key_characteristics_t** characteristics) {
Shawn Willdenf01329d2015-03-11 21:51:38 -0600650 if (!dev || !key_blob || !key_blob->key_material)
651 return KM_ERROR_UNEXPECTED_NULL_POINTER;
Shawn Willden5b53c992015-02-02 08:05:25 -0700652
653 if (!characteristics)
654 return KM_ERROR_OUTPUT_PARAMETER_NULL;
655
Shawn Willden2612fb52015-07-27 16:58:30 -0600656 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
657 if (km1_dev)
658 return km1_dev->get_key_characteristics(km1_dev, key_blob, client_id, app_data,
659 characteristics);
660
Shawn Willden5b53c992015-02-02 08:05:25 -0700661 GetKeyCharacteristicsRequest request;
662 request.SetKeyMaterial(*key_blob);
663 AddClientAndAppData(client_id, app_data, &request);
664
665 GetKeyCharacteristicsResponse response;
666 convert_device(dev)->impl_->GetKeyCharacteristics(request, &response);
667 if (response.error != KM_ERROR_OK)
668 return response.error;
669
670 *characteristics = BuildCharacteristics(response.enforced, response.unenforced);
671 if (!*characteristics)
672 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
673 return KM_ERROR_OK;
674}
675
676/* static */
Shawn Willden5b53c992015-02-02 08:05:25 -0700677keymaster_error_t SoftKeymasterDevice::import_key(
Shawn Willden0e2ee442015-06-01 14:42:16 -0600678 const keymaster1_device_t* dev, const keymaster_key_param_set_t* params,
679 keymaster_key_format_t key_format, const keymaster_blob_t* key_data,
Shawn Willden5b53c992015-02-02 08:05:25 -0700680 keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t** characteristics) {
681 if (!params || !key_data)
682 return KM_ERROR_UNEXPECTED_NULL_POINTER;
683
684 if (!key_blob)
685 return KM_ERROR_OUTPUT_PARAMETER_NULL;
686
Shawn Willden2612fb52015-07-27 16:58:30 -0600687 SoftKeymasterDevice* sk_dev = convert_device(dev);
Shawn Willden5b53c992015-02-02 08:05:25 -0700688
689 ImportKeyRequest request;
Shawn Willden0e2ee442015-06-01 14:42:16 -0600690 request.key_description.Reinitialize(*params);
Shawn Willden2612fb52015-07-27 16:58:30 -0600691
692 keymaster1_device_t* km1_dev = sk_dev->wrapped_km1_device_;
693 if (km1_dev && !sk_dev->KeyRequiresSoftwareDigesting(request.key_description))
694 return km1_dev->import_key(km1_dev, params, key_format, key_data, key_blob,
695 characteristics);
696
697 *characteristics = nullptr;
698
Shawn Willden5b53c992015-02-02 08:05:25 -0700699 request.key_format = key_format;
Shawn Willden0e2ee442015-06-01 14:42:16 -0600700 request.SetKeyMaterial(key_data->data, key_data->data_length);
Shawn Willden5b53c992015-02-02 08:05:25 -0700701
702 ImportKeyResponse response;
703 convert_device(dev)->impl_->ImportKey(request, &response);
704 if (response.error != KM_ERROR_OK)
705 return response.error;
706
707 key_blob->key_material_size = response.key_blob.key_material_size;
708 key_blob->key_material = reinterpret_cast<uint8_t*>(malloc(key_blob->key_material_size));
709 if (!key_blob->key_material)
710 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
711 memcpy(const_cast<uint8_t*>(key_blob->key_material), response.key_blob.key_material,
712 response.key_blob.key_material_size);
713
714 if (characteristics) {
715 *characteristics = BuildCharacteristics(response.enforced, response.unenforced);
716 if (!*characteristics)
717 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
718 }
719 return KM_ERROR_OK;
720}
721
722/* static */
Shawn Willden0e2ee442015-06-01 14:42:16 -0600723keymaster_error_t SoftKeymasterDevice::export_key(const keymaster1_device_t* dev,
724 keymaster_key_format_t export_format,
725 const keymaster_key_blob_t* key_to_export,
726 const keymaster_blob_t* client_id,
727 const keymaster_blob_t* app_data,
728 keymaster_blob_t* export_data) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700729 if (!key_to_export || !key_to_export->key_material)
Shawn Willdenf01329d2015-03-11 21:51:38 -0600730 return KM_ERROR_UNEXPECTED_NULL_POINTER;
Shawn Willden5b53c992015-02-02 08:05:25 -0700731
Shawn Willden0e2ee442015-06-01 14:42:16 -0600732 if (!export_data)
Shawn Willden5b53c992015-02-02 08:05:25 -0700733 return KM_ERROR_OUTPUT_PARAMETER_NULL;
734
Shawn Willden2612fb52015-07-27 16:58:30 -0600735 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
736 if (km1_dev)
737 return km1_dev->export_key(km1_dev, export_format, key_to_export, client_id, app_data,
738 export_data);
739
Shawn Willden0e2ee442015-06-01 14:42:16 -0600740 export_data->data = nullptr;
741 export_data->data_length = 0;
Shawn Willden5b53c992015-02-02 08:05:25 -0700742
743 ExportKeyRequest request;
744 request.key_format = export_format;
745 request.SetKeyMaterial(*key_to_export);
746 AddClientAndAppData(client_id, app_data, &request);
747
748 ExportKeyResponse response;
749 convert_device(dev)->impl_->ExportKey(request, &response);
750 if (response.error != KM_ERROR_OK)
751 return response.error;
752
Shawn Willden0e2ee442015-06-01 14:42:16 -0600753 export_data->data_length = response.key_data_length;
754 uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(export_data->data_length));
755 if (!tmp)
Shawn Willden5b53c992015-02-02 08:05:25 -0700756 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden0e2ee442015-06-01 14:42:16 -0600757 memcpy(tmp, response.key_data, export_data->data_length);
758 export_data->data = tmp;
Shawn Willden5b53c992015-02-02 08:05:25 -0700759 return KM_ERROR_OK;
760}
761
762/* static */
Shawn Willdend091b0a2015-07-06 11:35:10 -0600763keymaster_error_t SoftKeymasterDevice::delete_key(const struct keymaster1_device* dev,
764 const keymaster_key_blob_t* key) {
765 if (!dev || !key || !key->key_material)
766 return KM_ERROR_UNEXPECTED_NULL_POINTER;
767
Shawn Willden2612fb52015-07-27 16:58:30 -0600768 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
769 if (km1_dev && km1_dev->delete_key)
770 return km1_dev->delete_key(km1_dev, key);
Shawn Willdend091b0a2015-07-06 11:35:10 -0600771
Shawn Willden2612fb52015-07-27 16:58:30 -0600772 const keymaster0_device_t* km0_dev = convert_device(dev)->wrapped_km0_device_;
773 if (km0_dev && km0_dev->delete_keypair)
774 if (km0_dev->delete_keypair(km0_dev, key->key_material, key->key_material_size) < 0)
Shawn Willdend091b0a2015-07-06 11:35:10 -0600775 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2612fb52015-07-27 16:58:30 -0600776
Shawn Willdend091b0a2015-07-06 11:35:10 -0600777 return KM_ERROR_OK;
Shawn Willden2beb6282015-05-20 16:36:24 -0600778}
779
780/* static */
Shawn Willdend091b0a2015-07-06 11:35:10 -0600781keymaster_error_t SoftKeymasterDevice::delete_all_keys(const struct keymaster1_device* dev) {
782 if (!dev)
783 return KM_ERROR_UNEXPECTED_NULL_POINTER;
784
Shawn Willden2612fb52015-07-27 16:58:30 -0600785 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
786 if (km1_dev && km1_dev->delete_all_keys)
787 return km1_dev->delete_all_keys(km1_dev);
Shawn Willdend091b0a2015-07-06 11:35:10 -0600788
Shawn Willden2612fb52015-07-27 16:58:30 -0600789 const keymaster0_device_t* km0_dev = convert_device(dev)->wrapped_km0_device_;
790 if (km0_dev && km0_dev->delete_all)
791 if (km0_dev->delete_all(km0_dev) < 0)
Shawn Willdend091b0a2015-07-06 11:35:10 -0600792 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2612fb52015-07-27 16:58:30 -0600793
Shawn Willdend091b0a2015-07-06 11:35:10 -0600794 return KM_ERROR_OK;
Shawn Willden2beb6282015-05-20 16:36:24 -0600795}
796
Shawn Willden2612fb52015-07-27 16:58:30 -0600797static bool FindAlgorithm(const keymaster_key_param_set_t& params,
798 keymaster_algorithm_t* algorithm) {
799 for (size_t i = 0; i < params.length; ++i)
800 if (params.params[i].tag == KM_TAG_ALGORITHM) {
801 *algorithm = static_cast<keymaster_algorithm_t>(params.params[i].enumerated);
802 return true;
803 }
804 return false;
805}
806
807static keymaster_error_t GetAlgorithm(const keymaster1_device_t* dev,
808 const keymaster_key_blob_t& key,
809 const AuthorizationSet& in_params,
810 keymaster_algorithm_t* algorithm) {
811 keymaster_blob_t client_id = {nullptr, 0};
812 keymaster_blob_t app_data = {nullptr, 0};
813 keymaster_blob_t* client_id_ptr = nullptr;
814 keymaster_blob_t* app_data_ptr = nullptr;
815 if (in_params.GetTagValue(TAG_APPLICATION_ID, &client_id))
816 client_id_ptr = &client_id;
817 if (in_params.GetTagValue(TAG_APPLICATION_DATA, &app_data))
818 app_data_ptr = &app_data;
819
820 keymaster_key_characteristics_t* characteristics;
821 keymaster_error_t error =
822 dev->get_key_characteristics(dev, &key, client_id_ptr, app_data_ptr, &characteristics);
823 if (error != KM_ERROR_OK)
824 return error;
825 std::unique_ptr<keymaster_key_characteristics_t, Characteristics_Delete>
826 characteristics_deleter(characteristics);
827
828 if (FindAlgorithm(characteristics->hw_enforced, algorithm))
829 return KM_ERROR_OK;
830
831 if (FindAlgorithm(characteristics->sw_enforced, algorithm))
832 return KM_ERROR_OK;
833
834 return KM_ERROR_INVALID_KEY_BLOB;
835}
836
Shawn Willden2beb6282015-05-20 16:36:24 -0600837/* static */
Shawn Willden0e2ee442015-06-01 14:42:16 -0600838keymaster_error_t SoftKeymasterDevice::begin(const keymaster1_device_t* dev,
839 keymaster_purpose_t purpose,
840 const keymaster_key_blob_t* key,
841 const keymaster_key_param_set_t* in_params,
842 keymaster_key_param_set_t* out_params,
843 keymaster_operation_handle_t* operation_handle) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700844 if (!key || !key->key_material)
Shawn Willdenf01329d2015-03-11 21:51:38 -0600845 return KM_ERROR_UNEXPECTED_NULL_POINTER;
Shawn Willden5b53c992015-02-02 08:05:25 -0700846
Shawn Willden2612fb52015-07-27 16:58:30 -0600847 if (!operation_handle)
Shawn Willden5b53c992015-02-02 08:05:25 -0700848 return KM_ERROR_OUTPUT_PARAMETER_NULL;
849
Shawn Willden2612fb52015-07-27 16:58:30 -0600850 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
851 if (km1_dev) {
852 AuthorizationSet in_params_set(*in_params);
853
854 keymaster_algorithm_t algorithm = KM_ALGORITHM_AES;
855 keymaster_error_t error = GetAlgorithm(km1_dev, *key, in_params_set, &algorithm);
856 if (error != KM_ERROR_OK)
857 return error;
858
859 if (!convert_device(dev)->RequiresSoftwareDigesting(algorithm, purpose, in_params_set)) {
860 LOG_D("Operation supported by %s, passing through to keymaster1 module",
861 km1_dev->common.module->name);
862 return km1_dev->begin(km1_dev, purpose, key, in_params, out_params, operation_handle);
863 }
864 LOG_I("Doing software digesting for keymaster1 module %s", km1_dev->common.module->name);
865 }
866
867 if (out_params) {
868 out_params->params = nullptr;
869 out_params->length = 0;
870 }
Shawn Willden95e13822014-12-15 16:12:16 -0700871
Shawn Willden5b53c992015-02-02 08:05:25 -0700872 BeginOperationRequest request;
873 request.purpose = purpose;
874 request.SetKeyMaterial(*key);
Shawn Willden0e2ee442015-06-01 14:42:16 -0600875 request.additional_params.Reinitialize(*in_params);
Shawn Willden5b53c992015-02-02 08:05:25 -0700876
877 BeginOperationResponse response;
878 convert_device(dev)->impl_->BeginOperation(request, &response);
879 if (response.error != KM_ERROR_OK)
880 return response.error;
881
Shawn Willden2612fb52015-07-27 16:58:30 -0600882 if (response.output_params.size() > 0) {
883 if (out_params)
884 response.output_params.CopyToParamSet(out_params);
885 else
886 return KM_ERROR_OUTPUT_PARAMETER_NULL;
887 }
Shawn Willdendfa1c032015-02-07 00:39:01 -0700888
Shawn Willden5b53c992015-02-02 08:05:25 -0700889 *operation_handle = response.op_handle;
890 return KM_ERROR_OK;
891}
892
893/* static */
Shawn Willden30255022015-02-24 14:00:21 -0700894keymaster_error_t SoftKeymasterDevice::update(const keymaster1_device_t* dev,
Shawn Willden5b53c992015-02-02 08:05:25 -0700895 keymaster_operation_handle_t operation_handle,
Shawn Willden0e2ee442015-06-01 14:42:16 -0600896 const keymaster_key_param_set_t* in_params,
897 const keymaster_blob_t* input, size_t* input_consumed,
898 keymaster_key_param_set_t* out_params,
899 keymaster_blob_t* output) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700900 if (!input)
901 return KM_ERROR_UNEXPECTED_NULL_POINTER;
902
Shawn Willden2612fb52015-07-27 16:58:30 -0600903 if (!input_consumed)
Shawn Willden5b53c992015-02-02 08:05:25 -0700904 return KM_ERROR_OUTPUT_PARAMETER_NULL;
905
Shawn Willden2612fb52015-07-27 16:58:30 -0600906 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
907 if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
908 // This operation is being handled by km1_dev (or doesn't exist). Pass it through to
909 // km1_dev. Otherwise, we'll use the software AndroidKeymaster, which may delegate to
910 // km1_dev after doing necessary digesting.
911 return km1_dev->update(km1_dev, operation_handle, in_params, input, input_consumed,
912 out_params, output);
913 }
914
915 if (out_params) {
916 out_params->params = nullptr;
917 out_params->length = 0;
918 }
919 if (output) {
920 output->data = nullptr;
921 output->data_length = 0;
922 }
Shawn Willden0e2ee442015-06-01 14:42:16 -0600923
Shawn Willden5b53c992015-02-02 08:05:25 -0700924 UpdateOperationRequest request;
925 request.op_handle = operation_handle;
Shawn Willden0e2ee442015-06-01 14:42:16 -0600926 if (input)
927 request.input.Reinitialize(input->data, input->data_length);
928 if (in_params)
929 request.additional_params.Reinitialize(*in_params);
Shawn Willden5b53c992015-02-02 08:05:25 -0700930
931 UpdateOperationResponse response;
932 convert_device(dev)->impl_->UpdateOperation(request, &response);
933 if (response.error != KM_ERROR_OK)
934 return response.error;
935
Shawn Willden2612fb52015-07-27 16:58:30 -0600936 if (response.output_params.size() > 0) {
937 if (out_params)
938 response.output_params.CopyToParamSet(out_params);
939 else
940 return KM_ERROR_OUTPUT_PARAMETER_NULL;
941 }
Shawn Willden0e2ee442015-06-01 14:42:16 -0600942
Shawn Willden5b53c992015-02-02 08:05:25 -0700943 *input_consumed = response.input_consumed;
Shawn Willden2612fb52015-07-27 16:58:30 -0600944 if (output) {
945 output->data_length = response.output.available_read();
946 uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(output->data_length));
947 if (!tmp)
948 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
949 memcpy(tmp, response.output.peek_read(), output->data_length);
950 output->data = tmp;
951 } else if (response.output.available_read() > 0) {
952 return KM_ERROR_OUTPUT_PARAMETER_NULL;
953 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700954 return KM_ERROR_OK;
955}
956
957/* static */
Shawn Willden30255022015-02-24 14:00:21 -0700958keymaster_error_t SoftKeymasterDevice::finish(const keymaster1_device_t* dev,
Shawn Willden5b53c992015-02-02 08:05:25 -0700959 keymaster_operation_handle_t operation_handle,
Shawn Willden0e2ee442015-06-01 14:42:16 -0600960 const keymaster_key_param_set_t* params,
961 const keymaster_blob_t* signature,
962 keymaster_key_param_set_t* out_params,
963 keymaster_blob_t* output) {
Shawn Willden2612fb52015-07-27 16:58:30 -0600964 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
965 if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
966 // This operation is being handled by km1_dev (or doesn't exist). Pass it through to
967 // km1_dev. Otherwise, we'll use the software AndroidKeymaster, which may delegate to
968 // km1_dev after doing necessary digesting.
969 return km1_dev->finish(km1_dev, operation_handle, params, signature, out_params, output);
970 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700971
Shawn Willden2612fb52015-07-27 16:58:30 -0600972 if (out_params) {
973 out_params->params = nullptr;
974 out_params->length = 0;
975 }
976
977 if (output) {
978 output->data = nullptr;
979 output->data_length = 0;
980 }
Shawn Willden0e2ee442015-06-01 14:42:16 -0600981
Shawn Willden5b53c992015-02-02 08:05:25 -0700982 FinishOperationRequest request;
983 request.op_handle = operation_handle;
Shawn Willden2612fb52015-07-27 16:58:30 -0600984 if (signature && signature->data_length > 0)
Shawn Willden0e2ee442015-06-01 14:42:16 -0600985 request.signature.Reinitialize(signature->data, signature->data_length);
986 request.additional_params.Reinitialize(*params);
Shawn Willden5b53c992015-02-02 08:05:25 -0700987
988 FinishOperationResponse response;
989 convert_device(dev)->impl_->FinishOperation(request, &response);
990 if (response.error != KM_ERROR_OK)
991 return response.error;
992
Shawn Willden2612fb52015-07-27 16:58:30 -0600993 if (response.output_params.size() > 0) {
994 if (out_params)
995 response.output_params.CopyToParamSet(out_params);
996 else
997 return KM_ERROR_OUTPUT_PARAMETER_NULL;
998 }
999 if (output) {
Shawn Willden0e2ee442015-06-01 14:42:16 -06001000 output->data_length = response.output.available_read();
Shawn Willden2612fb52015-07-27 16:58:30 -06001001 uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(output->data_length));
1002 if (!tmp)
1003 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
1004 memcpy(tmp, response.output.peek_read(), output->data_length);
1005 output->data = tmp;
1006 } else if (response.output.available_read() > 0) {
1007 return KM_ERROR_OUTPUT_PARAMETER_NULL;
1008 }
1009
Shawn Willden5b53c992015-02-02 08:05:25 -07001010 return KM_ERROR_OK;
1011}
1012
1013/* static */
Shawn Willden30255022015-02-24 14:00:21 -07001014keymaster_error_t SoftKeymasterDevice::abort(const keymaster1_device_t* dev,
Shawn Willden5b53c992015-02-02 08:05:25 -07001015 keymaster_operation_handle_t operation_handle) {
Shawn Willden2612fb52015-07-27 16:58:30 -06001016 const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
1017 if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
1018 // This operation is being handled by km1_dev (or doesn't exist). Pass it through to
1019 // km1_dev. Otherwise, we'll use the software AndroidKeymaster, which may delegate to
1020 // km1_dev.
1021 return km1_dev->abort(km1_dev, operation_handle);
1022 }
1023
Shawn Willden36d41e22015-06-17 06:39:48 -06001024 AbortOperationRequest request;
1025 request.op_handle = operation_handle;
1026 AbortOperationResponse response;
1027 convert_device(dev)->impl_->AbortOperation(request, &response);
1028 return response.error;
Shawn Willden5b53c992015-02-02 08:05:25 -07001029}
1030
1031/* static */
Shawn Willden5cf45022015-07-20 09:10:32 -06001032void SoftKeymasterDevice::StoreDefaultNewKeyParams(keymaster_algorithm_t algorithm,
1033 AuthorizationSet* auth_set) {
Shawn Willden5b53c992015-02-02 08:05:25 -07001034 auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN);
1035 auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY);
1036 auth_set->push_back(TAG_ALL_USERS);
1037 auth_set->push_back(TAG_NO_AUTH_REQUIRED);
Shawn Willden5cf45022015-07-20 09:10:32 -06001038
1039 // All digests.
Shawn Willden30255022015-02-24 14:00:21 -07001040 auth_set->push_back(TAG_DIGEST, KM_DIGEST_NONE);
Shawn Willden5cf45022015-07-20 09:10:32 -06001041 auth_set->push_back(TAG_DIGEST, KM_DIGEST_MD5);
1042 auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA1);
1043 auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224);
1044 auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
1045 auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384);
1046 auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512);
1047
1048 if (algorithm == KM_ALGORITHM_RSA) {
1049 auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
1050 auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
1051 auth_set->push_back(TAG_PADDING, KM_PAD_NONE);
1052 auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
1053 auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
1054 auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PSS);
1055 auth_set->push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
1056 }
Shawn Willden5b53c992015-02-02 08:05:25 -07001057}
1058
1059} // namespace keymaster