Home | History | Annotate | Download | only in km_openssl
      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/km_openssl/ecdsa_operation.h>
     18 
     19 #include <openssl/ecdsa.h>
     20 
     21 #include <keymaster/km_openssl/ec_key.h>
     22 #include <keymaster/km_openssl/openssl_err.h>
     23 #include <keymaster/km_openssl/openssl_utils.h>
     24 
     25 namespace keymaster {
     26 
     27 static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE,      KM_DIGEST_SHA1,
     28                                                        KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256,
     29                                                        KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
     30 
     31 OperationPtr EcdsaOperationFactory::CreateOperation(Key&& key, const AuthorizationSet& begin_params,
     32                                                     keymaster_error_t* error) {
     33     const EcKey& ecdsa_key = static_cast<EcKey&>(key);
     34 
     35     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
     36     if (!ecdsa_key.InternalToEvp(pkey.get())) {
     37         *error = KM_ERROR_UNKNOWN_ERROR;
     38         return nullptr;
     39     }
     40 
     41     keymaster_digest_t digest;
     42     if (!GetAndValidateDigest(begin_params, ecdsa_key, &digest, error)) return nullptr;
     43 
     44     *error = KM_ERROR_OK;
     45     auto op = OperationPtr(InstantiateOperation(key.hw_enforced_move(), key.sw_enforced_move(),
     46                                                 digest, pkey.release()));
     47     if (!op) *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
     48     return op;
     49 }
     50 
     51 const keymaster_digest_t* EcdsaOperationFactory::SupportedDigests(size_t* digest_count) const {
     52     *digest_count = array_length(supported_digests);
     53     return supported_digests;
     54 }
     55 
     56 EcdsaOperation::~EcdsaOperation() {
     57     if (ecdsa_key_ != NULL)
     58         EVP_PKEY_free(ecdsa_key_);
     59     EVP_MD_CTX_cleanup(&digest_ctx_);
     60 }
     61 
     62 keymaster_error_t EcdsaOperation::InitDigest() {
     63     switch (digest_) {
     64     case KM_DIGEST_NONE:
     65         return KM_ERROR_OK;
     66     case KM_DIGEST_MD5:
     67         return KM_ERROR_UNSUPPORTED_DIGEST;
     68     case KM_DIGEST_SHA1:
     69         digest_algorithm_ = EVP_sha1();
     70         return KM_ERROR_OK;
     71     case KM_DIGEST_SHA_2_224:
     72         digest_algorithm_ = EVP_sha224();
     73         return KM_ERROR_OK;
     74     case KM_DIGEST_SHA_2_256:
     75         digest_algorithm_ = EVP_sha256();
     76         return KM_ERROR_OK;
     77     case KM_DIGEST_SHA_2_384:
     78         digest_algorithm_ = EVP_sha384();
     79         return KM_ERROR_OK;
     80     case KM_DIGEST_SHA_2_512:
     81         digest_algorithm_ = EVP_sha512();
     82         return KM_ERROR_OK;
     83     default:
     84         return KM_ERROR_UNSUPPORTED_DIGEST;
     85     }
     86 }
     87 
     88 inline size_t min(size_t a, size_t b) {
     89     return (a < b) ? a : b;
     90 }
     91 
     92 keymaster_error_t EcdsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
     93     if (!data_.reserve((EVP_PKEY_bits(ecdsa_key_) + 7) / 8))
     94         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
     95 
     96     if (!data_.write(input.peek_read(), min(data_.available_write(), input.available_read())))
     97         return KM_ERROR_UNKNOWN_ERROR;
     98 
     99     *input_consumed = input.available_read();
    100     return KM_ERROR_OK;
    101 }
    102 
    103 keymaster_error_t EcdsaSignOperation::Begin(const AuthorizationSet& /* input_params */,
    104                                             AuthorizationSet* /* output_params */) {
    105     auto rc = GenerateRandom(reinterpret_cast<uint8_t*>(&operation_handle_),
    106                              (size_t)sizeof(operation_handle_));
    107     if (rc != KM_ERROR_OK) return rc;
    108 
    109     keymaster_error_t error = InitDigest();
    110     if (error != KM_ERROR_OK)
    111         return error;
    112 
    113     if (digest_ == KM_DIGEST_NONE)
    114         return KM_ERROR_OK;
    115 
    116     EVP_PKEY_CTX* pkey_ctx;
    117     if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
    118                            ecdsa_key_) != 1)
    119         return TranslateLastOpenSslError();
    120     return KM_ERROR_OK;
    121 }
    122 
    123 keymaster_error_t EcdsaSignOperation::Update(const AuthorizationSet& /* additional_params */,
    124                                              const Buffer& input,
    125                                              AuthorizationSet* /* output_params */,
    126                                              Buffer* /* output */, size_t* input_consumed) {
    127     if (digest_ == KM_DIGEST_NONE)
    128         return StoreData(input, input_consumed);
    129 
    130     if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
    131         return TranslateLastOpenSslError();
    132     *input_consumed = input.available_read();
    133     return KM_ERROR_OK;
    134 }
    135 
    136 keymaster_error_t EcdsaSignOperation::Finish(const AuthorizationSet& additional_params,
    137                                              const Buffer& input, const Buffer& /* signature */,
    138                                              AuthorizationSet* /* output_params */,
    139                                              Buffer* output) {
    140     if (!output)
    141         return KM_ERROR_OUTPUT_PARAMETER_NULL;
    142 
    143     keymaster_error_t error = UpdateForFinish(additional_params, input);
    144     if (error != KM_ERROR_OK)
    145         return error;
    146 
    147     size_t siglen;
    148     if (digest_ == KM_DIGEST_NONE) {
    149         UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_));
    150         if (!ecdsa.get())
    151             return TranslateLastOpenSslError();
    152 
    153         output->Reinitialize(ECDSA_size(ecdsa.get()));
    154         unsigned int siglen_tmp;
    155         if (!ECDSA_sign(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
    156                         output->peek_write(), &siglen_tmp, ecdsa.get()))
    157             return TranslateLastOpenSslError();
    158         siglen = siglen_tmp;
    159     } else {
    160         if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
    161             return TranslateLastOpenSslError();
    162         if (!output->Reinitialize(siglen))
    163             return KM_ERROR_MEMORY_ALLOCATION_FAILED;
    164         if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
    165             return TranslateLastOpenSslError();
    166     }
    167     if (!output->advance_write(siglen))
    168         return KM_ERROR_UNKNOWN_ERROR;
    169     return KM_ERROR_OK;
    170 }
    171 
    172 keymaster_error_t EcdsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
    173                                               AuthorizationSet* /* output_params */) {
    174     auto rc = GenerateRandom(reinterpret_cast<uint8_t*>(&operation_handle_),
    175                              (size_t)sizeof(operation_handle_));
    176     if (rc != KM_ERROR_OK) return rc;
    177 
    178     keymaster_error_t error = InitDigest();
    179     if (error != KM_ERROR_OK)
    180         return error;
    181 
    182     if (digest_ == KM_DIGEST_NONE)
    183         return KM_ERROR_OK;
    184 
    185     EVP_PKEY_CTX* pkey_ctx;
    186     if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
    187                              ecdsa_key_) != 1)
    188         return TranslateLastOpenSslError();
    189     return KM_ERROR_OK;
    190 }
    191 
    192 keymaster_error_t EcdsaVerifyOperation::Update(const AuthorizationSet& /* additional_params */,
    193                                                const Buffer& input,
    194                                                AuthorizationSet* /* output_params */,
    195                                                Buffer* /* output */, size_t* input_consumed) {
    196     if (digest_ == KM_DIGEST_NONE)
    197         return StoreData(input, input_consumed);
    198 
    199     if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
    200         return TranslateLastOpenSslError();
    201     *input_consumed = input.available_read();
    202     return KM_ERROR_OK;
    203 }
    204 
    205 keymaster_error_t EcdsaVerifyOperation::Finish(const AuthorizationSet& additional_params,
    206                                                const Buffer& input, const Buffer& signature,
    207                                                AuthorizationSet* /* output_params */,
    208                                                Buffer* /* output */) {
    209     keymaster_error_t error = UpdateForFinish(additional_params, input);
    210     if (error != KM_ERROR_OK)
    211         return error;
    212 
    213     if (digest_ == KM_DIGEST_NONE) {
    214         UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_));
    215         if (!ecdsa.get())
    216             return TranslateLastOpenSslError();
    217 
    218         int result =
    219             ECDSA_verify(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
    220                          signature.peek_read(), signature.available_read(), ecdsa.get());
    221         if (result < 0)
    222             return TranslateLastOpenSslError();
    223         else if (result == 0)
    224             return KM_ERROR_VERIFICATION_FAILED;
    225     } else if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(),
    226                                       signature.available_read()))
    227         return KM_ERROR_VERIFICATION_FAILED;
    228 
    229     return KM_ERROR_OK;
    230 }
    231 
    232 }  // namespace keymaster
    233