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
39namespace keymaster {
40
41namespace {
42
43const uint8_t MAJOR_VER = 1;
44const uint8_t MINOR_VER = 1;
45const uint8_t SUBMINOR_VER = 0;
46
47keymaster_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
68AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size)
69    : context_(context), operation_table_(new OperationTable(operation_table_size)) {}
70
71AndroidKeymaster::~AndroidKeymaster() {}
72
73struct AE_CTX_Delete {
74    void operator()(ae_ctx* ctx) const { ae_free(ctx); }
75};
76typedef 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
84template <typename T>
85bool 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
94void 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
104void 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
121template <typename T>
122void 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
140void AndroidKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
141                                           SupportedBlockModesResponse* response) {
142    GetSupported(*context_, request.algorithm, request.purpose,
143                 &OperationFactory::SupportedBlockModes, response);
144}
145
146void AndroidKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
147                                             SupportedPaddingModesResponse* response) {
148    GetSupported(*context_, request.algorithm, request.purpose,
149                 &OperationFactory::SupportedPaddingModes, response);
150}
151
152void AndroidKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
153                                        SupportedDigestsResponse* response) {
154    GetSupported(*context_, request.algorithm, request.purpose, &OperationFactory::SupportedDigests,
155                 response);
156}
157
158void 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
169void 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
180void 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
186void 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
208void 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
223static 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
237void 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
289void 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
318void 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
343void 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
358void 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
392void 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
409void 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
421void 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
442void AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
443    if (!response)
444        return;
445    response->error = context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
446}
447
448void AndroidKeymaster::DeleteAllKeys(const DeleteAllKeysRequest&, DeleteAllKeysResponse* response) {
449    if (!response)
450        return;
451    response->error = context_->DeleteAllKeys();
452}
453
454bool AndroidKeymaster::has_operation(keymaster_operation_handle_t op_handle) const {
455    return operation_table_->Find(op_handle) != nullptr;
456}
457
458keymaster_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