blob: 55ff1b3e8b25a2d0e8fa5901e39ff226de7daf11 [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 */
34RSA* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
35 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;
39 return NULL;
40 }
Shawn Willden28eed512015-02-25 19:16:36 -070041 RSA_up_ref(rsa_key->key());
42 return rsa_key->key();
Shawn Willden63ac0432014-12-29 14:07:08 -070043}
44
Shawn Willden61902362014-12-18 10:33:24 -070045static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_DIGEST_SHA_2_256};
Shawn Willdenf90f2352014-12-18 23:01:15 -070046static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
47 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070048
Shawn Willden06298102015-05-25 23:12:48 -060049const keymaster_digest_t*
50RsaDigestingOperationFactory::SupportedDigests(size_t* digest_count) const {
51 *digest_count = array_length(supported_digests);
52 return supported_digests;
53}
Shawn Willden63ac0432014-12-29 14:07:08 -070054
Shawn Willden06298102015-05-25 23:12:48 -060055const keymaster_padding_t*
56RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
57 *padding_mode_count = array_length(supported_sig_padding);
58 return supported_sig_padding;
59}
Shawn Willden63ac0432014-12-29 14:07:08 -070060
Shawn Willden3ed6d062015-04-15 13:39:38 -060061Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
Shawn Willden226746b2015-05-08 11:36:56 -060062 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060063 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070064 keymaster_padding_t padding;
65 keymaster_digest_t digest;
66 RSA* rsa;
Shawn Willden226746b2015-05-08 11:36:56 -060067 if (!GetAndValidateDigest(begin_params, key, &digest, error) ||
Shawn Willden3ad5f052015-05-08 14:05:13 -060068 !GetAndValidatePadding(begin_params, key, &padding, error) ||
69 !(rsa = GetRsaKey(key, error)))
Shawn Willden63ac0432014-12-29 14:07:08 -070070 return NULL;
71
Shawn Willden567a4a02014-12-31 12:14:46 -070072 Operation* op = InstantiateOperation(digest, padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -070073 if (!op)
74 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
75 return op;
76}
77
78static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
79 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
80
Shawn Willden3ed6d062015-04-15 13:39:38 -060081Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
Shawn Willden3ad5f052015-05-08 14:05:13 -060082 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060083 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070084 keymaster_padding_t padding;
85 RSA* rsa;
Shawn Willden3ad5f052015-05-08 14:05:13 -060086 if (!GetAndValidatePadding(begin_params, key, &padding, error) ||
87 !(rsa = GetRsaKey(key, error)))
Shawn Willden63ac0432014-12-29 14:07:08 -070088 return NULL;
89
Shawn Willden567a4a02014-12-31 12:14:46 -070090 Operation* op = InstantiateOperation(padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -070091 if (!op)
92 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
93 return op;
94}
95
Shawn Willden06298102015-05-25 23:12:48 -060096const keymaster_padding_t*
97RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
98 *padding_mode_count = array_length(supported_crypt_padding);
99 return supported_crypt_padding;
100}
Shawn Willden63ac0432014-12-29 14:07:08 -0700101
Shawn Willden06298102015-05-25 23:12:48 -0600102const keymaster_digest_t*
103RsaCryptingOperationFactory::SupportedDigests(size_t* digest_count) const {
104 *digest_count = 0;
105 return NULL;
106}
Shawn Willden63ac0432014-12-29 14:07:08 -0700107
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600108RsaOperation::~RsaOperation() {
109 if (rsa_key_ != NULL)
110 RSA_free(rsa_key_);
111}
112
Shawn Willden6bfbff02015-02-06 19:48:24 -0700113keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
114 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700115 size_t* input_consumed) {
116 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600117 switch (purpose()) {
118 default:
119 return KM_ERROR_UNIMPLEMENTED;
120 case KM_PURPOSE_SIGN:
121 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700122 case KM_PURPOSE_ENCRYPT:
123 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700124 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600125 }
126}
127
Shawn Willdenb7361132014-12-08 08:15:14 -0700128keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
129 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600130 if (!data_.reserve(data_.available_read() + input.available_read()) ||
131 !data_.write(input.peek_read(), input.available_read()))
132 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700133 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600134 return KM_ERROR_OK;
135}
136
Shawn Willden61902362014-12-18 10:33:24 -0700137RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
138 keymaster_padding_t padding, RSA* key)
139 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
140 EVP_MD_CTX_init(&digest_ctx_);
141}
142RsaDigestingOperation::~RsaDigestingOperation() {
143 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700144 memset_s(digest_buf_, 0, sizeof(digest_buf_));
Shawn Willden61902362014-12-18 10:33:24 -0700145}
146
147keymaster_error_t RsaDigestingOperation::Begin(const AuthorizationSet& /* input_params */,
148 AuthorizationSet* /* output_params */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700149 if (require_digest() && digest_ == KM_DIGEST_NONE)
150 return KM_ERROR_INCOMPATIBLE_DIGEST;
151 return InitDigest();
152}
Shawn Willden61902362014-12-18 10:33:24 -0700153
Shawn Willdenf90f2352014-12-18 23:01:15 -0700154keymaster_error_t RsaDigestingOperation::Update(const AuthorizationSet& additional_params,
155 const Buffer& input, Buffer* output,
156 size_t* input_consumed) {
157 if (digest_ == KM_DIGEST_NONE)
158 return RsaOperation::Update(additional_params, input, output, input_consumed);
159 else
160 return UpdateDigest(input, input_consumed);
161}
162
163keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden61902362014-12-18 10:33:24 -0700164 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700165 case KM_DIGEST_NONE:
166 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700167 case KM_DIGEST_SHA_2_256:
168 digest_algorithm_ = EVP_sha256();
169 break;
170 default:
171 return KM_ERROR_UNSUPPORTED_DIGEST;
172 }
173
174 if (!EVP_DigestInit_ex(&digest_ctx_, digest_algorithm_, NULL /* engine */)) {
175 int err = ERR_get_error();
176 LOG_E("Failed to initialize digest: %d %s", err, ERR_error_string(err, NULL));
177 return KM_ERROR_UNKNOWN_ERROR;
178 }
Shawn Willden61902362014-12-18 10:33:24 -0700179 return KM_ERROR_OK;
180}
181
Shawn Willdenf90f2352014-12-18 23:01:15 -0700182keymaster_error_t RsaDigestingOperation::UpdateDigest(const Buffer& input, size_t* input_consumed) {
Shawn Willden61902362014-12-18 10:33:24 -0700183 if (!EVP_DigestUpdate(&digest_ctx_, input.peek_read(), input.available_read())) {
184 int err = ERR_get_error();
185 LOG_E("Failed to update digest: %d %s", err, ERR_error_string(err, NULL));
186 return KM_ERROR_UNKNOWN_ERROR;
187 }
188 *input_consumed = input.available_read();
189 return KM_ERROR_OK;
190}
191
Shawn Willdenf90f2352014-12-18 23:01:15 -0700192keymaster_error_t RsaDigestingOperation::FinishDigest(unsigned* digest_size) {
Shawn Willden61902362014-12-18 10:33:24 -0700193 assert(digest_algorithm_ != NULL);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700194 if (!EVP_DigestFinal_ex(&digest_ctx_, digest_buf_, digest_size)) {
Shawn Willden61902362014-12-18 10:33:24 -0700195 int err = ERR_get_error();
196 LOG_E("Failed to finalize digest: %d %s", err, ERR_error_string(err, NULL));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700197 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700198 }
199 assert(*digest_size == static_cast<unsigned>(EVP_MD_size(digest_algorithm_)));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700200 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700201}
202
Shawn Willden6bfbff02015-02-06 19:48:24 -0700203keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
204 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700205 assert(output);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600206 output->Reinitialize(RSA_size(rsa_key_));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700207 if (digest_ == KM_DIGEST_NONE)
208 return SignUndigested(output);
209 else
210 return SignDigested(output);
211}
Shawn Willden61902362014-12-18 10:33:24 -0700212
Shawn Willdenf90f2352014-12-18 23:01:15 -0700213keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
214 int bytes_encrypted;
215 switch (padding_) {
216 case KM_PAD_NONE:
217 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
218 output->peek_write(), rsa_key_, RSA_NO_PADDING);
219 break;
220 case KM_PAD_RSA_PKCS1_1_5_SIGN:
221 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
222 output->peek_write(), rsa_key_, RSA_PKCS1_PADDING);
223 break;
224 default:
225 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
226 }
Shawn Willden61902362014-12-18 10:33:24 -0700227
Shawn Willdenf90f2352014-12-18 23:01:15 -0700228 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600229 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600230 output->advance_write(bytes_encrypted);
231 return KM_ERROR_OK;
232}
233
Shawn Willdenf90f2352014-12-18 23:01:15 -0700234keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
235 unsigned digest_size = 0;
236 keymaster_error_t error = FinishDigest(&digest_size);
237 if (error != KM_ERROR_OK)
238 return error;
239
240 UniquePtr<uint8_t[]> padded_digest;
241 switch (padding_) {
242 case KM_PAD_NONE:
Shawn Willden3ad5f052015-05-08 14:05:13 -0600243 LOG_E("Digesting requires padding", 0);
244 return KM_ERROR_INCOMPATIBLE_PADDING_MODE;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700245 case KM_PAD_RSA_PKCS1_1_5_SIGN:
246 return PrivateEncrypt(digest_buf_, digest_size, RSA_PKCS1_PADDING, output);
247 case KM_PAD_RSA_PSS:
248 // OpenSSL doesn't verify that the key is large enough for the digest size. This can cause
249 // a segfault in some cases, and in others can result in a unsafely-small salt.
Shawn Willden3ad5f052015-05-08 14:05:13 -0600250 if ((unsigned)RSA_size(rsa_key_) < MIN_PSS_SALT_LEN + digest_size) {
251 LOG_E("%d-byte too small for PSS padding and %d-byte digest", RSA_size(rsa_key_),
252 digest_size);
Shawn Willden2c242002015-02-27 07:01:02 -0700253 // TODO(swillden): Add a better return code for this.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700254 return KM_ERROR_INCOMPATIBLE_DIGEST;
Shawn Willden3ad5f052015-05-08 14:05:13 -0600255 }
Shawn Willdenf90f2352014-12-18 23:01:15 -0700256
257 if ((error = PssPadDigest(&padded_digest)) != KM_ERROR_OK)
258 return error;
259 return PrivateEncrypt(padded_digest.get(), RSA_size(rsa_key_), RSA_NO_PADDING, output);
260 default:
261 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
262 }
Shawn Willden61902362014-12-18 10:33:24 -0700263}
264
Shawn Willdenf90f2352014-12-18 23:01:15 -0700265keymaster_error_t RsaSignOperation::PssPadDigest(UniquePtr<uint8_t[]>* padded_digest) {
266 padded_digest->reset(new uint8_t[RSA_size(rsa_key_)]);
267 if (!padded_digest->get())
268 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
269
Adam Langleyadb0f332015-03-05 19:57:29 -0800270 if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa_key_, padded_digest->get(), digest_buf_,
271 digest_algorithm_, NULL,
272 -2 /* Indicates maximum salt length */)) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700273 LOG_E("%s", "Failed to apply PSS padding");
Shawn Willden61902362014-12-18 10:33:24 -0700274 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700275 }
276 return KM_ERROR_OK;
277}
278
279keymaster_error_t RsaSignOperation::PrivateEncrypt(uint8_t* to_encrypt, size_t len,
280 int openssl_padding, Buffer* output) {
281 int bytes_encrypted =
282 RSA_private_encrypt(len, to_encrypt, output->peek_write(), rsa_key_, openssl_padding);
283 if (bytes_encrypted <= 0)
284 return KM_ERROR_UNKNOWN_ERROR;
285 output->advance_write(bytes_encrypted);
286 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700287}
288
Shawn Willden6bfbff02015-02-06 19:48:24 -0700289keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
290 const Buffer& signature, Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700291 if (digest_ == KM_DIGEST_NONE)
292 return VerifyUndigested(signature);
293 else
294 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700295}
296
Shawn Willdenf90f2352014-12-18 23:01:15 -0700297keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
298 return DecryptAndMatch(signature, data_.peek_read(), data_.available_read());
Shawn Willden61902362014-12-18 10:33:24 -0700299}
300
Shawn Willdenf90f2352014-12-18 23:01:15 -0700301keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
Shawn Willden61902362014-12-18 10:33:24 -0700302 unsigned digest_size = 0;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700303 keymaster_error_t error = FinishDigest(&digest_size);
304 if (error != KM_ERROR_OK)
305 return error;
306 return DecryptAndMatch(signature, digest_buf_, digest_size);
307}
Shawn Willden61902362014-12-18 10:33:24 -0700308
Shawn Willdenf90f2352014-12-18 23:01:15 -0700309keymaster_error_t RsaVerifyOperation::DecryptAndMatch(const Buffer& signature,
310 const uint8_t* to_match, size_t len) {
311#ifdef OPENSSL_IS_BORINGSSL
312 size_t key_len = RSA_size(rsa_key_);
313#else
314 size_t key_len = (size_t)RSA_size(rsa_key_);
315#endif
316
317 int openssl_padding;
318 switch (padding_) {
319 case KM_PAD_NONE:
320 if (len != key_len)
321 return KM_ERROR_INVALID_INPUT_LENGTH;
322 if (len != signature.available_read())
323 return KM_ERROR_VERIFICATION_FAILED;
324 openssl_padding = RSA_NO_PADDING;
325 break;
326 case KM_PAD_RSA_PSS: // Do a raw decrypt for PSS
327 openssl_padding = RSA_NO_PADDING;
328 break;
329 case KM_PAD_RSA_PKCS1_1_5_SIGN:
330 openssl_padding = RSA_PKCS1_PADDING;
331 break;
332 default:
333 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
334 }
335
336 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
337 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
338 decrypted_data.get(), rsa_key_, openssl_padding);
339 if (bytes_decrypted < 0)
340 return KM_ERROR_VERIFICATION_FAILED;
341
342 if (padding_ == KM_PAD_RSA_PSS &&
Adam Langleyadb0f332015-03-05 19:57:29 -0800343 RSA_verify_PKCS1_PSS_mgf1(rsa_key_, to_match, digest_algorithm_, NULL, decrypted_data.get(),
344 -2 /* salt length recovered from signature */))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700345 return KM_ERROR_OK;
Shawn Willden197d9af2015-05-09 12:48:16 +0000346 else if (padding_ != KM_PAD_RSA_PSS && memcmp_s(decrypted_data.get(), to_match, len) == 0)
Shawn Willden61902362014-12-18 10:33:24 -0700347 return KM_ERROR_OK;
348
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600349 return KM_ERROR_VERIFICATION_FAILED;
350}
351
Shawn Willden7bae1322015-05-26 10:16:49 -0600352const int OAEP_PADDING_OVERHEAD = 42;
Shawn Willden4200f212014-12-02 07:01:21 -0700353const int PKCS1_PADDING_OVERHEAD = 11;
354
Shawn Willden6bfbff02015-02-06 19:48:24 -0700355keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
356 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700357 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700358 int openssl_padding;
359
360#if defined(OPENSSL_IS_BORINGSSL)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700361 size_t key_len = RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700362#else
Shawn Willdenf90f2352014-12-18 23:01:15 -0700363 size_t key_len = (size_t)RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700364#endif
365
Shawn Willdenf90f2352014-12-18 23:01:15 -0700366 size_t message_size = data_.available_read();
Shawn Willden4200f212014-12-02 07:01:21 -0700367 switch (padding_) {
368 case KM_PAD_RSA_OAEP:
369 openssl_padding = RSA_PKCS1_OAEP_PADDING;
Shawn Willden7bae1322015-05-26 10:16:49 -0600370 if (message_size + OAEP_PADDING_OVERHEAD > key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700371 LOG_E("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700372 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700373 return KM_ERROR_INVALID_INPUT_LENGTH;
374 }
375 break;
376 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
377 openssl_padding = RSA_PKCS1_PADDING;
Shawn Willden7bae1322015-05-26 10:16:49 -0600378 if (message_size + PKCS1_PADDING_OVERHEAD > key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700379 LOG_E("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700380 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700381 return KM_ERROR_INVALID_INPUT_LENGTH;
382 }
383 break;
384 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700385 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700386 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
387 }
388
389 output->Reinitialize(RSA_size(rsa_key_));
390 int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(),
391 output->peek_write(), rsa_key_, openssl_padding);
392
393 if (bytes_encrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700394 LOG_E("Error %d encrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700395 return KM_ERROR_UNKNOWN_ERROR;
396 }
Shawn Willden67380a92015-05-13 12:07:50 -0600397 assert(bytes_encrypted == (int)RSA_size(rsa_key_));
Shawn Willden4200f212014-12-02 07:01:21 -0700398 output->advance_write(bytes_encrypted);
399
400 return KM_ERROR_OK;
401}
402
Shawn Willden6bfbff02015-02-06 19:48:24 -0700403keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
404 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700405 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700406 int openssl_padding;
407 switch (padding_) {
408 case KM_PAD_RSA_OAEP:
409 openssl_padding = RSA_PKCS1_OAEP_PADDING;
410 break;
411 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
412 openssl_padding = RSA_PKCS1_PADDING;
413 break;
414 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700415 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700416 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
417 }
418
419 output->Reinitialize(RSA_size(rsa_key_));
420 int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(),
421 output->peek_write(), rsa_key_, openssl_padding);
422
423 if (bytes_decrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700424 LOG_E("Error %d decrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700425 return KM_ERROR_UNKNOWN_ERROR;
426 }
427 output->advance_write(bytes_decrypted);
428
429 return KM_ERROR_OK;
430}
431
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600432} // namespace keymaster