1 /*
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 <keymaster/android_keymaster.h>
18
19 #include <assert.h>
20 #include <string.h>
21
22 #include <stddef.h>
23
24 #include <keymaster/UniquePtr.h>
25 #include <keymaster/android_keymaster_utils.h>
26 #include <keymaster/key.h>
27 #include <keymaster/key_blob_utils/ae.h>
28 #include <keymaster/key_factory.h>
29 #include <keymaster/keymaster_context.h>
30 #include <keymaster/km_openssl/openssl_err.h>
31 #include <keymaster/operation.h>
32 #include <keymaster/operation_table.h>
33
34 namespace keymaster {
35
36 namespace {
37
38 const uint8_t MAJOR_VER = 2;
39 const uint8_t MINOR_VER = 0;
40 const uint8_t SUBMINOR_VER = 0;
41
CheckVersionInfo(const AuthorizationSet & tee_enforced,const AuthorizationSet & sw_enforced,const KeymasterContext & context)42 keymaster_error_t CheckVersionInfo(const AuthorizationSet& tee_enforced,
43 const AuthorizationSet& sw_enforced,
44 const KeymasterContext& context) {
45 uint32_t os_version;
46 uint32_t os_patchlevel;
47 context.GetSystemVersion(&os_version, &os_patchlevel);
48
49 uint32_t key_os_patchlevel;
50 if (tee_enforced.GetTagValue(TAG_OS_PATCHLEVEL, &key_os_patchlevel) ||
51 sw_enforced.GetTagValue(TAG_OS_PATCHLEVEL, &key_os_patchlevel)) {
52 if (key_os_patchlevel < os_patchlevel)
53 return KM_ERROR_KEY_REQUIRES_UPGRADE;
54 else if (key_os_patchlevel > os_patchlevel)
55 return KM_ERROR_INVALID_KEY_BLOB;
56 }
57
58 return KM_ERROR_OK;
59 }
60
61 } // anonymous namespace
62
AndroidKeymaster(KeymasterContext * context,size_t operation_table_size)63 AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size)
64 : context_(context), operation_table_(new(std::nothrow) OperationTable(operation_table_size)) {}
65
~AndroidKeymaster()66 AndroidKeymaster::~AndroidKeymaster() {}
67
AndroidKeymaster(AndroidKeymaster && other)68 AndroidKeymaster::AndroidKeymaster(AndroidKeymaster&& other)
69 : context_(move(other.context_)), operation_table_(move(other.operation_table_)) {}
70
71 // TODO(swillden): Unify support analysis. Right now, we have per-keytype methods that determine if
72 // specific modes, padding, etc. are supported for that key type, and AndroidKeymaster also has
73 // methods that return the same information. They'll get out of sync. Best to put the knowledge in
74 // the keytypes and provide some mechanism for AndroidKeymaster to query the keytypes for the
75 // information.
76
77 template <typename T>
check_supported(const KeymasterContext & context,keymaster_algorithm_t algorithm,SupportedResponse<T> * response)78 bool check_supported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
79 SupportedResponse<T>* response) {
80 if (context.GetKeyFactory(algorithm) == NULL) {
81 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
82 return false;
83 }
84 return true;
85 }
86
GetVersion(const GetVersionRequest &,GetVersionResponse * rsp)87 void AndroidKeymaster::GetVersion(const GetVersionRequest&, GetVersionResponse* rsp) {
88 if (rsp == NULL)
89 return;
90
91 rsp->major_ver = MAJOR_VER;
92 rsp->minor_ver = MINOR_VER;
93 rsp->subminor_ver = SUBMINOR_VER;
94 rsp->error = KM_ERROR_OK;
95 }
96
SupportedAlgorithms(const SupportedAlgorithmsRequest &,SupportedAlgorithmsResponse * response)97 void AndroidKeymaster::SupportedAlgorithms(const SupportedAlgorithmsRequest& /* request */,
98 SupportedAlgorithmsResponse* response) {
99 if (response == NULL)
100 return;
101
102 response->error = KM_ERROR_OK;
103
104 size_t algorithm_count = 0;
105 const keymaster_algorithm_t* algorithms = context_->GetSupportedAlgorithms(&algorithm_count);
106 if (algorithm_count == 0)
107 return;
108 response->results_length = algorithm_count;
109 response->results = dup_array(algorithms, algorithm_count);
110 if (!response->results)
111 response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
112 }
113
114 template <typename T>
GetSupported(const KeymasterContext & context,keymaster_algorithm_t algorithm,keymaster_purpose_t purpose,const T * (OperationFactory::* get_supported_method)(size_t * count)const,SupportedResponse<T> * response)115 void GetSupported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
116 keymaster_purpose_t purpose,
117 const T* (OperationFactory::*get_supported_method)(size_t* count) const,
118 SupportedResponse<T>* response) {
119 if (response == NULL || !check_supported(context, algorithm, response))
120 return;
121
122 const OperationFactory* factory = context.GetOperationFactory(algorithm, purpose);
123 if (!factory) {
124 response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
125 return;
126 }
127
128 size_t count;
129 const T* supported = (factory->*get_supported_method)(&count);
130 response->SetResults(supported, count);
131 }
132
SupportedBlockModes(const SupportedBlockModesRequest & request,SupportedBlockModesResponse * response)133 void AndroidKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
134 SupportedBlockModesResponse* response) {
135 GetSupported(*context_, request.algorithm, request.purpose,
136 &OperationFactory::SupportedBlockModes, response);
137 }
138
SupportedPaddingModes(const SupportedPaddingModesRequest & request,SupportedPaddingModesResponse * response)139 void AndroidKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
140 SupportedPaddingModesResponse* response) {
141 GetSupported(*context_, request.algorithm, request.purpose,
142 &OperationFactory::SupportedPaddingModes, response);
143 }
144
SupportedDigests(const SupportedDigestsRequest & request,SupportedDigestsResponse * response)145 void AndroidKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
146 SupportedDigestsResponse* response) {
147 GetSupported(*context_, request.algorithm, request.purpose, &OperationFactory::SupportedDigests,
148 response);
149 }
150
SupportedImportFormats(const SupportedImportFormatsRequest & request,SupportedImportFormatsResponse * response)151 void AndroidKeymaster::SupportedImportFormats(const SupportedImportFormatsRequest& request,
152 SupportedImportFormatsResponse* response) {
153 if (response == NULL || !check_supported(*context_, request.algorithm, response))
154 return;
155
156 size_t count;
157 const keymaster_key_format_t* formats =
158 context_->GetKeyFactory(request.algorithm)->SupportedImportFormats(&count);
159 response->SetResults(formats, count);
160 }
161
SupportedExportFormats(const SupportedExportFormatsRequest & request,SupportedExportFormatsResponse * response)162 void AndroidKeymaster::SupportedExportFormats(const SupportedExportFormatsRequest& request,
163 SupportedExportFormatsResponse* response) {
164 if (response == NULL || !check_supported(*context_, request.algorithm, response))
165 return;
166
167 size_t count;
168 const keymaster_key_format_t* formats =
169 context_->GetKeyFactory(request.algorithm)->SupportedExportFormats(&count);
170 response->SetResults(formats, count);
171 }
172
GetHmacSharingParameters()173 GetHmacSharingParametersResponse AndroidKeymaster::GetHmacSharingParameters() {
174 GetHmacSharingParametersResponse response;
175 KeymasterEnforcement* policy = context_->enforcement_policy();
176 if (!policy) {
177 response.error = KM_ERROR_UNIMPLEMENTED;
178 return response;
179 }
180
181 response.error = policy->GetHmacSharingParameters(&response.params);
182 return response;
183 }
184
185 ComputeSharedHmacResponse
ComputeSharedHmac(const ComputeSharedHmacRequest & request)186 AndroidKeymaster::ComputeSharedHmac(const ComputeSharedHmacRequest& request) {
187 ComputeSharedHmacResponse response;
188 KeymasterEnforcement* policy = context_->enforcement_policy();
189 if (!policy) {
190 response.error = KM_ERROR_UNIMPLEMENTED;
191 return response;
192 }
193
194 response.error = policy->ComputeSharedHmac(request.params_array, &response.sharing_check);
195 return response;
196 }
197
198 VerifyAuthorizationResponse
VerifyAuthorization(const VerifyAuthorizationRequest & request)199 AndroidKeymaster::VerifyAuthorization(const VerifyAuthorizationRequest& request) {
200 KeymasterEnforcement* policy = context_->enforcement_policy();
201 if (!policy) {
202 VerifyAuthorizationResponse response;
203 response.error = KM_ERROR_UNIMPLEMENTED;
204 return response;
205 }
206
207 return policy->VerifyAuthorization(request);
208 }
209
AddRngEntropy(const AddEntropyRequest & request,AddEntropyResponse * response)210 void AndroidKeymaster::AddRngEntropy(const AddEntropyRequest& request,
211 AddEntropyResponse* response) {
212 response->error = context_->AddRngEntropy(request.random_data.peek_read(),
213 request.random_data.available_read());
214 }
215
GenerateKey(const GenerateKeyRequest & request,GenerateKeyResponse * response)216 void AndroidKeymaster::GenerateKey(const GenerateKeyRequest& request,
217 GenerateKeyResponse* response) {
218 if (response == NULL)
219 return;
220
221 keymaster_algorithm_t algorithm;
222 KeyFactory* factory = 0;
223 UniquePtr<Key> key;
224 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
225 !(factory = context_->GetKeyFactory(algorithm)))
226 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
227 else {
228 KeymasterKeyBlob key_blob;
229 response->enforced.Clear();
230 response->unenforced.Clear();
231 response->error = factory->GenerateKey(request.key_description, &key_blob,
232 &response->enforced, &response->unenforced);
233 if (response->error == KM_ERROR_OK)
234 response->key_blob = key_blob.release();
235 }
236 }
237
GetKeyCharacteristics(const GetKeyCharacteristicsRequest & request,GetKeyCharacteristicsResponse * response)238 void AndroidKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
239 GetKeyCharacteristicsResponse* response) {
240 if (response == NULL)
241 return;
242
243 UniquePtr<Key> key;
244 response->error =
245 context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
246 &key);
247 if (response->error != KM_ERROR_OK)
248 return;
249
250 // scavenge the key object for the auth lists
251 response->enforced = move(key->hw_enforced());
252 response->unenforced = move(key->sw_enforced());
253
254 response->error = CheckVersionInfo(response->enforced, response->unenforced, *context_);
255 }
256
BeginOperation(const BeginOperationRequest & request,BeginOperationResponse * response)257 void AndroidKeymaster::BeginOperation(const BeginOperationRequest& request,
258 BeginOperationResponse* response) {
259 if (response == NULL)
260 return;
261 response->op_handle = 0;
262
263 const KeyFactory* key_factory;
264 UniquePtr<Key> key;
265 response->error = LoadKey(request.key_blob, request.additional_params, &key_factory, &key);
266 if (response->error != KM_ERROR_OK)
267 return;
268
269 response->error = KM_ERROR_UNKNOWN_ERROR;
270 keymaster_algorithm_t key_algorithm;
271 if (!key->authorizations().GetTagValue(TAG_ALGORITHM, &key_algorithm))
272 return;
273
274 response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
275 OperationFactory* factory = key_factory->GetOperationFactory(request.purpose);
276 if (!factory) return;
277
278 OperationPtr operation(
279 factory->CreateOperation(move(*key), request.additional_params, &response->error));
280 if (operation.get() == NULL) return;
281
282 if (context_->enforcement_policy()) {
283 km_id_t key_id;
284 response->error = KM_ERROR_UNKNOWN_ERROR;
285 if (!context_->enforcement_policy()->CreateKeyId(request.key_blob, &key_id)) return;
286 operation->set_key_id(key_id);
287 response->error = context_->enforcement_policy()->AuthorizeOperation(
288 request.purpose, key_id, operation->authorizations(), request.additional_params,
289 0 /* op_handle */, true /* is_begin_operation */);
290 if (response->error != KM_ERROR_OK) return;
291 }
292
293 response->output_params.Clear();
294 response->error = operation->Begin(request.additional_params, &response->output_params);
295 if (response->error != KM_ERROR_OK)
296 return;
297
298 response->op_handle = operation->operation_handle();
299 response->error = operation_table_->Add(move(operation));
300 }
301
UpdateOperation(const UpdateOperationRequest & request,UpdateOperationResponse * response)302 void AndroidKeymaster::UpdateOperation(const UpdateOperationRequest& request,
303 UpdateOperationResponse* response) {
304 if (response == NULL)
305 return;
306
307 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
308 Operation* operation = operation_table_->Find(request.op_handle);
309 if (operation == NULL)
310 return;
311
312 if (context_->enforcement_policy()) {
313 response->error = context_->enforcement_policy()->AuthorizeOperation(
314 operation->purpose(), operation->key_id(), operation->authorizations(),
315 request.additional_params, request.op_handle, false /* is_begin_operation */);
316 if (response->error != KM_ERROR_OK) {
317 operation_table_->Delete(request.op_handle);
318 return;
319 }
320 }
321
322 response->error =
323 operation->Update(request.additional_params, request.input, &response->output_params,
324 &response->output, &response->input_consumed);
325 if (response->error != KM_ERROR_OK) {
326 // Any error invalidates the operation.
327 operation_table_->Delete(request.op_handle);
328 }
329 }
330
FinishOperation(const FinishOperationRequest & request,FinishOperationResponse * response)331 void AndroidKeymaster::FinishOperation(const FinishOperationRequest& request,
332 FinishOperationResponse* response) {
333 if (response == NULL)
334 return;
335
336 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
337 Operation* operation = operation_table_->Find(request.op_handle);
338 if (operation == NULL)
339 return;
340
341 if (context_->enforcement_policy()) {
342 response->error = context_->enforcement_policy()->AuthorizeOperation(
343 operation->purpose(), operation->key_id(), operation->authorizations(),
344 request.additional_params, request.op_handle, false /* is_begin_operation */);
345 if (response->error != KM_ERROR_OK) {
346 operation_table_->Delete(request.op_handle);
347 return;
348 }
349 }
350
351 response->error = operation->Finish(request.additional_params, request.input, request.signature,
352 &response->output_params, &response->output);
353 operation_table_->Delete(request.op_handle);
354 }
355
AbortOperation(const AbortOperationRequest & request,AbortOperationResponse * response)356 void AndroidKeymaster::AbortOperation(const AbortOperationRequest& request,
357 AbortOperationResponse* response) {
358 if (!response)
359 return;
360
361 Operation* operation = operation_table_->Find(request.op_handle);
362 if (!operation) {
363 response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
364 return;
365 }
366
367 response->error = operation->Abort();
368 operation_table_->Delete(request.op_handle);
369 }
370
ExportKey(const ExportKeyRequest & request,ExportKeyResponse * response)371 void AndroidKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
372 if (response == NULL)
373 return;
374
375 UniquePtr<Key> key;
376 response->error =
377 context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params, &key);
378 if (response->error != KM_ERROR_OK)
379 return;
380
381 UniquePtr<uint8_t[]> out_key;
382 size_t size;
383 response->error = key->formatted_key_material(request.key_format, &out_key, &size);
384 if (response->error == KM_ERROR_OK) {
385 response->key_data = out_key.release();
386 response->key_data_length = size;
387 }
388 }
389
AttestKey(const AttestKeyRequest & request,AttestKeyResponse * response)390 void AndroidKeymaster::AttestKey(const AttestKeyRequest& request, AttestKeyResponse* response) {
391 if (!response)
392 return;
393
394 const KeyFactory* key_factory;
395 UniquePtr<Key> key;
396 response->error = LoadKey(request.key_blob, request.attest_params,
397 &key_factory, &key);
398 if (response->error != KM_ERROR_OK)
399 return;
400
401 keymaster_blob_t attestation_application_id;
402 if (request.attest_params.GetTagValue(TAG_ATTESTATION_APPLICATION_ID,
403 &attestation_application_id)) {
404 key->sw_enforced().push_back(TAG_ATTESTATION_APPLICATION_ID, attestation_application_id);
405 }
406
407 CertChainPtr certchain;
408 response->error = context_->GenerateAttestation(*key, request.attest_params, &certchain);
409 if (response->error == KM_ERROR_OK) {
410 response->certificate_chain = *certchain;
411 // response->certificate_chain took possession of secondary resources. So we shallowly
412 // delete the keymaster_cert_chain_t object, but nothing else.
413 // TODO Can we switch to managed types eventually?
414 delete certchain.release();
415 }
416 }
417
UpgradeKey(const UpgradeKeyRequest & request,UpgradeKeyResponse * response)418 void AndroidKeymaster::UpgradeKey(const UpgradeKeyRequest& request, UpgradeKeyResponse* response) {
419 if (!response)
420 return;
421
422 KeymasterKeyBlob upgraded_key;
423 response->error = context_->UpgradeKeyBlob(KeymasterKeyBlob(request.key_blob),
424 request.upgrade_params, &upgraded_key);
425 if (response->error != KM_ERROR_OK)
426 return;
427 response->upgraded_key = upgraded_key.release();
428 }
429
ImportKey(const ImportKeyRequest & request,ImportKeyResponse * response)430 void AndroidKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
431 if (response == NULL)
432 return;
433
434 keymaster_algorithm_t algorithm;
435 KeyFactory* factory = 0;
436 UniquePtr<Key> key;
437 if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
438 !(factory = context_->GetKeyFactory(algorithm)))
439 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
440 else {
441 keymaster_key_blob_t key_material = {request.key_data, request.key_data_length};
442 KeymasterKeyBlob key_blob;
443 response->error = factory->ImportKey(request.key_description, request.key_format,
444 KeymasterKeyBlob(key_material), &key_blob,
445 &response->enforced, &response->unenforced);
446 if (response->error == KM_ERROR_OK)
447 response->key_blob = key_blob.release();
448 }
449 }
450
DeleteKey(const DeleteKeyRequest & request,DeleteKeyResponse * response)451 void AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
452 if (!response)
453 return;
454 response->error = context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
455 }
456
DeleteAllKeys(const DeleteAllKeysRequest &,DeleteAllKeysResponse * response)457 void AndroidKeymaster::DeleteAllKeys(const DeleteAllKeysRequest&, DeleteAllKeysResponse* response) {
458 if (!response)
459 return;
460 response->error = context_->DeleteAllKeys();
461 }
462
Configure(const ConfigureRequest & request,ConfigureResponse * response)463 void AndroidKeymaster::Configure(const ConfigureRequest& request, ConfigureResponse* response) {
464 if (!response)
465 return;
466 response->error = context_->SetSystemVersion(request.os_version, request.os_patchlevel);
467 }
468
has_operation(keymaster_operation_handle_t op_handle) const469 bool AndroidKeymaster::has_operation(keymaster_operation_handle_t op_handle) const {
470 return operation_table_->Find(op_handle) != nullptr;
471 }
472
LoadKey(const keymaster_key_blob_t & key_blob,const AuthorizationSet & additional_params,const KeyFactory ** factory,UniquePtr<Key> * key)473 keymaster_error_t AndroidKeymaster::LoadKey(const keymaster_key_blob_t& key_blob,
474 const AuthorizationSet& additional_params,
475 const KeyFactory** factory, UniquePtr<Key>* key) {
476 KeymasterKeyBlob key_material;
477 keymaster_error_t error = context_->ParseKeyBlob(KeymasterKeyBlob(key_blob), additional_params,
478 key);
479 if (error != KM_ERROR_OK)
480 return error;
481 if (factory) *factory = (*key)->key_factory();
482 return CheckVersionInfo((*key)->hw_enforced(), (*key)->sw_enforced(), *context_);
483 }
484
ImportWrappedKey(const ImportWrappedKeyRequest & request,ImportWrappedKeyResponse * response)485 void AndroidKeymaster::ImportWrappedKey(const ImportWrappedKeyRequest& request,
486 ImportWrappedKeyResponse* response) {
487 if (!response) return;
488
489 KeymasterKeyBlob secret_key;
490 AuthorizationSet key_description;
491 keymaster_key_format_t key_format;
492
493 response->error =
494 context_->UnwrapKey(request.wrapped_key, request.wrapping_key, request.additional_params,
495 request.masking_key, &key_description, &key_format, &secret_key);
496
497 if (response->error != KM_ERROR_OK) {
498 return;
499 }
500
501 int sid_idx = key_description.find(TAG_USER_SECURE_ID);
502 if (sid_idx != -1) {
503 uint8_t sids = key_description[sid_idx].long_integer;
504 if (!key_description.erase(sid_idx)) {
505 response->error = KM_ERROR_UNKNOWN_ERROR;
506 return;
507 }
508 if (sids & HW_AUTH_PASSWORD) {
509 key_description.push_back(TAG_USER_SECURE_ID, request.password_sid);
510 }
511 if (sids & HW_AUTH_FINGERPRINT) {
512 key_description.push_back(TAG_USER_SECURE_ID, request.biometric_sid);
513 }
514 }
515
516 keymaster_algorithm_t algorithm;
517 KeyFactory* factory = 0;
518 if (!key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
519 !(factory = context_->GetKeyFactory(algorithm))) {
520 response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
521 } else {
522 KeymasterKeyBlob key_blob;
523 response->error =
524 factory->ImportKey(key_description, key_format, KeymasterKeyBlob(secret_key), &key_blob,
525 &response->enforced, &response->unenforced);
526 if (response->error == KM_ERROR_OK) {
527 response->key_blob = key_blob;
528 }
529 }
530 }
531
532 } // namespace keymaster
533