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