blob: edbaa9eff4ced4a14f5452413422467858900bb4 [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 Willden63ac0432014-12-29 14:07:08 -070031/* static */
Shawn Willden2bf4ad32015-06-01 07:33:51 -060032EVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070033 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
34 assert(rsa_key);
35 if (!rsa_key || !rsa_key->key()) {
36 *error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060037 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070038 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -060039
40 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
41 if (!rsa_key->InternalToEvp(pkey.get())) {
42 *error = KM_ERROR_UNKNOWN_ERROR;
43 return nullptr;
44 }
45 return pkey.release();
Shawn Willden63ac0432014-12-29 14:07:08 -070046}
47
Shawn Willden2bf4ad32015-06-01 07:33:51 -060048static const keymaster_digest_t supported_digests[] = {
49 KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
50 KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
Shawn Willdenf90f2352014-12-18 23:01:15 -070051static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
52 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070053
Shawn Willden06298102015-05-25 23:12:48 -060054const keymaster_digest_t*
55RsaDigestingOperationFactory::SupportedDigests(size_t* digest_count) const {
56 *digest_count = array_length(supported_digests);
57 return supported_digests;
58}
Shawn Willden63ac0432014-12-29 14:07:08 -070059
Shawn Willden06298102015-05-25 23:12:48 -060060const keymaster_padding_t*
61RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
62 *padding_mode_count = array_length(supported_sig_padding);
63 return supported_sig_padding;
64}
Shawn Willden63ac0432014-12-29 14:07:08 -070065
Shawn Willden3ed6d062015-04-15 13:39:38 -060066Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
Shawn Willden226746b2015-05-08 11:36:56 -060067 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060068 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070069 keymaster_padding_t padding;
70 keymaster_digest_t digest;
Shawn Willden226746b2015-05-08 11:36:56 -060071 if (!GetAndValidateDigest(begin_params, key, &digest, error) ||
Shawn Willden2bf4ad32015-06-01 07:33:51 -060072 !GetAndValidatePadding(begin_params, key, &padding, error))
73 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070074
Shawn Willden2bf4ad32015-06-01 07:33:51 -060075 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
76 if (!rsa.get())
77 return nullptr;
78
79 Operation* op = InstantiateOperation(digest, padding, rsa.release());
Shawn Willden63ac0432014-12-29 14:07:08 -070080 if (!op)
81 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
82 return op;
83}
84
Shawn Willden30160842015-06-01 08:31:00 -060085static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
Shawn Willden63ac0432014-12-29 14:07:08 -070086 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
87
Shawn Willden3ed6d062015-04-15 13:39:38 -060088Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
Shawn Willden3ad5f052015-05-08 14:05:13 -060089 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060090 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070091 keymaster_padding_t padding;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060092 if (!GetAndValidatePadding(begin_params, key, &padding, error))
93 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070094
Shawn Willden2bf4ad32015-06-01 07:33:51 -060095 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
96 if (!rsa.get())
97 return nullptr;
98
99 Operation* op = InstantiateOperation(padding, rsa.release());
Shawn Willden63ac0432014-12-29 14:07:08 -0700100 if (!op)
101 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
102 return op;
103}
104
Shawn Willden06298102015-05-25 23:12:48 -0600105const keymaster_padding_t*
106RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
107 *padding_mode_count = array_length(supported_crypt_padding);
108 return supported_crypt_padding;
109}
Shawn Willden63ac0432014-12-29 14:07:08 -0700110
Shawn Willden06298102015-05-25 23:12:48 -0600111const keymaster_digest_t*
112RsaCryptingOperationFactory::SupportedDigests(size_t* digest_count) const {
113 *digest_count = 0;
114 return NULL;
115}
Shawn Willden63ac0432014-12-29 14:07:08 -0700116
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600117RsaOperation::~RsaOperation() {
118 if (rsa_key_ != NULL)
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600119 EVP_PKEY_free(rsa_key_);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600120}
121
Shawn Willden6bfbff02015-02-06 19:48:24 -0700122keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600123 const Buffer& input, AuthorizationSet* /* output_params */,
124 Buffer* /* output */, size_t* input_consumed) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700125 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600126 switch (purpose()) {
127 default:
128 return KM_ERROR_UNIMPLEMENTED;
129 case KM_PURPOSE_SIGN:
130 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700131 case KM_PURPOSE_ENCRYPT:
132 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700133 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600134 }
135}
136
Shawn Willdenb7361132014-12-08 08:15:14 -0700137keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
138 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600139 if (!data_.reserve(data_.available_read() + input.available_read()) ||
140 !data_.write(input.peek_read(), input.available_read()))
141 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700142 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600143 return KM_ERROR_OK;
144}
145
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600146keymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx) {
147 keymaster_error_t error;
148 int openssl_padding = GetOpensslPadding(&error);
149 if (error != KM_ERROR_OK)
150 return error;
151
152 if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, openssl_padding) <= 0)
153 return TranslateLastOpenSslError();
154 return KM_ERROR_OK;
155}
156
Shawn Willden61902362014-12-18 10:33:24 -0700157RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600158 keymaster_padding_t padding, EVP_PKEY* key)
Shawn Willden61902362014-12-18 10:33:24 -0700159 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
160 EVP_MD_CTX_init(&digest_ctx_);
161}
162RsaDigestingOperation::~RsaDigestingOperation() {
163 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700164}
165
166keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600167 if (digest_ == KM_DIGEST_NONE) {
168 if (require_digest())
169 return KM_ERROR_INCOMPATIBLE_DIGEST;
170 return KM_ERROR_OK;
171 }
172
Shawn Willden61902362014-12-18 10:33:24 -0700173 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700174 case KM_DIGEST_NONE:
175 return KM_ERROR_OK;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600176 case KM_DIGEST_MD5:
177 digest_algorithm_ = EVP_md5();
178 return KM_ERROR_OK;
179 case KM_DIGEST_SHA1:
180 digest_algorithm_ = EVP_sha1();
181 return KM_ERROR_OK;
182 case KM_DIGEST_SHA_2_224:
183 digest_algorithm_ = EVP_sha224();
184 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700185 case KM_DIGEST_SHA_2_256:
186 digest_algorithm_ = EVP_sha256();
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600187 return KM_ERROR_OK;
188 case KM_DIGEST_SHA_2_384:
189 digest_algorithm_ = EVP_sha384();
190 return KM_ERROR_OK;
191 case KM_DIGEST_SHA_2_512:
192 digest_algorithm_ = EVP_sha512();
193 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700194 default:
195 return KM_ERROR_UNSUPPORTED_DIGEST;
196 }
Shawn Willden61902362014-12-18 10:33:24 -0700197}
198
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600199const size_t PSS_OVERHEAD = 2;
200const size_t MIN_SALT_SIZE = 8;
201
202int RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) {
203 *error = KM_ERROR_OK;
204 switch (padding_) {
205 case KM_PAD_NONE:
206 return RSA_NO_PADDING;
207 case KM_PAD_RSA_PKCS1_1_5_SIGN:
208
209 return RSA_PKCS1_PADDING;
210 case KM_PAD_RSA_PSS:
211 if (digest_ == KM_DIGEST_NONE) {
212 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
213 return -1;
214 }
215 if (EVP_MD_size(digest_algorithm_) + PSS_OVERHEAD + MIN_SALT_SIZE >
216 (size_t)EVP_PKEY_size(rsa_key_)) {
Shawn Willdenbfd9ed72015-06-11 10:51:12 -0600217 LOG_E("%d-byte digest cannot be used with %d-byte RSA key in PSS padding mode",
218 EVP_MD_size(digest_algorithm_), EVP_PKEY_size(rsa_key_));
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600219 *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