blob: aeb4f4d2e160dc26466ace847afc0ce4114312bd [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 Willdenc15af192016-03-09 20:03:38 -070041namespace {
42
Shawn Willden2665e862014-11-24 14:46:21 -070043const uint8_t MAJOR_VER = 1;
Shawn Willdenac69d952015-06-01 14:40:19 -060044const uint8_t MINOR_VER = 1;
Shawn Willden2665e862014-11-24 14:46:21 -070045const uint8_t SUBMINOR_VER = 0;
46
Shawn Willdenc15af192016-03-09 20:03:38 -070047keymaster_error_t CheckVersionInfo(const AuthorizationSet& tee_enforced,
48 const AuthorizationSet& sw_enforced,
49 const KeymasterContext& context) {
50 uint32_t os_version;
51 uint32_t os_patchlevel;
52 context.GetSystemVersion(&os_version, &os_patchlevel);
53
54 uint32_t key_os_patchlevel;
55 if (tee_enforced.GetTagValue(TAG_OS_PATCHLEVEL, &key_os_patchlevel) ||
56 sw_enforced.GetTagValue(TAG_OS_PATCHLEVEL, &key_os_patchlevel)) {
57 if (key_os_patchlevel < os_patchlevel)
58 return KM_ERROR_KEY_REQUIRES_UPGRADE;
59 else if (key_os_patchlevel > os_patchlevel)
60 return KM_ERROR_INVALID_KEY_BLOB;
61 }
62
63 return KM_ERROR_OK;
64}
65
66} // anonymous namespace
67
Shawn Willden0cb69422015-05-26 08:31:37 -060068AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size)
Shawn Willden294a2db2015-06-17 11:20:56 -060069 : context_(context), operation_table_(new OperationTable(operation_table_size)) {}
Shawn Willdena278f612014-12-23 11:22:21 -070070
Shawn Willden294a2db2015-06-17 11:20:56 -060071AndroidKeymaster::~AndroidKeymaster() {}
Shawn Willden128ffe02014-08-06 12:31:33 -060072
Shawn Willden128ffe02014-08-06 12:31:33 -060073struct AE_CTX_Delete {
Shawn Willden802bb292014-08-18 10:46:29 -060074 void operator()(ae_ctx* ctx) const { ae_free(ctx); }
Shawn Willden128ffe02014-08-06 12:31:33 -060075};
76typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
77
Shawn Willden19fca882015-01-22 16:35:30 -070078// TODO(swillden): Unify support analysis. Right now, we have per-keytype methods that determine if
Shawn Willdenb6837e72015-05-16 09:20:59 -060079// specific modes, padding, etc. are supported for that key type, and AndroidKeymaster also has
Shawn Willden19fca882015-01-22 16:35:30 -070080// 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 -060081// the keytypes and provide some mechanism for AndroidKeymaster to query the keytypes for the
Shawn Willden19fca882015-01-22 16:35:30 -070082// information.
Shawn Willden128ffe02014-08-06 12:31:33 -060083
84template <typename T>
Shawn Willden06298102015-05-25 23:12:48 -060085bool check_supported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
86 SupportedResponse<T>* response) {
87 if (context.GetKeyFactory(algorithm) == NULL) {
Shawn Willden128ffe02014-08-06 12:31:33 -060088 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
89 return false;
90 }
91 return true;
92}
93
Shawn Willdenb6837e72015-05-16 09:20:59 -060094void AndroidKeymaster::GetVersion(const GetVersionRequest&, GetVersionResponse* rsp) {
Shawn Willden2665e862014-11-24 14:46:21 -070095 if (rsp == NULL)
96 return;
97
98 rsp->major_ver = MAJOR_VER;
99 rsp->minor_ver = MINOR_VER;
100 rsp->subminor_ver = SUBMINOR_VER;
101 rsp->error = KM_ERROR_OK;
102}
103
Shawn Willden36d41e22015-06-17 06:39:48 -0600104void AndroidKeymaster::SupportedAlgorithms(const SupportedAlgorithmsRequest& /* request */,
105 SupportedAlgorithmsResponse* response) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600106 if (response == NULL)
107 return;
Shawn Willdena278f612014-12-23 11:22:21 -0700108
Shawn Willdena278f612014-12-23 11:22:21 -0700109 response->error = KM_ERROR_OK;
Shawn Willden128ffe02014-08-06 12:31:33 -0600110
Shawn Willden06298102015-05-25 23:12:48 -0600111 size_t algorithm_count = 0;
112 const keymaster_algorithm_t* algorithms = context_->GetSupportedAlgorithms(&algorithm_count);
113 if (algorithm_count == 0)
114 return;
115 response->results_length = algorithm_count;
116 response->results = dup_array(algorithms, algorithm_count);
117 if (!response->results)
118 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden128ffe02014-08-06 12:31:33 -0600119}
120
Shawn Willden63ac0432014-12-29 14:07:08 -0700121template <typename T>
Shawn Willden06298102015-05-25 23:12:48 -0600122void GetSupported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
123 keymaster_purpose_t purpose,
Shawn Willden63ac0432014-12-29 14:07:08 -0700124 const T* (OperationFactory::*get_supported_method)(size_t* count) const,
125 SupportedResponse<T>* response) {
Shawn Willden06298102015-05-25 23:12:48 -0600126 if (response == NULL || !check_supported(context, algorithm, response))
Shawn Willden63ac0432014-12-29 14:07:08 -0700127 return;
128
Shawn Willden06298102015-05-25 23:12:48 -0600129 const OperationFactory* factory = context.GetOperationFactory(algorithm, purpose);
Shawn Willden63ac0432014-12-29 14:07:08 -0700130 if (!factory) {
131 response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
132 return;
133 }
134
135 size_t count;
136 const T* supported = (factory->*get_supported_method)(&count);
137 response->SetResults(supported, count);
138}
139
Shawn Willden36d41e22015-06-17 06:39:48 -0600140void AndroidKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
141 SupportedBlockModesResponse* response) {
142 GetSupported(*context_, request.algorithm, request.purpose,
143 &OperationFactory::SupportedBlockModes, response);
Shawn Willden63ac0432014-12-29 14:07:08 -0700144}
Shawn Willden3809b932014-12-02 06:59:46 -0700145
Shawn Willden36d41e22015-06-17 06:39:48 -0600146void AndroidKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
147 SupportedPaddingModesResponse* response) {
148 GetSupported(*context_, request.algorithm, request.purpose,
149 &OperationFactory::SupportedPaddingModes, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600150}
151
Shawn Willden36d41e22015-06-17 06:39:48 -0600152void AndroidKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
153 SupportedDigestsResponse* response) {
154 GetSupported(*context_, request.algorithm, request.purpose, &OperationFactory::SupportedDigests,
155 response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600156}
157
Shawn Willden36d41e22015-06-17 06:39:48 -0600158void AndroidKeymaster::SupportedImportFormats(const SupportedImportFormatsRequest& request,
159 SupportedImportFormatsResponse* response) {
160 if (response == NULL || !check_supported(*context_, request.algorithm, response))
Shawn Willden128ffe02014-08-06 12:31:33 -0600161 return;
162
Shawn Willdena278f612014-12-23 11:22:21 -0700163 size_t count;
164 const keymaster_key_format_t* formats =
Shawn Willden36d41e22015-06-17 06:39:48 -0600165 context_->GetKeyFactory(request.algorithm)->SupportedImportFormats(&count);
Shawn Willdena278f612014-12-23 11:22:21 -0700166 response->SetResults(formats, count);
Shawn Willden128ffe02014-08-06 12:31:33 -0600167}
168
Shawn Willden36d41e22015-06-17 06:39:48 -0600169void AndroidKeymaster::SupportedExportFormats(const SupportedExportFormatsRequest& request,
170 SupportedExportFormatsResponse* response) {
171 if (response == NULL || !check_supported(*context_, request.algorithm, response))
Shawn Willden128ffe02014-08-06 12:31:33 -0600172 return;
173
Shawn Willdena278f612014-12-23 11:22:21 -0700174 size_t count;
175 const keymaster_key_format_t* formats =
Shawn Willden36d41e22015-06-17 06:39:48 -0600176 context_->GetKeyFactory(request.algorithm)->SupportedExportFormats(&count);
Shawn Willdena278f612014-12-23 11:22:21 -0700177 response->SetResults(formats, count);
Shawn Willden128ffe02014-08-06 12:31:33 -0600178}
179
Shawn Willden36d41e22015-06-17 06:39:48 -0600180void AndroidKeymaster::AddRngEntropy(const AddEntropyRequest& request,
181 AddEntropyResponse* response) {
182 response->error = context_->AddRngEntropy(request.random_data.peek_read(),
183 request.random_data.available_read());
Shawn Willden0cb69422015-05-26 08:31:37 -0600184}
185
Shawn Willdenb6837e72015-05-16 09:20:59 -0600186void AndroidKeymaster::GenerateKey(const GenerateKeyRequest& request,
187 GenerateKeyResponse* response) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600188 if (response == NULL)
189 return;
Shawn Willden128ffe02014-08-06 12:31:33 -0600190
Shawn Willdena278f612014-12-23 11:22:21 -0700191 keymaster_algorithm_t algorithm;
192 KeyFactory* factory = 0;
193 UniquePtr<Key> key;
194 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
Shawn Willden06298102015-05-25 23:12:48 -0600195 !(factory = context_->GetKeyFactory(algorithm)))
Shawn Willdena278f612014-12-23 11:22:21 -0700196 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
Shawn Willden0cb69422015-05-26 08:31:37 -0600197 else {
198 KeymasterKeyBlob key_blob;
Shawn Willden2beb6282015-05-20 16:36:24 -0600199 response->enforced.Clear();
200 response->unenforced.Clear();
Shawn Willden0cb69422015-05-26 08:31:37 -0600201 response->error = factory->GenerateKey(request.key_description, &key_blob,
202 &response->enforced, &response->unenforced);
203 if (response->error == KM_ERROR_OK)
204 response->key_blob = key_blob.release();
205 }
Shawn Willden128ffe02014-08-06 12:31:33 -0600206}
207
Shawn Willdenb6837e72015-05-16 09:20:59 -0600208void AndroidKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
209 GetKeyCharacteristicsResponse* response) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600210 if (response == NULL)
211 return;
Shawn Willden76364712014-08-11 17:48:04 -0600212
Shawn Willden0cb69422015-05-26 08:31:37 -0600213 KeymasterKeyBlob key_material;
214 response->error =
215 context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
216 &key_material, &response->enforced, &response->unenforced);
217 if (response->error != KM_ERROR_OK)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600218 return;
Shawn Willdenc15af192016-03-09 20:03:38 -0700219
220 response->error = CheckVersionInfo(response->enforced, response->unenforced, *context_);
Shawn Willden0cb69422015-05-26 08:31:37 -0600221}
Shawn Willden1615f2e2014-08-13 10:37:40 -0600222
Shawn Willden06298102015-05-25 23:12:48 -0600223static KeyFactory* GetKeyFactory(const KeymasterContext& context,
224 const AuthorizationSet& hw_enforced,
Shawn Willden0cb69422015-05-26 08:31:37 -0600225 const AuthorizationSet& sw_enforced,
226 keymaster_algorithm_t* algorithm, keymaster_error_t* error) {
227 *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
228 if (!hw_enforced.GetTagValue(TAG_ALGORITHM, algorithm) &&
229 !sw_enforced.GetTagValue(TAG_ALGORITHM, algorithm))
230 return nullptr;
Shawn Willden06298102015-05-25 23:12:48 -0600231 KeyFactory* factory = context.GetKeyFactory(*algorithm);
Shawn Willden0cb69422015-05-26 08:31:37 -0600232 if (factory)
233 *error = KM_ERROR_OK;
234 return factory;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600235}
236
Shawn Willdenb6837e72015-05-16 09:20:59 -0600237void AndroidKeymaster::BeginOperation(const BeginOperationRequest& request,
238 BeginOperationResponse* response) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600239 if (response == NULL)
240 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600241 response->op_handle = 0;
242
Shawn Willden0cb69422015-05-26 08:31:37 -0600243 AuthorizationSet hw_enforced;
244 AuthorizationSet sw_enforced;
Shawn Willden06298102015-05-25 23:12:48 -0600245 const KeyFactory* key_factory;
Shawn Willden0cb69422015-05-26 08:31:37 -0600246 UniquePtr<Key> key;
247 response->error = LoadKey(request.key_blob, request.additional_params, &hw_enforced,
Shawn Willden06298102015-05-25 23:12:48 -0600248 &sw_enforced, &key_factory, &key);
Shawn Willden2beb6282015-05-20 16:36:24 -0600249 if (response->error != KM_ERROR_OK)
250 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600251
Shawn Willden294a2db2015-06-17 11:20:56 -0600252 response->error = KM_ERROR_UNKNOWN_ERROR;
253 keymaster_algorithm_t key_algorithm;
254 if (!key->authorizations().GetTagValue(TAG_ALGORITHM, &key_algorithm))
Shawn Willdenedb79942015-05-08 06:46:44 -0600255 return;
Shawn Willdenedb79942015-05-08 06:46:44 -0600256
Shawn Willden0cb69422015-05-26 08:31:37 -0600257 response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
Shawn Willden06298102015-05-25 23:12:48 -0600258 OperationFactory* factory = key_factory->GetOperationFactory(request.purpose);
Shawn Willden0cb69422015-05-26 08:31:37 -0600259 if (!factory)
Shawn Willden63ac0432014-12-29 14:07:08 -0700260 return;
Shawn Willden63ac0432014-12-29 14:07:08 -0700261
Shawn Willden3ed6d062015-04-15 13:39:38 -0600262 UniquePtr<Operation> operation(
263 factory->CreateOperation(*key, request.additional_params, &response->error));
Shawn Willdend67afae2014-08-19 12:36:27 -0600264 if (operation.get() == NULL)
Shawn Willden76364712014-08-11 17:48:04 -0600265 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600266
Shawn Willdenada48502015-06-25 06:26:05 -0700267 if (context_->enforcement_policy()) {
268 km_id_t key_id;
269 response->error = KM_ERROR_UNKNOWN_ERROR;
270 if (!context_->enforcement_policy()->CreateKeyId(request.key_blob, &key_id))
271 return;
272 operation->set_key_id(key_id);
273 response->error = context_->enforcement_policy()->AuthorizeOperation(
274 request.purpose, key_id, key->authorizations(), request.additional_params,
275 0 /* op_handle */, true /* is_begin_operation */);
276 if (response->error != KM_ERROR_OK)
277 return;
278 }
279
Shawn Willden111edb32015-02-05 22:44:24 -0700280 response->output_params.Clear();
281 response->error = operation->Begin(request.additional_params, &response->output_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600282 if (response->error != KM_ERROR_OK)
283 return;
284
Shawn Willdenada48502015-06-25 06:26:05 -0700285 operation->SetAuthorizations(key->authorizations());
Shawn Willden23d4a742015-03-19 15:33:21 -0600286 response->error = operation_table_->Add(operation.release(), &response->op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600287}
288
Shawn Willdenb6837e72015-05-16 09:20:59 -0600289void AndroidKeymaster::UpdateOperation(const UpdateOperationRequest& request,
290 UpdateOperationResponse* 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 Willdenada48502015-06-25 06:26:05 -0700299 if (context_->enforcement_policy()) {
300 response->error = context_->enforcement_policy()->AuthorizeOperation(
301 operation->purpose(), operation->key_id(), operation->authorizations(),
302 request.additional_params, request.op_handle, false /* is_begin_operation */);
Shawn Willdend599b152015-07-27 16:58:30 -0600303 if (response->error != KM_ERROR_OK) {
304 operation_table_->Delete(request.op_handle);
Shawn Willdenada48502015-06-25 06:26:05 -0700305 return;
Shawn Willdend599b152015-07-27 16:58:30 -0600306 }
Shawn Willdenada48502015-06-25 06:26:05 -0700307 }
308
Shawn Willdended8e7d2015-06-01 15:29:12 -0600309 response->error =
310 operation->Update(request.additional_params, request.input, &response->output_params,
311 &response->output, &response->input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600312 if (response->error != KM_ERROR_OK) {
313 // Any error invalidates the operation.
Shawn Willden23d4a742015-03-19 15:33:21 -0600314 operation_table_->Delete(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600315 }
316}
317
Shawn Willdenb6837e72015-05-16 09:20:59 -0600318void AndroidKeymaster::FinishOperation(const FinishOperationRequest& request,
319 FinishOperationResponse* response) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700320 if (response == NULL)
321 return;
322
Shawn Willden23d4a742015-03-19 15:33:21 -0600323 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
324 Operation* operation = operation_table_->Find(request.op_handle);
325 if (operation == NULL)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600326 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600327
Shawn Willdenada48502015-06-25 06:26:05 -0700328 if (context_->enforcement_policy()) {
329 response->error = context_->enforcement_policy()->AuthorizeOperation(
330 operation->purpose(), operation->key_id(), operation->authorizations(),
331 request.additional_params, request.op_handle, false /* is_begin_operation */);
Shawn Willdend599b152015-07-27 16:58:30 -0600332 if (response->error != KM_ERROR_OK) {
333 operation_table_->Delete(request.op_handle);
Shawn Willdenada48502015-06-25 06:26:05 -0700334 return;
Shawn Willdend599b152015-07-27 16:58:30 -0600335 }
Shawn Willdenada48502015-06-25 06:26:05 -0700336 }
337
Shawn Willdencb647fe2016-01-27 12:59:13 -0700338 response->error = operation->Finish(request.additional_params, request.input, request.signature,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600339 &response->output_params, &response->output);
Shawn Willden23d4a742015-03-19 15:33:21 -0600340 operation_table_->Delete(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600341}
342
Shawn Willden36d41e22015-06-17 06:39:48 -0600343void AndroidKeymaster::AbortOperation(const AbortOperationRequest& request,
344 AbortOperationResponse* response) {
345 if (!response)
346 return;
Shawn Willden23d4a742015-03-19 15:33:21 -0600347
Shawn Willden36d41e22015-06-17 06:39:48 -0600348 Operation* operation = operation_table_->Find(request.op_handle);
349 if (!operation) {
350 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
351 return;
352 }
353
354 response->error = operation->Abort();
355 operation_table_->Delete(request.op_handle);
Shawn Willden76364712014-08-11 17:48:04 -0600356}
357
Shawn Willdenb6837e72015-05-16 09:20:59 -0600358void AndroidKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
Shawn Willdenffd790c2014-08-18 21:20:06 -0600359 if (response == NULL)
360 return;
361
Shawn Willden0cb69422015-05-26 08:31:37 -0600362 AuthorizationSet hw_enforced;
363 AuthorizationSet sw_enforced;
364 KeymasterKeyBlob key_material;
365 response->error =
366 context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
367 &key_material, &hw_enforced, &sw_enforced);
368 if (response->error != KM_ERROR_OK)
369 return;
370
Shawn Willden63ac0432014-12-29 14:07:08 -0700371 keymaster_algorithm_t algorithm;
Shawn Willden06298102015-05-25 23:12:48 -0600372 KeyFactory* key_factory =
373 GetKeyFactory(*context_, hw_enforced, sw_enforced, &algorithm, &response->error);
Shawn Willden0cb69422015-05-26 08:31:37 -0600374 if (!key_factory)
375 return;
376
377 UniquePtr<Key> key;
Shawn Willdend599b152015-07-27 16:58:30 -0600378 response->error = key_factory->LoadKey(key_material, request.additional_params, hw_enforced,
379 sw_enforced, &key);
Shawn Willden0cb69422015-05-26 08:31:37 -0600380 if (response->error != KM_ERROR_OK)
Shawn Willdenffd790c2014-08-18 21:20:06 -0600381 return;
382
Shawn Willdenf268d742014-08-19 15:36:26 -0600383 UniquePtr<uint8_t[]> out_key;
384 size_t size;
Shawn Willden0cb69422015-05-26 08:31:37 -0600385 response->error = key->formatted_key_material(request.key_format, &out_key, &size);
Shawn Willdenf268d742014-08-19 15:36:26 -0600386 if (response->error == KM_ERROR_OK) {
387 response->key_data = out_key.release();
388 response->key_data_length = size;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600389 }
Shawn Willdenffd790c2014-08-18 21:20:06 -0600390}
391
Shawn Willdend3ee5502016-01-05 19:40:43 -0700392void AndroidKeymaster::AttestKey(const AttestKeyRequest& request, AttestKeyResponse* response) {
393 if (!response)
394 return;
395
396 AuthorizationSet tee_enforced;
397 AuthorizationSet sw_enforced;
398 const KeyFactory* key_factory;
399 UniquePtr<Key> key;
400 response->error = LoadKey(request.key_blob, request.attest_params, &tee_enforced, &sw_enforced,
401 &key_factory, &key);
402 if (response->error != KM_ERROR_OK)
403 return;
404
405 response->error = key->GenerateAttestation(*context_, request.attest_params, tee_enforced,
406 sw_enforced, &response->certificate_chain);
407}
408
Shawn Willdenc15af192016-03-09 20:03:38 -0700409void AndroidKeymaster::UpgradeKey(const UpgradeKeyRequest& request, UpgradeKeyResponse* response) {
410 if (!response)
411 return;
412
413 KeymasterKeyBlob upgraded_key;
414 response->error = context_->UpgradeKeyBlob(KeymasterKeyBlob(request.key_blob),
415 request.upgrade_params, &upgraded_key);
416 if (response->error != KM_ERROR_OK)
417 return;
418 response->upgraded_key = upgraded_key.release();
419}
420
Shawn Willdenb6837e72015-05-16 09:20:59 -0600421void AndroidKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600422 if (response == NULL)
Shawn Willdenffd790c2014-08-18 21:20:06 -0600423 return;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600424
Shawn Willdena278f612014-12-23 11:22:21 -0700425 keymaster_algorithm_t algorithm;
426 KeyFactory* factory = 0;
427 UniquePtr<Key> key;
428 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
Shawn Willden06298102015-05-25 23:12:48 -0600429 !(factory = context_->GetKeyFactory(algorithm)))
Shawn Willdena278f612014-12-23 11:22:21 -0700430 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
Shawn Willden0cb69422015-05-26 08:31:37 -0600431 else {
432 keymaster_key_blob_t key_material = {request.key_data, request.key_data_length};
433 KeymasterKeyBlob key_blob;
434 response->error = factory->ImportKey(request.key_description, request.key_format,
435 KeymasterKeyBlob(key_material), &key_blob,
436 &response->enforced, &response->unenforced);
437 if (response->error == KM_ERROR_OK)
438 response->key_blob = key_blob.release();
439 }
Shawn Willdenffd790c2014-08-18 21:20:06 -0600440}
441
Shawn Willden36d41e22015-06-17 06:39:48 -0600442void AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
443 if (!response)
444 return;
445 response->error = context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
Shawn Willden2beb6282015-05-20 16:36:24 -0600446}
447
Shawn Willden36d41e22015-06-17 06:39:48 -0600448void AndroidKeymaster::DeleteAllKeys(const DeleteAllKeysRequest&, DeleteAllKeysResponse* response) {
449 if (!response)
450 return;
451 response->error = context_->DeleteAllKeys();
Shawn Willden2beb6282015-05-20 16:36:24 -0600452}
453
Shawn Willdend599b152015-07-27 16:58:30 -0600454bool AndroidKeymaster::has_operation(keymaster_operation_handle_t op_handle) const {
455 return operation_table_->Find(op_handle) != nullptr;
456}
457
Shawn Willden0cb69422015-05-26 08:31:37 -0600458keymaster_error_t AndroidKeymaster::LoadKey(const keymaster_key_blob_t& key_blob,
459 const AuthorizationSet& additional_params,
460 AuthorizationSet* hw_enforced,
461 AuthorizationSet* sw_enforced,
Shawn Willden06298102015-05-25 23:12:48 -0600462 const KeyFactory** factory, UniquePtr<Key>* key) {
Shawn Willden0cb69422015-05-26 08:31:37 -0600463 KeymasterKeyBlob key_material;
464 keymaster_error_t error = context_->ParseKeyBlob(KeymasterKeyBlob(key_blob), additional_params,
465 &key_material, hw_enforced, sw_enforced);
Shawn Willden437fbd12014-08-20 11:59:49 -0600466 if (error != KM_ERROR_OK)
467 return error;
468
Shawn Willdenc15af192016-03-09 20:03:38 -0700469 error = CheckVersionInfo(*hw_enforced, *sw_enforced, *context_);
470 if (error != KM_ERROR_OK)
471 return error;
472
Shawn Willden06298102015-05-25 23:12:48 -0600473 keymaster_algorithm_t algorithm;
474 *factory = GetKeyFactory(*context_, *hw_enforced, *sw_enforced, &algorithm, &error);
475 if (error != KM_ERROR_OK)
Shawn Willden437fbd12014-08-20 11:59:49 -0600476 return error;
Shawn Willden128ffe02014-08-06 12:31:33 -0600477
Shawn Willdend599b152015-07-27 16:58:30 -0600478 return (*factory)->LoadKey(key_material, additional_params, *hw_enforced, *sw_enforced, key);
Shawn Willden128ffe02014-08-06 12:31:33 -0600479}
480
Shawn Willden128ffe02014-08-06 12:31:33 -0600481} // namespace keymaster