• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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