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) {}
     35 
     36 keymaster_error_t EcdsaKeymaster0KeyFactory::GenerateKey(const AuthorizationSet& key_description,
     37                                                          KeymasterKeyBlob* key_blob,
     38                                                          AuthorizationSet* hw_enforced,
     39                                                          AuthorizationSet* sw_enforced) const {
     40     if (!key_blob || !hw_enforced || !sw_enforced)
     41         return KM_ERROR_OUTPUT_PARAMETER_NULL;
     42 
     43     if (!engine_ || !engine_->supports_ec())
     44         return super::GenerateKey(key_description, key_blob, hw_enforced, sw_enforced);
     45 
     46     keymaster_ec_curve_t ec_curve;
     47     uint32_t key_size;
     48     keymaster_error_t error = GetCurveAndSize(key_description, &ec_curve, &key_size);
     49     if (error != KM_ERROR_OK) {
     50         return error;
     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_EC_CURVE, ec_curve);
     62     hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
     63 
     64     return context_->CreateKeyBlob(key_description, KM_ORIGIN_UNKNOWN, key_material, key_blob,
     65                                    hw_enforced, sw_enforced);
     66 }
     67 
     68 keymaster_error_t EcdsaKeymaster0KeyFactory::ImportKey(
     69     const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
     70     const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
     71     AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
     72     if (!output_key_blob || !hw_enforced || !sw_enforced)
     73         return KM_ERROR_OUTPUT_PARAMETER_NULL;
     74 
     75     if (!engine_ || !engine_->supports_ec())
     76         return super::ImportKey(key_description, input_key_material_format, input_key_material,
     77                                 output_key_blob, hw_enforced, sw_enforced);
     78 
     79     AuthorizationSet authorizations;
     80     uint32_t key_size;
     81     keymaster_error_t error = UpdateImportKeyDescription(
     82         key_description, input_key_material_format, input_key_material, &authorizations, &key_size);
     83     if (error != KM_ERROR_OK)
     84         return error;
     85 
     86     KeymasterKeyBlob imported_hw_key;
     87     if (!engine_->ImportKey(input_key_material_format, input_key_material, &imported_hw_key))
     88         return KM_ERROR_UNKNOWN_ERROR;
     89 
     90     // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
     91     // context_->CreateKeyBlob doesn't put them in sw_enforced.
     92     hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_EC);
     93     hw_enforced->push_back(TAG_KEY_SIZE, key_size);
     94     hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
     95 
     96     return context_->CreateKeyBlob(authorizations, KM_ORIGIN_UNKNOWN, imported_hw_key,
     97                                    output_key_blob, hw_enforced, sw_enforced);
     98 }
     99 
    100 keymaster_error_t EcdsaKeymaster0KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
    101                                                      const AuthorizationSet& additional_params,
    102                                                      const AuthorizationSet& hw_enforced,
    103                                                      const AuthorizationSet& sw_enforced,
    104                                                      UniquePtr<Key>* key) const {
    105     if (!key)
    106         return KM_ERROR_OUTPUT_PARAMETER_NULL;
    107 
    108     if (sw_enforced.GetTagCount(TAG_ALGORITHM) == 1)
    109         return super::LoadKey(key_material, additional_params, hw_enforced, sw_enforced, key);
    110 
    111     unique_ptr<EC_KEY, EC_KEY_Delete> ec_key(engine_->BlobToEcKey(key_material));
    112     if (!ec_key)
    113         return KM_ERROR_UNKNOWN_ERROR;
    114 
    115     keymaster_error_t error;
    116     key->reset(new (std::nothrow)
    117                    EcKeymaster0Key(ec_key.release(), hw_enforced, sw_enforced, &error));
    118     if (error != KM_ERROR_OK)
    119         return error;
    120 
    121     return KM_ERROR_OK;
    122 }
    123 
    124 }  // namespace keymaster
    125