blob: ce3e2a17dc364bb994ac69c783ad261b342114f1 [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
Shawn Willden0f906ec2015-06-20 09:16:30 -060021#include <new>
22
Shawn Willden4200f212014-12-02 07:01:21 -070023#include <openssl/err.h>
Shawn Willden0a4df7e2014-08-28 16:09:05 -060024
Shawn Willden567a4a02014-12-31 12:14:46 -070025#include <keymaster/logger.h>
26
27#include "openssl_err.h"
Shawn Willden0a4df7e2014-08-28 16:09:05 -060028#include "openssl_utils.h"
Shawn Willden63ac0432014-12-29 14:07:08 -070029#include "rsa_key.h"
Shawn Willden0a4df7e2014-08-28 16:09:05 -060030
31namespace keymaster {
32
Shawn Willdend5303052015-06-22 05:25:59 -060033const size_t kPssOverhead = 2;
34const size_t kMinPssSaltSize = 8;
35
36// Overhead for PKCS#1 v1.5 signature padding of undigested messages. Digested messages have
37// additional overhead, for the digest algorithmIdentifier required by PKCS#1.
38const size_t kPkcs1UndigestedSignaturePaddingOverhead = 11;
39
Shawn Willden63ac0432014-12-29 14:07:08 -070040/* static */
Shawn Willden2bf4ad32015-06-01 07:33:51 -060041EVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070042 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
43 assert(rsa_key);
44 if (!rsa_key || !rsa_key->key()) {
45 *error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060046 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070047 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -060048
49 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
50 if (!rsa_key->InternalToEvp(pkey.get())) {
51 *error = KM_ERROR_UNKNOWN_ERROR;
52 return nullptr;
53 }
54 return pkey.release();
Shawn Willden63ac0432014-12-29 14:07:08 -070055}
56
Shawn Willden2bf4ad32015-06-01 07:33:51 -060057static const keymaster_digest_t supported_digests[] = {
58 KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
59 KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
Shawn Willden63ac0432014-12-29 14:07:08 -070060
Shawn Willden0afa3c82015-06-22 10:39:21 -060061const keymaster_digest_t* RsaOperationFactory::SupportedDigests(size_t* digest_count) const {
Shawn Willden06298102015-05-25 23:12:48 -060062 *digest_count = array_length(supported_digests);
63 return supported_digests;
64}
Shawn Willden63ac0432014-12-29 14:07:08 -070065
Shawn Willden0afa3c82015-06-22 10:39:21 -060066RsaOperation* RsaOperationFactory::CreateRsaOperation(const Key& key,
67 const AuthorizationSet& begin_params,
68 keymaster_error_t* error) {
69 keymaster_padding_t padding;
70 keymaster_digest_t digest = KM_DIGEST_NONE;
71 if (!GetAndValidatePadding(begin_params, key, &padding, error))
72 return nullptr;
73
74 bool require_digest = (purpose() == KM_PURPOSE_SIGN || purpose() == KM_PURPOSE_VERIFY ||
75 padding == KM_PAD_RSA_OAEP);
76
77 if (require_digest && !GetAndValidateDigest(begin_params, key, &digest, error))
78 return nullptr;
79 if (!require_digest && begin_params.find(TAG_DIGEST) != -1) {
80 *error = KM_ERROR_UNSUPPORTED_DIGEST;
81 return nullptr;
82 }
83
84 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
85 if (!rsa.get())
86 return nullptr;
87
88 RsaOperation* op = InstantiateOperation(digest, padding, rsa.release());
89 if (!op)
90 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
91 return op;
92}
93
94static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
95 KM_PAD_RSA_PSS};
Shawn Willden06298102015-05-25 23:12:48 -060096const keymaster_padding_t*
97RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
98 *padding_mode_count = array_length(supported_sig_padding);
99 return supported_sig_padding;
100}
Shawn Willden63ac0432014-12-29 14:07:08 -0700101
Shawn Willden0afa3c82015-06-22 10:39:21 -0600102RsaOperation* RsaCryptingOperationFactory::CreateRsaOperation(const Key& key,
103 const AuthorizationSet& begin_params,
104 keymaster_error_t* error) {
105 UniquePtr<RsaOperation> op(RsaOperationFactory::CreateRsaOperation(key, begin_params, error));
106 if (op.get()) {
107 switch (op->padding()) {
108 case KM_PAD_NONE:
109 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
110 if (op->digest() != KM_DIGEST_NONE) {
111 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
112 return nullptr;
113 }
114 break;
Shawn Willden63ac0432014-12-29 14:07:08 -0700115
Shawn Willden0afa3c82015-06-22 10:39:21 -0600116 case KM_PAD_RSA_OAEP:
117 if (op->digest() == KM_DIGEST_NONE) {
118 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
119 return nullptr;
120 }
121 break;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600122
Shawn Willden0afa3c82015-06-22 10:39:21 -0600123 default:
124 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
125 return nullptr;
126 }
127 }
128 return op.release();
Shawn Willden63ac0432014-12-29 14:07:08 -0700129}
130
Shawn Willden30160842015-06-01 08:31:00 -0600131static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
Shawn Willden63ac0432014-12-29 14:07:08 -0700132 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
Shawn Willden06298102015-05-25 23:12:48 -0600133const keymaster_padding_t*
134RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
135 *padding_mode_count = array_length(supported_crypt_padding);
136 return supported_crypt_padding;
137}
Shawn Willden63ac0432014-12-29 14:07:08 -0700138
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600139RsaOperation::~RsaOperation() {
140 if (rsa_key_ != NULL)
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600141 EVP_PKEY_free(rsa_key_);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600142}
143
Shawn Willden6bfbff02015-02-06 19:48:24 -0700144keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600145 const Buffer& input, AuthorizationSet* /* output_params */,
146 Buffer* /* output */, size_t* input_consumed) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700147 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600148 switch (purpose()) {
149 default:
150 return KM_ERROR_UNIMPLEMENTED;
151 case KM_PURPOSE_SIGN:
152 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700153 case KM_PURPOSE_ENCRYPT:
154 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700155 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600156 }
157}
158
Shawn Willdenb7361132014-12-08 08:15:14 -0700159keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
160 assert(input_consumed);
Shawn Willdend5303052015-06-22 05:25:59 -0600161
162 if (!data_.reserve(EVP_PKEY_size(rsa_key_)))
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600163 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdend5303052015-06-22 05:25:59 -0600164 // If the write fails, it's because input length exceeds key size.
165 if (!data_.write(input.peek_read(), input.available_read())) {
Shawn Willden2101e9e2015-06-24 12:22:02 -0700166 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_));
Shawn Willdend5303052015-06-22 05:25:59 -0600168 return KM_ERROR_INVALID_INPUT_LENGTH;
169 }
170
Shawn Willdenb7361132014-12-08 08:15:14 -0700171 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600172 return KM_ERROR_OK;
173}
174
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600175keymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx) {
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 return KM_ERROR_OK;
184}
185
Shawn Willden0afa3c82015-06-22 10:39:21 -0600186keymaster_error_t RsaOperation::InitDigest() {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600187 if (digest_ == KM_DIGEST_NONE) {
188 if (require_digest())
189 return KM_ERROR_INCOMPATIBLE_DIGEST;
190 return KM_ERROR_OK;
191 }
192
Shawn Willden61902362014-12-18 10:33:24 -0700193 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700194 case KM_DIGEST_NONE:
195 return KM_ERROR_OK;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600196 case KM_DIGEST_MD5:
197 digest_algorithm_ = EVP_md5();
198 return KM_ERROR_OK;
199 case KM_DIGEST_SHA1:
200 digest_algorithm_ = EVP_sha1();
201 return KM_ERROR_OK;
202 case KM_DIGEST_SHA_2_224:
203 digest_algorithm_ = EVP_sha224();
204 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700205 case KM_DIGEST_SHA_2_256:
206 digest_algorithm_ = EVP_sha256();
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600207 return KM_ERROR_OK;
208 case KM_DIGEST_SHA_2_384:
209 digest_algorithm_ = EVP_sha384();
210 return KM_ERROR_OK;
211 case KM_DIGEST_SHA_2_512:
212 digest_algorithm_ = EVP_sha512();
213 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700214 default:
215 return KM_ERROR_UNSUPPORTED_DIGEST;
216 }
Shawn Willden61902362014-12-18 10:33:24 -0700217}
218
Shawn Willden0afa3c82015-06-22 10:39:21 -0600219RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
220 keymaster_padding_t padding, EVP_PKEY* key)
221 : RsaOperation(purpose, digest, padding, key) {
222 EVP_MD_CTX_init(&digest_ctx_);
223}
224RsaDigestingOperation::~RsaDigestingOperation() {
225 EVP_MD_CTX_cleanup(&digest_ctx_);
226}
227
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600228int RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) {
229 *error = KM_ERROR_OK;
230 switch (padding_) {
231 case KM_PAD_NONE:
232 return RSA_NO_PADDING;
233 case KM_PAD_RSA_PKCS1_1_5_SIGN:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600234 return RSA_PKCS1_PADDING;
235 case KM_PAD_RSA_PSS:
236 if (digest_ == KM_DIGEST_NONE) {
237 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
238 return -1;
239 }
Shawn Willdend5303052015-06-22 05:25:59 -0600240 if (EVP_MD_size(digest_algorithm_) + kPssOverhead + kMinPssSaltSize >
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600241 (size_t)EVP_PKEY_size(rsa_key_)) {
Shawn Willdend5303052015-06-22 05:25:59 -0600242 LOG_E("Input too long: %d-byte digest cannot be used with %d-byte RSA key in PSS "
243 "padding mode",
Shawn Willdenbfd9ed72015-06-11 10:51:12 -0600244 EVP_MD_size(digest_algorithm_), EVP_PKEY_size(rsa_key_));
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600245 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
246 return -1;
247 }
248 return RSA_PKCS1_PSS_PADDING;
249 default:
250 return -1;
Shawn Willden61902362014-12-18 10:33:24 -0700251 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600252}
253
254keymaster_error_t RsaSignOperation::Begin(const AuthorizationSet& /* input_params */,
255 AuthorizationSet* /* output_params */) {
256 keymaster_error_t error = InitDigest();
257 if (error != KM_ERROR_OK)
258 return error;
259
260 if (digest_ == KM_DIGEST_NONE)
261 return KM_ERROR_OK;
262
263 EVP_PKEY_CTX* pkey_ctx;
264 if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
265 rsa_key_) != 1)
266 return TranslateLastOpenSslError();
267 return SetRsaPaddingInEvpContext(pkey_ctx);
268}
269
270keymaster_error_t RsaSignOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600271 const Buffer& input, AuthorizationSet* output_params,
272 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600273 if (digest_ == KM_DIGEST_NONE)
274 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600275 return RsaOperation::Update(additional_params, input, output_params, output,
276 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600277
278 if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
279 return TranslateLastOpenSslError();
Shawn Willden61902362014-12-18 10:33:24 -0700280 *input_consumed = input.available_read();
281 return KM_ERROR_OK;
282}
283
Shawn Willden6bfbff02015-02-06 19:48:24 -0700284keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600285 const Buffer& /* signature */,
286 AuthorizationSet* /* output_params */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700287 assert(output);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600288
Shawn Willdenf90f2352014-12-18 23:01:15 -0700289 if (digest_ == KM_DIGEST_NONE)
290 return SignUndigested(output);
291 else
292 return SignDigested(output);
293}
Shawn Willden61902362014-12-18 10:33:24 -0700294
Shawn Willdenf90f2352014-12-18 23:01:15 -0700295keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600296 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
297 if (!rsa.get())
298 return TranslateLastOpenSslError();
299
300 if (!output->Reinitialize(RSA_size(rsa.get())))
301 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
302
Shawn Willdenf90f2352014-12-18 23:01:15 -0700303 int bytes_encrypted;
304 switch (padding_) {
305 case KM_PAD_NONE:
306 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600307 output->peek_write(), rsa.get(), RSA_NO_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700308 break;
309 case KM_PAD_RSA_PKCS1_1_5_SIGN:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600310 // Does PKCS1 padding without digesting even make sense? Dunno. We'll support it.
Shawn Willdend5303052015-06-22 05:25:59 -0600311 if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead >
312 static_cast<size_t>(EVP_PKEY_size(rsa_key_))) {
313 LOG_E("Input too long: cannot sign %u-byte message with PKCS1 padding with %u-bit key",
314 data_.available_read(), EVP_PKEY_size(rsa_key_) * 8);
315 return KM_ERROR_INVALID_INPUT_LENGTH;
316 }
Shawn Willdenf90f2352014-12-18 23:01:15 -0700317 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600318 output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700319 break;
320 default:
321 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
322 }
Shawn Willden61902362014-12-18 10:33:24 -0700323
Shawn Willdenf90f2352014-12-18 23:01:15 -0700324 if (bytes_encrypted <= 0)
Shawn Willden0f906ec2015-06-20 09:16:30 -0600325 return TranslateLastOpenSslError();
326 if (!output->advance_write(bytes_encrypted))
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600327 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600328 return KM_ERROR_OK;
329}
330
Shawn Willdenf90f2352014-12-18 23:01:15 -0700331keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600332 size_t siglen;
333 if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
334 return TranslateLastOpenSslError();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700335
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600336 if (!output->Reinitialize(siglen))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700337 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
338
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600339 if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
340 return TranslateLastOpenSslError();
Shawn Willden0f906ec2015-06-20 09:16:30 -0600341 if (!output->advance_write(siglen))
342 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600343
Shawn Willdenf90f2352014-12-18 23:01:15 -0700344 return KM_ERROR_OK;
345}
346
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600347keymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
348 AuthorizationSet* /* output_params */) {
349 keymaster_error_t error = InitDigest();
350 if (error != KM_ERROR_OK)
351 return error;
352
353 if (digest_ == KM_DIGEST_NONE)
354 return KM_ERROR_OK;
355
356 EVP_PKEY_CTX* pkey_ctx;
357 if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
358 return TranslateLastOpenSslError();
359 return SetRsaPaddingInEvpContext(pkey_ctx);
360}
361
362keymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600363 const Buffer& input, AuthorizationSet* output_params,
364 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600365 if (digest_ == KM_DIGEST_NONE)
366 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600367 return RsaOperation::Update(additional_params, input, output_params, output,
368 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600369
370 if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
371 return TranslateLastOpenSslError();
372 *input_consumed = input.available_read();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700373 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700374}
375
Shawn Willden6bfbff02015-02-06 19:48:24 -0700376keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600377 const Buffer& signature,
378 AuthorizationSet* /* output_params */,
379 Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700380 if (digest_ == KM_DIGEST_NONE)
381 return VerifyUndigested(signature);
382 else
383 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700384}
385
Shawn Willdenf90f2352014-12-18 23:01:15 -0700386keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600387 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
388 if (!rsa.get())
389 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700390
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600391 size_t key_len = RSA_size(rsa.get());
Shawn Willdenf90f2352014-12-18 23:01:15 -0700392 int openssl_padding;
393 switch (padding_) {
394 case KM_PAD_NONE:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600395 if (data_.available_read() != key_len)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700396 return KM_ERROR_INVALID_INPUT_LENGTH;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600397 if (data_.available_read() != signature.available_read())
Shawn Willdenf90f2352014-12-18 23:01:15 -0700398 return KM_ERROR_VERIFICATION_FAILED;
399 openssl_padding = RSA_NO_PADDING;
400 break;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700401 case KM_PAD_RSA_PKCS1_1_5_SIGN:
Shawn Willdend5303052015-06-22 05:25:59 -0600402 if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead > key_len) {
403 LOG_E("Input too long: cannot verify %u-byte message with PKCS1 padding && %u-bit key",
404 data_.available_read(), key_len * 8);
405 return KM_ERROR_INVALID_INPUT_LENGTH;
406 }
Shawn Willdenf90f2352014-12-18 23:01:15 -0700407 openssl_padding = RSA_PKCS1_PADDING;
408 break;
409 default:
410 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
411 }
412
Shawn Willden0f906ec2015-06-20 09:16:30 -0600413 UniquePtr<uint8_t[]> decrypted_data(new (std::nothrow) uint8_t[key_len]);
414 if (!decrypted_data.get())
415 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700416 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600417 decrypted_data.get(), rsa.get(), openssl_padding);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700418 if (bytes_decrypted < 0)
419 return KM_ERROR_VERIFICATION_FAILED;
420
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600421 if (memcmp_s(decrypted_data.get(), data_.peek_read(), data_.available_read()) != 0)
422 return KM_ERROR_VERIFICATION_FAILED;
423 return KM_ERROR_OK;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600424}
425
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600426keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
427 if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
428 return KM_ERROR_VERIFICATION_FAILED;
429 return KM_ERROR_OK;
430}
431
432int RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
433 *error = KM_ERROR_OK;
434 switch (padding_) {
Shawn Willden30160842015-06-01 08:31:00 -0600435 case KM_PAD_NONE:
436 return RSA_NO_PADDING;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600437 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
438 return RSA_PKCS1_PADDING;
439 case KM_PAD_RSA_OAEP:
440 return RSA_PKCS1_OAEP_PADDING;
441 default:
442 return -1;
443 }
444}
445
446struct EVP_PKEY_CTX_Delete {
447 void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
448};
Shawn Willden4200f212014-12-02 07:01:21 -0700449
Shawn Willden6bfbff02015-02-06 19:48:24 -0700450keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600451 const Buffer& /* signature */,
452 AuthorizationSet* /* output_params */,
453 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700454 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700455
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600456 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
457 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
458 if (!ctx.get())
459 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700460
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600461 if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
462 return TranslateLastOpenSslError();
Shawn Willden4200f212014-12-02 07:01:21 -0700463
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600464 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
465 if (error != KM_ERROR_OK)
466 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700467
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600468 size_t outlen;
469 if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
470 data_.available_read()) <= 0)
471 return TranslateLastOpenSslError();
472
473 if (!output->Reinitialize(outlen))
474 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
475
476 if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
477 data_.available_read()) <= 0)
478 return TranslateLastOpenSslError();
Shawn Willden0f906ec2015-06-20 09:16:30 -0600479 if (!output->advance_write(outlen))
480 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden4200f212014-12-02 07:01:21 -0700481
482 return KM_ERROR_OK;
483}
484
Shawn Willden6bfbff02015-02-06 19:48:24 -0700485keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600486 const Buffer& /* signature */,
487 AuthorizationSet* /* output_params */,
488 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700489 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700490
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600491 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
492 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
493 if (!ctx.get())
494 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700495
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600496 if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
497 return TranslateLastOpenSslError();
498
499 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
500 if (error != KM_ERROR_OK)
501 return error;
502
503 size_t outlen;
504 if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
505 data_.available_read()) <= 0)
506 return TranslateLastOpenSslError();
507
508 if (!output->Reinitialize(outlen))
509 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
510
511 if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
512 data_.available_read()) <= 0)
513 return TranslateLastOpenSslError();
Shawn Willden0f906ec2015-06-20 09:16:30 -0600514 if (!output->advance_write(outlen))
515 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden4200f212014-12-02 07:01:21 -0700516
517 return KM_ERROR_OK;
518}
519
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600520} // namespace keymaster