blob: d4bc7a890aa3927e338fb05f80b595c4bea9a4a3 [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
17#include <assert.h>
18#include <string.h>
19
Shawn Willden4db3fbd2014-08-08 22:13:44 -060020#include <cstddef>
21
Shawn Willden1615f2e2014-08-13 10:37:40 -060022#include <openssl/rand.h>
Shawn Willden128ffe02014-08-06 12:31:33 -060023
24#include <UniquePtr.h>
25
Shawn Willden3879f862014-08-06 14:40:48 -060026#include "ae.h"
Shawn Willden28e41472014-08-18 13:35:22 -060027#include "dsa_operation.h"
Shawn Willdenc3864dd2014-08-18 15:20:01 -060028#include "ecdsa_operation.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060029#include "google_keymaster.h"
30#include "google_keymaster_utils.h"
Shawn Willden4db3fbd2014-08-08 22:13:44 -060031#include "key_blob.h"
Shawn Willden1615f2e2014-08-13 10:37:40 -060032#include "rsa_operation.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060033
34namespace keymaster {
35
Shawn Willden1615f2e2014-08-13 10:37:40 -060036GoogleKeymaster::GoogleKeymaster(size_t operation_table_size)
37 : operation_table_(new OpTableEntry[operation_table_size]),
38 operation_table_size_(operation_table_size) {
39 if (operation_table_.get() == NULL)
40 operation_table_size_ = 0;
Shawn Willden39b970b2014-08-11 09:11:21 -060041}
42GoogleKeymaster::~GoogleKeymaster() {
Shawn Willden1615f2e2014-08-13 10:37:40 -060043 for (size_t i = 0; i < operation_table_size_; ++i)
44 if (operation_table_[i].operation != NULL)
45 delete operation_table_[i].operation;
Shawn Willden39b970b2014-08-11 09:11:21 -060046}
Shawn Willden128ffe02014-08-06 12:31:33 -060047
Shawn Willden28e41472014-08-18 13:35:22 -060048const uint32_t RSA_DEFAULT_KEY_SIZE = 2048;
49const uint32_t DSA_DEFAULT_KEY_SIZE = 2048;
50const uint64_t RSA_DEFAULT_EXPONENT = 65537;
Shawn Willden128ffe02014-08-06 12:31:33 -060051
Shawn Willden128ffe02014-08-06 12:31:33 -060052struct AE_CTX_Delete {
Shawn Willden802bb292014-08-18 10:46:29 -060053 void operator()(ae_ctx* ctx) const { ae_free(ctx); }
Shawn Willden128ffe02014-08-06 12:31:33 -060054};
55typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
56
Shawn Willden128ffe02014-08-06 12:31:33 -060057keymaster_algorithm_t supported_algorithms[] = {
Shawn Willdenc3864dd2014-08-18 15:20:01 -060058 KM_ALGORITHM_RSA, KM_ALGORITHM_DSA, KM_ALGORITHM_ECDSA,
Shawn Willden128ffe02014-08-06 12:31:33 -060059};
60
61template <typename T>
62bool check_supported(keymaster_algorithm_t algorithm, SupportedResponse<T>* response) {
63 if (!array_contains(supported_algorithms, algorithm)) {
64 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
65 return false;
66 }
67 return true;
68}
69
70void
71GoogleKeymaster::SupportedAlgorithms(SupportedResponse<keymaster_algorithm_t>* response) const {
72 if (response == NULL)
73 return;
74 response->SetResults(supported_algorithms);
75}
76
77void
78GoogleKeymaster::SupportedBlockModes(keymaster_algorithm_t algorithm,
79 SupportedResponse<keymaster_block_mode_t>* response) const {
80 if (response == NULL || !check_supported(algorithm, response))
81 return;
82 response->error = KM_ERROR_OK;
83}
84
Shawn Willden28e41472014-08-18 13:35:22 -060085keymaster_padding_t supported_padding[] = {KM_PAD_NONE};
Shawn Willden128ffe02014-08-06 12:31:33 -060086void
87GoogleKeymaster::SupportedPaddingModes(keymaster_algorithm_t algorithm,
88 SupportedResponse<keymaster_padding_t>* response) const {
89 if (response == NULL || !check_supported(algorithm, response))
90 return;
91
92 response->error = KM_ERROR_OK;
93 switch (algorithm) {
94 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -060095 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -060096 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -060097 response->SetResults(supported_padding);
Shawn Willden128ffe02014-08-06 12:31:33 -060098 break;
99 default:
100 response->results_length = 0;
101 break;
102 }
103}
104
Shawn Willden28e41472014-08-18 13:35:22 -0600105keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE};
Shawn Willden128ffe02014-08-06 12:31:33 -0600106void GoogleKeymaster::SupportedDigests(keymaster_algorithm_t algorithm,
107 SupportedResponse<keymaster_digest_t>* response) const {
108 if (response == NULL || !check_supported(algorithm, response))
109 return;
110
111 response->error = KM_ERROR_OK;
112 switch (algorithm) {
113 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600114 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600115 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600116 response->SetResults(supported_digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600117 break;
118 default:
119 response->results_length = 0;
120 break;
121 }
122}
123
Shawn Willden28e41472014-08-18 13:35:22 -0600124keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_PKCS8};
Shawn Willden128ffe02014-08-06 12:31:33 -0600125void
126GoogleKeymaster::SupportedImportFormats(keymaster_algorithm_t algorithm,
127 SupportedResponse<keymaster_key_format_t>* response) const {
128 if (response == NULL || !check_supported(algorithm, response))
129 return;
130
131 response->error = KM_ERROR_OK;
132 switch (algorithm) {
133 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600134 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600135 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600136 response->SetResults(supported_import_formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600137 break;
138 default:
139 response->results_length = 0;
140 break;
141 }
142}
143
Shawn Willden28e41472014-08-18 13:35:22 -0600144keymaster_key_format_t supported_export_formats[] = {KM_KEY_FORMAT_X509};
Shawn Willden128ffe02014-08-06 12:31:33 -0600145void
146GoogleKeymaster::SupportedExportFormats(keymaster_algorithm_t algorithm,
147 SupportedResponse<keymaster_key_format_t>* response) const {
148 if (response == NULL || !check_supported(algorithm, response))
149 return;
150
151 response->error = KM_ERROR_OK;
152 switch (algorithm) {
153 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600154 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600155 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600156 response->SetResults(supported_export_formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600157 break;
158 default:
159 response->results_length = 0;
160 break;
161 }
162}
163
Shawn Willden128ffe02014-08-06 12:31:33 -0600164void GoogleKeymaster::GenerateKey(const GenerateKeyRequest& request,
165 GenerateKeyResponse* response) {
166 if (response == NULL)
167 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600168 response->error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden128ffe02014-08-06 12:31:33 -0600169
Shawn Willden76364712014-08-11 17:48:04 -0600170 if (!CopyAuthorizations(request.key_description, response))
171 return;
172
Shawn Willden39b970b2014-08-11 09:11:21 -0600173 AuthorizationSet hidden_auths;
Shawn Willden76364712014-08-11 17:48:04 -0600174 response->error = BuildHiddenAuthorizations(request.key_description, &hidden_auths);
175 if (response->error != KM_ERROR_OK)
Shawn Willden128ffe02014-08-06 12:31:33 -0600176 return;
177
178 keymaster_algorithm_t algorithm;
179 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm)) {
180 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
181 return;
182 }
Shawn Willden28e41472014-08-18 13:35:22 -0600183
Shawn Willden128ffe02014-08-06 12:31:33 -0600184 switch (algorithm) {
185 case KM_ALGORITHM_RSA:
Shawn Willden39b970b2014-08-11 09:11:21 -0600186 if (!GenerateRsa(request.key_description, response, &hidden_auths))
Shawn Willden128ffe02014-08-06 12:31:33 -0600187 return;
188 break;
Shawn Willden28e41472014-08-18 13:35:22 -0600189 case KM_ALGORITHM_DSA:
190 if (!GenerateDsa(request.key_description, response, &hidden_auths))
191 return;
192 break;
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600193 case KM_ALGORITHM_ECDSA:
194 if (!GenerateEcdsa(request.key_description, response, &hidden_auths))
195 return;
196 break;
Shawn Willden128ffe02014-08-06 12:31:33 -0600197 default:
198 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
199 return;
200 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600201
202 response->error = KM_ERROR_OK;
Shawn Willden128ffe02014-08-06 12:31:33 -0600203}
204
Shawn Willden76364712014-08-11 17:48:04 -0600205void GoogleKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
206 GetKeyCharacteristicsResponse* response) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600207 if (response == NULL)
208 return;
209 response->error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden76364712014-08-11 17:48:04 -0600210
Shawn Willden1615f2e2014-08-13 10:37:40 -0600211 UniquePtr<KeyBlob> blob(
212 LoadKeyBlob(request.key_blob, request.additional_params, &(response->error)));
213 if (blob.get() == NULL)
214 return;
215
216 response->enforced.Reinitialize(blob->enforced());
217 response->unenforced.Reinitialize(blob->unenforced());
218 response->error = KM_ERROR_OK;
219}
220
221void GoogleKeymaster::BeginOperation(const BeginOperationRequest& request,
222 BeginOperationResponse* response) {
223 if (response == NULL)
224 return;
225 response->error = KM_ERROR_UNKNOWN_ERROR;
226 response->op_handle = 0;
227
228 UniquePtr<KeyBlob> key(
229 LoadKeyBlob(request.key_blob, request.additional_params, &response->error));
230 if (key.get() == NULL)
231 return;
232
233 UniquePtr<Operation> operation;
234 switch (key->algorithm()) {
235 case KM_ALGORITHM_RSA:
236 operation.reset(new RsaOperation(request.purpose, *key));
237 break;
Shawn Willden5b41ca22014-08-18 14:29:14 -0600238 case KM_ALGORITHM_DSA:
239 operation.reset(new DsaOperation(request.purpose, *key));
240 break;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600241 default:
242 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
243 break;
244 }
245
246 if (operation.get() == NULL) {
Shawn Willden76364712014-08-11 17:48:04 -0600247 return;
248 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600249
250 response->error = operation->Begin();
251 if (response->error != KM_ERROR_OK)
252 return;
253
254 response->error = AddOperation(operation.release(), &response->op_handle);
255}
256
257void GoogleKeymaster::UpdateOperation(const UpdateOperationRequest& request,
258 UpdateOperationResponse* response) {
259 OpTableEntry* entry = FindOperation(request.op_handle);
260 if (entry == NULL) {
261 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
262 return;
263 }
264
265 response->error = entry->operation->Update(request.input, &response->output);
266 if (response->error != KM_ERROR_OK) {
267 // Any error invalidates the operation.
268 DeleteOperation(entry);
269 }
270}
271
Shawn Willden43e999e2014-08-13 13:29:50 -0600272void GoogleKeymaster::FinishOperation(const FinishOperationRequest& request,
Shawn Willden1615f2e2014-08-13 10:37:40 -0600273 FinishOperationResponse* response) {
Shawn Willden43e999e2014-08-13 13:29:50 -0600274 OpTableEntry* entry = FindOperation(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600275 if (entry == NULL) {
276 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
277 return;
278 }
279
Shawn Willden43e999e2014-08-13 13:29:50 -0600280 response->error = entry->operation->Finish(request.signature, &response->output);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600281 DeleteOperation(entry);
282}
283
284keymaster_error_t GoogleKeymaster::AbortOperation(const keymaster_operation_handle_t op_handle) {
285 OpTableEntry* entry = FindOperation(op_handle);
286 if (entry == NULL)
287 return KM_ERROR_INVALID_OPERATION_HANDLE;
288 DeleteOperation(entry);
289 return KM_ERROR_OK;
Shawn Willden76364712014-08-11 17:48:04 -0600290}
291
Shawn Willden39b970b2014-08-11 09:11:21 -0600292bool GoogleKeymaster::GenerateRsa(const AuthorizationSet& key_auths, GenerateKeyResponse* response,
293 AuthorizationSet* hidden_auths) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600294 uint64_t public_exponent = RSA_DEFAULT_EXPONENT;
295 if (!key_auths.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent))
Shawn Willden76364712014-08-11 17:48:04 -0600296 AddAuthorization(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent), response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600297
298 uint32_t key_size = RSA_DEFAULT_KEY_SIZE;
299 if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
Shawn Willden76364712014-08-11 17:48:04 -0600300 AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600301
Shawn Willden802bb292014-08-18 10:46:29 -0600302 UniquePtr<uint8_t[]> key_data;
303 size_t key_data_size;
304 keymaster_error_t error =
305 RsaOperation::Generate(public_exponent, key_size, &key_data, &key_data_size);
306 if (error != KM_ERROR_OK) {
307 response->error = error;
Shawn Willden128ffe02014-08-06 12:31:33 -0600308 return false;
309 }
310
Shawn Willden802bb292014-08-18 10:46:29 -0600311 return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
Shawn Willden39b970b2014-08-11 09:11:21 -0600312}
313
Shawn Willden28e41472014-08-18 13:35:22 -0600314template <keymaster_tag_t Tag>
315static void GetDsaParamData(const AuthorizationSet& auths, TypedTag<KM_BIGNUM, Tag> tag,
316 keymaster_blob_t* blob) {
317 if (!auths.GetTagValue(tag, blob))
318 blob->data = NULL;
319}
320
321bool GoogleKeymaster::GenerateDsa(const AuthorizationSet& key_auths, GenerateKeyResponse* response,
322 AuthorizationSet* hidden_auths) {
323 keymaster_blob_t g_blob;
324 GetDsaParamData(key_auths, TAG_DSA_GENERATOR, &g_blob);
325 const uint8_t* original_g = g_blob.data;
326
327 keymaster_blob_t p_blob;
328 GetDsaParamData(key_auths, TAG_DSA_P, &p_blob);
329 const uint8_t* original_p = p_blob.data;
330
331 keymaster_blob_t q_blob;
332 GetDsaParamData(key_auths, TAG_DSA_Q, &q_blob);
333 const uint8_t* original_q = q_blob.data;
334
335 uint32_t key_size = DSA_DEFAULT_KEY_SIZE;
336 if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
337 AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
338
339 UniquePtr<uint8_t[]> key_data;
340 size_t key_data_size;
341 keymaster_error_t error =
342 DsaOperation::Generate(key_size, &g_blob, &p_blob, &q_blob, &key_data, &key_data_size);
343
344 // If any the original_* pointers are NULL, DsaOperation::Generate should have generated values
345 // for the corressponding blobs. We need to put them in the authorization set and clean up the
346 // allocated memory.
347 if (original_g == NULL && g_blob.data != NULL) {
348 if (!AddAuthorization(Authorization(TAG_DSA_GENERATOR, g_blob), response))
349 error = KM_ERROR_INVALID_DSA_PARAMS;
350 delete[] g_blob.data;
351 }
352 if (original_p == NULL && p_blob.data != NULL) {
353 if (!AddAuthorization(Authorization(TAG_DSA_P, p_blob), response))
354 error = KM_ERROR_INVALID_DSA_PARAMS;
355 delete[] p_blob.data;
356 }
357 if (original_q == NULL && q_blob.data != NULL) {
358 if (!AddAuthorization(Authorization(TAG_DSA_Q, q_blob), response))
359 error = KM_ERROR_INVALID_DSA_PARAMS;
360 delete[] q_blob.data;
361 }
362
363 if (error != KM_ERROR_OK) {
364 response->error = error;
365 return false;
366 }
367
368 return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
369}
370
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600371bool GoogleKeymaster::GenerateEcdsa(const AuthorizationSet& key_auths,
372 GenerateKeyResponse* response, AuthorizationSet* hidden_auths) {
373 uint64_t public_exponent = RSA_DEFAULT_EXPONENT;
374 if (!key_auths.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent))
375 AddAuthorization(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent), response);
376
377 uint32_t key_size = RSA_DEFAULT_KEY_SIZE;
378 if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
379 AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
380
381 UniquePtr<uint8_t[]> key_data;
382 size_t key_data_size;
383 keymaster_error_t error = EcdsaOperation::Generate(key_size, &key_data, &key_data_size);
384 if (error != KM_ERROR_OK) {
385 response->error = error;
386 return false;
387 }
388
389 return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
390}
391
Shawn Willden39b970b2014-08-11 09:11:21 -0600392bool GoogleKeymaster::CreateKeyBlob(GenerateKeyResponse* response,
393 const AuthorizationSet& hidden_auths, uint8_t* key_bytes,
394 size_t key_length) {
395 uint8_t nonce[KeyBlob::NONCE_LENGTH];
396 GenerateNonce(nonce, array_size(nonce));
397
398 keymaster_key_blob_t key_data = {key_bytes, key_length};
399 UniquePtr<KeyBlob> blob(new KeyBlob(response->enforced, response->unenforced, hidden_auths,
400 key_data, MasterKey(), nonce));
401 if (blob.get() == NULL) {
402 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
403 return false;
404 }
405
406 if (blob->error() != KM_ERROR_OK) {
407 return blob->error();
408 return false;
409 }
410
411 size_t size = blob->SerializedSize();
412 UniquePtr<uint8_t[]> blob_bytes(new uint8_t[size]);
413 if (blob_bytes.get() == NULL) {
414 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
415 return false;
416 }
417 blob->Serialize(blob_bytes.get(), blob_bytes.get() + size);
418 response->key_blob.key_material_size = size;
419 response->key_blob.key_material = blob_bytes.release();
420 return true;
Shawn Willden128ffe02014-08-06 12:31:33 -0600421}
422
Shawn Willden1615f2e2014-08-13 10:37:40 -0600423KeyBlob* GoogleKeymaster::LoadKeyBlob(const keymaster_key_blob_t& key,
424 const AuthorizationSet& client_params,
425 keymaster_error_t* error) {
426 AuthorizationSet hidden;
427 BuildHiddenAuthorizations(client_params, &hidden);
428 UniquePtr<KeyBlob> blob(new KeyBlob(key, hidden, MasterKey()));
429 if (blob.get() == NULL) {
430 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
431 return NULL;
432 } else if (blob->error() != KM_ERROR_OK) {
433 *error = blob->error();
434 return NULL;
435 }
436 return blob.release();
437}
438
Shawn Willden128ffe02014-08-06 12:31:33 -0600439static keymaster_error_t CheckAuthorizationSet(const AuthorizationSet& set) {
440 switch (set.is_valid()) {
Shawn Willden58e1a542014-08-08 21:58:29 -0600441 case AuthorizationSet::OK:
Shawn Willden128ffe02014-08-06 12:31:33 -0600442 return KM_ERROR_OK;
443 case AuthorizationSet::ALLOCATION_FAILURE:
444 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden128ffe02014-08-06 12:31:33 -0600445 case AuthorizationSet::MALFORMED_DATA:
446 return KM_ERROR_UNKNOWN_ERROR;
447 }
448 return KM_ERROR_OK;
449}
450
451bool GoogleKeymaster::CopyAuthorizations(const AuthorizationSet& key_description,
Shawn Willden76364712014-08-11 17:48:04 -0600452 GenerateKeyResponse* response) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600453 for (size_t i = 0; i < key_description.size(); ++i) {
454 switch (key_description[i].tag) {
455 case KM_TAG_ROOT_OF_TRUST:
456 case KM_TAG_CREATION_DATETIME:
457 case KM_TAG_ORIGIN:
458 response->error = KM_ERROR_INVALID_TAG;
459 return false;
460 case KM_TAG_ROLLBACK_RESISTANT:
461 response->error = KM_ERROR_UNSUPPORTED_TAG;
462 return false;
463 default:
Shawn Willden28e41472014-08-18 13:35:22 -0600464 if (!AddAuthorization(key_description[i], response))
465 return false;
Shawn Willden128ffe02014-08-06 12:31:33 -0600466 break;
467 }
468 }
469
Shawn Willden28e41472014-08-18 13:35:22 -0600470 if (!AddAuthorization(Authorization(TAG_CREATION_DATETIME, java_time(time(NULL))), response) ||
471 !AddAuthorization(Authorization(TAG_ORIGIN, origin()), response))
472 return false;
Shawn Willden128ffe02014-08-06 12:31:33 -0600473
474 response->error = CheckAuthorizationSet(response->enforced);
475 if (response->error != KM_ERROR_OK)
476 return false;
477 response->error = CheckAuthorizationSet(response->unenforced);
478 if (response->error != KM_ERROR_OK)
479 return false;
480
481 return true;
482}
483
Shawn Willden76364712014-08-11 17:48:04 -0600484keymaster_error_t GoogleKeymaster::BuildHiddenAuthorizations(const AuthorizationSet& input_set,
Shawn Willden1615f2e2014-08-13 10:37:40 -0600485 AuthorizationSet* hidden) {
Shawn Willden76364712014-08-11 17:48:04 -0600486 keymaster_blob_t entry;
487 if (input_set.GetTagValue(TAG_APPLICATION_ID, &entry))
488 hidden->push_back(TAG_APPLICATION_ID, entry.data, entry.data_length);
489 if (input_set.GetTagValue(TAG_APPLICATION_DATA, &entry))
490 hidden->push_back(TAG_APPLICATION_DATA, entry.data, entry.data_length);
491 hidden->push_back(RootOfTrustTag());
492
493 return CheckAuthorizationSet(*hidden);
494}
495
Shawn Willden28e41472014-08-18 13:35:22 -0600496bool GoogleKeymaster::AddAuthorization(const keymaster_key_param_t& auth,
Shawn Willden76364712014-08-11 17:48:04 -0600497 GenerateKeyResponse* response) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600498 switch (auth.tag) {
499 case KM_TAG_ROOT_OF_TRUST:
500 case KM_TAG_APPLICATION_ID:
501 case KM_TAG_APPLICATION_DATA:
Shawn Willden76364712014-08-11 17:48:04 -0600502 // Skip. We handle these tags separately.
Shawn Willden28e41472014-08-18 13:35:22 -0600503 return true;
Shawn Willden39b970b2014-08-11 09:11:21 -0600504 default:
505 if (is_enforced(auth.tag))
Shawn Willden28e41472014-08-18 13:35:22 -0600506 return response->enforced.push_back(auth);
Shawn Willden39b970b2014-08-11 09:11:21 -0600507 else
Shawn Willden28e41472014-08-18 13:35:22 -0600508 return response->unenforced.push_back(auth);
Shawn Willden39b970b2014-08-11 09:11:21 -0600509 }
Shawn Willden128ffe02014-08-06 12:31:33 -0600510}
511
Shawn Willden1615f2e2014-08-13 10:37:40 -0600512keymaster_error_t GoogleKeymaster::AddOperation(Operation* operation,
513 keymaster_operation_handle_t* op_handle) {
514 UniquePtr<Operation> op(operation);
515 if (RAND_bytes(reinterpret_cast<uint8_t*>(op_handle), sizeof(*op_handle)) == 0)
516 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden802bb292014-08-18 10:46:29 -0600517 if (*op_handle == 0) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600518 // Statistically this is vanishingly unlikely, which means if it ever happens in practice,
519 // it indicates a broken RNG.
520 return KM_ERROR_UNKNOWN_ERROR;
521 }
522 for (size_t i = 0; i < operation_table_size_; ++i) {
523 if (operation_table_[i].operation == NULL) {
524 operation_table_[i].operation = op.release();
525 operation_table_[i].handle = *op_handle;
526 return KM_ERROR_OK;
527 }
528 }
529 return KM_ERROR_TOO_MANY_OPERATIONS;
530}
531
532GoogleKeymaster::OpTableEntry*
533GoogleKeymaster::FindOperation(keymaster_operation_handle_t op_handle) {
534 if (op_handle == 0)
535 return NULL;
536
537 for (size_t i = 0; i < operation_table_size_; ++i) {
538 if (operation_table_[i].handle == op_handle)
539 return operation_table_.get() + i;
540 }
541 return NULL;
542}
543
544void GoogleKeymaster::DeleteOperation(OpTableEntry* entry) {
545 delete entry->operation;
546 entry->operation = NULL;
547 entry->handle = 0;
548}
549
Shawn Willden128ffe02014-08-06 12:31:33 -0600550} // namespace keymaster