blob: df3373c4236b049fa9168e9574ec6fa5f640c62a [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 Willden3879f862014-08-06 14:40:48 -060027#include "ae.h"
Shawn Willden28e41472014-08-18 13:35:22 -060028#include "dsa_operation.h"
Shawn Willdenc3864dd2014-08-18 15:20:01 -060029#include "ecdsa_operation.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060030#include "google_keymaster.h"
31#include "google_keymaster_utils.h"
Shawn Willden4db3fbd2014-08-08 22:13:44 -060032#include "key_blob.h"
Shawn Willden1615f2e2014-08-13 10:37:40 -060033#include "rsa_operation.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060034
35namespace keymaster {
36
Shawn Willden1615f2e2014-08-13 10:37:40 -060037GoogleKeymaster::GoogleKeymaster(size_t operation_table_size)
38 : operation_table_(new OpTableEntry[operation_table_size]),
39 operation_table_size_(operation_table_size) {
40 if (operation_table_.get() == NULL)
41 operation_table_size_ = 0;
Shawn Willden39b970b2014-08-11 09:11:21 -060042}
43GoogleKeymaster::~GoogleKeymaster() {
Shawn Willden1615f2e2014-08-13 10:37:40 -060044 for (size_t i = 0; i < operation_table_size_; ++i)
45 if (operation_table_[i].operation != NULL)
46 delete operation_table_[i].operation;
Shawn Willden39b970b2014-08-11 09:11:21 -060047}
Shawn Willden128ffe02014-08-06 12:31:33 -060048
Shawn Willden28e41472014-08-18 13:35:22 -060049const uint32_t RSA_DEFAULT_KEY_SIZE = 2048;
50const uint32_t DSA_DEFAULT_KEY_SIZE = 2048;
51const uint64_t RSA_DEFAULT_EXPONENT = 65537;
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 Willdenffd790c2014-08-18 21:20:06 -060058struct EVP_PKEY_Delete {
59 void operator()(EVP_PKEY* p) { EVP_PKEY_free(p); }
60};
61typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
62
63struct PKCS8_PRIV_KEY_INFO_Delete {
64 void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); }
65};
66typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
67
Shawn Willden128ffe02014-08-06 12:31:33 -060068keymaster_algorithm_t supported_algorithms[] = {
Shawn Willdenc3864dd2014-08-18 15:20:01 -060069 KM_ALGORITHM_RSA, KM_ALGORITHM_DSA, KM_ALGORITHM_ECDSA,
Shawn Willden128ffe02014-08-06 12:31:33 -060070};
71
72template <typename T>
73bool check_supported(keymaster_algorithm_t algorithm, SupportedResponse<T>* response) {
74 if (!array_contains(supported_algorithms, algorithm)) {
75 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
76 return false;
77 }
78 return true;
79}
80
81void
82GoogleKeymaster::SupportedAlgorithms(SupportedResponse<keymaster_algorithm_t>* response) const {
83 if (response == NULL)
84 return;
85 response->SetResults(supported_algorithms);
86}
87
88void
89GoogleKeymaster::SupportedBlockModes(keymaster_algorithm_t algorithm,
90 SupportedResponse<keymaster_block_mode_t>* response) const {
91 if (response == NULL || !check_supported(algorithm, response))
92 return;
93 response->error = KM_ERROR_OK;
94}
95
Shawn Willden28e41472014-08-18 13:35:22 -060096keymaster_padding_t supported_padding[] = {KM_PAD_NONE};
Shawn Willden128ffe02014-08-06 12:31:33 -060097void
98GoogleKeymaster::SupportedPaddingModes(keymaster_algorithm_t algorithm,
99 SupportedResponse<keymaster_padding_t>* response) const {
100 if (response == NULL || !check_supported(algorithm, response))
101 return;
102
103 response->error = KM_ERROR_OK;
104 switch (algorithm) {
105 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600106 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600107 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600108 response->SetResults(supported_padding);
Shawn Willden128ffe02014-08-06 12:31:33 -0600109 break;
110 default:
111 response->results_length = 0;
112 break;
113 }
114}
115
Shawn Willden28e41472014-08-18 13:35:22 -0600116keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE};
Shawn Willden128ffe02014-08-06 12:31:33 -0600117void GoogleKeymaster::SupportedDigests(keymaster_algorithm_t algorithm,
118 SupportedResponse<keymaster_digest_t>* response) const {
119 if (response == NULL || !check_supported(algorithm, response))
120 return;
121
122 response->error = KM_ERROR_OK;
123 switch (algorithm) {
124 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600125 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600126 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600127 response->SetResults(supported_digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600128 break;
129 default:
130 response->results_length = 0;
131 break;
132 }
133}
134
Shawn Willden28e41472014-08-18 13:35:22 -0600135keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_PKCS8};
Shawn Willden128ffe02014-08-06 12:31:33 -0600136void
137GoogleKeymaster::SupportedImportFormats(keymaster_algorithm_t algorithm,
138 SupportedResponse<keymaster_key_format_t>* response) const {
139 if (response == NULL || !check_supported(algorithm, response))
140 return;
141
142 response->error = KM_ERROR_OK;
143 switch (algorithm) {
144 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600145 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600146 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600147 response->SetResults(supported_import_formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600148 break;
149 default:
150 response->results_length = 0;
151 break;
152 }
153}
154
Shawn Willden28e41472014-08-18 13:35:22 -0600155keymaster_key_format_t supported_export_formats[] = {KM_KEY_FORMAT_X509};
Shawn Willden128ffe02014-08-06 12:31:33 -0600156void
157GoogleKeymaster::SupportedExportFormats(keymaster_algorithm_t algorithm,
158 SupportedResponse<keymaster_key_format_t>* response) const {
159 if (response == NULL || !check_supported(algorithm, response))
160 return;
161
162 response->error = KM_ERROR_OK;
163 switch (algorithm) {
164 case KM_ALGORITHM_RSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600165 case KM_ALGORITHM_DSA:
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600166 case KM_ALGORITHM_ECDSA:
Shawn Willden28e41472014-08-18 13:35:22 -0600167 response->SetResults(supported_export_formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600168 break;
169 default:
170 response->results_length = 0;
171 break;
172 }
173}
174
Shawn Willden128ffe02014-08-06 12:31:33 -0600175void GoogleKeymaster::GenerateKey(const GenerateKeyRequest& request,
176 GenerateKeyResponse* response) {
177 if (response == NULL)
178 return;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600179 response->error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden128ffe02014-08-06 12:31:33 -0600180
Shawn Willden76364712014-08-11 17:48:04 -0600181 if (!CopyAuthorizations(request.key_description, response))
182 return;
183
Shawn Willden39b970b2014-08-11 09:11:21 -0600184 AuthorizationSet hidden_auths;
Shawn Willden76364712014-08-11 17:48:04 -0600185 response->error = BuildHiddenAuthorizations(request.key_description, &hidden_auths);
186 if (response->error != KM_ERROR_OK)
Shawn Willden128ffe02014-08-06 12:31:33 -0600187 return;
188
189 keymaster_algorithm_t algorithm;
190 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm)) {
191 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
192 return;
193 }
Shawn Willden28e41472014-08-18 13:35:22 -0600194
Shawn Willden128ffe02014-08-06 12:31:33 -0600195 switch (algorithm) {
196 case KM_ALGORITHM_RSA:
Shawn Willden39b970b2014-08-11 09:11:21 -0600197 if (!GenerateRsa(request.key_description, response, &hidden_auths))
Shawn Willden128ffe02014-08-06 12:31:33 -0600198 return;
199 break;
Shawn Willden28e41472014-08-18 13:35:22 -0600200 case KM_ALGORITHM_DSA:
201 if (!GenerateDsa(request.key_description, response, &hidden_auths))
202 return;
203 break;
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600204 case KM_ALGORITHM_ECDSA:
205 if (!GenerateEcdsa(request.key_description, response, &hidden_auths))
206 return;
207 break;
Shawn Willden128ffe02014-08-06 12:31:33 -0600208 default:
209 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
210 return;
211 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600212
213 response->error = KM_ERROR_OK;
Shawn Willden128ffe02014-08-06 12:31:33 -0600214}
215
Shawn Willden76364712014-08-11 17:48:04 -0600216void GoogleKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
217 GetKeyCharacteristicsResponse* response) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600218 if (response == NULL)
219 return;
220 response->error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden76364712014-08-11 17:48:04 -0600221
Shawn Willden1615f2e2014-08-13 10:37:40 -0600222 UniquePtr<KeyBlob> blob(
223 LoadKeyBlob(request.key_blob, request.additional_params, &(response->error)));
224 if (blob.get() == NULL)
225 return;
226
227 response->enforced.Reinitialize(blob->enforced());
228 response->unenforced.Reinitialize(blob->unenforced());
229 response->error = KM_ERROR_OK;
230}
231
232void GoogleKeymaster::BeginOperation(const BeginOperationRequest& request,
233 BeginOperationResponse* response) {
234 if (response == NULL)
235 return;
236 response->error = KM_ERROR_UNKNOWN_ERROR;
237 response->op_handle = 0;
238
239 UniquePtr<KeyBlob> key(
240 LoadKeyBlob(request.key_blob, request.additional_params, &response->error));
241 if (key.get() == NULL)
242 return;
243
244 UniquePtr<Operation> operation;
245 switch (key->algorithm()) {
246 case KM_ALGORITHM_RSA:
247 operation.reset(new RsaOperation(request.purpose, *key));
248 break;
Shawn Willden5b41ca22014-08-18 14:29:14 -0600249 case KM_ALGORITHM_DSA:
250 operation.reset(new DsaOperation(request.purpose, *key));
251 break;
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600252 case KM_ALGORITHM_ECDSA:
253 operation.reset(new EcdsaOperation(request.purpose, *key));
254 break;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600255 default:
256 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
257 break;
258 }
259
260 if (operation.get() == NULL) {
Shawn Willden76364712014-08-11 17:48:04 -0600261 return;
262 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600263
264 response->error = operation->Begin();
265 if (response->error != KM_ERROR_OK)
266 return;
267
268 response->error = AddOperation(operation.release(), &response->op_handle);
269}
270
271void GoogleKeymaster::UpdateOperation(const UpdateOperationRequest& request,
272 UpdateOperationResponse* response) {
273 OpTableEntry* entry = FindOperation(request.op_handle);
274 if (entry == NULL) {
275 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
276 return;
277 }
278
279 response->error = entry->operation->Update(request.input, &response->output);
280 if (response->error != KM_ERROR_OK) {
281 // Any error invalidates the operation.
282 DeleteOperation(entry);
283 }
284}
285
Shawn Willden43e999e2014-08-13 13:29:50 -0600286void GoogleKeymaster::FinishOperation(const FinishOperationRequest& request,
Shawn Willden1615f2e2014-08-13 10:37:40 -0600287 FinishOperationResponse* response) {
Shawn Willden43e999e2014-08-13 13:29:50 -0600288 OpTableEntry* entry = FindOperation(request.op_handle);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600289 if (entry == NULL) {
290 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
291 return;
292 }
293
Shawn Willden43e999e2014-08-13 13:29:50 -0600294 response->error = entry->operation->Finish(request.signature, &response->output);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600295 DeleteOperation(entry);
296}
297
298keymaster_error_t GoogleKeymaster::AbortOperation(const keymaster_operation_handle_t op_handle) {
299 OpTableEntry* entry = FindOperation(op_handle);
300 if (entry == NULL)
301 return KM_ERROR_INVALID_OPERATION_HANDLE;
302 DeleteOperation(entry);
303 return KM_ERROR_OK;
Shawn Willden76364712014-08-11 17:48:04 -0600304}
305
Shawn Willdenffd790c2014-08-18 21:20:06 -0600306bool GoogleKeymaster::is_supported_export_format(keymaster_key_format_t test_format) {
307 unsigned int index;
308 for (index = 0; index < array_length(supported_export_formats); index++) {
309 if (test_format == supported_export_formats[index]) {
310 return true;
311 }
312 }
313
314 return false;
315}
316
317bool GoogleKeymaster::is_supported_import_format(keymaster_key_format_t test_format) {
318 unsigned int index;
319 for (index = 0; index < array_length(supported_import_formats); index++) {
320 if (test_format == supported_import_formats[index]) {
321 return true;
322 }
323 }
324
325 return false;
326}
327
328void GoogleKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
329 if (response == NULL)
330 return;
331
332 keymaster_error_t blob_error;
333 UniquePtr<KeyBlob> to_export(
334 LoadKeyBlob(request.key_blob, request.additional_params, &response->error));
335 if (to_export.get() == NULL)
336 return;
337
338 Unique_EVP_PKEY pkey(EVP_PKEY_new());
339 if (pkey.get() == NULL) {
340 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
341 return;
342 }
343
344 EVP_PKEY* pkey_tmp = pkey.get();
345 const uint8_t* km_tmp = to_export->key_material();
346 if (d2i_PrivateKey(EVP_PKEY_RSA, &pkey_tmp, &km_tmp, to_export->key_material_length()) ==
347 NULL) {
348 response->error = KM_ERROR_INVALID_KEY_BLOB;
349 return;
350 }
351
352 int len = i2d_PUBKEY(pkey.get(), NULL);
353 if (len <= 0) {
354 response->error = KM_ERROR_UNKNOWN_ERROR;
355 return;
356 }
357
358 UniquePtr<uint8_t[]> out_key(new uint8_t[len]);
359 if (out_key.get() == NULL) {
360 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
361 return;
362 }
363
364 uint8_t* tmp = out_key.get();
365 if (i2d_PUBKEY(pkey.get(), &tmp) != len) {
366 fprintf(stderr, "i2d_pubkey(x, len) failed.\n");
367 response->error = KM_ERROR_INVALID_KEY_BLOB;
368
369 return;
370 }
371
372 response->key_data = out_key.release();
373 response->error = KM_ERROR_OK;
374}
375
376void GoogleKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
377
378 if (request.key_data == NULL || request.key_data_length <= 0) {
379 response->error = KM_ERROR_INVALID_KEY_BLOB;
380 return;
381 }
382
383 if (!is_supported_export_format(request.key_format)) {
384 response->error = KM_ERROR_UNSUPPORTED_KEY_FORMAT;
385 return;
386 }
387
388 const uint8_t* key_data = request.key_data;
389 Unique_PKCS8_PRIV_KEY_INFO pkcs8(
390 d2i_PKCS8_PRIV_KEY_INFO(NULL, &key_data, request.key_data_length));
391 if (pkcs8.get() == NULL) {
392 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
393 return;
394 }
395
396 Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
397 if (pkey.get() == NULL) {
398 response->error = KM_ERROR_INVALID_KEY_BLOB;
399 return;
400 }
401
402 int len = i2d_PrivateKey(pkey.get(), NULL);
403 if (len <= 0) {
404 response->error = KM_ERROR_INVALID_KEY_BLOB;
405 return;
406 }
407
408 UniquePtr<uint8_t[]> der_encoded_key(new uint8_t[len]);
409 if (der_encoded_key.get() == NULL) {
410 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
411 return;
412 }
413
414 uint8_t* tmp_der = der_encoded_key.get();
415 if (i2d_PrivateKey(pkey.get(), &tmp_der) != len) {
416 response->error = KM_ERROR_INVALID_KEY_BLOB;
417 return;
418 }
419
420 void* key_material = der_encoded_key.release();
421 response->SetKeyMaterial(key_material, len);
422
423 response->error = KM_ERROR_OK;
424}
425
Shawn Willden39b970b2014-08-11 09:11:21 -0600426bool GoogleKeymaster::GenerateRsa(const AuthorizationSet& key_auths, GenerateKeyResponse* response,
427 AuthorizationSet* hidden_auths) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600428 uint64_t public_exponent = RSA_DEFAULT_EXPONENT;
429 if (!key_auths.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent))
Shawn Willden76364712014-08-11 17:48:04 -0600430 AddAuthorization(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent), response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600431
432 uint32_t key_size = RSA_DEFAULT_KEY_SIZE;
433 if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
Shawn Willden76364712014-08-11 17:48:04 -0600434 AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600435
Shawn Willden802bb292014-08-18 10:46:29 -0600436 UniquePtr<uint8_t[]> key_data;
437 size_t key_data_size;
438 keymaster_error_t error =
439 RsaOperation::Generate(public_exponent, key_size, &key_data, &key_data_size);
440 if (error != KM_ERROR_OK) {
441 response->error = error;
Shawn Willden128ffe02014-08-06 12:31:33 -0600442 return false;
443 }
444
Shawn Willden802bb292014-08-18 10:46:29 -0600445 return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
Shawn Willden39b970b2014-08-11 09:11:21 -0600446}
447
Shawn Willden28e41472014-08-18 13:35:22 -0600448template <keymaster_tag_t Tag>
449static void GetDsaParamData(const AuthorizationSet& auths, TypedTag<KM_BIGNUM, Tag> tag,
450 keymaster_blob_t* blob) {
451 if (!auths.GetTagValue(tag, blob))
452 blob->data = NULL;
453}
454
455bool GoogleKeymaster::GenerateDsa(const AuthorizationSet& key_auths, GenerateKeyResponse* response,
456 AuthorizationSet* hidden_auths) {
457 keymaster_blob_t g_blob;
458 GetDsaParamData(key_auths, TAG_DSA_GENERATOR, &g_blob);
459 const uint8_t* original_g = g_blob.data;
460
461 keymaster_blob_t p_blob;
462 GetDsaParamData(key_auths, TAG_DSA_P, &p_blob);
463 const uint8_t* original_p = p_blob.data;
464
465 keymaster_blob_t q_blob;
466 GetDsaParamData(key_auths, TAG_DSA_Q, &q_blob);
467 const uint8_t* original_q = q_blob.data;
468
469 uint32_t key_size = DSA_DEFAULT_KEY_SIZE;
470 if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
471 AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
472
473 UniquePtr<uint8_t[]> key_data;
474 size_t key_data_size;
475 keymaster_error_t error =
476 DsaOperation::Generate(key_size, &g_blob, &p_blob, &q_blob, &key_data, &key_data_size);
477
478 // If any the original_* pointers are NULL, DsaOperation::Generate should have generated values
479 // for the corressponding blobs. We need to put them in the authorization set and clean up the
480 // allocated memory.
481 if (original_g == NULL && g_blob.data != NULL) {
482 if (!AddAuthorization(Authorization(TAG_DSA_GENERATOR, g_blob), response))
483 error = KM_ERROR_INVALID_DSA_PARAMS;
484 delete[] g_blob.data;
485 }
486 if (original_p == NULL && p_blob.data != NULL) {
487 if (!AddAuthorization(Authorization(TAG_DSA_P, p_blob), response))
488 error = KM_ERROR_INVALID_DSA_PARAMS;
489 delete[] p_blob.data;
490 }
491 if (original_q == NULL && q_blob.data != NULL) {
492 if (!AddAuthorization(Authorization(TAG_DSA_Q, q_blob), response))
493 error = KM_ERROR_INVALID_DSA_PARAMS;
494 delete[] q_blob.data;
495 }
496
497 if (error != KM_ERROR_OK) {
498 response->error = error;
499 return false;
500 }
501
502 return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
503}
504
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600505bool GoogleKeymaster::GenerateEcdsa(const AuthorizationSet& key_auths,
506 GenerateKeyResponse* response, AuthorizationSet* hidden_auths) {
507 uint64_t public_exponent = RSA_DEFAULT_EXPONENT;
508 if (!key_auths.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent))
509 AddAuthorization(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent), response);
510
511 uint32_t key_size = RSA_DEFAULT_KEY_SIZE;
512 if (!key_auths.GetTagValue(TAG_KEY_SIZE, &key_size))
513 AddAuthorization(Authorization(TAG_KEY_SIZE, key_size), response);
514
515 UniquePtr<uint8_t[]> key_data;
516 size_t key_data_size;
517 keymaster_error_t error = EcdsaOperation::Generate(key_size, &key_data, &key_data_size);
518 if (error != KM_ERROR_OK) {
519 response->error = error;
520 return false;
521 }
522
523 return CreateKeyBlob(response, *hidden_auths, key_data.get(), key_data_size);
524}
525
Shawn Willden39b970b2014-08-11 09:11:21 -0600526bool GoogleKeymaster::CreateKeyBlob(GenerateKeyResponse* response,
527 const AuthorizationSet& hidden_auths, uint8_t* key_bytes,
528 size_t key_length) {
529 uint8_t nonce[KeyBlob::NONCE_LENGTH];
530 GenerateNonce(nonce, array_size(nonce));
531
532 keymaster_key_blob_t key_data = {key_bytes, key_length};
533 UniquePtr<KeyBlob> blob(new KeyBlob(response->enforced, response->unenforced, hidden_auths,
534 key_data, MasterKey(), nonce));
535 if (blob.get() == NULL) {
536 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
537 return false;
538 }
539
540 if (blob->error() != KM_ERROR_OK) {
541 return blob->error();
542 return false;
543 }
544
545 size_t size = blob->SerializedSize();
546 UniquePtr<uint8_t[]> blob_bytes(new uint8_t[size]);
547 if (blob_bytes.get() == NULL) {
548 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
549 return false;
550 }
551 blob->Serialize(blob_bytes.get(), blob_bytes.get() + size);
552 response->key_blob.key_material_size = size;
553 response->key_blob.key_material = blob_bytes.release();
554 return true;
Shawn Willden128ffe02014-08-06 12:31:33 -0600555}
556
Shawn Willden1615f2e2014-08-13 10:37:40 -0600557KeyBlob* GoogleKeymaster::LoadKeyBlob(const keymaster_key_blob_t& key,
558 const AuthorizationSet& client_params,
559 keymaster_error_t* error) {
560 AuthorizationSet hidden;
561 BuildHiddenAuthorizations(client_params, &hidden);
562 UniquePtr<KeyBlob> blob(new KeyBlob(key, hidden, MasterKey()));
563 if (blob.get() == NULL) {
564 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
565 return NULL;
566 } else if (blob->error() != KM_ERROR_OK) {
567 *error = blob->error();
568 return NULL;
569 }
570 return blob.release();
571}
572
Shawn Willden128ffe02014-08-06 12:31:33 -0600573static keymaster_error_t CheckAuthorizationSet(const AuthorizationSet& set) {
574 switch (set.is_valid()) {
Shawn Willden58e1a542014-08-08 21:58:29 -0600575 case AuthorizationSet::OK:
Shawn Willden128ffe02014-08-06 12:31:33 -0600576 return KM_ERROR_OK;
577 case AuthorizationSet::ALLOCATION_FAILURE:
578 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden128ffe02014-08-06 12:31:33 -0600579 case AuthorizationSet::MALFORMED_DATA:
580 return KM_ERROR_UNKNOWN_ERROR;
581 }
582 return KM_ERROR_OK;
583}
584
585bool GoogleKeymaster::CopyAuthorizations(const AuthorizationSet& key_description,
Shawn Willden76364712014-08-11 17:48:04 -0600586 GenerateKeyResponse* response) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600587 for (size_t i = 0; i < key_description.size(); ++i) {
588 switch (key_description[i].tag) {
589 case KM_TAG_ROOT_OF_TRUST:
590 case KM_TAG_CREATION_DATETIME:
591 case KM_TAG_ORIGIN:
592 response->error = KM_ERROR_INVALID_TAG;
593 return false;
594 case KM_TAG_ROLLBACK_RESISTANT:
595 response->error = KM_ERROR_UNSUPPORTED_TAG;
596 return false;
597 default:
Shawn Willden28e41472014-08-18 13:35:22 -0600598 if (!AddAuthorization(key_description[i], response))
599 return false;
Shawn Willden128ffe02014-08-06 12:31:33 -0600600 break;
601 }
602 }
603
Shawn Willden28e41472014-08-18 13:35:22 -0600604 if (!AddAuthorization(Authorization(TAG_CREATION_DATETIME, java_time(time(NULL))), response) ||
605 !AddAuthorization(Authorization(TAG_ORIGIN, origin()), response))
606 return false;
Shawn Willden128ffe02014-08-06 12:31:33 -0600607
608 response->error = CheckAuthorizationSet(response->enforced);
609 if (response->error != KM_ERROR_OK)
610 return false;
611 response->error = CheckAuthorizationSet(response->unenforced);
612 if (response->error != KM_ERROR_OK)
613 return false;
614
615 return true;
616}
617
Shawn Willden76364712014-08-11 17:48:04 -0600618keymaster_error_t GoogleKeymaster::BuildHiddenAuthorizations(const AuthorizationSet& input_set,
Shawn Willden1615f2e2014-08-13 10:37:40 -0600619 AuthorizationSet* hidden) {
Shawn Willden76364712014-08-11 17:48:04 -0600620 keymaster_blob_t entry;
621 if (input_set.GetTagValue(TAG_APPLICATION_ID, &entry))
622 hidden->push_back(TAG_APPLICATION_ID, entry.data, entry.data_length);
623 if (input_set.GetTagValue(TAG_APPLICATION_DATA, &entry))
624 hidden->push_back(TAG_APPLICATION_DATA, entry.data, entry.data_length);
625 hidden->push_back(RootOfTrustTag());
626
627 return CheckAuthorizationSet(*hidden);
628}
629
Shawn Willden28e41472014-08-18 13:35:22 -0600630bool GoogleKeymaster::AddAuthorization(const keymaster_key_param_t& auth,
Shawn Willden76364712014-08-11 17:48:04 -0600631 GenerateKeyResponse* response) {
Shawn Willden39b970b2014-08-11 09:11:21 -0600632 switch (auth.tag) {
633 case KM_TAG_ROOT_OF_TRUST:
634 case KM_TAG_APPLICATION_ID:
635 case KM_TAG_APPLICATION_DATA:
Shawn Willden76364712014-08-11 17:48:04 -0600636 // Skip. We handle these tags separately.
Shawn Willden28e41472014-08-18 13:35:22 -0600637 return true;
Shawn Willden39b970b2014-08-11 09:11:21 -0600638 default:
639 if (is_enforced(auth.tag))
Shawn Willden28e41472014-08-18 13:35:22 -0600640 return response->enforced.push_back(auth);
Shawn Willden39b970b2014-08-11 09:11:21 -0600641 else
Shawn Willden28e41472014-08-18 13:35:22 -0600642 return response->unenforced.push_back(auth);
Shawn Willden39b970b2014-08-11 09:11:21 -0600643 }
Shawn Willden128ffe02014-08-06 12:31:33 -0600644}
645
Shawn Willden1615f2e2014-08-13 10:37:40 -0600646keymaster_error_t GoogleKeymaster::AddOperation(Operation* operation,
647 keymaster_operation_handle_t* op_handle) {
648 UniquePtr<Operation> op(operation);
649 if (RAND_bytes(reinterpret_cast<uint8_t*>(op_handle), sizeof(*op_handle)) == 0)
650 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden802bb292014-08-18 10:46:29 -0600651 if (*op_handle == 0) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600652 // Statistically this is vanishingly unlikely, which means if it ever happens in practice,
653 // it indicates a broken RNG.
654 return KM_ERROR_UNKNOWN_ERROR;
655 }
656 for (size_t i = 0; i < operation_table_size_; ++i) {
657 if (operation_table_[i].operation == NULL) {
658 operation_table_[i].operation = op.release();
659 operation_table_[i].handle = *op_handle;
660 return KM_ERROR_OK;
661 }
662 }
663 return KM_ERROR_TOO_MANY_OPERATIONS;
664}
665
666GoogleKeymaster::OpTableEntry*
667GoogleKeymaster::FindOperation(keymaster_operation_handle_t op_handle) {
668 if (op_handle == 0)
669 return NULL;
670
671 for (size_t i = 0; i < operation_table_size_; ++i) {
672 if (operation_table_[i].handle == op_handle)
673 return operation_table_.get() + i;
674 }
675 return NULL;
676}
677
678void GoogleKeymaster::DeleteOperation(OpTableEntry* entry) {
679 delete entry->operation;
680 entry->operation = NULL;
681 entry->handle = 0;
682}
683
Shawn Willden128ffe02014-08-06 12:31:33 -0600684} // namespace keymaster