Home | History | Annotate | Download | only in keymaster
      1 /*
      2  * Copyright 2015 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 "ec_keymaster0_key.h"
     18 
     19 #include <memory>
     20 
     21 #include <keymaster/android_keymaster_utils.h>
     22 #include <keymaster/logger.h>
     23 #include <keymaster/soft_keymaster_context.h>
     24 
     25 #include "keymaster0_engine.h"
     26 #include "openssl_utils.h"
     27 
     28 using std::unique_ptr;
     29 
     30 namespace keymaster {
     31 
     32 EcdsaKeymaster0KeyFactory::EcdsaKeymaster0KeyFactory(const SoftKeymasterContext* context,
     33                                                      const Keymaster0Engine* engine)
     34     : EcKeyFactory(context), engine_(engine), soft_context_(context) {
     35 }
     36 
     37 keymaster_error_t EcdsaKeymaster0KeyFactory::GenerateKey(const AuthorizationSet& key_description,
     38                                                          KeymasterKeyBlob* key_blob,
     39                                                          AuthorizationSet* hw_enforced,
     40                                                          AuthorizationSet* sw_enforced) const {
     41     if (!key_blob || !hw_enforced || !sw_enforced)
     42         return KM_ERROR_OUTPUT_PARAMETER_NULL;
     43 
     44     if (!engine_ || !engine_->supports_ec())
     45         return super::GenerateKey(key_description, key_blob, hw_enforced, sw_enforced);
     46 
     47     uint32_t key_size;
     48     if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size)) {
     49         LOG_E("%s", "No key size specified for EC key generation");
     50         return KM_ERROR_UNSUPPORTED_KEY_SIZE;
     51     }
     52 
     53     KeymasterKeyBlob key_material;
     54     if (!engine_->GenerateEcKey(key_size, &key_material))
     55         return KM_ERROR_UNKNOWN_ERROR;
     56 
     57     // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
     58     // context_->CreateKeyBlob doesn't put them in sw_enforced.
     59     hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_EC);
     60     hw_enforced->push_back(TAG_KEY_SIZE, key_size);
     61     hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
     62 
     63     return context_->CreateKeyBlob(key_description, KM_ORIGIN_UNKNOWN, key_material, key_blob,
     64                                    hw_enforced, sw_enforced);
     65 }
     66 
     67 keymaster_error_t EcdsaKeymaster0KeyFactory::ImportKey(
     68     const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
     69     const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
     70     AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
     71     if (!output_key_blob || !hw_enforced || !sw_enforced)
     72         return KM_ERROR_OUTPUT_PARAMETER_NULL;
     73 
     74     if (!engine_ || !engine_->supports_ec())
     75         return super::ImportKey(key_description, input_key_material_format, input_key_material,
     76                                 output_key_blob, hw_enforced, sw_enforced);
     77 
     78     AuthorizationSet authorizations;
     79     uint32_t key_size;
     80     keymaster_error_t error = UpdateImportKeyDescription(
     81         key_description, input_key_material_format, input_key_material, &authorizations, &key_size);
     82     if (error != KM_ERROR_OK)
     83         return error;
     84 
     85     KeymasterKeyBlob imported_hw_key;
     86     if (!engine_->ImportKey(input_key_material_format, input_key_material, &imported_hw_key))
     87         return KM_ERROR_UNKNOWN_ERROR;
     88 
     89     // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
     90     // context_->CreateKeyBlob doesn't put them in sw_enforced.
     91     hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_EC);
     92     hw_enforced->push_back(TAG_KEY_SIZE, key_size);
     93     hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
     94 
     95     return context_->CreateKeyBlob(authorizations, KM_ORIGIN_UNKNOWN, imported_hw_key,
     96                                    output_key_blob, hw_enforced, sw_enforced);
     97 }
     98 
     99 keymaster_error_t EcdsaKeymaster0KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
    100                                                      const AuthorizationSet& hw_enforced,
    101                                                      const AuthorizationSet& sw_enforced,
    102                                                      UniquePtr<Key>* key) const {
    103     if (!key)
    104         return KM_ERROR_OUTPUT_PARAMETER_NULL;
    105 
    106     if (sw_enforced.GetTagCount(TAG_ALGORITHM) == 1)
    107         return super::LoadKey(key_material, hw_enforced, sw_enforced, key);
    108 
    109     unique_ptr<EC_KEY, EC_Delete> ec_key(engine_->BlobToEcKey(key_material));
    110     if (!ec_key)
    111         return KM_ERROR_UNKNOWN_ERROR;
    112 
    113     keymaster_error_t error;
    114     key->reset(new (std::nothrow)
    115                    EcKeymaster0Key(ec_key.release(), hw_enforced, sw_enforced, engine_, &error));
    116     if (error != KM_ERROR_OK)
    117         return error;
    118 
    119     return KM_ERROR_OK;
    120 }
    121 
    122 EcKeymaster0Key::EcKeymaster0Key(EC_KEY* ec_key, const AuthorizationSet& hw_enforced,
    123                                  const AuthorizationSet& sw_enforced,
    124                                  const Keymaster0Engine* engine, keymaster_error_t* error)
    125     : EcKey(ec_key, hw_enforced, sw_enforced, error), engine_(engine) {
    126 }
    127 
    128 keymaster_error_t EcKeymaster0Key::key_material(UniquePtr<uint8_t[]>* material,
    129                                                 size_t* size) const {
    130     if (!engine_)
    131         return super::key_material(material, size);
    132 
    133     const keymaster_key_blob_t* blob = engine_->EcKeyToBlob(key());
    134     if (!blob)
    135         return KM_ERROR_UNKNOWN_ERROR;
    136 
    137     *size = blob->key_material_size;
    138     material->reset(dup_buffer(blob->key_material, *size));
    139     if (!material->get())
    140         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
    141     return KM_ERROR_OK;
    142 }
    143 
    144 }  // namespace keymaster
    145