Home | History | Annotate | Download | only in keymaster
      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 
     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 
     68 AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size)
     69     : context_(context), operation_table_(new OperationTable(operation_table_size)) {}
     70 
     71 AndroidKeymaster::~AndroidKeymaster() {}
     72 
     73 struct AE_CTX_Delete {
     74     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>
     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 
     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 
    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>
    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 
    140 void AndroidKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
    141                                            SupportedBlockModesResponse* response) {
    142     GetSupported(*context_, request.algorithm, request.purpose,
    143                  &OperationFactory::SupportedBlockModes, response);
    144 }
    145 
    146 void AndroidKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
    147                                              SupportedPaddingModesResponse* response) {
    148     GetSupported(*context_, request.algorithm, request.purpose,
    149                  &OperationFactory::SupportedPaddingModes, response);
    150 }
    151 
    152 void AndroidKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
    153                                         SupportedDigestsResponse* response) {
    154     GetSupported(*context_, request.algorithm, request.purpose, &OperationFactory::SupportedDigests,
    155                  response);
    156 }
    157 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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     keymaster_blob_t attestation_application_id;
    406     if (request.attest_params.GetTagValue(TAG_ATTESTATION_APPLICATION_ID,
    407                                           &attestation_application_id)) {
    408         sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, attestation_application_id);
    409     }
    410 
    411     response->error = key->GenerateAttestation(*context_, request.attest_params, tee_enforced,
    412                                                sw_enforced, &response->certificate_chain);
    413 }
    414 
    415 void AndroidKeymaster::UpgradeKey(const UpgradeKeyRequest& request, UpgradeKeyResponse* response) {
    416     if (!response)
    417         return;
    418 
    419     KeymasterKeyBlob upgraded_key;
    420     response->error = context_->UpgradeKeyBlob(KeymasterKeyBlob(request.key_blob),
    421                                                request.upgrade_params, &upgraded_key);
    422     if (response->error != KM_ERROR_OK)
    423         return;
    424     response->upgraded_key = upgraded_key.release();
    425 }
    426 
    427 void AndroidKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
    428     if (response == NULL)
    429         return;
    430 
    431     keymaster_algorithm_t algorithm;
    432     KeyFactory* factory = 0;
    433     UniquePtr<Key> key;
    434     if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
    435         !(factory = context_->GetKeyFactory(algorithm)))
    436         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
    437     else {
    438         keymaster_key_blob_t key_material = {request.key_data, request.key_data_length};
    439         KeymasterKeyBlob key_blob;
    440         response->error = factory->ImportKey(request.key_description, request.key_format,
    441                                              KeymasterKeyBlob(key_material), &key_blob,
    442                                              &response->enforced, &response->unenforced);
    443         if (response->error == KM_ERROR_OK)
    444             response->key_blob = key_blob.release();
    445     }
    446 }
    447 
    448 void AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
    449     if (!response)
    450         return;
    451     response->error = context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
    452 }
    453 
    454 void AndroidKeymaster::DeleteAllKeys(const DeleteAllKeysRequest&, DeleteAllKeysResponse* response) {
    455     if (!response)
    456         return;
    457     response->error = context_->DeleteAllKeys();
    458 }
    459 
    460 bool AndroidKeymaster::has_operation(keymaster_operation_handle_t op_handle) const {
    461     return operation_table_->Find(op_handle) != nullptr;
    462 }
    463 
    464 keymaster_error_t AndroidKeymaster::LoadKey(const keymaster_key_blob_t& key_blob,
    465                                             const AuthorizationSet& additional_params,
    466                                             AuthorizationSet* hw_enforced,
    467                                             AuthorizationSet* sw_enforced,
    468                                             const KeyFactory** factory, UniquePtr<Key>* key) {
    469     KeymasterKeyBlob key_material;
    470     keymaster_error_t error = context_->ParseKeyBlob(KeymasterKeyBlob(key_blob), additional_params,
    471                                                      &key_material, hw_enforced, sw_enforced);
    472     if (error != KM_ERROR_OK)
    473         return error;
    474 
    475     error = CheckVersionInfo(*hw_enforced, *sw_enforced, *context_);
    476     if (error != KM_ERROR_OK)
    477         return error;
    478 
    479     keymaster_algorithm_t algorithm;
    480     *factory = GetKeyFactory(*context_, *hw_enforced, *sw_enforced, &algorithm, &error);
    481     if (error != KM_ERROR_OK)
    482         return error;
    483 
    484     return (*factory)->LoadKey(key_material, additional_params, *hw_enforced, *sw_enforced, key);
    485 }
    486 
    487 }  // namespace keymaster
    488