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