blob: 0524ed422fc66b84d7bc8a7cd9b1987e8571cd79 [file] [log] [blame]
Shawn Willden128ffe02014-08-06 12:31:33 -06001/*
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
Shawn Willdenb6837e72015-05-16 09:20:59 -060017#include <keymaster/android_keymaster.h>
Shawn Willden567a4a02014-12-31 12:14:46 -070018
Shawn Willden128ffe02014-08-06 12:31:33 -060019#include <assert.h>
20#include <string.h>
21
Shawn Willden4db3fbd2014-08-08 22:13:44 -060022#include <cstddef>
23
Shawn Willden1615f2e2014-08-13 10:37:40 -060024#include <openssl/rand.h>
Shawn Willdenffd790c2014-08-18 21:20:06 -060025#include <openssl/x509.h>
Shawn Willden128ffe02014-08-06 12:31:33 -060026
27#include <UniquePtr.h>
28
Shawn Willdenb6837e72015-05-16 09:20:59 -060029#include <keymaster/android_keymaster_utils.h>
Shawn Willden0cb69422015-05-26 08:31:37 -060030#include <keymaster/keymaster_context.h>
Shawn Willden98d9b922014-08-26 08:14:10 -060031
Shawn Willden3879f862014-08-06 14:40:48 -060032#include "ae.h"
Shawn Willdend67afae2014-08-19 12:36:27 -060033#include "key.h"
Shawn Willden567a4a02014-12-31 12:14:46 -070034#include "openssl_err.h"
Shawn Willdend67afae2014-08-19 12:36:27 -060035#include "operation.h"
Shawn Willden23d4a742015-03-19 15:33:21 -060036#include "operation_table.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060037
38namespace keymaster {
39
Shawn Willden2665e862014-11-24 14:46:21 -070040const uint8_t MAJOR_VER = 1;
41const uint8_t MINOR_VER = 0;
42const uint8_t SUBMINOR_VER = 0;
43
Shawn Willden0cb69422015-05-26 08:31:37 -060044AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size)
45 : context_(context), operation_table_(new OperationTable(operation_table_size)) {
Shawn Willden39b970b2014-08-11 09:11:21 -060046}
Shawn Willdena278f612014-12-23 11:22:21 -070047
Shawn Willdenb6837e72015-05-16 09:20:59 -060048AndroidKeymaster::~AndroidKeymaster() {
Shawn Willden39b970b2014-08-11 09:11:21 -060049}
Shawn Willden128ffe02014-08-06 12:31:33 -060050
Shawn Willden128ffe02014-08-06 12:31:33 -060051struct AE_CTX_Delete {
Shawn Willden802bb292014-08-18 10:46:29 -060052 void operator()(ae_ctx* ctx) const { ae_free(ctx); }
Shawn Willden128ffe02014-08-06 12:31:33 -060053};
54typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
55
Shawn Willden19fca882015-01-22 16:35:30 -070056// TODO(swillden): Unify support analysis. Right now, we have per-keytype methods that determine if
Shawn Willdenb6837e72015-05-16 09:20:59 -060057// specific modes, padding, etc. are supported for that key type, and AndroidKeymaster also has
Shawn Willden19fca882015-01-22 16:35:30 -070058// methods that return the same information. They'll get out of sync. Best to put the knowledge in
Shawn Willdenb6837e72015-05-16 09:20:59 -060059// the keytypes and provide some mechanism for AndroidKeymaster to query the keytypes for the
Shawn Willden19fca882015-01-22 16:35:30 -070060// information.
Shawn Willden128ffe02014-08-06 12:31:33 -060061
62template <typename T>
63bool check_supported(keymaster_algorithm_t algorithm, SupportedResponse<T>* response) {
Shawn Willdena278f612014-12-23 11:22:21 -070064 if (KeyFactoryRegistry::Get(algorithm) == NULL) {
Shawn Willden128ffe02014-08-06 12:31:33 -060065 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
66 return false;
67 }
68 return true;
69}
70
Shawn Willdenb6837e72015-05-16 09:20:59 -060071void AndroidKeymaster::GetVersion(const GetVersionRequest&, GetVersionResponse* rsp) {
Shawn Willden2665e862014-11-24 14:46:21 -070072 if (rsp == NULL)
73 return;
74
75 rsp->major_ver = MAJOR_VER;
76 rsp->minor_ver = MINOR_VER;
77 rsp->subminor_ver = SUBMINOR_VER;
78 rsp->error = KM_ERROR_OK;
79}
80
Shawn Willdenb6837e72015-05-16 09:20:59 -060081void AndroidKeymaster::SupportedAlgorithms(
Shawn Willden3809b932014-12-02 06:59:46 -070082 SupportedResponse<keymaster_algorithm_t>* response) const {
Shawn Willden128ffe02014-08-06 12:31:33 -060083 if (response == NULL)
84 return;
Shawn Willdena278f612014-12-23 11:22:21 -070085
86 size_t factory_count = 0;
87 const KeyFactory** factories = KeyFactoryRegistry::GetAll(&factory_count);
88 assert(factories != NULL);
89 assert(factory_count > 0);
90
91 UniquePtr<keymaster_algorithm_t[]> algorithms(new keymaster_algorithm_t[factory_count]);
92 if (!algorithms.get()) {
93 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
94 return;
95 }
96
97 for (size_t i = 0; i < factory_count; ++i)
98 algorithms[i] = factories[i]->registry_key();
99
100 response->results = algorithms.release();
101 response->results_length = factory_count;
102 response->error = KM_ERROR_OK;
Shawn Willden128ffe02014-08-06 12:31:33 -0600103}
104
Shawn Willden63ac0432014-12-29 14:07:08 -0700105static OperationFactory* GetOperationFactory(keymaster_algorithm_t algorithm,
106 keymaster_purpose_t purpose,
107 keymaster_error_t* error) {
108 assert(error);
109 if (error)
110 *error = KM_ERROR_OK;
111
112 OperationFactory* factory =
113 OperationFactoryRegistry::Get(OperationFactory::KeyType(algorithm, purpose));
114 if (factory == NULL && error)
115 *error = KM_ERROR_UNSUPPORTED_PURPOSE;
116
117 return factory;
Shawn Willden128ffe02014-08-06 12:31:33 -0600118}
119
Shawn Willden63ac0432014-12-29 14:07:08 -0700120template <typename T>
121void GetSupported(keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
122 const T* (OperationFactory::*get_supported_method)(size_t* count) const,
123 SupportedResponse<T>* response) {
124 if (response == NULL || !check_supported(algorithm, response))
125 return;
126
127 OperationFactory* factory = GetOperationFactory(algorithm, purpose, &response->error);
128 if (!factory) {
129 response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
130 return;
131 }
132
133 size_t count;
134 const T* supported = (factory->*get_supported_method)(&count);
135 response->SetResults(supported, count);
136}
137
Shawn Willdenb6837e72015-05-16 09:20:59 -0600138void AndroidKeymaster::SupportedBlockModes(
Shawn Willden63ac0432014-12-29 14:07:08 -0700139 keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
140 SupportedResponse<keymaster_block_mode_t>* response) const {
141 GetSupported(algorithm, purpose, &OperationFactory::SupportedBlockModes, response);
142}
Shawn Willden3809b932014-12-02 06:59:46 -0700143
Shawn Willdenb6837e72015-05-16 09:20:59 -0600144void AndroidKeymaster::SupportedPaddingModes(
Shawn Willden4200f212014-12-02 07:01:21 -0700145 keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
Shawn Willden3809b932014-12-02 06:59:46 -0700146 SupportedResponse<keymaster_padding_t>* response) const {
Shawn Willden63ac0432014-12-29 14:07:08 -0700147 GetSupported(algorithm, purpose, &OperationFactory::SupportedPaddingModes, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600148}
149
Shawn Willdenb6837e72015-05-16 09:20:59 -0600150void AndroidKeymaster::SupportedDigests(keymaster_algorithm_t algorithm,
151 keymaster_purpose_t purpose,
152 SupportedResponse<keymaster_digest_t>* response) const {
Shawn Willden63ac0432014-12-29 14:07:08 -0700153 GetSupported(algorithm, purpose, &OperationFactory::SupportedDigests, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600154}
155
Shawn Willdenb6837e72015-05-16 09:20:59 -0600156void AndroidKeymaster::SupportedImportFormats(
Shawn Willden3809b932014-12-02 06:59:46 -0700157 keymaster_algorithm_t algorithm, SupportedResponse<keymaster_key_format_t>* response) const {
Shawn Willden128ffe02014-08-06 12:31:33 -0600158 if (response == NULL || !check_supported(algorithm, response))
159 return;
160
Shawn Willdena278f612014-12-23 11:22:21 -0700161 size_t count;
162 const keymaster_key_format_t* formats =
163 KeyFactoryRegistry::Get(algorithm)->SupportedImportFormats(&count);
164 response->SetResults(formats, count);
Shawn Willden128ffe02014-08-06 12:31:33 -0600165}
166
Shawn Willdenb6837e72015-05-16 09:20:59 -0600167void AndroidKeymaster::SupportedExportFormats(
Shawn Willden3809b932014-12-02 06:59:46 -0700168 keymaster_algorithm_t algorithm, SupportedResponse<keymaster_key_format_t>* response) const {
Shawn Willden128ffe02014-08-06 12:31:33 -0600169 if (response == NULL || !check_supported(algorithm, response))
170 return;
171
Shawn Willdena278f612014-12-23 11:22:21 -0700172 size_t count;
173 const keymaster_key_format_t* formats =
174 KeyFactoryRegistry::Get(algorithm)->SupportedExportFormats(&count);
175 response->SetResults(formats, count);
Shawn Willden128ffe02014-08-06 12:31:33 -0600176}
177
Shawn Willden0cb69422015-05-26 08:31:37 -0600178keymaster_error_t AndroidKeymaster::AddRngEntropy(const AddEntropyRequest& request) {
179 return context_->AddRngEntropy(request.random_data.peek_read(),
180 request.random_data.available_read());
181}
182
Shawn Willdenb6837e72015-05-16 09:20:59 -0600183void AndroidKeymaster::GenerateKey(const GenerateKeyRequest& request,
184 GenerateKeyResponse* response) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600185 if (response == NULL)
186 return;
Shawn Willden128ffe02014-08-06 12:31:33 -0600187
Shawn Willdena278f612014-12-23 11:22:21 -0700188 keymaster_algorithm_t algorithm;
189 KeyFactory* factory = 0;
190 UniquePtr<Key> key;
191 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
192 !(factory = KeyFactoryRegistry::Get(algorithm)))
193 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
Shawn Willden0cb69422015-05-26 08:31:37 -0600194 else {
195 KeymasterKeyBlob key_blob;
Shawn Willden2beb6282015-05-20 16:36:24 -0600196 response->enforced.Clear();
197 response->unenforced.Clear();
Shawn Willden0cb69422015-05-26 08:31:37 -0600198 response->error = factory->GenerateKey(request.key_description, &key_blob,
199 &response->enforced, &response->unenforced);
200 if (response->error == KM_ERROR_OK)
201 response->key_blob = key_blob.release();
202 }
Shawn Willden128ffe02014-08-06 12:31:33 -0600203}
204
Shawn Willdenb6837e72015-05-16 09:20:59 -0600205void AndroidKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
206 GetKeyCharacteristicsResponse* response) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600207 if (response == NULL)
208 return;
Shawn Willden76364712014-08-11 17:48:04 -0600209
Shawn Willden0cb69422015-05-26 08:31:37 -0600210 KeymasterKeyBlob key_material;
211 response->error =
212 context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
213 &key_material, &response->enforced, &response->unenforced);
214 if (response->error != KM_ERROR_OK)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600215 return;
Shawn Willden0cb69422015-05-26 08:31:37 -0600216}
Shawn Willden1615f2e2014-08-13 10:37:40 -0600217
Shawn Willden0cb69422015-05-26 08:31:37 -0600218static KeyFactory* GetKeyFactory(const AuthorizationSet& hw_enforced,
219 const AuthorizationSet& sw_enforced,
220 keymaster_algorithm_t* algorithm, keymaster_error_t* error) {
221 *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
222 if (!hw_enforced.GetTagValue(TAG_ALGORITHM, algorithm) &&
223 !sw_enforced.GetTagValue(TAG_ALGORITHM, algorithm))
224 return nullptr;
225 KeyFactory* factory = KeyFactoryRegistry::Get(*algorithm);
226 if (factory)
227 *error = KM_ERROR_OK;
228 return factory;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600229}
230
Shawn Willdenb6837e72015-05-16 09:20:59 -0600231void AndroidKeymaster::BeginOperation(const BeginOperationRequest& request,
232 BeginOperationResponse* response) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600233 if (response == NULL)
234 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600235 response->op_handle = 0;
236
Shawn Willden0cb69422015-05-26 08:31:37 -0600237 AuthorizationSet hw_enforced;
238 AuthorizationSet sw_enforced;
Shawn Willden63ac0432014-12-29 14:07:08 -0700239 keymaster_algorithm_t algorithm;
Shawn Willden0cb69422015-05-26 08:31:37 -0600240 UniquePtr<Key> key;
241 response->error = LoadKey(request.key_blob, request.additional_params, &hw_enforced,
242 &sw_enforced, &algorithm, &key);
Shawn Willden2beb6282015-05-20 16:36:24 -0600243 if (response->error != KM_ERROR_OK)
244 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600245
Shawn Willdenedb79942015-05-08 06:46:44 -0600246 // TODO(swillden): Move this check to a general authorization checker.
Shawn Willden0cb69422015-05-26 08:31:37 -0600247 // TODO(swillden): Consider introducing error codes for unauthorized usages.
248 response->error = KM_ERROR_INCOMPATIBLE_PURPOSE;
249 if (!hw_enforced.Contains(TAG_PURPOSE, request.purpose) &&
250 !sw_enforced.Contains(TAG_PURPOSE, request.purpose))
Shawn Willdenedb79942015-05-08 06:46:44 -0600251 return;
Shawn Willdenedb79942015-05-08 06:46:44 -0600252
Shawn Willden0cb69422015-05-26 08:31:37 -0600253 response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
254 OperationFactory* factory = OperationFactoryRegistry::Get({algorithm, request.purpose});
255 if (!factory)
Shawn Willden63ac0432014-12-29 14:07:08 -0700256 return;
Shawn Willden63ac0432014-12-29 14:07:08 -0700257
Shawn Willden3ed6d062015-04-15 13:39:38 -0600258 UniquePtr<Operation> operation(
259 factory->CreateOperation(*key, request.additional_params, &response->error));
Shawn Willdend67afae2014-08-19 12:36:27 -0600260 if (operation.get() == NULL)
Shawn Willden76364712014-08-11 17:48:04 -0600261 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600262
Shawn Willden111edb32015-02-05 22:44:24 -0700263 response->output_params.Clear();
264 response->error = operation->Begin(request.additional_params, &response->output_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600265 if (response->error != KM_ERROR_OK)
266 return;
267
Shawn Willden23d4a742015-03-19 15:33:21 -0600268 response->error = operation_table_->Add(operation.release(), &response->op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600269}
270
Shawn Willdenb6837e72015-05-16 09:20:59 -0600271void AndroidKeymaster::UpdateOperation(const UpdateOperationRequest& request,
272 UpdateOperationResponse* response) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700273 if (response == NULL)
274 return;
275
Shawn Willden23d4a742015-03-19 15:33:21 -0600276 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
277 Operation* operation = operation_table_->Find(request.op_handle);
278 if (operation == NULL)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600279 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600280
Shawn Willden23d4a742015-03-19 15:33:21 -0600281 response->error = operation->Update(request.additional_params, request.input, &response->output,
282 &response->input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600283 if (response->error != KM_ERROR_OK) {
284 // Any error invalidates the operation.
Shawn Willden23d4a742015-03-19 15:33:21 -0600285 operation_table_->Delete(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600286 }
287}
288
Shawn Willdenb6837e72015-05-16 09:20:59 -0600289void AndroidKeymaster::FinishOperation(const FinishOperationRequest& request,
290 FinishOperationResponse* response) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700291 if (response == NULL)
292 return;
293
Shawn Willden23d4a742015-03-19 15:33:21 -0600294 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
295 Operation* operation = operation_table_->Find(request.op_handle);
296 if (operation == NULL)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600297 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600298
Shawn Willden6bfbff02015-02-06 19:48:24 -0700299 response->error =
Shawn Willden23d4a742015-03-19 15:33:21 -0600300 operation->Finish(request.additional_params, request.signature, &response->output);
301 operation_table_->Delete(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600302}
303
Shawn Willdenb6837e72015-05-16 09:20:59 -0600304keymaster_error_t AndroidKeymaster::AbortOperation(const keymaster_operation_handle_t op_handle) {
Shawn Willden23d4a742015-03-19 15:33:21 -0600305 Operation* operation = operation_table_->Find(op_handle);
306 if (operation == NULL)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600307 return KM_ERROR_INVALID_OPERATION_HANDLE;
Shawn Willden23d4a742015-03-19 15:33:21 -0600308
309 keymaster_error_t error = operation->Abort();
310 operation_table_->Delete(op_handle);
Shawn Willden7ec74f92014-12-11 13:57:59 -0700311 if (error != KM_ERROR_OK)
312 return error;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600313 return KM_ERROR_OK;
Shawn Willden76364712014-08-11 17:48:04 -0600314}
315
Shawn Willdenb6837e72015-05-16 09:20:59 -0600316void AndroidKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
Shawn Willdenffd790c2014-08-18 21:20:06 -0600317 if (response == NULL)
318 return;
319
Shawn Willden0cb69422015-05-26 08:31:37 -0600320 AuthorizationSet hw_enforced;
321 AuthorizationSet sw_enforced;
322 KeymasterKeyBlob key_material;
323 response->error =
324 context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
325 &key_material, &hw_enforced, &sw_enforced);
326 if (response->error != KM_ERROR_OK)
327 return;
328
Shawn Willden63ac0432014-12-29 14:07:08 -0700329 keymaster_algorithm_t algorithm;
Shawn Willden0cb69422015-05-26 08:31:37 -0600330 KeyFactory* key_factory = GetKeyFactory(hw_enforced, sw_enforced, &algorithm, &response->error);
331 if (!key_factory)
332 return;
333
334 UniquePtr<Key> key;
335 response->error = key_factory->LoadKey(key_material, hw_enforced, sw_enforced, &key);
336 if (response->error != KM_ERROR_OK)
Shawn Willdenffd790c2014-08-18 21:20:06 -0600337 return;
338
Shawn Willdenf268d742014-08-19 15:36:26 -0600339 UniquePtr<uint8_t[]> out_key;
340 size_t size;
Shawn Willden0cb69422015-05-26 08:31:37 -0600341 response->error = key->formatted_key_material(request.key_format, &out_key, &size);
Shawn Willdenf268d742014-08-19 15:36:26 -0600342 if (response->error == KM_ERROR_OK) {
343 response->key_data = out_key.release();
344 response->key_data_length = size;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600345 }
Shawn Willdenffd790c2014-08-18 21:20:06 -0600346}
347
Shawn Willdenb6837e72015-05-16 09:20:59 -0600348void AndroidKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600349 if (response == NULL)
Shawn Willdenffd790c2014-08-18 21:20:06 -0600350 return;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600351
Shawn Willdena278f612014-12-23 11:22:21 -0700352 keymaster_algorithm_t algorithm;
353 KeyFactory* factory = 0;
354 UniquePtr<Key> key;
355 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
356 !(factory = KeyFactoryRegistry::Get(algorithm)))
357 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
Shawn Willden0cb69422015-05-26 08:31:37 -0600358 else {
359 keymaster_key_blob_t key_material = {request.key_data, request.key_data_length};
360 KeymasterKeyBlob key_blob;
361 response->error = factory->ImportKey(request.key_description, request.key_format,
362 KeymasterKeyBlob(key_material), &key_blob,
363 &response->enforced, &response->unenforced);
364 if (response->error == KM_ERROR_OK)
365 response->key_blob = key_blob.release();
366 }
Shawn Willdenffd790c2014-08-18 21:20:06 -0600367}
368
Shawn Willden2beb6282015-05-20 16:36:24 -0600369keymaster_error_t AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request) {
370 return context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
371}
372
373keymaster_error_t AndroidKeymaster::DeleteAllKeys() {
374 return context_->DeleteAllKeys();
375}
376
Shawn Willden0cb69422015-05-26 08:31:37 -0600377keymaster_error_t AndroidKeymaster::LoadKey(const keymaster_key_blob_t& key_blob,
378 const AuthorizationSet& additional_params,
379 AuthorizationSet* hw_enforced,
380 AuthorizationSet* sw_enforced,
381 keymaster_algorithm_t* algorithm, UniquePtr<Key>* key) {
382 KeymasterKeyBlob key_material;
383 keymaster_error_t error = context_->ParseKeyBlob(KeymasterKeyBlob(key_blob), additional_params,
384 &key_material, hw_enforced, sw_enforced);
Shawn Willden437fbd12014-08-20 11:59:49 -0600385 if (error != KM_ERROR_OK)
386 return error;
387
Shawn Willden0cb69422015-05-26 08:31:37 -0600388 KeyFactory* key_factory = GetKeyFactory(*hw_enforced, *sw_enforced, algorithm, &error);
389 if (error != KM_ERROR_OK) {
390 assert(!key_factory);
Shawn Willden437fbd12014-08-20 11:59:49 -0600391 return error;
Shawn Willden128ffe02014-08-06 12:31:33 -0600392 }
393
Shawn Willden0cb69422015-05-26 08:31:37 -0600394 return key_factory->LoadKey(key_material, *hw_enforced, *sw_enforced, key);
Shawn Willden128ffe02014-08-06 12:31:33 -0600395}
396
Shawn Willden128ffe02014-08-06 12:31:33 -0600397} // namespace keymaster