1c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden/* 2c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * Copyright 2014 The Android Open Source Project 3c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * 4c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * Licensed under the Apache License, Version 2.0 (the "License"); 5c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * you may not use this file except in compliance with the License. 6c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * You may obtain a copy of the License at 7c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * 8c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * http://www.apache.org/licenses/LICENSE-2.0 9c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * 10c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * Unless required by applicable law or agreed to in writing, software 11c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * distributed under the License is distributed on an "AS IS" BASIS, 12c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * See the License for the specific language governing permissions and 14c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden * limitations under the License. 15c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden */ 16c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden 17efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden#include "ecdsa_operation.h" 18efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 19c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden#include <openssl/ecdsa.h> 20c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden 21f862a764e4d20495d484664de852e4d6de26f08bThai Duong#include "ec_key.h" 22567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden#include "openssl_err.h" 23c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden#include "openssl_utils.h" 24c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden 25c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willdennamespace keymaster { 26c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden 270d061c80d06f94291568e725f9eb649962a80352Shawn Willdenstatic const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_DIGEST_SHA1, 280d061c80d06f94291568e725f9eb649962a80352Shawn Willden KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256, 290d061c80d06f94291568e725f9eb649962a80352Shawn Willden KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512}; 3084b8da52a242c42d9a6a8cc8f128fb4c8baa6f8fShawn Willden 3113e29e0e2a3377ec50b5168b4384d3912559bb63Shawn WilldenOperation* EcdsaOperationFactory::CreateOperation(const Key& key, 32226746bfb5f79857145d5f3ebdfd6f49b6c114acShawn Willden const AuthorizationSet& begin_params, 3313e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden keymaster_error_t* error) { 3413e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden const EcKey* ecdsa_key = static_cast<const EcKey*>(&key); 3513e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden if (!ecdsa_key) { 3613e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 3713e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden return nullptr; 3813e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden } 3984b8da52a242c42d9a6a8cc8f128fb4c8baa6f8fShawn Willden 40efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); 41efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (!ecdsa_key->InternalToEvp(pkey.get())) { 42efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 43226746bfb5f79857145d5f3ebdfd6f49b6c114acShawn Willden return nullptr; 4463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden } 45226746bfb5f79857145d5f3ebdfd6f49b6c114acShawn Willden 46efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden keymaster_digest_t digest; 47efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (!GetAndValidateDigest(begin_params, key, &digest, error)) 48efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return nullptr; 49efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 50efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden *error = KM_ERROR_OK; 51efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden Operation* op = InstantiateOperation(digest, pkey.release()); 5213e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden if (!op) 5313e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 5413e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden return op; 5513e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden} 5684b8da52a242c42d9a6a8cc8f128fb4c8baa6f8fShawn Willden 5713e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willdenconst keymaster_digest_t* EcdsaOperationFactory::SupportedDigests(size_t* digest_count) const { 5813e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden *digest_count = array_length(supported_digests); 5913e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden return supported_digests; 6013e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden} 6113e29e0e2a3377ec50b5168b4384d3912559bb63Shawn Willden 625ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn WilldenEcdsaOperation::~EcdsaOperation() { 635ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden if (ecdsa_key_ != NULL) 64efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden EVP_PKEY_free(ecdsa_key_); 65efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden EVP_MD_CTX_cleanup(&digest_ctx_); 665ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden} 675ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden 68efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willdenkeymaster_error_t EcdsaOperation::InitDigest() { 69efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden switch (digest_) { 70efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden case KM_DIGEST_NONE: 71efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 72efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden case KM_DIGEST_MD5: 730d061c80d06f94291568e725f9eb649962a80352Shawn Willden return KM_ERROR_UNSUPPORTED_DIGEST; 74efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden case KM_DIGEST_SHA1: 75efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden digest_algorithm_ = EVP_sha1(); 76efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 77efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden case KM_DIGEST_SHA_2_224: 78efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden digest_algorithm_ = EVP_sha224(); 79efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 80efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden case KM_DIGEST_SHA_2_256: 81efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden digest_algorithm_ = EVP_sha256(); 82efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 83efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden case KM_DIGEST_SHA_2_384: 84efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden digest_algorithm_ = EVP_sha384(); 85efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 86efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden case KM_DIGEST_SHA_2_512: 87efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden digest_algorithm_ = EVP_sha512(); 88efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 895ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden default: 90efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_UNSUPPORTED_DIGEST; 915ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden } 925ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden} 935ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden 94d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdeninline size_t min(size_t a, size_t b) { 95d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden return (a < b) ? a : b; 96d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden} 97d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden 98b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willdenkeymaster_error_t EcdsaOperation::StoreData(const Buffer& input, size_t* input_consumed) { 992101e9e8215cce6da36d8d7382486737b68e8c93Shawn Willden if (!data_.reserve((EVP_PKEY_bits(ecdsa_key_) + 7) / 8)) 100d67afae61f822463120c36fea846362450dd7d71Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 101d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden 102d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden if (!data_.write(input.peek_read(), min(data_.available_write(), input.available_read()))) 103d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 104d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden 105b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden *input_consumed = input.available_read(); 1065ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden return KM_ERROR_OK; 1075ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden} 1085ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden 109efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willdenkeymaster_error_t EcdsaSignOperation::Begin(const AuthorizationSet& /* input_params */, 110efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden AuthorizationSet* /* output_params */) { 111efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden keymaster_error_t error = InitDigest(); 112efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (error != KM_ERROR_OK) 113efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return error; 114efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 115efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (digest_ == KM_DIGEST_NONE) 116efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 117efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 118efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden EVP_PKEY_CTX* pkey_ctx; 119efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */, 120efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden ecdsa_key_) != 1) 121efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 122efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 123efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden} 124efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 125efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willdenkeymaster_error_t EcdsaSignOperation::Update(const AuthorizationSet& /* additional_params */, 126ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden const Buffer& input, 127ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden AuthorizationSet* /* output_params */, 128ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden Buffer* /* output */, size_t* input_consumed) { 129efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (digest_ == KM_DIGEST_NONE) 130efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return StoreData(input, input_consumed); 131efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 132efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1) 133efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 134efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden *input_consumed = input.available_read(); 135efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 136efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden} 137efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 138cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willdenkeymaster_error_t EcdsaSignOperation::Finish(const AuthorizationSet& additional_params, 139cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden const Buffer& input, const Buffer& /* signature */, 140ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden AuthorizationSet* /* output_params */, 141ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden Buffer* output) { 142efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (!output) 143efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OUTPUT_PARAMETER_NULL; 144efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 145cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden keymaster_error_t error = UpdateForFinish(additional_params, input); 146cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden if (error != KM_ERROR_OK) 147cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden return error; 148cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden 149efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden size_t siglen; 150efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (digest_ == KM_DIGEST_NONE) { 151fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_)); 152efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (!ecdsa.get()) 153efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 154efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 155efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden output->Reinitialize(ECDSA_size(ecdsa.get())); 156efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden unsigned int siglen_tmp; 157efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (!ECDSA_sign(0 /* type -- ignored */, data_.peek_read(), data_.available_read(), 158efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden output->peek_write(), &siglen_tmp, ecdsa.get())) 159efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 160efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden siglen = siglen_tmp; 161efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden } else { 162efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1) 163efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 164efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (!output->Reinitialize(siglen)) 165efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 166efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0) 167efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 168efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden } 1690f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden if (!output->advance_write(siglen)) 1700f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 171d67afae61f822463120c36fea846362450dd7d71Shawn Willden return KM_ERROR_OK; 172d67afae61f822463120c36fea846362450dd7d71Shawn Willden} 173d67afae61f822463120c36fea846362450dd7d71Shawn Willden 174efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willdenkeymaster_error_t EcdsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */, 175efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden AuthorizationSet* /* output_params */) { 176efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden keymaster_error_t error = InitDigest(); 177efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (error != KM_ERROR_OK) 178efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return error; 179efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 180efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (digest_ == KM_DIGEST_NONE) 181efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 182efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 183efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden EVP_PKEY_CTX* pkey_ctx; 184efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */, 185efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden ecdsa_key_) != 1) 186efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 187efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 188efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden} 189efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 190efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willdenkeymaster_error_t EcdsaVerifyOperation::Update(const AuthorizationSet& /* additional_params */, 191ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden const Buffer& input, 192ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden AuthorizationSet* /* output_params */, 193ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden Buffer* /* output */, size_t* input_consumed) { 194efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (digest_ == KM_DIGEST_NONE) 195efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return StoreData(input, input_consumed); 196efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 197efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1) 198efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 199efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden *input_consumed = input.available_read(); 200efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 201efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden} 202efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 203cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willdenkeymaster_error_t EcdsaVerifyOperation::Finish(const AuthorizationSet& additional_params, 204cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden const Buffer& input, const Buffer& signature, 205ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden AuthorizationSet* /* output_params */, 206ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden Buffer* /* output */) { 207cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden keymaster_error_t error = UpdateForFinish(additional_params, input); 208cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden if (error != KM_ERROR_OK) 209cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden return error; 210cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden 211efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (digest_ == KM_DIGEST_NONE) { 212fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_)); 213efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (!ecdsa.get()) 214efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 215efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 216efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden int result = 217efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden ECDSA_verify(0 /* type -- ignored */, data_.peek_read(), data_.available_read(), 218efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden signature.peek_read(), signature.available_read(), ecdsa.get()); 219efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden if (result < 0) 220efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return TranslateLastOpenSslError(); 221efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden else if (result == 0) 222efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_VERIFICATION_FAILED; 223efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden } else if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), 224efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden signature.available_read())) 225d67afae61f822463120c36fea846362450dd7d71Shawn Willden return KM_ERROR_VERIFICATION_FAILED; 226efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden 227efbd7e432228cf1e65abb6d85dffa38ec03f7a26Shawn Willden return KM_ERROR_OK; 2285ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden} 2295ac2f8ff7c82d2b5c2dd17273ce58c7806df0ec2Shawn Willden 230c3864dde9ffa9a52bb60802664e1cab1de5c0287Shawn Willden} // namespace keymaster 231