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_keymaster1_key.h"
     18 
     19 #include <memory>
     20 
     21 #include <keymaster/logger.h>
     22 #include <keymaster/soft_keymaster_context.h>
     23 
     24 #include "rsa_keymaster1_operation.h"
     25 
     26 using std::unique_ptr;
     27 
     28 namespace keymaster {
     29 
     30 RsaKeymaster1KeyFactory::RsaKeymaster1KeyFactory(const SoftKeymasterContext* context,
     31                                                  const Keymaster1Engine* engine)
     32     : RsaKeyFactory(context), engine_(engine),
     33       sign_factory_(new RsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)),
     34       decrypt_factory_(new RsaKeymaster1OperationFactory(KM_PURPOSE_DECRYPT, engine)),
     35       // For pubkey ops we can use the normal operation factories.
     36       verify_factory_(new RsaVerificationOperationFactory),
     37       encrypt_factory_(new RsaEncryptionOperationFactory) {}
     38 
     39 static bool is_supported(uint32_t digest) {
     40     return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256;
     41 }
     42 
     43 static void UpdateToWorkAroundUnsupportedDigests(const AuthorizationSet& key_description,
     44                                                  AuthorizationSet* new_description) {
     45     bool have_unsupported_digests = false;
     46     bool have_digest_none = false;
     47     bool have_pad_none = false;
     48     bool have_padding_requiring_digest = false;
     49     for (const keymaster_key_param_t& entry : key_description) {
     50         new_description->push_back(entry);
     51 
     52         if (entry.tag == TAG_DIGEST) {
     53             if (entry.enumerated == KM_DIGEST_NONE) {
     54                 have_digest_none = true;
     55             } else if (!is_supported(entry.enumerated)) {
     56                 LOG_D("Found request for unsupported digest %u", entry.enumerated);
     57                 have_unsupported_digests = true;
     58             }
     59         }
     60 
     61         if (entry.tag == TAG_PADDING) {
     62             switch (entry.enumerated) {
     63             case KM_PAD_RSA_PSS:
     64             case KM_PAD_RSA_OAEP:
     65                 have_padding_requiring_digest = true;
     66                 break;
     67             case KM_PAD_NONE:
     68                 have_pad_none = true;
     69                 break;
     70             }
     71         }
     72     }
     73 
     74     if (have_unsupported_digests && !have_digest_none) {
     75         LOG_I("Adding KM_DIGEST_NONE to key authorization, to enable software digesting", 0);
     76         new_description->push_back(TAG_DIGEST, KM_DIGEST_NONE);
     77     }
     78 
     79     if (have_unsupported_digests && have_padding_requiring_digest && !have_pad_none) {
     80         LOG_I("Adding KM_PAD_NONE to key authorization, to enable PSS or OAEP software padding", 0);
     81         new_description->push_back(TAG_PADDING, KM_PAD_NONE);
     82     }
     83 }
     84 
     85 keymaster_error_t RsaKeymaster1KeyFactory::GenerateKey(const AuthorizationSet& key_description,
     86                                                        KeymasterKeyBlob* key_blob,
     87                                                        AuthorizationSet* hw_enforced,
     88                                                        AuthorizationSet* sw_enforced) const {
     89     AuthorizationSet key_params_copy;
     90     UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
     91     return engine_->GenerateKey(key_params_copy, key_blob, hw_enforced, sw_enforced);
     92 }
     93 
     94 keymaster_error_t RsaKeymaster1KeyFactory::ImportKey(
     95     const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
     96     const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
     97     AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
     98     AuthorizationSet key_params_copy;
     99     UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
    100     return engine_->ImportKey(key_params_copy, input_key_material_format, input_key_material,
    101                               output_key_blob, hw_enforced, sw_enforced);
    102 }
    103 
    104 keymaster_error_t RsaKeymaster1KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
    105                                                    const AuthorizationSet& additional_params,
    106                                                    const AuthorizationSet& hw_enforced,
    107                                                    const AuthorizationSet& sw_enforced,
    108                                                    UniquePtr<Key>* key) const {
    109     if (!key)
    110         return KM_ERROR_OUTPUT_PARAMETER_NULL;
    111 
    112     keymaster_error_t error;
    113     unique_ptr<RSA, RSA_Delete> rsa(engine_->BuildRsaKey(key_material, additional_params, &error));
    114     if (!rsa)
    115         return error;
    116 
    117     key->reset(new (std::nothrow)
    118                    RsaKeymaster1Key(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 OperationFactory* RsaKeymaster1KeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
    129     switch (purpose) {
    130     case KM_PURPOSE_SIGN:
    131         return sign_factory_.get();
    132     case KM_PURPOSE_VERIFY:
    133         return verify_factory_.get();
    134     case KM_PURPOSE_ENCRYPT:
    135         return encrypt_factory_.get();
    136     case KM_PURPOSE_DECRYPT:
    137         return decrypt_factory_.get();
    138     case KM_PURPOSE_DERIVE_KEY:
    139         break;
    140     }
    141     return nullptr;
    142 }
    143 
    144 }  // namespace keymaster
    145