blob: c2ff8e6a197c19caf673ef70e281f28f2295520e [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 Willden398c1582015-05-28 00:04:06 -060030#include <keymaster/key_factory.h>
Shawn Willden0cb69422015-05-26 08:31:37 -060031#include <keymaster/keymaster_context.h>
Shawn Willden98d9b922014-08-26 08:14:10 -060032
Shawn Willden3879f862014-08-06 14:40:48 -060033#include "ae.h"
Shawn Willdend67afae2014-08-19 12:36:27 -060034#include "key.h"
Shawn Willden567a4a02014-12-31 12:14:46 -070035#include "openssl_err.h"
Shawn Willdend67afae2014-08-19 12:36:27 -060036#include "operation.h"
Shawn Willden23d4a742015-03-19 15:33:21 -060037#include "operation_table.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060038
39namespace keymaster {
40
Shawn Willden2665e862014-11-24 14:46:21 -070041const uint8_t MAJOR_VER = 1;
Shawn Willdenac69d952015-06-01 14:40:19 -060042const uint8_t MINOR_VER = 1;
Shawn Willden2665e862014-11-24 14:46:21 -070043const uint8_t SUBMINOR_VER = 0;
44
Shawn Willden0cb69422015-05-26 08:31:37 -060045AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size)
Shawn Willden294a2db2015-06-17 11:20:56 -060046 : context_(context), operation_table_(new OperationTable(operation_table_size)) {}
Shawn Willdena278f612014-12-23 11:22:21 -070047
Shawn Willden294a2db2015-06-17 11:20:56 -060048AndroidKeymaster::~AndroidKeymaster() {}
Shawn Willden128ffe02014-08-06 12:31:33 -060049
Shawn Willden128ffe02014-08-06 12:31:33 -060050struct AE_CTX_Delete {
Shawn Willden802bb292014-08-18 10:46:29 -060051 void operator()(ae_ctx* ctx) const { ae_free(ctx); }
Shawn Willden128ffe02014-08-06 12:31:33 -060052};
53typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
54
Shawn Willden19fca882015-01-22 16:35:30 -070055// TODO(swillden): Unify support analysis. Right now, we have per-keytype methods that determine if
Shawn Willdenb6837e72015-05-16 09:20:59 -060056// specific modes, padding, etc. are supported for that key type, and AndroidKeymaster also has
Shawn Willden19fca882015-01-22 16:35:30 -070057// 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 -060058// the keytypes and provide some mechanism for AndroidKeymaster to query the keytypes for the
Shawn Willden19fca882015-01-22 16:35:30 -070059// information.
Shawn Willden128ffe02014-08-06 12:31:33 -060060
61template <typename T>
Shawn Willden06298102015-05-25 23:12:48 -060062bool check_supported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
63 SupportedResponse<T>* response) {
64 if (context.GetKeyFactory(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 Willden36d41e22015-06-17 06:39:48 -060081void AndroidKeymaster::SupportedAlgorithms(const SupportedAlgorithmsRequest& /* request */,
82 SupportedAlgorithmsResponse* response) {
Shawn Willden128ffe02014-08-06 12:31:33 -060083 if (response == NULL)
84 return;
Shawn Willdena278f612014-12-23 11:22:21 -070085
Shawn Willdena278f612014-12-23 11:22:21 -070086 response->error = KM_ERROR_OK;
Shawn Willden128ffe02014-08-06 12:31:33 -060087
Shawn Willden06298102015-05-25 23:12:48 -060088 size_t algorithm_count = 0;
89 const keymaster_algorithm_t* algorithms = context_->GetSupportedAlgorithms(&algorithm_count);
90 if (algorithm_count == 0)
91 return;
92 response->results_length = algorithm_count;
93 response->results = dup_array(algorithms, algorithm_count);
94 if (!response->results)
95 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden128ffe02014-08-06 12:31:33 -060096}
97
Shawn Willden63ac0432014-12-29 14:07:08 -070098template <typename T>
Shawn Willden06298102015-05-25 23:12:48 -060099void GetSupported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
100 keymaster_purpose_t purpose,
Shawn Willden63ac0432014-12-29 14:07:08 -0700101 const T* (OperationFactory::*get_supported_method)(size_t* count) const,
102 SupportedResponse<T>* response) {
Shawn Willden06298102015-05-25 23:12:48 -0600103 if (response == NULL || !check_supported(context, algorithm, response))
Shawn Willden63ac0432014-12-29 14:07:08 -0700104 return;
105
Shawn Willden06298102015-05-25 23:12:48 -0600106 const OperationFactory* factory = context.GetOperationFactory(algorithm, purpose);
Shawn Willden63ac0432014-12-29 14:07:08 -0700107 if (!factory) {
108 response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
109 return;
110 }
111
112 size_t count;
113 const T* supported = (factory->*get_supported_method)(&count);
114 response->SetResults(supported, count);
115}
116
Shawn Willden36d41e22015-06-17 06:39:48 -0600117void AndroidKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
118 SupportedBlockModesResponse* response) {
119 GetSupported(*context_, request.algorithm, request.purpose,
120 &OperationFactory::SupportedBlockModes, response);
Shawn Willden63ac0432014-12-29 14:07:08 -0700121}
Shawn Willden3809b932014-12-02 06:59:46 -0700122
Shawn Willden36d41e22015-06-17 06:39:48 -0600123void AndroidKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
124 SupportedPaddingModesResponse* response) {
125 GetSupported(*context_, request.algorithm, request.purpose,
126 &OperationFactory::SupportedPaddingModes, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600127}
128
Shawn Willden36d41e22015-06-17 06:39:48 -0600129void AndroidKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
130 SupportedDigestsResponse* response) {
131 GetSupported(*context_, request.algorithm, request.purpose, &OperationFactory::SupportedDigests,
132 response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600133}
134
Shawn Willden36d41e22015-06-17 06:39:48 -0600135void AndroidKeymaster::SupportedImportFormats(const SupportedImportFormatsRequest& request,
136 SupportedImportFormatsResponse* response) {
137 if (response == NULL || !check_supported(*context_, request.algorithm, response))
Shawn Willden128ffe02014-08-06 12:31:33 -0600138 return;
139
Shawn Willdena278f612014-12-23 11:22:21 -0700140 size_t count;
141 const keymaster_key_format_t* formats =
Shawn Willden36d41e22015-06-17 06:39:48 -0600142 context_->GetKeyFactory(request.algorithm)->SupportedImportFormats(&count);
Shawn Willdena278f612014-12-23 11:22:21 -0700143 response->SetResults(formats, count);
Shawn Willden128ffe02014-08-06 12:31:33 -0600144}
145
Shawn Willden36d41e22015-06-17 06:39:48 -0600146void AndroidKeymaster::SupportedExportFormats(const SupportedExportFormatsRequest& request,
147 SupportedExportFormatsResponse* response) {
148 if (response == NULL || !check_supported(*context_, request.algorithm, response))
Shawn Willden128ffe02014-08-06 12:31:33 -0600149 return;
150
Shawn Willdena278f612014-12-23 11:22:21 -0700151 size_t count;
152 const keymaster_key_format_t* formats =
Shawn Willden36d41e22015-06-17 06:39:48 -0600153 context_->GetKeyFactory(request.algorithm)->SupportedExportFormats(&count);
Shawn Willdena278f612014-12-23 11:22:21 -0700154 response->SetResults(formats, count);
Shawn Willden128ffe02014-08-06 12:31:33 -0600155}
156
Shawn Willden36d41e22015-06-17 06:39:48 -0600157void AndroidKeymaster::AddRngEntropy(const AddEntropyRequest& request,
158 AddEntropyResponse* response) {
159 response->error = context_->AddRngEntropy(request.random_data.peek_read(),
160 request.random_data.available_read());
Shawn Willden0cb69422015-05-26 08:31:37 -0600161}
162
Shawn Willdenb6837e72015-05-16 09:20:59 -0600163void AndroidKeymaster::GenerateKey(const GenerateKeyRequest& request,
164 GenerateKeyResponse* response) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600165 if (response == NULL)
166 return;
Shawn Willden128ffe02014-08-06 12:31:33 -0600167
Shawn Willdena278f612014-12-23 11:22:21 -0700168 keymaster_algorithm_t algorithm;
169 KeyFactory* factory = 0;
170 UniquePtr<Key> key;
171 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
Shawn Willden06298102015-05-25 23:12:48 -0600172 !(factory = context_->GetKeyFactory(algorithm)))
Shawn Willdena278f612014-12-23 11:22:21 -0700173 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
Shawn Willden0cb69422015-05-26 08:31:37 -0600174 else {
175 KeymasterKeyBlob key_blob;
Shawn Willden2beb6282015-05-20 16:36:24 -0600176 response->enforced.Clear();
177 response->unenforced.Clear();
Shawn Willden0cb69422015-05-26 08:31:37 -0600178 response->error = factory->GenerateKey(request.key_description, &key_blob,
179 &response->enforced, &response->unenforced);
180 if (response->error == KM_ERROR_OK)
181 response->key_blob = key_blob.release();
182 }
Shawn Willden128ffe02014-08-06 12:31:33 -0600183}
184
Shawn Willdenb6837e72015-05-16 09:20:59 -0600185void AndroidKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
186 GetKeyCharacteristicsResponse* response) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600187 if (response == NULL)
188 return;
Shawn Willden76364712014-08-11 17:48:04 -0600189
Shawn Willden0cb69422015-05-26 08:31:37 -0600190 KeymasterKeyBlob key_material;
191 response->error =
192 context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
193 &key_material, &response->enforced, &response->unenforced);
194 if (response->error != KM_ERROR_OK)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600195 return;
Shawn Willden0cb69422015-05-26 08:31:37 -0600196}
Shawn Willden1615f2e2014-08-13 10:37:40 -0600197
Shawn Willden06298102015-05-25 23:12:48 -0600198static KeyFactory* GetKeyFactory(const KeymasterContext& context,
199 const AuthorizationSet& hw_enforced,
Shawn Willden0cb69422015-05-26 08:31:37 -0600200 const AuthorizationSet& sw_enforced,
201 keymaster_algorithm_t* algorithm, keymaster_error_t* error) {
202 *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
203 if (!hw_enforced.GetTagValue(TAG_ALGORITHM, algorithm) &&
204 !sw_enforced.GetTagValue(TAG_ALGORITHM, algorithm))
205 return nullptr;
Shawn Willden06298102015-05-25 23:12:48 -0600206 KeyFactory* factory = context.GetKeyFactory(*algorithm);
Shawn Willden0cb69422015-05-26 08:31:37 -0600207 if (factory)
208 *error = KM_ERROR_OK;
209 return factory;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600210}
211
Shawn Willdenb6837e72015-05-16 09:20:59 -0600212void AndroidKeymaster::BeginOperation(const BeginOperationRequest& request,
213 BeginOperationResponse* response) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600214 if (response == NULL)
215 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600216 response->op_handle = 0;
217
Shawn Willden0cb69422015-05-26 08:31:37 -0600218 AuthorizationSet hw_enforced;
219 AuthorizationSet sw_enforced;
Shawn Willden06298102015-05-25 23:12:48 -0600220 const KeyFactory* key_factory;
Shawn Willden0cb69422015-05-26 08:31:37 -0600221 UniquePtr<Key> key;
222 response->error = LoadKey(request.key_blob, request.additional_params, &hw_enforced,
Shawn Willden06298102015-05-25 23:12:48 -0600223 &sw_enforced, &key_factory, &key);
Shawn Willden2beb6282015-05-20 16:36:24 -0600224 if (response->error != KM_ERROR_OK)
225 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600226
Shawn Willden294a2db2015-06-17 11:20:56 -0600227 response->error = KM_ERROR_UNKNOWN_ERROR;
228 keymaster_algorithm_t key_algorithm;
229 if (!key->authorizations().GetTagValue(TAG_ALGORITHM, &key_algorithm))
Shawn Willdenedb79942015-05-08 06:46:44 -0600230 return;
Shawn Willdenedb79942015-05-08 06:46:44 -0600231
Shawn Willden0cb69422015-05-26 08:31:37 -0600232 response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
Shawn Willden06298102015-05-25 23:12:48 -0600233 OperationFactory* factory = key_factory->GetOperationFactory(request.purpose);
Shawn Willden0cb69422015-05-26 08:31:37 -0600234 if (!factory)
Shawn Willden63ac0432014-12-29 14:07:08 -0700235 return;
Shawn Willden63ac0432014-12-29 14:07:08 -0700236
Shawn Willden3ed6d062015-04-15 13:39:38 -0600237 UniquePtr<Operation> operation(
238 factory->CreateOperation(*key, request.additional_params, &response->error));
Shawn Willdend67afae2014-08-19 12:36:27 -0600239 if (operation.get() == NULL)
Shawn Willden76364712014-08-11 17:48:04 -0600240 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600241
Shawn Willdenada48502015-06-25 06:26:05 -0700242 if (context_->enforcement_policy()) {
243 km_id_t key_id;
244 response->error = KM_ERROR_UNKNOWN_ERROR;
245 if (!context_->enforcement_policy()->CreateKeyId(request.key_blob, &key_id))
246 return;
247 operation->set_key_id(key_id);
248 response->error = context_->enforcement_policy()->AuthorizeOperation(
249 request.purpose, key_id, key->authorizations(), request.additional_params,
250 0 /* op_handle */, true /* is_begin_operation */);
251 if (response->error != KM_ERROR_OK)
252 return;
253 }
254
Shawn Willden111edb32015-02-05 22:44:24 -0700255 response->output_params.Clear();
256 response->error = operation->Begin(request.additional_params, &response->output_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600257 if (response->error != KM_ERROR_OK)
258 return;
259
Shawn Willdenada48502015-06-25 06:26:05 -0700260 operation->SetAuthorizations(key->authorizations());
Shawn Willden23d4a742015-03-19 15:33:21 -0600261 response->error = operation_table_->Add(operation.release(), &response->op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600262}
263
Shawn Willdenb6837e72015-05-16 09:20:59 -0600264void AndroidKeymaster::UpdateOperation(const UpdateOperationRequest& request,
265 UpdateOperationResponse* response) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700266 if (response == NULL)
267 return;
268
Shawn Willden23d4a742015-03-19 15:33:21 -0600269 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
270 Operation* operation = operation_table_->Find(request.op_handle);
271 if (operation == NULL)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600272 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600273
Shawn Willdenada48502015-06-25 06:26:05 -0700274 if (context_->enforcement_policy()) {
275 response->error = context_->enforcement_policy()->AuthorizeOperation(
276 operation->purpose(), operation->key_id(), operation->authorizations(),
277 request.additional_params, request.op_handle, false /* is_begin_operation */);
Shawn Willdend599b152015-07-27 16:58:30 -0600278 if (response->error != KM_ERROR_OK) {
279 operation_table_->Delete(request.op_handle);
Shawn Willdenada48502015-06-25 06:26:05 -0700280 return;
Shawn Willdend599b152015-07-27 16:58:30 -0600281 }
Shawn Willdenada48502015-06-25 06:26:05 -0700282 }
283
Shawn Willdended8e7d2015-06-01 15:29:12 -0600284 response->error =
285 operation->Update(request.additional_params, request.input, &response->output_params,
286 &response->output, &response->input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600287 if (response->error != KM_ERROR_OK) {
288 // Any error invalidates the operation.
Shawn Willden23d4a742015-03-19 15:33:21 -0600289 operation_table_->Delete(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600290 }
291}
292
Shawn Willdenb6837e72015-05-16 09:20:59 -0600293void AndroidKeymaster::FinishOperation(const FinishOperationRequest& request,
294 FinishOperationResponse* response) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700295 if (response == NULL)
296 return;
297
Shawn Willden23d4a742015-03-19 15:33:21 -0600298 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
299 Operation* operation = operation_table_->Find(request.op_handle);
300 if (operation == NULL)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600301 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600302
Shawn Willdenada48502015-06-25 06:26:05 -0700303 if (context_->enforcement_policy()) {
304 response->error = context_->enforcement_policy()->AuthorizeOperation(
305 operation->purpose(), operation->key_id(), operation->authorizations(),
306 request.additional_params, request.op_handle, false /* is_begin_operation */);
Shawn Willdend599b152015-07-27 16:58:30 -0600307 if (response->error != KM_ERROR_OK) {
308 operation_table_->Delete(request.op_handle);
Shawn Willdenada48502015-06-25 06:26:05 -0700309 return;
Shawn Willdend599b152015-07-27 16:58:30 -0600310 }
Shawn Willdenada48502015-06-25 06:26:05 -0700311 }
312
Shawn Willdended8e7d2015-06-01 15:29:12 -0600313 response->error = operation->Finish(request.additional_params, request.signature,
314 &response->output_params, &response->output);
Shawn Willden23d4a742015-03-19 15:33:21 -0600315 operation_table_->Delete(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600316}
317
Shawn Willden36d41e22015-06-17 06:39:48 -0600318void AndroidKeymaster::AbortOperation(const AbortOperationRequest& request,
319 AbortOperationResponse* response) {
320 if (!response)
321 return;
Shawn Willden23d4a742015-03-19 15:33:21 -0600322
Shawn Willden36d41e22015-06-17 06:39:48 -0600323 Operation* operation = operation_table_->Find(request.op_handle);
324 if (!operation) {
325 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
326 return;
327 }
328
329 response->error = operation->Abort();
330 operation_table_->Delete(request.op_handle);
Shawn Willden76364712014-08-11 17:48:04 -0600331}
332
Shawn Willdenb6837e72015-05-16 09:20:59 -0600333void AndroidKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
Shawn Willdenffd790c2014-08-18 21:20:06 -0600334 if (response == NULL)
335 return;
336
Shawn Willden0cb69422015-05-26 08:31:37 -0600337 AuthorizationSet hw_enforced;
338 AuthorizationSet sw_enforced;
339 KeymasterKeyBlob key_material;
340 response->error =
341 context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
342 &key_material, &hw_enforced, &sw_enforced);
343 if (response->error != KM_ERROR_OK)
344 return;
345
Shawn Willden63ac0432014-12-29 14:07:08 -0700346 keymaster_algorithm_t algorithm;
Shawn Willden06298102015-05-25 23:12:48 -0600347 KeyFactory* key_factory =
348 GetKeyFactory(*context_, hw_enforced, sw_enforced, &algorithm, &response->error);
Shawn Willden0cb69422015-05-26 08:31:37 -0600349 if (!key_factory)
350 return;
351
352 UniquePtr<Key> key;
Shawn Willdend599b152015-07-27 16:58:30 -0600353 response->error = key_factory->LoadKey(key_material, request.additional_params, hw_enforced,
354 sw_enforced, &key);
Shawn Willden0cb69422015-05-26 08:31:37 -0600355 if (response->error != KM_ERROR_OK)
Shawn Willdenffd790c2014-08-18 21:20:06 -0600356 return;
357
Shawn Willdenf268d742014-08-19 15:36:26 -0600358 UniquePtr<uint8_t[]> out_key;
359 size_t size;
Shawn Willden0cb69422015-05-26 08:31:37 -0600360 response->error = key->formatted_key_material(request.key_format, &out_key, &size);
Shawn Willdenf268d742014-08-19 15:36:26 -0600361 if (response->error == KM_ERROR_OK) {
362 response->key_data = out_key.release();
363 response->key_data_length = size;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600364 }
Shawn Willdenffd790c2014-08-18 21:20:06 -0600365}
366
Shawn Willdend3ee5502016-01-05 19:40:43 -0700367void AndroidKeymaster::AttestKey(const AttestKeyRequest& request, AttestKeyResponse* response) {
368 if (!response)
369 return;
370
371 AuthorizationSet tee_enforced;
372 AuthorizationSet sw_enforced;
373 const KeyFactory* key_factory;
374 UniquePtr<Key> key;
375 response->error = LoadKey(request.key_blob, request.attest_params, &tee_enforced, &sw_enforced,
376 &key_factory, &key);
377 if (response->error != KM_ERROR_OK)
378 return;
379
380 response->error = key->GenerateAttestation(*context_, request.attest_params, tee_enforced,
381 sw_enforced, &response->certificate_chain);
382}
383
Shawn Willdenb6837e72015-05-16 09:20:59 -0600384void AndroidKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600385 if (response == NULL)
Shawn Willdenffd790c2014-08-18 21:20:06 -0600386 return;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600387
Shawn Willdena278f612014-12-23 11:22:21 -0700388 keymaster_algorithm_t algorithm;
389 KeyFactory* factory = 0;
390 UniquePtr<Key> key;
391 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
Shawn Willden06298102015-05-25 23:12:48 -0600392 !(factory = context_->GetKeyFactory(algorithm)))
Shawn Willdena278f612014-12-23 11:22:21 -0700393 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
Shawn Willden0cb69422015-05-26 08:31:37 -0600394 else {
395 keymaster_key_blob_t key_material = {request.key_data, request.key_data_length};
396 KeymasterKeyBlob key_blob;
397 response->error = factory->ImportKey(request.key_description, request.key_format,
398 KeymasterKeyBlob(key_material), &key_blob,
399 &response->enforced, &response->unenforced);
400 if (response->error == KM_ERROR_OK)
401 response->key_blob = key_blob.release();
402 }
Shawn Willdenffd790c2014-08-18 21:20:06 -0600403}
404
Shawn Willden36d41e22015-06-17 06:39:48 -0600405void AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
406 if (!response)
407 return;
408 response->error = context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
Shawn Willden2beb6282015-05-20 16:36:24 -0600409}
410
Shawn Willden36d41e22015-06-17 06:39:48 -0600411void AndroidKeymaster::DeleteAllKeys(const DeleteAllKeysRequest&, DeleteAllKeysResponse* response) {
412 if (!response)
413 return;
414 response->error = context_->DeleteAllKeys();
Shawn Willden2beb6282015-05-20 16:36:24 -0600415}
416
Shawn Willdend599b152015-07-27 16:58:30 -0600417bool AndroidKeymaster::has_operation(keymaster_operation_handle_t op_handle) const {
418 return operation_table_->Find(op_handle) != nullptr;
419}
420
Shawn Willden0cb69422015-05-26 08:31:37 -0600421keymaster_error_t AndroidKeymaster::LoadKey(const keymaster_key_blob_t& key_blob,
422 const AuthorizationSet& additional_params,
423 AuthorizationSet* hw_enforced,
424 AuthorizationSet* sw_enforced,
Shawn Willden06298102015-05-25 23:12:48 -0600425 const KeyFactory** factory, UniquePtr<Key>* key) {
Shawn Willden0cb69422015-05-26 08:31:37 -0600426 KeymasterKeyBlob key_material;
427 keymaster_error_t error = context_->ParseKeyBlob(KeymasterKeyBlob(key_blob), additional_params,
428 &key_material, hw_enforced, sw_enforced);
Shawn Willden437fbd12014-08-20 11:59:49 -0600429 if (error != KM_ERROR_OK)
430 return error;
431
Shawn Willden06298102015-05-25 23:12:48 -0600432 keymaster_algorithm_t algorithm;
433 *factory = GetKeyFactory(*context_, *hw_enforced, *sw_enforced, &algorithm, &error);
434 if (error != KM_ERROR_OK)
Shawn Willden437fbd12014-08-20 11:59:49 -0600435 return error;
Shawn Willden128ffe02014-08-06 12:31:33 -0600436
Shawn Willdend599b152015-07-27 16:58:30 -0600437 return (*factory)->LoadKey(key_material, additional_params, *hw_enforced, *sw_enforced, key);
Shawn Willden128ffe02014-08-06 12:31:33 -0600438}
439
Shawn Willden128ffe02014-08-06 12:31:33 -0600440} // namespace keymaster