blob: 6e9d5cf11470bc5e97861d5b08ef9a6b7df82d4e [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 Willden5ac2f8f2014-08-18 15:33:10 -0600241 case KM_ALGORITHM_ECDSA:
242 operation.reset(new EcdsaOperation(request.purpose, *key));
243 break;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600244 default:
245 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
246 break;
247 }
248
249 if (operation.get() == NULL) {
Shawn Willden76364712014-08-11 17:48:04 -0600250 return;
251 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600252
253 response->error = operation->Begin();
254 if (response->error != KM_ERROR_OK)
255 return;
256
257 response->error = AddOperation(operation.release(), &response->op_handle);
258}
259
260void GoogleKeymaster::UpdateOperation(const UpdateOperationRequest& request,
261 UpdateOperationResponse* response) {
262 OpTableEntry* entry = FindOperation(request.op_handle);
263 if (entry == NULL) {
264 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
265 return;
266 }
267
268 response->error = entry->operation->Update(request.input, &response->output);
269 if (response->error != KM_ERROR_OK) {
270 // Any error invalidates the operation.
271 DeleteOperation(entry);
272 }
273}
274
Shawn Willden43e999e2014-08-13 13:29:50 -0600275void GoogleKeymaster::FinishOperation(const FinishOperationRequest& request,
Shawn Willden1615f2e2014-08-13 10:37:40 -0600276 FinishOperationResponse* response) {
Shawn Willden43e999e2014-08-13 13:29:50 -0600277 OpTableEntry* entry = FindOperation(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600278 if (entry == NULL) {
279 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
280 return;
281 }
282
Shawn Willden43e999e2014-08-13 13:29:50 -0600283 response->error = entry->operation->Finish(request.signature, &response->output);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600284 DeleteOperation(entry);
285}
286
287keymaster_error_t GoogleKeymaster::AbortOperation(const keymaster_operation_handle_t op_handle) {
288 OpTableEntry* entry = FindOperation(op_handle);
289 if (entry == NULL)
290 return KM_ERROR_INVALID_OPERATION_HANDLE;
291 DeleteOperation(entry);
292 return KM_ERROR_OK;
Shawn Willden76364712014-08-11 17:48:04 -0600293}
294
Shawn Willden39b970b2014-08-11 09:11:21 -0600295bool GoogleKeymaster::GenerateRsa(const AuthorizationSet& key_auths, GenerateKeyResponse* response,
296 AuthorizationSet* hidden_auths) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600297 uint64_t public_exponent = RSA_DEFAULT_EXPONENT;
298 if (!key_auths.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent))
Shawn Willden76364712014-08-11 17:48:04 -0600299 AddAuthorization(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent), response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600300
301 uint32_t key_size = RSA_DEFAULT_KEY_SIZE;
302 if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
Shawn Willden76364712014-08-11 17:48:04 -0600303 AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600304
Shawn Willden802bb292014-08-18 10:46:29 -0600305 UniquePtr<uint8_t[]> key_data;
306 size_t key_data_size;
307 keymaster_error_t error =
308 RsaOperation::Generate(public_exponent, key_size, &key_data, &key_data_size);
309 if (error != KM_ERROR_OK) {
310 response->error = error;
Shawn Willden128ffe02014-08-06 12:31:33 -0600311 return false;
312 }
313
Shawn Willden802bb292014-08-18 10:46:29 -0600314 return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
Shawn Willden39b970b2014-08-11 09:11:21 -0600315}
316
Shawn Willden28e41472014-08-18 13:35:22 -0600317template <keymaster_tag_t Tag>
318static void GetDsaParamData(const AuthorizationSet& auths, TypedTag<KM_BIGNUM, Tag> tag,
319 keymaster_blob_t* blob) {
320 if (!auths.GetTagValue(tag, blob))
321 blob->data = NULL;
322}
323
324bool GoogleKeymaster::GenerateDsa(const AuthorizationSet& key_auths, GenerateKeyResponse* response,
325 AuthorizationSet* hidden_auths) {
326 keymaster_blob_t g_blob;
327 GetDsaParamData(key_auths, TAG_DSA_GENERATOR, &g_blob);
328 const uint8_t* original_g = g_blob.data;
329
330 keymaster_blob_t p_blob;
331 GetDsaParamData(key_auths, TAG_DSA_P, &p_blob);
332 const uint8_t* original_p = p_blob.data;
333
334 keymaster_blob_t q_blob;
335 GetDsaParamData(key_auths, TAG_DSA_Q, &q_blob);
336 const uint8_t* original_q = q_blob.data;
337
338 uint32_t key_size = DSA_DEFAULT_KEY_SIZE;
339 if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
340 AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
341
342 UniquePtr<uint8_t[]> key_data;
343 size_t key_data_size;
344 keymaster_error_t error =
345 DsaOperation::Generate(key_size, &g_blob, &p_blob, &q_blob, &key_data, &key_data_size);
346
347 // If any the original_* pointers are NULL, DsaOperation::Generate should have generated values
348 // for the corressponding blobs. We need to put them in the authorization set and clean up the
349 // allocated memory.
350 if (original_g == NULL && g_blob.data != NULL) {
351 if (!AddAuthorization(Authorization(TAG_DSA_GENERATOR, g_blob), response))
352 error = KM_ERROR_INVALID_DSA_PARAMS;
353 delete[] g_blob.data;
354 }
355 if (original_p == NULL && p_blob.data != NULL) {
356 if (!AddAuthorization(Authorization(TAG_DSA_P, p_blob), response))
357 error = KM_ERROR_INVALID_DSA_PARAMS;
358 delete[] p_blob.data;
359 }
360 if (original_q == NULL && q_blob.data != NULL) {
361 if (!AddAuthorization(Authorization(TAG_DSA_Q, q_blob), response))
362 error = KM_ERROR_INVALID_DSA_PARAMS;
363 delete[] q_blob.data;
364 }
365
366 if (error != KM_ERROR_OK) {
367 response->error = error;
368 return false;
369 }
370
371 return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
372}
373
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600374bool GoogleKeymaster::GenerateEcdsa(const AuthorizationSet& key_auths,
375 GenerateKeyResponse* response, AuthorizationSet* hidden_auths) {
376 uint64_t public_exponent = RSA_DEFAULT_EXPONENT;
377 if (!key_auths.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent))
378 AddAuthorization(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent), response);
379
380 uint32_t key_size = RSA_DEFAULT_KEY_SIZE;
381 if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
382 AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
383
384 UniquePtr<uint8_t[]> key_data;
385 size_t key_data_size;
386 keymaster_error_t error = EcdsaOperation::Generate(key_size, &key_data, &key_data_size);
387 if (error != KM_ERROR_OK) {
388 response->error = error;
389 return false;
390 }
391
392 return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
393}
394
Shawn Willden39b970b2014-08-11 09:11:21 -0600395bool GoogleKeymaster::CreateKeyBlob(GenerateKeyResponse* response,
396 const AuthorizationSet& hidden_auths, uint8_t* key_bytes,
397 size_t key_length) {
398 uint8_t nonce[KeyBlob::NONCE_LENGTH];
399 GenerateNonce(nonce, array_size(nonce));
400
401 keymaster_key_blob_t key_data = {key_bytes, key_length};
402 UniquePtr<KeyBlob> blob(new KeyBlob(response->enforced, response->unenforced, hidden_auths,
403 key_data, MasterKey(), nonce));
404 if (blob.get() == NULL) {
405 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
406 return false;
407 }
408
409 if (blob->error() != KM_ERROR_OK) {
410 return blob->error();
411 return false;
412 }
413
414 size_t size = blob->SerializedSize();
415 UniquePtr<uint8_t[]> blob_bytes(new uint8_t[size]);
416 if (blob_bytes.get() == NULL) {
417 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
418 return false;
419 }
420 blob->Serialize(blob_bytes.get(), blob_bytes.get() + size);
421 response->key_blob.key_material_size = size;
422 response->key_blob.key_material = blob_bytes.release();
423 return true;
Shawn Willden128ffe02014-08-06 12:31:33 -0600424}
425
Shawn Willden1615f2e2014-08-13 10:37:40 -0600426KeyBlob* GoogleKeymaster::LoadKeyBlob(const keymaster_key_blob_t& key,
427 const AuthorizationSet& client_params,
428 keymaster_error_t* error) {
429 AuthorizationSet hidden;
430 BuildHiddenAuthorizations(client_params, &hidden);
431 UniquePtr<KeyBlob> blob(new KeyBlob(key, hidden, MasterKey()));
432 if (blob.get() == NULL) {
433 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
434 return NULL;
435 } else if (blob->error() != KM_ERROR_OK) {
436 *error = blob->error();
437 return NULL;
438 }
439 return blob.release();
440}
441
Shawn Willden128ffe02014-08-06 12:31:33 -0600442static keymaster_error_t CheckAuthorizationSet(const AuthorizationSet& set) {
443 switch (set.is_valid()) {
Shawn Willden58e1a542014-08-08 21:58:29 -0600444 case AuthorizationSet::OK:
Shawn Willden128ffe02014-08-06 12:31:33 -0600445 return KM_ERROR_OK;
446 case AuthorizationSet::ALLOCATION_FAILURE:
447 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden128ffe02014-08-06 12:31:33 -0600448 case AuthorizationSet::MALFORMED_DATA:
449 return KM_ERROR_UNKNOWN_ERROR;
450 }
451 return KM_ERROR_OK;
452}
453
454bool GoogleKeymaster::CopyAuthorizations(const AuthorizationSet& key_description,
Shawn Willden76364712014-08-11 17:48:04 -0600455 GenerateKeyResponse* response) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600456 for (size_t i = 0; i < key_description.size(); ++i) {
457 switch (key_description[i].tag) {
458 case KM_TAG_ROOT_OF_TRUST:
459 case KM_TAG_CREATION_DATETIME:
460 case KM_TAG_ORIGIN:
461 response->error = KM_ERROR_INVALID_TAG;
462 return false;
463 case KM_TAG_ROLLBACK_RESISTANT:
464 response->error = KM_ERROR_UNSUPPORTED_TAG;
465 return false;
466 default:
Shawn Willden28e41472014-08-18 13:35:22 -0600467 if (!AddAuthorization(key_description[i], response))
468 return false;
Shawn Willden128ffe02014-08-06 12:31:33 -0600469 break;
470 }
471 }
472
Shawn Willden28e41472014-08-18 13:35:22 -0600473 if (!AddAuthorization(Authorization(TAG_CREATION_DATETIME, java_time(time(NULL))), response) ||
474 !AddAuthorization(Authorization(TAG_ORIGIN, origin()), response))
475 return false;
Shawn Willden128ffe02014-08-06 12:31:33 -0600476
477 response->error = CheckAuthorizationSet(response->enforced);
478 if (response->error != KM_ERROR_OK)
479 return false;
480 response->error = CheckAuthorizationSet(response->unenforced);
481 if (response->error != KM_ERROR_OK)
482 return false;
483
484 return true;
485}
486
Shawn Willden76364712014-08-11 17:48:04 -0600487keymaster_error_t GoogleKeymaster::BuildHiddenAuthorizations(const AuthorizationSet& input_set,
Shawn Willden1615f2e2014-08-13 10:37:40 -0600488 AuthorizationSet* hidden) {
Shawn Willden76364712014-08-11 17:48:04 -0600489 keymaster_blob_t entry;
490 if (input_set.GetTagValue(TAG_APPLICATION_ID, &entry))
491 hidden->push_back(TAG_APPLICATION_ID, entry.data, entry.data_length);
492 if (input_set.GetTagValue(TAG_APPLICATION_DATA, &entry))
493 hidden->push_back(TAG_APPLICATION_DATA, entry.data, entry.data_length);
494 hidden->push_back(RootOfTrustTag());
495
496 return CheckAuthorizationSet(*hidden);
497}
498
Shawn Willden28e41472014-08-18 13:35:22 -0600499bool GoogleKeymaster::AddAuthorization(const keymaster_key_param_t& auth,
Shawn Willden76364712014-08-11 17:48:04 -0600500 GenerateKeyResponse* response) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600501 switch (auth.tag) {
502 case KM_TAG_ROOT_OF_TRUST:
503 case KM_TAG_APPLICATION_ID:
504 case KM_TAG_APPLICATION_DATA:
Shawn Willden76364712014-08-11 17:48:04 -0600505 // Skip. We handle these tags separately.
Shawn Willden28e41472014-08-18 13:35:22 -0600506 return true;
Shawn Willden39b970b2014-08-11 09:11:21 -0600507 default:
508 if (is_enforced(auth.tag))
Shawn Willden28e41472014-08-18 13:35:22 -0600509 return response->enforced.push_back(auth);
Shawn Willden39b970b2014-08-11 09:11:21 -0600510 else
Shawn Willden28e41472014-08-18 13:35:22 -0600511 return response->unenforced.push_back(auth);
Shawn Willden39b970b2014-08-11 09:11:21 -0600512 }
Shawn Willden128ffe02014-08-06 12:31:33 -0600513}
514
Shawn Willden1615f2e2014-08-13 10:37:40 -0600515keymaster_error_t GoogleKeymaster::AddOperation(Operation* operation,
516 keymaster_operation_handle_t* op_handle) {
517 UniquePtr<Operation> op(operation);
518 if (RAND_bytes(reinterpret_cast<uint8_t*>(op_handle), sizeof(*op_handle)) == 0)
519 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden802bb292014-08-18 10:46:29 -0600520 if (*op_handle == 0) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600521 // Statistically this is vanishingly unlikely, which means if it ever happens in practice,
522 // it indicates a broken RNG.
523 return KM_ERROR_UNKNOWN_ERROR;
524 }
525 for (size_t i = 0; i < operation_table_size_; ++i) {
526 if (operation_table_[i].operation == NULL) {
527 operation_table_[i].operation = op.release();
528 operation_table_[i].handle = *op_handle;
529 return KM_ERROR_OK;
530 }
531 }
532 return KM_ERROR_TOO_MANY_OPERATIONS;
533}
534
535GoogleKeymaster::OpTableEntry*
536GoogleKeymaster::FindOperation(keymaster_operation_handle_t op_handle) {
537 if (op_handle == 0)
538 return NULL;
539
540 for (size_t i = 0; i < operation_table_size_; ++i) {
541 if (operation_table_[i].handle == op_handle)
542 return operation_table_.get() + i;
543 }
544 return NULL;
545}
546
547void GoogleKeymaster::DeleteOperation(OpTableEntry* entry) {
548 delete entry->operation;
549 entry->operation = NULL;
550 entry->handle = 0;
551}
552
Shawn Willden128ffe02014-08-06 12:31:33 -0600553} // namespace keymaster