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