blob: 4b66b34e0386a2ca1d08b0fd570be3ff3ea44883 [file] [log] [blame]
Shawn Willden0a4df7e2014-08-28 16:09:05 -06001/*
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
Shawn Willden63ac0432014-12-29 14:07:08 -070017#include "rsa_operation.h"
18
Shawn Willden4200f212014-12-02 07:01:21 -070019#include <limits.h>
20
21#include <openssl/err.h>
Shawn Willden0a4df7e2014-08-28 16:09:05 -060022
Shawn Willden567a4a02014-12-31 12:14:46 -070023#include <keymaster/logger.h>
24
25#include "openssl_err.h"
Shawn Willden0a4df7e2014-08-28 16:09:05 -060026#include "openssl_utils.h"
Shawn Willden63ac0432014-12-29 14:07:08 -070027#include "rsa_key.h"
Shawn Willden0a4df7e2014-08-28 16:09:05 -060028
29namespace keymaster {
30
Shawn Willdenf90f2352014-12-18 23:01:15 -070031static const int MIN_PSS_SALT_LEN = 8 /* salt len */ + 2 /* overhead */;
32
Shawn Willden63ac0432014-12-29 14:07:08 -070033/* static */
Shawn Willden2bf4ad32015-06-01 07:33:51 -060034EVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070035 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
36 assert(rsa_key);
37 if (!rsa_key || !rsa_key->key()) {
38 *error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060039 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070040 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -060041
42 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
43 if (!rsa_key->InternalToEvp(pkey.get())) {
44 *error = KM_ERROR_UNKNOWN_ERROR;
45 return nullptr;
46 }
47 return pkey.release();
Shawn Willden63ac0432014-12-29 14:07:08 -070048}
49
Shawn Willden2bf4ad32015-06-01 07:33:51 -060050static const keymaster_digest_t supported_digests[] = {
51 KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
52 KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
Shawn Willdenf90f2352014-12-18 23:01:15 -070053static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
54 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070055
Shawn Willden06298102015-05-25 23:12:48 -060056const keymaster_digest_t*
57RsaDigestingOperationFactory::SupportedDigests(size_t* digest_count) const {
58 *digest_count = array_length(supported_digests);
59 return supported_digests;
60}
Shawn Willden63ac0432014-12-29 14:07:08 -070061
Shawn Willden06298102015-05-25 23:12:48 -060062const keymaster_padding_t*
63RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
64 *padding_mode_count = array_length(supported_sig_padding);
65 return supported_sig_padding;
66}
Shawn Willden63ac0432014-12-29 14:07:08 -070067
Shawn Willden3ed6d062015-04-15 13:39:38 -060068Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
Shawn Willden226746b2015-05-08 11:36:56 -060069 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060070 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070071 keymaster_padding_t padding;
72 keymaster_digest_t digest;
Shawn Willden226746b2015-05-08 11:36:56 -060073 if (!GetAndValidateDigest(begin_params, key, &digest, error) ||
Shawn Willden2bf4ad32015-06-01 07:33:51 -060074 !GetAndValidatePadding(begin_params, key, &padding, error))
75 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070076
Shawn Willden2bf4ad32015-06-01 07:33:51 -060077 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
78 if (!rsa.get())
79 return nullptr;
80
81 Operation* op = InstantiateOperation(digest, padding, rsa.release());
Shawn Willden63ac0432014-12-29 14:07:08 -070082 if (!op)
83 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
84 return op;
85}
86
Shawn Willden30160842015-06-01 08:31:00 -060087static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
Shawn Willden63ac0432014-12-29 14:07:08 -070088 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
89
Shawn Willden3ed6d062015-04-15 13:39:38 -060090Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
Shawn Willden3ad5f052015-05-08 14:05:13 -060091 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060092 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070093 keymaster_padding_t padding;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060094 if (!GetAndValidatePadding(begin_params, key, &padding, error))
95 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070096
Shawn Willden2bf4ad32015-06-01 07:33:51 -060097 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
98 if (!rsa.get())
99 return nullptr;
100
101 Operation* op = InstantiateOperation(padding, rsa.release());
Shawn Willden63ac0432014-12-29 14:07:08 -0700102 if (!op)
103 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
104 return op;
105}
106
Shawn Willden06298102015-05-25 23:12:48 -0600107const keymaster_padding_t*
108RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
109 *padding_mode_count = array_length(supported_crypt_padding);
110 return supported_crypt_padding;
111}
Shawn Willden63ac0432014-12-29 14:07:08 -0700112
Shawn Willden06298102015-05-25 23:12:48 -0600113const keymaster_digest_t*
114RsaCryptingOperationFactory::SupportedDigests(size_t* digest_count) const {
115 *digest_count = 0;
116 return NULL;
117}
Shawn Willden63ac0432014-12-29 14:07:08 -0700118
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600119RsaOperation::~RsaOperation() {
120 if (rsa_key_ != NULL)
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600121 EVP_PKEY_free(rsa_key_);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600122}
123
Shawn Willden6bfbff02015-02-06 19:48:24 -0700124keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600125 const Buffer& input, AuthorizationSet* /* output_params */,
126 Buffer* /* output */, size_t* input_consumed) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700127 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600128 switch (purpose()) {
129 default:
130 return KM_ERROR_UNIMPLEMENTED;
131 case KM_PURPOSE_SIGN:
132 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700133 case KM_PURPOSE_ENCRYPT:
134 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700135 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600136 }
137}
138
Shawn Willdenb7361132014-12-08 08:15:14 -0700139keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
140 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600141 if (!data_.reserve(data_.available_read() + input.available_read()) ||
142 !data_.write(input.peek_read(), input.available_read()))
143 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700144 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600145 return KM_ERROR_OK;
146}
147
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600148keymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx) {
149 keymaster_error_t error;
150 int openssl_padding = GetOpensslPadding(&error);
151 if (error != KM_ERROR_OK)
152 return error;
153
154 if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, openssl_padding) <= 0)
155 return TranslateLastOpenSslError();
156 return KM_ERROR_OK;
157}
158
Shawn Willden61902362014-12-18 10:33:24 -0700159RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600160 keymaster_padding_t padding, EVP_PKEY* key)
Shawn Willden61902362014-12-18 10:33:24 -0700161 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
162 EVP_MD_CTX_init(&digest_ctx_);
163}
164RsaDigestingOperation::~RsaDigestingOperation() {
165 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700166}
167
168keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600169 if (digest_ == KM_DIGEST_NONE) {
170 if (require_digest())
171 return KM_ERROR_INCOMPATIBLE_DIGEST;
172 return KM_ERROR_OK;
173 }
174
Shawn Willden61902362014-12-18 10:33:24 -0700175 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700176 case KM_DIGEST_NONE:
177 return KM_ERROR_OK;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600178 case KM_DIGEST_MD5:
179 digest_algorithm_ = EVP_md5();
180 return KM_ERROR_OK;
181 case KM_DIGEST_SHA1:
182 digest_algorithm_ = EVP_sha1();
183 return KM_ERROR_OK;
184 case KM_DIGEST_SHA_2_224:
185 digest_algorithm_ = EVP_sha224();
186 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700187 case KM_DIGEST_SHA_2_256:
188 digest_algorithm_ = EVP_sha256();
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600189 return KM_ERROR_OK;
190 case KM_DIGEST_SHA_2_384:
191 digest_algorithm_ = EVP_sha384();
192 return KM_ERROR_OK;
193 case KM_DIGEST_SHA_2_512:
194 digest_algorithm_ = EVP_sha512();
195 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700196 default:
197 return KM_ERROR_UNSUPPORTED_DIGEST;
198 }
Shawn Willden61902362014-12-18 10:33:24 -0700199}
200
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600201const size_t PSS_OVERHEAD = 2;
202const size_t MIN_SALT_SIZE = 8;
203
204int RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) {
205 *error = KM_ERROR_OK;
206 switch (padding_) {
207 case KM_PAD_NONE:
208 return RSA_NO_PADDING;
209 case KM_PAD_RSA_PKCS1_1_5_SIGN:
210
211 return RSA_PKCS1_PADDING;
212 case KM_PAD_RSA_PSS:
213 if (digest_ == KM_DIGEST_NONE) {
214 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
215 return -1;
216 }
217 if (EVP_MD_size(digest_algorithm_) + PSS_OVERHEAD + MIN_SALT_SIZE >
218 (size_t)EVP_PKEY_size(rsa_key_)) {
219 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
220 return -1;
221 }
222 return RSA_PKCS1_PSS_PADDING;
223 default:
224 return -1;
Shawn Willden61902362014-12-18 10:33:24 -0700225 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600226}
227
228keymaster_error_t RsaSignOperation::Begin(const AuthorizationSet& /* input_params */,
229 AuthorizationSet* /* output_params */) {
230 keymaster_error_t error = InitDigest();
231 if (error != KM_ERROR_OK)
232 return error;
233
234 if (digest_ == KM_DIGEST_NONE)
235 return KM_ERROR_OK;
236
237 EVP_PKEY_CTX* pkey_ctx;
238 if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
239 rsa_key_) != 1)
240 return TranslateLastOpenSslError();
241 return SetRsaPaddingInEvpContext(pkey_ctx);
242}
243
244keymaster_error_t RsaSignOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600245 const Buffer& input, AuthorizationSet* output_params,
246 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600247 if (digest_ == KM_DIGEST_NONE)
248 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600249 return RsaOperation::Update(additional_params, input, output_params, output,
250 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600251
252 if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
253 return TranslateLastOpenSslError();
Shawn Willden61902362014-12-18 10:33:24 -0700254 *input_consumed = input.available_read();
255 return KM_ERROR_OK;
256}
257
Shawn Willden6bfbff02015-02-06 19:48:24 -0700258keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600259 const Buffer& /* signature */,
260 AuthorizationSet* /* output_params */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700261 assert(output);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600262
Shawn Willdenf90f2352014-12-18 23:01:15 -0700263 if (digest_ == KM_DIGEST_NONE)
264 return SignUndigested(output);
265 else
266 return SignDigested(output);
267}
Shawn Willden61902362014-12-18 10:33:24 -0700268
Shawn Willdenf90f2352014-12-18 23:01:15 -0700269keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600270 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
271 if (!rsa.get())
272 return TranslateLastOpenSslError();
273
274 if (!output->Reinitialize(RSA_size(rsa.get())))
275 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
276
Shawn Willdenf90f2352014-12-18 23:01:15 -0700277 int bytes_encrypted;
278 switch (padding_) {
279 case KM_PAD_NONE:
280 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600281 output->peek_write(), rsa.get(), RSA_NO_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700282 break;
283 case KM_PAD_RSA_PKCS1_1_5_SIGN:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600284 // Does PKCS1 padding without digesting even make sense? Dunno. We'll support it.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700285 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600286 output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700287 break;
288 default:
289 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
290 }
Shawn Willden61902362014-12-18 10:33:24 -0700291
Shawn Willdenf90f2352014-12-18 23:01:15 -0700292 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600293 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600294 output->advance_write(bytes_encrypted);
295 return KM_ERROR_OK;
296}
297
Shawn Willdenf90f2352014-12-18 23:01:15 -0700298keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600299 size_t siglen;
300 if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
301 return TranslateLastOpenSslError();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700302
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600303 if (!output->Reinitialize(siglen))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700304 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
305
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600306 if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
307 return TranslateLastOpenSslError();
308 output->advance_write(siglen);
309
Shawn Willdenf90f2352014-12-18 23:01:15 -0700310 return KM_ERROR_OK;
311}
312
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600313keymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
314 AuthorizationSet* /* output_params */) {
315 keymaster_error_t error = InitDigest();
316 if (error != KM_ERROR_OK)
317 return error;
318
319 if (digest_ == KM_DIGEST_NONE)
320 return KM_ERROR_OK;
321
322 EVP_PKEY_CTX* pkey_ctx;
323 if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
324 return TranslateLastOpenSslError();
325 return SetRsaPaddingInEvpContext(pkey_ctx);
326}
327
328keymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600329 const Buffer& input, AuthorizationSet* output_params,
330 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600331 if (digest_ == KM_DIGEST_NONE)
332 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600333 return RsaOperation::Update(additional_params, input, output_params, output,
334 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600335
336 if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
337 return TranslateLastOpenSslError();
338 *input_consumed = input.available_read();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700339 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700340}
341
Shawn Willden6bfbff02015-02-06 19:48:24 -0700342keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600343 const Buffer& signature,
344 AuthorizationSet* /* output_params */,
345 Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700346 if (digest_ == KM_DIGEST_NONE)
347 return VerifyUndigested(signature);
348 else
349 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700350}
351
Shawn Willdenf90f2352014-12-18 23:01:15 -0700352keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600353 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
354 if (!rsa.get())
355 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700356
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600357 size_t key_len = RSA_size(rsa.get());
Shawn Willdenf90f2352014-12-18 23:01:15 -0700358 int openssl_padding;
359 switch (padding_) {
360 case KM_PAD_NONE:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600361 if (data_.available_read() != key_len)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700362 return KM_ERROR_INVALID_INPUT_LENGTH;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600363 if (data_.available_read() != signature.available_read())
Shawn Willdenf90f2352014-12-18 23:01:15 -0700364 return KM_ERROR_VERIFICATION_FAILED;
365 openssl_padding = RSA_NO_PADDING;
366 break;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700367 case KM_PAD_RSA_PKCS1_1_5_SIGN:
368 openssl_padding = RSA_PKCS1_PADDING;
369 break;
370 default:
371 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
372 }
373
374 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
375 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600376 decrypted_data.get(), rsa.get(), openssl_padding);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700377 if (bytes_decrypted < 0)
378 return KM_ERROR_VERIFICATION_FAILED;
379
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600380 if (memcmp_s(decrypted_data.get(), data_.peek_read(), data_.available_read()) != 0)
381 return KM_ERROR_VERIFICATION_FAILED;
382 return KM_ERROR_OK;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600383}
384
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600385keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
386 if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
387 return KM_ERROR_VERIFICATION_FAILED;
388 return KM_ERROR_OK;
389}
390
391int RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
392 *error = KM_ERROR_OK;
393 switch (padding_) {
Shawn Willden30160842015-06-01 08:31:00 -0600394 case KM_PAD_NONE:
395 return RSA_NO_PADDING;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600396 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
397 return RSA_PKCS1_PADDING;
398 case KM_PAD_RSA_OAEP:
399 return RSA_PKCS1_OAEP_PADDING;
400 default:
401 return -1;
402 }
403}
404
405struct EVP_PKEY_CTX_Delete {
406 void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
407};
Shawn Willden4200f212014-12-02 07:01:21 -0700408
Shawn Willden6bfbff02015-02-06 19:48:24 -0700409keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600410 const Buffer& /* signature */,
411 AuthorizationSet* /* output_params */,
412 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700413 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700414
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600415 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
416 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
417 if (!ctx.get())
418 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700419
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600420 if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
421 return TranslateLastOpenSslError();
Shawn Willden4200f212014-12-02 07:01:21 -0700422
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600423 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
424 if (error != KM_ERROR_OK)
425 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700426
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600427 size_t outlen;
428 if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
429 data_.available_read()) <= 0)
430 return TranslateLastOpenSslError();
431
432 if (!output->Reinitialize(outlen))
433 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
434
435 if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
436 data_.available_read()) <= 0)
437 return TranslateLastOpenSslError();
438 output->advance_write(outlen);
Shawn Willden4200f212014-12-02 07:01:21 -0700439
440 return KM_ERROR_OK;
441}
442
Shawn Willden6bfbff02015-02-06 19:48:24 -0700443keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600444 const Buffer& /* signature */,
445 AuthorizationSet* /* output_params */,
446 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700447 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700448
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600449 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
450 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
451 if (!ctx.get())
452 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700453
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600454 if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
455 return TranslateLastOpenSslError();
456
457 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
458 if (error != KM_ERROR_OK)
459 return error;
460
461 size_t outlen;
462 if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
463 data_.available_read()) <= 0)
464 return TranslateLastOpenSslError();
465
466 if (!output->Reinitialize(outlen))
467 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
468
469 if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
470 data_.available_read()) <= 0)
471 return TranslateLastOpenSslError();
472 output->advance_write(outlen);
Shawn Willden4200f212014-12-02 07:01:21 -0700473
474 return KM_ERROR_OK;
475}
476
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600477} // namespace keymaster