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