blob: 3d50ba9e46c3c1ae3ec5e01d66d6fd395a9a5218 [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
87static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
88 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 */,
125 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700126 size_t* input_consumed) {
127 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,
245 const Buffer& input, Buffer* output,
246 size_t* input_consumed) {
247 if (digest_ == KM_DIGEST_NONE)
248 // Just buffer the data.
249 return RsaOperation::Update(additional_params, input, output, input_consumed);
250
251 if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
252 return TranslateLastOpenSslError();
Shawn Willden61902362014-12-18 10:33:24 -0700253 *input_consumed = input.available_read();
254 return KM_ERROR_OK;
255}
256
Shawn Willden6bfbff02015-02-06 19:48:24 -0700257keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
258 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700259 assert(output);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600260
Shawn Willdenf90f2352014-12-18 23:01:15 -0700261 if (digest_ == KM_DIGEST_NONE)
262 return SignUndigested(output);
263 else
264 return SignDigested(output);
265}
Shawn Willden61902362014-12-18 10:33:24 -0700266
Shawn Willdenf90f2352014-12-18 23:01:15 -0700267keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600268 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
269 if (!rsa.get())
270 return TranslateLastOpenSslError();
271
272 if (!output->Reinitialize(RSA_size(rsa.get())))
273 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
274
Shawn Willdenf90f2352014-12-18 23:01:15 -0700275 int bytes_encrypted;
276 switch (padding_) {
277 case KM_PAD_NONE:
278 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600279 output->peek_write(), rsa.get(), RSA_NO_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700280 break;
281 case KM_PAD_RSA_PKCS1_1_5_SIGN:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600282 // Does PKCS1 padding without digesting even make sense? Dunno. We'll support it.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700283 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600284 output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700285 break;
286 default:
287 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
288 }
Shawn Willden61902362014-12-18 10:33:24 -0700289
Shawn Willdenf90f2352014-12-18 23:01:15 -0700290 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600291 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600292 output->advance_write(bytes_encrypted);
293 return KM_ERROR_OK;
294}
295
Shawn Willdenf90f2352014-12-18 23:01:15 -0700296keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600297 size_t siglen;
298 if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
299 return TranslateLastOpenSslError();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700300
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600301 if (!output->Reinitialize(siglen))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700302 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
303
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600304 if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
305 return TranslateLastOpenSslError();
306 output->advance_write(siglen);
307
Shawn Willdenf90f2352014-12-18 23:01:15 -0700308 return KM_ERROR_OK;
309}
310
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600311keymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
312 AuthorizationSet* /* output_params */) {
313 keymaster_error_t error = InitDigest();
314 if (error != KM_ERROR_OK)
315 return error;
316
317 if (digest_ == KM_DIGEST_NONE)
318 return KM_ERROR_OK;
319
320 EVP_PKEY_CTX* pkey_ctx;
321 if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
322 return TranslateLastOpenSslError();
323 return SetRsaPaddingInEvpContext(pkey_ctx);
324}
325
326keymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
327 const Buffer& input, Buffer* output,
328 size_t* input_consumed) {
329 if (digest_ == KM_DIGEST_NONE)
330 // Just buffer the data.
331 return RsaOperation::Update(additional_params, input, output, input_consumed);
332
333 if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
334 return TranslateLastOpenSslError();
335 *input_consumed = input.available_read();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700336 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700337}
338
Shawn Willden6bfbff02015-02-06 19:48:24 -0700339keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
340 const Buffer& signature, Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700341 if (digest_ == KM_DIGEST_NONE)
342 return VerifyUndigested(signature);
343 else
344 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700345}
346
Shawn Willdenf90f2352014-12-18 23:01:15 -0700347keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600348 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
349 if (!rsa.get())
350 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700351
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600352 size_t key_len = RSA_size(rsa.get());
Shawn Willdenf90f2352014-12-18 23:01:15 -0700353 int openssl_padding;
354 switch (padding_) {
355 case KM_PAD_NONE:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600356 if (data_.available_read() != key_len)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700357 return KM_ERROR_INVALID_INPUT_LENGTH;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600358 if (data_.available_read() != signature.available_read())
Shawn Willdenf90f2352014-12-18 23:01:15 -0700359 return KM_ERROR_VERIFICATION_FAILED;
360 openssl_padding = RSA_NO_PADDING;
361 break;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700362 case KM_PAD_RSA_PKCS1_1_5_SIGN:
363 openssl_padding = RSA_PKCS1_PADDING;
364 break;
365 default:
366 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
367 }
368
369 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
370 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600371 decrypted_data.get(), rsa.get(), openssl_padding);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700372 if (bytes_decrypted < 0)
373 return KM_ERROR_VERIFICATION_FAILED;
374
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600375 if (memcmp_s(decrypted_data.get(), data_.peek_read(), data_.available_read()) != 0)
376 return KM_ERROR_VERIFICATION_FAILED;
377 return KM_ERROR_OK;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600378}
379
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600380keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
381 if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
382 return KM_ERROR_VERIFICATION_FAILED;
383 return KM_ERROR_OK;
384}
385
386int RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
387 *error = KM_ERROR_OK;
388 switch (padding_) {
389 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
390 return RSA_PKCS1_PADDING;
391 case KM_PAD_RSA_OAEP:
392 return RSA_PKCS1_OAEP_PADDING;
393 default:
394 return -1;
395 }
396}
397
398struct EVP_PKEY_CTX_Delete {
399 void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
400};
Shawn Willden4200f212014-12-02 07:01:21 -0700401
Shawn Willden6bfbff02015-02-06 19:48:24 -0700402keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
403 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700404 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700405
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600406 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
407 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
408 if (!ctx.get())
409 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700410
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600411 if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
412 return TranslateLastOpenSslError();
Shawn Willden4200f212014-12-02 07:01:21 -0700413
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600414 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
415 if (error != KM_ERROR_OK)
416 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700417
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600418 size_t outlen;
419 if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
420 data_.available_read()) <= 0)
421 return TranslateLastOpenSslError();
422
423 if (!output->Reinitialize(outlen))
424 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
425
426 if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
427 data_.available_read()) <= 0)
428 return TranslateLastOpenSslError();
429 output->advance_write(outlen);
Shawn Willden4200f212014-12-02 07:01:21 -0700430
431 return KM_ERROR_OK;
432}
433
Shawn Willden6bfbff02015-02-06 19:48:24 -0700434keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
435 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700436 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700437
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600438 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
439 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
440 if (!ctx.get())
441 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700442
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600443 if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
444 return TranslateLastOpenSslError();
445
446 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
447 if (error != KM_ERROR_OK)
448 return error;
449
450 size_t outlen;
451 if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
452 data_.available_read()) <= 0)
453 return TranslateLastOpenSslError();
454
455 if (!output->Reinitialize(outlen))
456 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
457
458 if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
459 data_.available_read()) <= 0)
460 return TranslateLastOpenSslError();
461 output->advance_write(outlen);
Shawn Willden4200f212014-12-02 07:01:21 -0700462
463 return KM_ERROR_OK;
464}
465
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600466} // namespace keymaster