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 inline size_t min(size_t a, size_t b) {
     95     return (a < b) ? a : b;
     96 }
     97 
     98 keymaster_error_t EcdsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
     99     if (!data_.reserve((EVP_PKEY_bits(ecdsa_key_) + 7) / 8))
    100         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
    101 
    102     if (!data_.write(input.peek_read(), min(data_.available_write(), input.available_read())))
    103         return KM_ERROR_UNKNOWN_ERROR;
    104 
    105     *input_consumed = input.available_read();
    106     return KM_ERROR_OK;
    107 }
    108 
    109 keymaster_error_t EcdsaSignOperation::Begin(const AuthorizationSet& /* input_params */,
    110                                             AuthorizationSet* /* output_params */) {
    111     keymaster_error_t error = InitDigest();
    112     if (error != KM_ERROR_OK)
    113         return error;
    114 
    115     if (digest_ == KM_DIGEST_NONE)
    116         return KM_ERROR_OK;
    117 
    118     EVP_PKEY_CTX* pkey_ctx;
    119     if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
    120                            ecdsa_key_) != 1)
    121         return TranslateLastOpenSslError();
    122     return KM_ERROR_OK;
    123 }
    124 
    125 keymaster_error_t EcdsaSignOperation::Update(const AuthorizationSet& /* additional_params */,
    126                                              const Buffer& input,
    127                                              AuthorizationSet* /* output_params */,
    128                                              Buffer* /* output */, size_t* input_consumed) {
    129     if (digest_ == KM_DIGEST_NONE)
    130         return StoreData(input, input_consumed);
    131 
    132     if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
    133         return TranslateLastOpenSslError();
    134     *input_consumed = input.available_read();
    135     return KM_ERROR_OK;
    136 }
    137 
    138 keymaster_error_t EcdsaSignOperation::Finish(const AuthorizationSet& additional_params,
    139                                              const Buffer& input, const Buffer& /* signature */,
    140                                              AuthorizationSet* /* output_params */,
    141                                              Buffer* output) {
    142     if (!output)
    143         return KM_ERROR_OUTPUT_PARAMETER_NULL;
    144 
    145     keymaster_error_t error = UpdateForFinish(additional_params, input);
    146     if (error != KM_ERROR_OK)
    147         return error;
    148 
    149     size_t siglen;
    150     if (digest_ == KM_DIGEST_NONE) {
    151         UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_));
    152         if (!ecdsa.get())
    153             return TranslateLastOpenSslError();
    154 
    155         output->Reinitialize(ECDSA_size(ecdsa.get()));
    156         unsigned int siglen_tmp;
    157         if (!ECDSA_sign(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
    158                         output->peek_write(), &siglen_tmp, ecdsa.get()))
    159             return TranslateLastOpenSslError();
    160         siglen = siglen_tmp;
    161     } else {
    162         if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
    163             return TranslateLastOpenSslError();
    164         if (!output->Reinitialize(siglen))
    165             return KM_ERROR_MEMORY_ALLOCATION_FAILED;
    166         if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
    167             return TranslateLastOpenSslError();
    168     }
    169     if (!output->advance_write(siglen))
    170         return KM_ERROR_UNKNOWN_ERROR;
    171     return KM_ERROR_OK;
    172 }
    173 
    174 keymaster_error_t EcdsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
    175                                               AuthorizationSet* /* output_params */) {
    176     keymaster_error_t error = InitDigest();
    177     if (error != KM_ERROR_OK)
    178         return error;
    179 
    180     if (digest_ == KM_DIGEST_NONE)
    181         return KM_ERROR_OK;
    182 
    183     EVP_PKEY_CTX* pkey_ctx;
    184     if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
    185                              ecdsa_key_) != 1)
    186         return TranslateLastOpenSslError();
    187     return KM_ERROR_OK;
    188 }
    189 
    190 keymaster_error_t EcdsaVerifyOperation::Update(const AuthorizationSet& /* additional_params */,
    191                                                const Buffer& input,
    192                                                AuthorizationSet* /* output_params */,
    193                                                Buffer* /* output */, size_t* input_consumed) {
    194     if (digest_ == KM_DIGEST_NONE)
    195         return StoreData(input, input_consumed);
    196 
    197     if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
    198         return TranslateLastOpenSslError();
    199     *input_consumed = input.available_read();
    200     return KM_ERROR_OK;
    201 }
    202 
    203 keymaster_error_t EcdsaVerifyOperation::Finish(const AuthorizationSet& additional_params,
    204                                                const Buffer& input, const Buffer& signature,
    205                                                AuthorizationSet* /* output_params */,
    206                                                Buffer* /* output */) {
    207     keymaster_error_t error = UpdateForFinish(additional_params, input);
    208     if (error != KM_ERROR_OK)
    209         return error;
    210 
    211     if (digest_ == KM_DIGEST_NONE) {
    212         UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_));
    213         if (!ecdsa.get())
    214             return TranslateLastOpenSslError();
    215 
    216         int result =
    217             ECDSA_verify(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
    218                          signature.peek_read(), signature.available_read(), ecdsa.get());
    219         if (result < 0)
    220             return TranslateLastOpenSslError();
    221         else if (result == 0)
    222             return KM_ERROR_VERIFICATION_FAILED;
    223     } else if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(),
    224                                       signature.available_read()))
    225         return KM_ERROR_VERIFICATION_FAILED;
    226 
    227     return KM_ERROR_OK;
    228 }
    229 
    230 }  // namespace keymaster
    231