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