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/curve25519.h>
20 #include <openssl/ecdsa.h>
21
22 #include <keymaster/km_openssl/ec_key.h>
23 #include <keymaster/km_openssl/openssl_err.h>
24 #include <keymaster/km_openssl/openssl_utils.h>
25
26 namespace keymaster {
27
28 // Message size limit for Ed25519 messages, which are not pre-digested.
29 static const size_t MAX_ED25519_MSG_SIZE = 16 * 1024;
30
31 static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_DIGEST_SHA1,
32 KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256,
33 KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
34
CreateOperation(Key && key,const AuthorizationSet & begin_params,keymaster_error_t * error)35 OperationPtr EcdsaOperationFactory::CreateOperation(Key&& key, const AuthorizationSet& begin_params,
36 keymaster_error_t* error) {
37 const AsymmetricKey& ecdsa_key = static_cast<AsymmetricKey&>(key);
38
39 EVP_PKEY_Ptr pkey(ecdsa_key.InternalToEvp());
40 if (pkey.get() == nullptr) {
41 *error = KM_ERROR_UNKNOWN_ERROR;
42 return nullptr;
43 }
44
45 keymaster_digest_t digest;
46 if (!GetAndValidateDigest(begin_params, ecdsa_key, &digest, error, true)) {
47 return nullptr;
48 }
49
50 *error = KM_ERROR_OK;
51 auto op = OperationPtr(InstantiateOperation(key.hw_enforced_move(), key.sw_enforced_move(),
52 digest, pkey.release()));
53 if (!op) *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
54 return op;
55 }
56
SupportedDigests(size_t * digest_count) const57 const keymaster_digest_t* EcdsaOperationFactory::SupportedDigests(size_t* digest_count) const {
58 *digest_count = array_length(supported_digests);
59 return supported_digests;
60 }
61
~EcdsaOperation()62 EcdsaOperation::~EcdsaOperation() {
63 if (ecdsa_key_ != nullptr) EVP_PKEY_free(ecdsa_key_);
64 EVP_MD_CTX_cleanup(&digest_ctx_);
65 }
66
InitDigest()67 keymaster_error_t EcdsaOperation::InitDigest() {
68 switch (digest_) {
69 case KM_DIGEST_NONE:
70 return KM_ERROR_OK;
71 case KM_DIGEST_MD5:
72 return KM_ERROR_UNSUPPORTED_DIGEST;
73 case KM_DIGEST_SHA1:
74 digest_algorithm_ = EVP_sha1();
75 return KM_ERROR_OK;
76 case KM_DIGEST_SHA_2_224:
77 digest_algorithm_ = EVP_sha224();
78 return KM_ERROR_OK;
79 case KM_DIGEST_SHA_2_256:
80 digest_algorithm_ = EVP_sha256();
81 return KM_ERROR_OK;
82 case KM_DIGEST_SHA_2_384:
83 digest_algorithm_ = EVP_sha384();
84 return KM_ERROR_OK;
85 case KM_DIGEST_SHA_2_512:
86 digest_algorithm_ = EVP_sha512();
87 return KM_ERROR_OK;
88 default:
89 return KM_ERROR_UNSUPPORTED_DIGEST;
90 }
91 }
92
min(size_t a,size_t b)93 inline size_t min(size_t a, size_t b) {
94 return (a < b) ? a : b;
95 }
96
StoreData(const Buffer & input,size_t * input_consumed)97 keymaster_error_t EcdsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
98 if (!data_.reserve((EVP_PKEY_bits(ecdsa_key_) + 7) / 8))
99 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
100
101 if (!data_.write(input.peek_read(), min(data_.available_write(), input.available_read())))
102 return KM_ERROR_UNKNOWN_ERROR;
103
104 *input_consumed = input.available_read();
105 return KM_ERROR_OK;
106 }
107
Begin(const AuthorizationSet &,AuthorizationSet *)108 keymaster_error_t EcdsaSignOperation::Begin(const AuthorizationSet& /* input_params */,
109 AuthorizationSet* /* output_params */) {
110 auto rc = GenerateRandom(reinterpret_cast<uint8_t*>(&operation_handle_),
111 (size_t)sizeof(operation_handle_));
112 if (rc != KM_ERROR_OK) return rc;
113
114 keymaster_error_t error = InitDigest();
115 if (error != KM_ERROR_OK) return error;
116
117 if (digest_ == KM_DIGEST_NONE) return KM_ERROR_OK;
118
119 EVP_PKEY_CTX* pkey_ctx;
120 if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
121 ecdsa_key_) != 1)
122 return TranslateLastOpenSslError();
123 return KM_ERROR_OK;
124 }
125
Update(const AuthorizationSet &,const Buffer & input,AuthorizationSet *,Buffer *,size_t * input_consumed)126 keymaster_error_t EcdsaSignOperation::Update(const AuthorizationSet& /* additional_params */,
127 const Buffer& input,
128 AuthorizationSet* /* output_params */,
129 Buffer* /* output */, size_t* input_consumed) {
130 if (digest_ == KM_DIGEST_NONE) 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
Finish(const AuthorizationSet & additional_params,const Buffer & input,const Buffer &,AuthorizationSet *,Buffer * output)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) return KM_ERROR_OUTPUT_PARAMETER_NULL;
143
144 keymaster_error_t error = UpdateForFinish(additional_params, input);
145 if (error != KM_ERROR_OK) return error;
146
147 size_t siglen;
148 if (digest_ == KM_DIGEST_NONE) {
149 UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_));
150 if (!ecdsa.get()) return TranslateLastOpenSslError();
151
152 output->Reinitialize(ECDSA_size(ecdsa.get()));
153 unsigned int siglen_tmp;
154 if (!ECDSA_sign(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
155 output->peek_write(), &siglen_tmp, ecdsa.get()))
156 return TranslateLastOpenSslError();
157 siglen = siglen_tmp;
158 } else {
159 if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
160 return TranslateLastOpenSslError();
161 if (!output->Reinitialize(siglen)) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
162 if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
163 return TranslateLastOpenSslError();
164 }
165 if (!output->advance_write(siglen)) return KM_ERROR_UNKNOWN_ERROR;
166 return KM_ERROR_OK;
167 }
168
Begin(const AuthorizationSet &,AuthorizationSet *)169 keymaster_error_t Ed25519SignOperation::Begin(const AuthorizationSet& /* input_params */,
170 AuthorizationSet* /* output_params */) {
171 if (digest_ != KM_DIGEST_NONE) {
172 // Ed25519 includes an internal digest, so no pre-digesting is supported.
173 return KM_ERROR_UNSUPPORTED_DIGEST;
174 }
175 return GenerateRandom(reinterpret_cast<uint8_t*>(&operation_handle_),
176 (size_t)sizeof(operation_handle_));
177 }
178
Update(const AuthorizationSet &,const Buffer & input,AuthorizationSet *,Buffer *,size_t * input_consumed)179 keymaster_error_t Ed25519SignOperation::Update(const AuthorizationSet& /* additional_params */,
180 const Buffer& input,
181 AuthorizationSet* /* output_params */,
182 Buffer* /* output */, size_t* input_consumed) {
183 return StoreAllData(input, input_consumed);
184 }
185
Finish(const AuthorizationSet & additional_params,const Buffer & input,const Buffer &,AuthorizationSet *,Buffer * output)186 keymaster_error_t Ed25519SignOperation::Finish(const AuthorizationSet& additional_params,
187 const Buffer& input, const Buffer& /* signature */,
188 AuthorizationSet* /* output_params */,
189 Buffer* output) {
190 if (!output) return KM_ERROR_OUTPUT_PARAMETER_NULL;
191
192 keymaster_error_t error = UpdateForFinish(additional_params, input);
193 if (error != KM_ERROR_OK) return error;
194
195 if (!output->Reinitialize(ED25519_SIGNATURE_LEN)) {
196 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
197 }
198
199 EVP_MD_CTX ctx;
200 EVP_MD_CTX_init(&ctx);
201 if (!EVP_DigestSignInit(&ctx, /* pctx */ nullptr, /* digest */ nullptr, /* engine */ nullptr,
202 ecdsa_key_)) {
203 EVP_MD_CTX_cleanup(&ctx);
204 return TranslateLastOpenSslError();
205 }
206 size_t out_len = ED25519_SIGNATURE_LEN;
207 if (!EVP_DigestSign(&ctx, output->peek_write(), &out_len, data_.peek_read(),
208 data_.available_read())) {
209 EVP_MD_CTX_cleanup(&ctx);
210 return TranslateLastOpenSslError();
211 }
212 EVP_MD_CTX_cleanup(&ctx);
213 output->advance_write(out_len);
214 return KM_ERROR_OK;
215 }
216
StoreAllData(const Buffer & input,size_t * input_consumed)217 keymaster_error_t Ed25519SignOperation::StoreAllData(const Buffer& input, size_t* input_consumed) {
218 if ((data_.available_read() + input.available_read()) > MAX_ED25519_MSG_SIZE) {
219 return KM_ERROR_INVALID_INPUT_LENGTH;
220 }
221 if (!data_.reserve(input.available_read())) {
222 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
223 }
224 if (!data_.write(input.peek_read(), input.available_read())) {
225 return KM_ERROR_UNKNOWN_ERROR;
226 }
227
228 *input_consumed = input.available_read();
229 return KM_ERROR_OK;
230 }
231
Begin(const AuthorizationSet &,AuthorizationSet *)232 keymaster_error_t EcdsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
233 AuthorizationSet* /* output_params */) {
234 auto rc = GenerateRandom(reinterpret_cast<uint8_t*>(&operation_handle_),
235 (size_t)sizeof(operation_handle_));
236 if (rc != KM_ERROR_OK) return rc;
237
238 keymaster_error_t error = InitDigest();
239 if (error != KM_ERROR_OK) return error;
240
241 if (digest_ == KM_DIGEST_NONE) return KM_ERROR_OK;
242
243 EVP_PKEY_CTX* pkey_ctx;
244 if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
245 ecdsa_key_) != 1)
246 return TranslateLastOpenSslError();
247 return KM_ERROR_OK;
248 }
249
Update(const AuthorizationSet &,const Buffer & input,AuthorizationSet *,Buffer *,size_t * input_consumed)250 keymaster_error_t EcdsaVerifyOperation::Update(const AuthorizationSet& /* additional_params */,
251 const Buffer& input,
252 AuthorizationSet* /* output_params */,
253 Buffer* /* output */, size_t* input_consumed) {
254 if (digest_ == KM_DIGEST_NONE) return StoreData(input, input_consumed);
255
256 if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
257 return TranslateLastOpenSslError();
258 *input_consumed = input.available_read();
259 return KM_ERROR_OK;
260 }
261
Finish(const AuthorizationSet & additional_params,const Buffer & input,const Buffer & signature,AuthorizationSet *,Buffer *)262 keymaster_error_t EcdsaVerifyOperation::Finish(const AuthorizationSet& additional_params,
263 const Buffer& input, const Buffer& signature,
264 AuthorizationSet* /* output_params */,
265 Buffer* /* output */) {
266 keymaster_error_t error = UpdateForFinish(additional_params, input);
267 if (error != KM_ERROR_OK) return error;
268
269 if (digest_ == KM_DIGEST_NONE) {
270 UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_));
271 if (!ecdsa.get()) return TranslateLastOpenSslError();
272
273 int result =
274 ECDSA_verify(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
275 signature.peek_read(), signature.available_read(), ecdsa.get());
276 if (result < 0)
277 return TranslateLastOpenSslError();
278 else if (result == 0)
279 return KM_ERROR_VERIFICATION_FAILED;
280 } else if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(),
281 signature.available_read()))
282 return KM_ERROR_VERIFICATION_FAILED;
283
284 return KM_ERROR_OK;
285 }
286
287 } // namespace keymaster
288