blob: 47f22cfa4a84113920fd95495cb5c338279ae5ba [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 Willdenffd790c2014-08-18 21:20:06 -060023#include <openssl/x509.h>
Shawn Willden128ffe02014-08-06 12:31:33 -060024
25#include <UniquePtr.h>
26
Shawn Willden98d9b922014-08-26 08:14:10 -060027#include <keymaster/google_keymaster.h>
28#include <keymaster/google_keymaster_utils.h>
29
Shawn Willden3879f862014-08-06 14:40:48 -060030#include "ae.h"
Shawn Willdend67afae2014-08-19 12:36:27 -060031#include "key.h"
Shawn Willdend67afae2014-08-19 12:36:27 -060032#include "operation.h"
Shawn Willden72014ad2014-09-17 13:04:10 -060033#include "unencrypted_key_blob.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060034
35namespace keymaster {
36
Shawn Willden2665e862014-11-24 14:46:21 -070037const uint8_t MAJOR_VER = 1;
38const uint8_t MINOR_VER = 0;
39const uint8_t SUBMINOR_VER = 0;
40
Shawn Willden2f3be362014-08-25 11:31:39 -060041GoogleKeymaster::GoogleKeymaster(size_t operation_table_size, Logger* logger)
Shawn Willden1615f2e2014-08-13 10:37:40 -060042 : operation_table_(new OpTableEntry[operation_table_size]),
Shawn Willden2f3be362014-08-25 11:31:39 -060043 operation_table_size_(operation_table_size), logger_(logger) {
Shawn Willden1615f2e2014-08-13 10:37:40 -060044 if (operation_table_.get() == NULL)
45 operation_table_size_ = 0;
Shawn Willden39b970b2014-08-11 09:11:21 -060046}
47GoogleKeymaster::~GoogleKeymaster() {
Shawn Willden1615f2e2014-08-13 10:37:40 -060048 for (size_t i = 0; i < operation_table_size_; ++i)
49 if (operation_table_[i].operation != NULL)
50 delete operation_table_[i].operation;
Shawn Willden39b970b2014-08-11 09:11:21 -060051}
Shawn Willden128ffe02014-08-06 12:31:33 -060052
Shawn Willden128ffe02014-08-06 12:31:33 -060053struct AE_CTX_Delete {
Shawn Willden802bb292014-08-18 10:46:29 -060054 void operator()(ae_ctx* ctx) const { ae_free(ctx); }
Shawn Willden128ffe02014-08-06 12:31:33 -060055};
56typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
57
Shawn Willden128ffe02014-08-06 12:31:33 -060058keymaster_algorithm_t supported_algorithms[] = {
Shawn Willden4d024ce2015-01-20 11:45:11 -070059 KM_ALGORITHM_RSA, KM_ALGORITHM_DSA, KM_ALGORITHM_ECDSA,
Shawn Willden128ffe02014-08-06 12:31:33 -060060};
61
62template <typename T>
63bool check_supported(keymaster_algorithm_t algorithm, SupportedResponse<T>* response) {
64 if (!array_contains(supported_algorithms, algorithm)) {
65 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
66 return false;
67 }
68 return true;
69}
70
Shawn Willden2665e862014-11-24 14:46:21 -070071void GoogleKeymaster::GetVersion(const GetVersionRequest&, GetVersionResponse* rsp) {
72 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 Willden3809b932014-12-02 06:59:46 -070081void GoogleKeymaster::SupportedAlgorithms(
82 SupportedResponse<keymaster_algorithm_t>* response) const {
Shawn Willden128ffe02014-08-06 12:31:33 -060083 if (response == NULL)
84 return;
85 response->SetResults(supported_algorithms);
86}
87
Shawn Willden3809b932014-12-02 06:59:46 -070088void GoogleKeymaster::SupportedBlockModes(
89 keymaster_algorithm_t algorithm, keymaster_purpose_t /* purpose */,
90 SupportedResponse<keymaster_block_mode_t>* response) const {
Shawn Willden128ffe02014-08-06 12:31:33 -060091 if (response == NULL || !check_supported(algorithm, response))
92 return;
Shawn Willden3809b932014-12-02 06:59:46 -070093 response->error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
Shawn Willden128ffe02014-08-06 12:31:33 -060094}
95
Shawn Willden4200f212014-12-02 07:01:21 -070096keymaster_padding_t supported_rsa_crypt_padding[] = {KM_PAD_RSA_OAEP, KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
97keymaster_padding_t supported_rsa_sign_padding[] = {KM_PAD_NONE};
Shawn Willden28e41472014-08-18 13:35:22 -060098keymaster_padding_t supported_padding[] = {KM_PAD_NONE};
Shawn Willden3809b932014-12-02 06:59:46 -070099
100void GoogleKeymaster::SupportedPaddingModes(
Shawn Willden4200f212014-12-02 07:01:21 -0700101 keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
Shawn Willden3809b932014-12-02 06:59:46 -0700102 SupportedResponse<keymaster_padding_t>* response) const {
Shawn Willden128ffe02014-08-06 12:31:33 -0600103 if (response == NULL || !check_supported(algorithm, response))
104 return;
105
106 response->error = KM_ERROR_OK;
107 switch (algorithm) {
108 case KM_ALGORITHM_RSA:
Shawn Willden4200f212014-12-02 07:01:21 -0700109 switch (purpose) {
110 case KM_PURPOSE_ENCRYPT:
111 case KM_PURPOSE_DECRYPT:
112 response->SetResults(supported_rsa_crypt_padding);
113 break;
114 case KM_PURPOSE_SIGN:
115 case KM_PURPOSE_VERIFY:
116 response->SetResults(supported_rsa_sign_padding);
117 break;
118 }
119 break;
Shawn Willden28e41472014-08-18 13:35:22 -0600120 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600121 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600122 response->SetResults(supported_padding);
Shawn Willden128ffe02014-08-06 12:31:33 -0600123 break;
124 default:
125 response->results_length = 0;
126 break;
127 }
128}
129
Shawn Willden28e41472014-08-18 13:35:22 -0600130keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE};
Shawn Willden128ffe02014-08-06 12:31:33 -0600131void GoogleKeymaster::SupportedDigests(keymaster_algorithm_t algorithm,
Shawn Willden3809b932014-12-02 06:59:46 -0700132 keymaster_purpose_t /* purpose */,
Shawn Willden128ffe02014-08-06 12:31:33 -0600133 SupportedResponse<keymaster_digest_t>* response) const {
134 if (response == NULL || !check_supported(algorithm, response))
135 return;
136
137 response->error = KM_ERROR_OK;
138 switch (algorithm) {
139 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600140 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600141 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600142 response->SetResults(supported_digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600143 break;
144 default:
145 response->results_length = 0;
146 break;
147 }
148}
149
Shawn Willden28e41472014-08-18 13:35:22 -0600150keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_PKCS8};
Shawn Willden3809b932014-12-02 06:59:46 -0700151void GoogleKeymaster::SupportedImportFormats(
152 keymaster_algorithm_t algorithm, SupportedResponse<keymaster_key_format_t>* response) const {
Shawn Willden128ffe02014-08-06 12:31:33 -0600153 if (response == NULL || !check_supported(algorithm, response))
154 return;
155
156 response->error = KM_ERROR_OK;
157 switch (algorithm) {
158 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600159 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600160 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600161 response->SetResults(supported_import_formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600162 break;
163 default:
164 response->results_length = 0;
165 break;
166 }
167}
168
Shawn Willden28e41472014-08-18 13:35:22 -0600169keymaster_key_format_t supported_export_formats[] = {KM_KEY_FORMAT_X509};
Shawn Willden3809b932014-12-02 06:59:46 -0700170void GoogleKeymaster::SupportedExportFormats(
171 keymaster_algorithm_t algorithm, SupportedResponse<keymaster_key_format_t>* response) const {
Shawn Willden128ffe02014-08-06 12:31:33 -0600172 if (response == NULL || !check_supported(algorithm, response))
173 return;
174
175 response->error = KM_ERROR_OK;
176 switch (algorithm) {
177 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600178 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600179 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600180 response->SetResults(supported_export_formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600181 break;
182 default:
183 response->results_length = 0;
184 break;
185 }
186}
187
Shawn Willden128ffe02014-08-06 12:31:33 -0600188void GoogleKeymaster::GenerateKey(const GenerateKeyRequest& request,
189 GenerateKeyResponse* response) {
190 if (response == NULL)
191 return;
Shawn Willden128ffe02014-08-06 12:31:33 -0600192
Shawn Willden2f3be362014-08-25 11:31:39 -0600193 UniquePtr<Key> key(Key::GenerateKey(request.key_description, logger(), &response->error));
Shawn Willden76364712014-08-11 17:48:04 -0600194 if (response->error != KM_ERROR_OK)
Shawn Willden128ffe02014-08-06 12:31:33 -0600195 return;
196
Shawn Willden437fbd12014-08-20 11:59:49 -0600197 response->error = SerializeKey(key.get(), origin(), &response->key_blob, &response->enforced,
198 &response->unenforced);
Shawn Willden128ffe02014-08-06 12:31:33 -0600199}
200
Shawn Willden76364712014-08-11 17:48:04 -0600201void GoogleKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
202 GetKeyCharacteristicsResponse* response) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600203 if (response == NULL)
204 return;
205 response->error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden76364712014-08-11 17:48:04 -0600206
Shawn Willden1615f2e2014-08-13 10:37:40 -0600207 UniquePtr<KeyBlob> blob(
208 LoadKeyBlob(request.key_blob, request.additional_params, &(response->error)));
209 if (blob.get() == NULL)
210 return;
211
212 response->enforced.Reinitialize(blob->enforced());
213 response->unenforced.Reinitialize(blob->unenforced());
214 response->error = KM_ERROR_OK;
215}
216
217void GoogleKeymaster::BeginOperation(const BeginOperationRequest& request,
218 BeginOperationResponse* response) {
219 if (response == NULL)
220 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600221 response->op_handle = 0;
222
Shawn Willdend67afae2014-08-19 12:36:27 -0600223 UniquePtr<Key> key(LoadKey(request.key_blob, request.additional_params, &response->error));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600224 if (key.get() == NULL)
225 return;
226
Shawn Willdend67afae2014-08-19 12:36:27 -0600227 UniquePtr<Operation> operation(key->CreateOperation(request.purpose, &response->error));
228 if (operation.get() == NULL)
Shawn Willden76364712014-08-11 17:48:04 -0600229 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600230
231 response->error = operation->Begin();
232 if (response->error != KM_ERROR_OK)
233 return;
234
235 response->error = AddOperation(operation.release(), &response->op_handle);
236}
237
238void GoogleKeymaster::UpdateOperation(const UpdateOperationRequest& request,
239 UpdateOperationResponse* response) {
240 OpTableEntry* entry = FindOperation(request.op_handle);
241 if (entry == NULL) {
242 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
243 return;
244 }
245
Shawn Willden5da34d22015-01-20 11:44:47 -0700246 response->error = entry->operation->Update(request.input, &response->output);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600247 if (response->error != KM_ERROR_OK) {
248 // Any error invalidates the operation.
249 DeleteOperation(entry);
250 }
251}
252
Shawn Willden43e999e2014-08-13 13:29:50 -0600253void GoogleKeymaster::FinishOperation(const FinishOperationRequest& request,
Shawn Willden1615f2e2014-08-13 10:37:40 -0600254 FinishOperationResponse* response) {
Shawn Willden43e999e2014-08-13 13:29:50 -0600255 OpTableEntry* entry = FindOperation(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600256 if (entry == NULL) {
257 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
258 return;
259 }
260
Shawn Willden43e999e2014-08-13 13:29:50 -0600261 response->error = entry->operation->Finish(request.signature, &response->output);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600262 DeleteOperation(entry);
263}
264
265keymaster_error_t GoogleKeymaster::AbortOperation(const keymaster_operation_handle_t op_handle) {
266 OpTableEntry* entry = FindOperation(op_handle);
267 if (entry == NULL)
268 return KM_ERROR_INVALID_OPERATION_HANDLE;
269 DeleteOperation(entry);
270 return KM_ERROR_OK;
Shawn Willden76364712014-08-11 17:48:04 -0600271}
272
Shawn Willdenffd790c2014-08-18 21:20:06 -0600273void GoogleKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
274 if (response == NULL)
275 return;
276
Shawn Willdenf268d742014-08-19 15:36:26 -0600277 UniquePtr<Key> to_export(
278 LoadKey(request.key_blob, request.additional_params, &response->error));
Shawn Willdenffd790c2014-08-18 21:20:06 -0600279 if (to_export.get() == NULL)
280 return;
281
Shawn Willdenf268d742014-08-19 15:36:26 -0600282 UniquePtr<uint8_t[]> out_key;
283 size_t size;
284 response->error = to_export->formatted_key_material(request.key_format, &out_key, &size);
285 if (response->error == KM_ERROR_OK) {
286 response->key_data = out_key.release();
287 response->key_data_length = size;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600288 }
Shawn Willdenffd790c2014-08-18 21:20:06 -0600289}
290
291void GoogleKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600292 if (response == NULL)
Shawn Willdenffd790c2014-08-18 21:20:06 -0600293 return;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600294
Shawn Willden437fbd12014-08-20 11:59:49 -0600295 UniquePtr<Key> key(Key::ImportKey(request.key_description, request.key_format, request.key_data,
Shawn Willden2f3be362014-08-25 11:31:39 -0600296 request.key_data_length, logger(), &response->error));
Shawn Willden437fbd12014-08-20 11:59:49 -0600297 if (response->error != KM_ERROR_OK)
Shawn Willdenffd790c2014-08-18 21:20:06 -0600298 return;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600299
Shawn Willden437fbd12014-08-20 11:59:49 -0600300 response->error = SerializeKey(key.get(), KM_ORIGIN_IMPORTED, &response->key_blob,
301 &response->enforced, &response->unenforced);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600302}
303
Shawn Willden437fbd12014-08-20 11:59:49 -0600304keymaster_error_t GoogleKeymaster::SerializeKey(const Key* key, keymaster_key_origin_t origin,
305 keymaster_key_blob_t* keymaster_blob,
306 AuthorizationSet* enforced,
307 AuthorizationSet* unenforced) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600308 keymaster_error_t error;
309
310 error = SetAuthorizations(key->authorizations(), origin, enforced, unenforced);
311 if (error != KM_ERROR_OK)
312 return error;
313
314 AuthorizationSet hidden_auths;
315 error = BuildHiddenAuthorizations(key->authorizations(), &hidden_auths);
316 if (error != KM_ERROR_OK)
317 return error;
318
319 UniquePtr<uint8_t[]> key_material;
320 size_t key_material_size;
321 error = key->key_material(&key_material, &key_material_size);
322 if (error != KM_ERROR_OK)
323 return error;
324
Shawn Willden39b970b2014-08-11 09:11:21 -0600325 uint8_t nonce[KeyBlob::NONCE_LENGTH];
326 GenerateNonce(nonce, array_size(nonce));
327
Shawn Willden72014ad2014-09-17 13:04:10 -0600328 keymaster_key_blob_t master_key = MasterKey();
329 UniquePtr<KeyBlob> blob(new UnencryptedKeyBlob(
330 *enforced, *unenforced, hidden_auths, key_material.get(), key_material_size,
331 master_key.key_material, master_key.key_material_size, nonce));
Shawn Willdend67afae2014-08-19 12:36:27 -0600332 if (blob.get() == NULL)
333 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdend67afae2014-08-19 12:36:27 -0600334 if (blob->error() != KM_ERROR_OK)
Shawn Willden39b970b2014-08-11 09:11:21 -0600335 return blob->error();
Shawn Willden39b970b2014-08-11 09:11:21 -0600336
337 size_t size = blob->SerializedSize();
338 UniquePtr<uint8_t[]> blob_bytes(new uint8_t[size]);
Shawn Willdend67afae2014-08-19 12:36:27 -0600339 if (blob_bytes.get() == NULL)
340 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
341
Shawn Willden39b970b2014-08-11 09:11:21 -0600342 blob->Serialize(blob_bytes.get(), blob_bytes.get() + size);
Shawn Willden437fbd12014-08-20 11:59:49 -0600343 keymaster_blob->key_material_size = size;
344 keymaster_blob->key_material = blob_bytes.release();
Shawn Willdend67afae2014-08-19 12:36:27 -0600345
346 return KM_ERROR_OK;
347}
348
349Key* GoogleKeymaster::LoadKey(const keymaster_key_blob_t& key,
350 const AuthorizationSet& client_params, keymaster_error_t* error) {
Shawn Willden72014ad2014-09-17 13:04:10 -0600351 UniquePtr<UnencryptedKeyBlob> blob(LoadKeyBlob(key, client_params, error));
Shawn Willdend67afae2014-08-19 12:36:27 -0600352 if (*error != KM_ERROR_OK)
353 return NULL;
Shawn Willden2f3be362014-08-25 11:31:39 -0600354 return Key::CreateKey(*blob, logger(), error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600355}
356
Shawn Willden72014ad2014-09-17 13:04:10 -0600357UnencryptedKeyBlob* GoogleKeymaster::LoadKeyBlob(const keymaster_key_blob_t& key,
358 const AuthorizationSet& client_params,
359 keymaster_error_t* error) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600360 AuthorizationSet hidden;
361 BuildHiddenAuthorizations(client_params, &hidden);
Shawn Willden72014ad2014-09-17 13:04:10 -0600362 keymaster_key_blob_t master_key = MasterKey();
363 UniquePtr<UnencryptedKeyBlob> blob(
364 new UnencryptedKeyBlob(key, hidden, master_key.key_material, master_key.key_material_size));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600365 if (blob.get() == NULL) {
366 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
367 return NULL;
368 } else if (blob->error() != KM_ERROR_OK) {
369 *error = blob->error();
370 return NULL;
371 }
Shawn Willdend67afae2014-08-19 12:36:27 -0600372 *error = KM_ERROR_OK;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600373 return blob.release();
374}
375
Shawn Willden437fbd12014-08-20 11:59:49 -0600376static keymaster_error_t TranslateAuthorizationSetError(AuthorizationSet::Error err) {
377 switch (err) {
Shawn Willden58e1a542014-08-08 21:58:29 -0600378 case AuthorizationSet::OK:
Shawn Willden128ffe02014-08-06 12:31:33 -0600379 return KM_ERROR_OK;
380 case AuthorizationSet::ALLOCATION_FAILURE:
381 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden128ffe02014-08-06 12:31:33 -0600382 case AuthorizationSet::MALFORMED_DATA:
383 return KM_ERROR_UNKNOWN_ERROR;
384 }
385 return KM_ERROR_OK;
386}
387
Shawn Willden437fbd12014-08-20 11:59:49 -0600388keymaster_error_t GoogleKeymaster::SetAuthorizations(const AuthorizationSet& key_description,
389 keymaster_key_origin_t origin,
390 AuthorizationSet* enforced,
391 AuthorizationSet* unenforced) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600392 for (size_t i = 0; i < key_description.size(); ++i) {
393 switch (key_description[i].tag) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600394 // These cannot be specified by the client.
Shawn Willden128ffe02014-08-06 12:31:33 -0600395 case KM_TAG_ROOT_OF_TRUST:
Shawn Willden128ffe02014-08-06 12:31:33 -0600396 case KM_TAG_ORIGIN:
Shawn Willden437fbd12014-08-20 11:59:49 -0600397 return KM_ERROR_INVALID_TAG;
398
399 // These don't work.
Shawn Willden128ffe02014-08-06 12:31:33 -0600400 case KM_TAG_ROLLBACK_RESISTANT:
Shawn Willden437fbd12014-08-20 11:59:49 -0600401 return KM_ERROR_UNSUPPORTED_TAG;
402
403 // These are hidden.
404 case KM_TAG_APPLICATION_ID:
405 case KM_TAG_APPLICATION_DATA:
406 break;
407
408 // Everything else we just copy into the appropriate set.
Shawn Willden128ffe02014-08-06 12:31:33 -0600409 default:
Shawn Willden437fbd12014-08-20 11:59:49 -0600410 AddAuthorization(key_description[i], enforced, unenforced);
Shawn Willden128ffe02014-08-06 12:31:33 -0600411 break;
412 }
413 }
414
Shawn Willden437fbd12014-08-20 11:59:49 -0600415 AddAuthorization(Authorization(TAG_CREATION_DATETIME, java_time(time(NULL))), enforced,
416 unenforced);
417 AddAuthorization(Authorization(TAG_ORIGIN, origin), enforced, unenforced);
Shawn Willden128ffe02014-08-06 12:31:33 -0600418
Shawn Willden437fbd12014-08-20 11:59:49 -0600419 if (enforced->is_valid() != AuthorizationSet::OK)
420 return TranslateAuthorizationSetError(enforced->is_valid());
Shawn Willden128ffe02014-08-06 12:31:33 -0600421
Shawn Willden437fbd12014-08-20 11:59:49 -0600422 return TranslateAuthorizationSetError(unenforced->is_valid());
Shawn Willden128ffe02014-08-06 12:31:33 -0600423}
424
Shawn Willden76364712014-08-11 17:48:04 -0600425keymaster_error_t GoogleKeymaster::BuildHiddenAuthorizations(const AuthorizationSet& input_set,
Shawn Willden1615f2e2014-08-13 10:37:40 -0600426 AuthorizationSet* hidden) {
Shawn Willden76364712014-08-11 17:48:04 -0600427 keymaster_blob_t entry;
428 if (input_set.GetTagValue(TAG_APPLICATION_ID, &entry))
429 hidden->push_back(TAG_APPLICATION_ID, entry.data, entry.data_length);
430 if (input_set.GetTagValue(TAG_APPLICATION_DATA, &entry))
431 hidden->push_back(TAG_APPLICATION_DATA, entry.data, entry.data_length);
432 hidden->push_back(RootOfTrustTag());
433
Shawn Willden437fbd12014-08-20 11:59:49 -0600434 return TranslateAuthorizationSetError(hidden->is_valid());
Shawn Willden76364712014-08-11 17:48:04 -0600435}
436
Shawn Willden437fbd12014-08-20 11:59:49 -0600437void GoogleKeymaster::AddAuthorization(const keymaster_key_param_t& auth,
438 AuthorizationSet* enforced, AuthorizationSet* unenforced) {
439 if (is_enforced(auth.tag))
440 enforced->push_back(auth);
441 else
442 unenforced->push_back(auth);
Shawn Willden128ffe02014-08-06 12:31:33 -0600443}
444
Shawn Willden1615f2e2014-08-13 10:37:40 -0600445keymaster_error_t GoogleKeymaster::AddOperation(Operation* operation,
446 keymaster_operation_handle_t* op_handle) {
447 UniquePtr<Operation> op(operation);
448 if (RAND_bytes(reinterpret_cast<uint8_t*>(op_handle), sizeof(*op_handle)) == 0)
449 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden802bb292014-08-18 10:46:29 -0600450 if (*op_handle == 0) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600451 // Statistically this is vanishingly unlikely, which means if it ever happens in practice,
452 // it indicates a broken RNG.
453 return KM_ERROR_UNKNOWN_ERROR;
454 }
455 for (size_t i = 0; i < operation_table_size_; ++i) {
456 if (operation_table_[i].operation == NULL) {
457 operation_table_[i].operation = op.release();
458 operation_table_[i].handle = *op_handle;
459 return KM_ERROR_OK;
460 }
461 }
462 return KM_ERROR_TOO_MANY_OPERATIONS;
463}
464
465GoogleKeymaster::OpTableEntry*
466GoogleKeymaster::FindOperation(keymaster_operation_handle_t op_handle) {
467 if (op_handle == 0)
468 return NULL;
469
470 for (size_t i = 0; i < operation_table_size_; ++i) {
471 if (operation_table_[i].handle == op_handle)
472 return operation_table_.get() + i;
473 }
474 return NULL;
475}
476
477void GoogleKeymaster::DeleteOperation(OpTableEntry* entry) {
478 delete entry->operation;
479 entry->operation = NULL;
480 entry->handle = 0;
481}
482
Shawn Willden128ffe02014-08-06 12:31:33 -0600483} // namespace keymaster