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