• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "rsa_operation.h"
18 
19 #include <limits.h>
20 
21 #include <new>
22 
23 #include <openssl/err.h>
24 
25 #include <keymaster/logger.h>
26 
27 #include "openssl_err.h"
28 #include "openssl_utils.h"
29 #include "rsa_key.h"
30 
31 namespace keymaster {
32 
33 const size_t kPssOverhead = 2;
34 
35 // Overhead for PKCS#1 v1.5 signature padding of undigested messages.  Digested messages have
36 // additional overhead, for the digest algorithmIdentifier required by PKCS#1.
37 const size_t kPkcs1UndigestedSignaturePaddingOverhead = 11;
38 
39 /* static */
GetRsaKey(const Key & key,keymaster_error_t * error)40 EVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
41     const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
42     assert(rsa_key);
43     if (!rsa_key || !rsa_key->key()) {
44         *error = KM_ERROR_UNKNOWN_ERROR;
45         return nullptr;
46     }
47 
48     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
49     if (!rsa_key->InternalToEvp(pkey.get())) {
50         *error = KM_ERROR_UNKNOWN_ERROR;
51         return nullptr;
52     }
53     return pkey.release();
54 }
55 
56 static const keymaster_digest_t supported_digests[] = {
57     KM_DIGEST_NONE,      KM_DIGEST_MD5,       KM_DIGEST_SHA1,     KM_DIGEST_SHA_2_224,
58     KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
59 
SupportedDigests(size_t * digest_count) const60 const keymaster_digest_t* RsaOperationFactory::SupportedDigests(size_t* digest_count) const {
61     *digest_count = array_length(supported_digests);
62     return supported_digests;
63 }
64 
CreateRsaOperation(const Key & key,const AuthorizationSet & begin_params,keymaster_error_t * error)65 RsaOperation* RsaOperationFactory::CreateRsaOperation(const Key& key,
66                                                       const AuthorizationSet& begin_params,
67                                                       keymaster_error_t* error) {
68     keymaster_padding_t padding;
69     if (!GetAndValidatePadding(begin_params, key, &padding, error))
70         return nullptr;
71 
72     bool require_digest = (purpose() == KM_PURPOSE_SIGN || purpose() == KM_PURPOSE_VERIFY ||
73                            padding == KM_PAD_RSA_OAEP);
74 
75     keymaster_digest_t digest = KM_DIGEST_NONE;
76     if (require_digest && !GetAndValidateDigest(begin_params, key, &digest, error))
77         return nullptr;
78 
79     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
80     if (!rsa.get())
81         return nullptr;
82 
83     RsaOperation* op = InstantiateOperation(digest, padding, rsa.release());
84     if (!op)
85         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
86     return op;
87 }
88 
89 static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
90                                                             KM_PAD_RSA_PSS};
91 const keymaster_padding_t*
SupportedPaddingModes(size_t * padding_mode_count) const92 RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
93     *padding_mode_count = array_length(supported_sig_padding);
94     return supported_sig_padding;
95 }
96 
CreateRsaOperation(const Key & key,const AuthorizationSet & begin_params,keymaster_error_t * error)97 RsaOperation* RsaCryptingOperationFactory::CreateRsaOperation(const Key& key,
98                                                               const AuthorizationSet& begin_params,
99                                                               keymaster_error_t* error) {
100     UniquePtr<RsaOperation> op(RsaOperationFactory::CreateRsaOperation(key, begin_params, error));
101     if (op.get()) {
102         switch (op->padding()) {
103         case KM_PAD_NONE:
104         case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
105             if (op->digest() != KM_DIGEST_NONE) {
106                 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
107                 return nullptr;
108             }
109             break;
110 
111         case KM_PAD_RSA_OAEP:
112             if (op->digest() == KM_DIGEST_NONE) {
113                 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
114                 return nullptr;
115             }
116             break;
117 
118         default:
119             *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
120             return nullptr;
121         }
122     }
123     return op.release();
124 }
125 
126 static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
127                                                               KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
128 const keymaster_padding_t*
SupportedPaddingModes(size_t * padding_mode_count) const129 RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
130     *padding_mode_count = array_length(supported_crypt_padding);
131     return supported_crypt_padding;
132 }
133 
~RsaOperation()134 RsaOperation::~RsaOperation() {
135     if (rsa_key_ != NULL)
136         EVP_PKEY_free(rsa_key_);
137 }
138 
Begin(const AuthorizationSet &,AuthorizationSet *)139 keymaster_error_t RsaOperation::Begin(const AuthorizationSet& /* input_params */,
140                                       AuthorizationSet* /* output_params */) {
141     return InitDigest();
142 }
143 
Update(const AuthorizationSet &,const Buffer & input,AuthorizationSet *,Buffer *,size_t * input_consumed)144 keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
145                                        const Buffer& input, AuthorizationSet* /* output_params */,
146                                        Buffer* /* output */, size_t* input_consumed) {
147     assert(input_consumed);
148     switch (purpose()) {
149     default:
150         return KM_ERROR_UNIMPLEMENTED;
151     case KM_PURPOSE_SIGN:
152     case KM_PURPOSE_VERIFY:
153     case KM_PURPOSE_ENCRYPT:
154     case KM_PURPOSE_DECRYPT:
155         return StoreData(input, input_consumed);
156     }
157 }
158 
StoreData(const Buffer & input,size_t * input_consumed)159 keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
160     assert(input_consumed);
161 
162     if (!data_.reserve(EVP_PKEY_size(rsa_key_)))
163         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
164     // If the write fails, it's because input length exceeds key size.
165     if (!data_.write(input.peek_read(), input.available_read())) {
166         LOG_E("Input too long: cannot operate on %u bytes of data with %u-byte RSA key",
167               input.available_read() + data_.available_read(), EVP_PKEY_size(rsa_key_));
168         return KM_ERROR_INVALID_INPUT_LENGTH;
169     }
170 
171     *input_consumed = input.available_read();
172     return KM_ERROR_OK;
173 }
174 
SetRsaPaddingInEvpContext(EVP_PKEY_CTX * pkey_ctx,bool signing)175 keymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx, bool signing) {
176     keymaster_error_t error;
177     int openssl_padding = GetOpensslPadding(&error);
178     if (error != KM_ERROR_OK)
179         return error;
180 
181     if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, openssl_padding) <= 0)
182         return TranslateLastOpenSslError();
183 
184     if (signing && openssl_padding == RSA_PKCS1_PSS_PADDING) {
185         // Also need to set the length of the salt used in the padding generation.  We set it equal
186         // to the length of the selected digest.
187         assert(digest_algorithm_);
188         if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(digest_algorithm_)) <= 0)
189             return TranslateLastOpenSslError();
190     }
191 
192     return KM_ERROR_OK;
193 }
194 
InitDigest()195 keymaster_error_t RsaOperation::InitDigest() {
196     if (digest_ == KM_DIGEST_NONE) {
197         if (require_digest())
198             return KM_ERROR_INCOMPATIBLE_DIGEST;
199         return KM_ERROR_OK;
200     }
201 
202     switch (digest_) {
203     case KM_DIGEST_NONE:
204         return KM_ERROR_OK;
205     case KM_DIGEST_MD5:
206         digest_algorithm_ = EVP_md5();
207         return KM_ERROR_OK;
208     case KM_DIGEST_SHA1:
209         digest_algorithm_ = EVP_sha1();
210         return KM_ERROR_OK;
211     case KM_DIGEST_SHA_2_224:
212         digest_algorithm_ = EVP_sha224();
213         return KM_ERROR_OK;
214     case KM_DIGEST_SHA_2_256:
215         digest_algorithm_ = EVP_sha256();
216         return KM_ERROR_OK;
217     case KM_DIGEST_SHA_2_384:
218         digest_algorithm_ = EVP_sha384();
219         return KM_ERROR_OK;
220     case KM_DIGEST_SHA_2_512:
221         digest_algorithm_ = EVP_sha512();
222         return KM_ERROR_OK;
223     default:
224         return KM_ERROR_UNSUPPORTED_DIGEST;
225     }
226 }
227 
RsaDigestingOperation(keymaster_purpose_t purpose,keymaster_digest_t digest,keymaster_padding_t padding,EVP_PKEY * key)228 RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
229                                              keymaster_padding_t padding, EVP_PKEY* key)
230     : RsaOperation(purpose, digest, padding, key) {
231     EVP_MD_CTX_init(&digest_ctx_);
232 }
~RsaDigestingOperation()233 RsaDigestingOperation::~RsaDigestingOperation() {
234     EVP_MD_CTX_cleanup(&digest_ctx_);
235 }
236 
GetOpensslPadding(keymaster_error_t * error)237 int RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) {
238     *error = KM_ERROR_OK;
239     switch (padding_) {
240     case KM_PAD_NONE:
241         return RSA_NO_PADDING;
242     case KM_PAD_RSA_PKCS1_1_5_SIGN:
243         return RSA_PKCS1_PADDING;
244     case KM_PAD_RSA_PSS:
245         if (digest_ == KM_DIGEST_NONE) {
246             *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
247             return -1;
248         }
249         if (EVP_MD_size(digest_algorithm_) * 2 + kPssOverhead > (size_t)EVP_PKEY_size(rsa_key_)) {
250             LOG_E("Input too long: %d-byte digest cannot be used with %d-byte RSA key in PSS "
251                   "padding mode",
252                   EVP_MD_size(digest_algorithm_), EVP_PKEY_size(rsa_key_));
253             *error = KM_ERROR_INCOMPATIBLE_DIGEST;
254             return -1;
255         }
256         return RSA_PKCS1_PSS_PADDING;
257     default:
258         return -1;
259     }
260 }
261 
Begin(const AuthorizationSet & input_params,AuthorizationSet * output_params)262 keymaster_error_t RsaSignOperation::Begin(const AuthorizationSet& input_params,
263                                           AuthorizationSet* output_params) {
264     keymaster_error_t error = RsaDigestingOperation::Begin(input_params, output_params);
265     if (error != KM_ERROR_OK)
266         return error;
267 
268     if (digest_ == KM_DIGEST_NONE)
269         return KM_ERROR_OK;
270 
271     EVP_PKEY_CTX* pkey_ctx;
272     if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
273                            rsa_key_) != 1)
274         return TranslateLastOpenSslError();
275     return SetRsaPaddingInEvpContext(pkey_ctx, true /* signing */);
276 }
277 
Update(const AuthorizationSet & additional_params,const Buffer & input,AuthorizationSet * output_params,Buffer * output,size_t * input_consumed)278 keymaster_error_t RsaSignOperation::Update(const AuthorizationSet& additional_params,
279                                            const Buffer& input, AuthorizationSet* output_params,
280                                            Buffer* output, size_t* input_consumed) {
281     if (digest_ == KM_DIGEST_NONE)
282         // Just buffer the data.
283         return RsaOperation::Update(additional_params, input, output_params, output,
284                                     input_consumed);
285 
286     if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
287         return TranslateLastOpenSslError();
288     *input_consumed = input.available_read();
289     return KM_ERROR_OK;
290 }
291 
Finish(const AuthorizationSet & additional_params,const Buffer & input,const Buffer &,AuthorizationSet *,Buffer * output)292 keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& additional_params,
293                                            const Buffer& input, const Buffer& /* signature */,
294                                            AuthorizationSet* /* output_params */, Buffer* output) {
295     assert(output);
296 
297     keymaster_error_t error = UpdateForFinish(additional_params, input);
298     if (error != KM_ERROR_OK)
299         return error;
300 
301     if (digest_ == KM_DIGEST_NONE)
302         return SignUndigested(output);
303     else
304         return SignDigested(output);
305 }
306 
zero_pad_left(UniquePtr<uint8_t[]> * dest,size_t padded_len,Buffer & src)307 static keymaster_error_t zero_pad_left(UniquePtr<uint8_t[]>* dest, size_t padded_len, Buffer& src) {
308     assert(padded_len > src.available_read());
309 
310     dest->reset(new uint8_t[padded_len]);
311     if (!dest->get())
312         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
313 
314     size_t padding_len = padded_len - src.available_read();
315     memset(dest->get(), 0, padding_len);
316     if (!src.read(dest->get() + padding_len, src.available_read()))
317         return KM_ERROR_UNKNOWN_ERROR;
318 
319     return KM_ERROR_OK;
320 }
321 
SignUndigested(Buffer * output)322 keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
323     UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
324     if (!rsa.get())
325         return TranslateLastOpenSslError();
326 
327     if (!output->Reinitialize(RSA_size(rsa.get())))
328         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
329 
330     size_t key_len = EVP_PKEY_size(rsa_key_);
331     int bytes_encrypted;
332     switch (padding_) {
333     case KM_PAD_NONE: {
334         const uint8_t* to_encrypt = data_.peek_read();
335         UniquePtr<uint8_t[]> zero_padded;
336         if (data_.available_read() > key_len) {
337             return KM_ERROR_INVALID_INPUT_LENGTH;
338         } else if (data_.available_read() < key_len) {
339             keymaster_error_t error = zero_pad_left(&zero_padded, key_len, data_);
340             if (error != KM_ERROR_OK)
341                 return error;
342             to_encrypt = zero_padded.get();
343         }
344         bytes_encrypted = RSA_private_encrypt(key_len, to_encrypt, output->peek_write(), rsa.get(),
345                                               RSA_NO_PADDING);
346         break;
347     }
348     case KM_PAD_RSA_PKCS1_1_5_SIGN:
349         // Does PKCS1 padding without digesting even make sense?  Dunno.  We'll support it.
350         if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead > key_len) {
351             LOG_E("Input too long: cannot sign %u-byte message with PKCS1 padding with %u-bit key",
352                   data_.available_read(), EVP_PKEY_size(rsa_key_) * 8);
353             return KM_ERROR_INVALID_INPUT_LENGTH;
354         }
355         bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
356                                               output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
357         break;
358 
359     default:
360         return KM_ERROR_UNSUPPORTED_PADDING_MODE;
361     }
362 
363     if (bytes_encrypted <= 0)
364         return TranslateLastOpenSslError();
365     if (!output->advance_write(bytes_encrypted))
366         return KM_ERROR_UNKNOWN_ERROR;
367     return KM_ERROR_OK;
368 }
369 
SignDigested(Buffer * output)370 keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
371     size_t siglen;
372     if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
373         return TranslateLastOpenSslError();
374 
375     if (!output->Reinitialize(siglen))
376         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
377 
378     if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
379         return TranslateLastOpenSslError();
380     if (!output->advance_write(siglen))
381         return KM_ERROR_UNKNOWN_ERROR;
382 
383     return KM_ERROR_OK;
384 }
385 
Begin(const AuthorizationSet & input_params,AuthorizationSet * output_params)386 keymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& input_params,
387                                             AuthorizationSet* output_params) {
388     keymaster_error_t error = RsaDigestingOperation::Begin(input_params, output_params);
389     if (error != KM_ERROR_OK)
390         return error;
391 
392     if (digest_ == KM_DIGEST_NONE)
393         return KM_ERROR_OK;
394 
395     EVP_PKEY_CTX* pkey_ctx;
396     if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
397         return TranslateLastOpenSslError();
398     return SetRsaPaddingInEvpContext(pkey_ctx, false /* signing */);
399 }
400 
Update(const AuthorizationSet & additional_params,const Buffer & input,AuthorizationSet * output_params,Buffer * output,size_t * input_consumed)401 keymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
402                                              const Buffer& input, AuthorizationSet* output_params,
403                                              Buffer* output, size_t* input_consumed) {
404     if (digest_ == KM_DIGEST_NONE)
405         // Just buffer the data.
406         return RsaOperation::Update(additional_params, input, output_params, output,
407                                     input_consumed);
408 
409     if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
410         return TranslateLastOpenSslError();
411     *input_consumed = input.available_read();
412     return KM_ERROR_OK;
413 }
414 
Finish(const AuthorizationSet & additional_params,const Buffer & input,const Buffer & signature,AuthorizationSet *,Buffer *)415 keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& additional_params,
416                                              const Buffer& input, const Buffer& signature,
417                                              AuthorizationSet* /* output_params */,
418                                              Buffer* /* output */) {
419     keymaster_error_t error = UpdateForFinish(additional_params, input);
420     if (error != KM_ERROR_OK)
421         return error;
422 
423     if (digest_ == KM_DIGEST_NONE)
424         return VerifyUndigested(signature);
425     else
426         return VerifyDigested(signature);
427 }
428 
VerifyUndigested(const Buffer & signature)429 keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
430     UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
431     if (!rsa.get())
432         return KM_ERROR_UNKNOWN_ERROR;
433 
434     size_t key_len = RSA_size(rsa.get());
435     int openssl_padding;
436     switch (padding_) {
437     case KM_PAD_NONE:
438         if (data_.available_read() > key_len)
439             return KM_ERROR_INVALID_INPUT_LENGTH;
440         if (key_len != signature.available_read())
441             return KM_ERROR_VERIFICATION_FAILED;
442         openssl_padding = RSA_NO_PADDING;
443         break;
444     case KM_PAD_RSA_PKCS1_1_5_SIGN:
445         if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead > key_len) {
446             LOG_E("Input too long: cannot verify %u-byte message with PKCS1 padding && %u-bit key",
447                   data_.available_read(), key_len * 8);
448             return KM_ERROR_INVALID_INPUT_LENGTH;
449         }
450         openssl_padding = RSA_PKCS1_PADDING;
451         break;
452     default:
453         return KM_ERROR_UNSUPPORTED_PADDING_MODE;
454     }
455 
456     UniquePtr<uint8_t[]> decrypted_data(new (std::nothrow) uint8_t[key_len]);
457     if (!decrypted_data.get())
458         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
459     int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
460                                              decrypted_data.get(), rsa.get(), openssl_padding);
461     if (bytes_decrypted < 0)
462         return KM_ERROR_VERIFICATION_FAILED;
463 
464     const uint8_t* compare_pos = decrypted_data.get();
465     size_t bytes_to_compare = bytes_decrypted;
466     uint8_t zero_check_result = 0;
467     if (padding_ == KM_PAD_NONE && data_.available_read() < bytes_to_compare) {
468         // If the data is short, for "unpadded" signing we zero-pad to the left.  So during
469         // verification we should have zeros on the left of the decrypted data.  Do a constant-time
470         // check.
471         const uint8_t* zero_end = compare_pos + bytes_to_compare - data_.available_read();
472         while (compare_pos < zero_end)
473             zero_check_result |= *compare_pos++;
474         bytes_to_compare = data_.available_read();
475     }
476     if (memcmp_s(compare_pos, data_.peek_read(), bytes_to_compare) != 0 || zero_check_result != 0)
477         return KM_ERROR_VERIFICATION_FAILED;
478     return KM_ERROR_OK;
479 }
480 
VerifyDigested(const Buffer & signature)481 keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
482     if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
483         return KM_ERROR_VERIFICATION_FAILED;
484     return KM_ERROR_OK;
485 }
486 
SetOaepDigestIfRequired(EVP_PKEY_CTX * pkey_ctx)487 keymaster_error_t RsaCryptOperation::SetOaepDigestIfRequired(EVP_PKEY_CTX* pkey_ctx) {
488     if (padding() != KM_PAD_RSA_OAEP)
489         return KM_ERROR_OK;
490 
491     assert(digest_algorithm_ != nullptr);
492     if (!EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, digest_algorithm_))
493         return TranslateLastOpenSslError();
494 
495     // MGF1 MD is always SHA1.
496     if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha1()))
497         return TranslateLastOpenSslError();
498 
499     return KM_ERROR_OK;
500 }
501 
GetOpensslPadding(keymaster_error_t * error)502 int RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
503     *error = KM_ERROR_OK;
504     switch (padding_) {
505     case KM_PAD_NONE:
506         return RSA_NO_PADDING;
507     case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
508         return RSA_PKCS1_PADDING;
509     case KM_PAD_RSA_OAEP:
510         return RSA_PKCS1_OAEP_PADDING;
511     default:
512         return -1;
513     }
514 }
515 
516 struct EVP_PKEY_CTX_Delete {
operator ()keymaster::EVP_PKEY_CTX_Delete517     void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
518 };
519 
Finish(const AuthorizationSet & additional_params,const Buffer & input,const Buffer &,AuthorizationSet *,Buffer * output)520 keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& additional_params,
521                                               const Buffer& input, const Buffer& /* signature */,
522                                               AuthorizationSet* /* output_params */,
523                                               Buffer* output) {
524     if (!output)
525         return KM_ERROR_OUTPUT_PARAMETER_NULL;
526 
527     keymaster_error_t error = UpdateForFinish(additional_params, input);
528     if (error != KM_ERROR_OK)
529         return error;
530 
531     UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
532         EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
533     if (!ctx.get())
534         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
535 
536     if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
537         return TranslateLastOpenSslError();
538 
539     error = SetRsaPaddingInEvpContext(ctx.get(), false /* signing */);
540     if (error != KM_ERROR_OK)
541         return error;
542     error = SetOaepDigestIfRequired(ctx.get());
543     if (error != KM_ERROR_OK)
544         return error;
545 
546     size_t outlen;
547     if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
548                          data_.available_read()) <= 0)
549         return TranslateLastOpenSslError();
550 
551     if (!output->Reinitialize(outlen))
552         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
553 
554     const uint8_t* to_encrypt = data_.peek_read();
555     size_t to_encrypt_len = data_.available_read();
556     UniquePtr<uint8_t[]> zero_padded;
557     if (padding_ == KM_PAD_NONE && to_encrypt_len < outlen) {
558         keymaster_error_t error = zero_pad_left(&zero_padded, outlen, data_);
559         if (error != KM_ERROR_OK)
560             return error;
561         to_encrypt = zero_padded.get();
562         to_encrypt_len = outlen;
563     }
564 
565     if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, to_encrypt, to_encrypt_len) <= 0)
566         return TranslateLastOpenSslError();
567     if (!output->advance_write(outlen))
568         return KM_ERROR_UNKNOWN_ERROR;
569 
570     return KM_ERROR_OK;
571 }
572 
Finish(const AuthorizationSet & additional_params,const Buffer & input,const Buffer &,AuthorizationSet *,Buffer * output)573 keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& additional_params,
574                                               const Buffer& input, const Buffer& /* signature */,
575                                               AuthorizationSet* /* output_params */,
576                                               Buffer* output) {
577     if (!output)
578         return KM_ERROR_OUTPUT_PARAMETER_NULL;
579 
580     keymaster_error_t error = UpdateForFinish(additional_params, input);
581     if (error != KM_ERROR_OK)
582         return error;
583 
584     UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
585         EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
586     if (!ctx.get())
587         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
588 
589     if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
590         return TranslateLastOpenSslError();
591 
592     error = SetRsaPaddingInEvpContext(ctx.get(), false /* signing */);
593     if (error != KM_ERROR_OK)
594         return error;
595     error = SetOaepDigestIfRequired(ctx.get());
596     if (error != KM_ERROR_OK)
597         return error;
598 
599     size_t outlen;
600     if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
601                          data_.available_read()) <= 0)
602         return TranslateLastOpenSslError();
603 
604     if (!output->Reinitialize(outlen))
605         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
606 
607     const uint8_t* to_decrypt = data_.peek_read();
608     size_t to_decrypt_len = data_.available_read();
609     UniquePtr<uint8_t[]> zero_padded;
610     if (padding_ == KM_PAD_NONE && to_decrypt_len < outlen) {
611         keymaster_error_t error = zero_pad_left(&zero_padded, outlen, data_);
612         if (error != KM_ERROR_OK)
613             return error;
614         to_decrypt = zero_padded.get();
615         to_decrypt_len = outlen;
616     }
617 
618     if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, to_decrypt, to_decrypt_len) <= 0)
619         return TranslateLastOpenSslError();
620     if (!output->advance_write(outlen))
621         return KM_ERROR_UNKNOWN_ERROR;
622 
623     return KM_ERROR_OK;
624 }
625 
626 }  // namespace keymaster
627