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 "rsa_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 RsaKeymaster0KeyFactory::RsaKeymaster0KeyFactory(const SoftKeymasterContext* context,
     33                                                  const Keymaster0Engine* engine)
     34     : RsaKeyFactory(context), engine_(engine) {}
     35 
     36 keymaster_error_t RsaKeymaster0KeyFactory::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     uint64_t public_exponent;
     44     if (!key_description.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) {
     45         LOG_E("%s", "No public exponent specified for RSA key generation");
     46         return KM_ERROR_INVALID_ARGUMENT;
     47     }
     48 
     49     uint32_t key_size;
     50     if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size)) {
     51         LOG_E("%s", "No key size specified for RSA key generation");
     52         return KM_ERROR_UNSUPPORTED_KEY_SIZE;
     53     }
     54 
     55     KeymasterKeyBlob key_material;
     56     if (!engine_->GenerateRsaKey(public_exponent, key_size, &key_material))
     57         return KM_ERROR_UNKNOWN_ERROR;
     58 
     59     // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
     60     // context_->CreateKeyBlob doesn't put them in sw_enforced.
     61     hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
     62     hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
     63     hw_enforced->push_back(TAG_KEY_SIZE, key_size);
     64     hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
     65 
     66     return context_->CreateKeyBlob(key_description, KM_ORIGIN_UNKNOWN, key_material, key_blob,
     67                                    hw_enforced, sw_enforced);
     68 }
     69 
     70 keymaster_error_t RsaKeymaster0KeyFactory::ImportKey(
     71     const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
     72     const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
     73     AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
     74     if (!output_key_blob || !hw_enforced || !sw_enforced)
     75         return KM_ERROR_OUTPUT_PARAMETER_NULL;
     76 
     77     AuthorizationSet authorizations;
     78     uint64_t public_exponent;
     79     uint32_t key_size;
     80     keymaster_error_t error =
     81         UpdateImportKeyDescription(key_description, input_key_material_format, input_key_material,
     82                                    &authorizations, &public_exponent, &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_RSA);
     93     hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
     94     hw_enforced->push_back(TAG_KEY_SIZE, key_size);
     95     hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
     96 
     97     return context_->CreateKeyBlob(authorizations, KM_ORIGIN_UNKNOWN, imported_hw_key,
     98                                    output_key_blob, hw_enforced, sw_enforced);
     99 }
    100 
    101 keymaster_error_t RsaKeymaster0KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
    102                                                    const AuthorizationSet& additional_params,
    103                                                    const AuthorizationSet& hw_enforced,
    104                                                    const AuthorizationSet& sw_enforced,
    105                                                    UniquePtr<Key>* key) const {
    106     if (!key)
    107         return KM_ERROR_OUTPUT_PARAMETER_NULL;
    108 
    109     if (sw_enforced.GetTagCount(TAG_ALGORITHM) == 1)
    110         return super::LoadKey(key_material, additional_params, hw_enforced, sw_enforced, key);
    111 
    112     unique_ptr<RSA, RSA_Delete> rsa(engine_->BlobToRsaKey(key_material));
    113     if (!rsa)
    114         return KM_ERROR_UNKNOWN_ERROR;
    115 
    116     keymaster_error_t error;
    117     key->reset(new (std::nothrow)
    118                    RsaKeymaster0Key(rsa.release(), hw_enforced, sw_enforced, &error));
    119     if (!key->get())
    120         error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
    121 
    122     if (error != KM_ERROR_OK)
    123         return error;
    124 
    125     return KM_ERROR_OK;
    126 }
    127 
    128 }  // namespace keymaster
    129