blob: 846eaa32383de7c27ef5650f0a65731eeff334a1 [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;
Shawn Willdend5303052015-06-22 05:25:59 -060034
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.
37const size_t kPkcs1UndigestedSignaturePaddingOverhead = 11;
38
Shawn Willden63ac0432014-12-29 14:07:08 -070039/* static */
Shawn Willden2bf4ad32015-06-01 07:33:51 -060040EVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070041 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;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060045 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070046 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -060047
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();
Shawn Willden63ac0432014-12-29 14:07:08 -070054}
55
Shawn Willden2bf4ad32015-06-01 07:33:51 -060056static 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};
Shawn Willden63ac0432014-12-29 14:07:08 -070059
Shawn Willden0afa3c82015-06-22 10:39:21 -060060const keymaster_digest_t* RsaOperationFactory::SupportedDigests(size_t* digest_count) const {
Shawn Willden06298102015-05-25 23:12:48 -060061 *digest_count = array_length(supported_digests);
62 return supported_digests;
63}
Shawn Willden63ac0432014-12-29 14:07:08 -070064
Shawn Willden0afa3c82015-06-22 10:39:21 -060065RsaOperation* RsaOperationFactory::CreateRsaOperation(const Key& key,
66 const AuthorizationSet& begin_params,
67 keymaster_error_t* error) {
68 keymaster_padding_t padding;
Shawn Willden0afa3c82015-06-22 10:39:21 -060069 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
Shawn Willden7d05d882015-07-10 14:03:14 -060075 keymaster_digest_t digest = KM_DIGEST_NONE;
Shawn Willden0afa3c82015-06-22 10:39:21 -060076 if (require_digest && !GetAndValidateDigest(begin_params, key, &digest, error))
77 return nullptr;
Shawn Willden0afa3c82015-06-22 10:39:21 -060078
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
89static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
90 KM_PAD_RSA_PSS};
Shawn Willden06298102015-05-25 23:12:48 -060091const keymaster_padding_t*
92RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
93 *padding_mode_count = array_length(supported_sig_padding);
94 return supported_sig_padding;
95}
Shawn Willden63ac0432014-12-29 14:07:08 -070096
Shawn Willden0afa3c82015-06-22 10:39:21 -060097RsaOperation* 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;
Shawn Willden63ac0432014-12-29 14:07:08 -0700110
Shawn Willden0afa3c82015-06-22 10:39:21 -0600111 case KM_PAD_RSA_OAEP:
112 if (op->digest() == KM_DIGEST_NONE) {
113 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
114 return nullptr;
115 }
116 break;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600117
Shawn Willden0afa3c82015-06-22 10:39:21 -0600118 default:
119 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
120 return nullptr;
121 }
122 }
123 return op.release();
Shawn Willden63ac0432014-12-29 14:07:08 -0700124}
125
Shawn Willden30160842015-06-01 08:31:00 -0600126static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
Shawn Willden63ac0432014-12-29 14:07:08 -0700127 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
Shawn Willden06298102015-05-25 23:12:48 -0600128const keymaster_padding_t*
129RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
130 *padding_mode_count = array_length(supported_crypt_padding);
131 return supported_crypt_padding;
132}
Shawn Willden63ac0432014-12-29 14:07:08 -0700133
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600134RsaOperation::~RsaOperation() {
135 if (rsa_key_ != NULL)
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600136 EVP_PKEY_free(rsa_key_);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600137}
138
Shawn Willden7d05d882015-07-10 14:03:14 -0600139keymaster_error_t RsaOperation::Begin(const AuthorizationSet& /* input_params */,
140 AuthorizationSet* /* output_params */) {
141 return InitDigest();
142}
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 Willdenb6179f42016-01-26 11:47:34 -0700175keymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx, bool signing) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600176 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();
Shawn Willdenb6179f42016-01-26 11:47:34 -0700183
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
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600192 return KM_ERROR_OK;
193}
194
Shawn Willden0afa3c82015-06-22 10:39:21 -0600195keymaster_error_t RsaOperation::InitDigest() {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600196 if (digest_ == KM_DIGEST_NONE) {
197 if (require_digest())
198 return KM_ERROR_INCOMPATIBLE_DIGEST;
199 return KM_ERROR_OK;
200 }
201
Shawn Willden61902362014-12-18 10:33:24 -0700202 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700203 case KM_DIGEST_NONE:
204 return KM_ERROR_OK;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600205 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;
Shawn Willden61902362014-12-18 10:33:24 -0700214 case KM_DIGEST_SHA_2_256:
215 digest_algorithm_ = EVP_sha256();
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600216 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;
Shawn Willden61902362014-12-18 10:33:24 -0700223 default:
224 return KM_ERROR_UNSUPPORTED_DIGEST;
225 }
Shawn Willden61902362014-12-18 10:33:24 -0700226}
227
Shawn Willden0afa3c82015-06-22 10:39:21 -0600228RsaDigestingOperation::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}
233RsaDigestingOperation::~RsaDigestingOperation() {
234 EVP_MD_CTX_cleanup(&digest_ctx_);
235}
236
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600237int 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:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600243 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 }
Shawn Willdenb6179f42016-01-26 11:47:34 -0700249 if (EVP_MD_size(digest_algorithm_) * 2 + kPssOverhead > (size_t)EVP_PKEY_size(rsa_key_)) {
Shawn Willdend5303052015-06-22 05:25:59 -0600250 LOG_E("Input too long: %d-byte digest cannot be used with %d-byte RSA key in PSS "
251 "padding mode",
Shawn Willdenbfd9ed72015-06-11 10:51:12 -0600252 EVP_MD_size(digest_algorithm_), EVP_PKEY_size(rsa_key_));
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600253 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
254 return -1;
255 }
256 return RSA_PKCS1_PSS_PADDING;
257 default:
258 return -1;
Shawn Willden61902362014-12-18 10:33:24 -0700259 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600260}
261
Shawn Willden7d05d882015-07-10 14:03:14 -0600262keymaster_error_t RsaSignOperation::Begin(const AuthorizationSet& input_params,
263 AuthorizationSet* output_params) {
264 keymaster_error_t error = RsaDigestingOperation::Begin(input_params, output_params);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600265 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();
Shawn Willdenb6179f42016-01-26 11:47:34 -0700275 return SetRsaPaddingInEvpContext(pkey_ctx, true /* signing */);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600276}
277
278keymaster_error_t RsaSignOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600279 const Buffer& input, AuthorizationSet* output_params,
280 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600281 if (digest_ == KM_DIGEST_NONE)
282 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600283 return RsaOperation::Update(additional_params, input, output_params, output,
284 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600285
286 if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
287 return TranslateLastOpenSslError();
Shawn Willden61902362014-12-18 10:33:24 -0700288 *input_consumed = input.available_read();
289 return KM_ERROR_OK;
290}
291
Shawn Willden6bfbff02015-02-06 19:48:24 -0700292keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600293 const Buffer& /* signature */,
294 AuthorizationSet* /* output_params */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700295 assert(output);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600296
Shawn Willdenf90f2352014-12-18 23:01:15 -0700297 if (digest_ == KM_DIGEST_NONE)
298 return SignUndigested(output);
299 else
300 return SignDigested(output);
301}
Shawn Willden61902362014-12-18 10:33:24 -0700302
Shawn Willdenc0a63802015-07-29 16:43:17 -0600303static keymaster_error_t zero_pad_left(UniquePtr<uint8_t[]>* dest, size_t padded_len, Buffer& src) {
304 assert(padded_len > src.available_read());
305
306 dest->reset(new uint8_t[padded_len]);
307 if (!dest->get())
308 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
309
310 size_t padding_len = padded_len - src.available_read();
311 memset(dest->get(), 0, padding_len);
312 if (!src.read(dest->get() + padding_len, src.available_read()))
313 return KM_ERROR_UNKNOWN_ERROR;
314
315 return KM_ERROR_OK;
316}
317
Shawn Willdenf90f2352014-12-18 23:01:15 -0700318keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600319 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
320 if (!rsa.get())
321 return TranslateLastOpenSslError();
322
323 if (!output->Reinitialize(RSA_size(rsa.get())))
324 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
325
Shawn Willdenc0a63802015-07-29 16:43:17 -0600326 size_t key_len = EVP_PKEY_size(rsa_key_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700327 int bytes_encrypted;
328 switch (padding_) {
Shawn Willdenc0a63802015-07-29 16:43:17 -0600329 case KM_PAD_NONE: {
330 const uint8_t* to_encrypt = data_.peek_read();
331 UniquePtr<uint8_t[]> zero_padded;
332 if (data_.available_read() > key_len) {
333 return KM_ERROR_INVALID_INPUT_LENGTH;
334 } else if (data_.available_read() < key_len) {
335 keymaster_error_t error = zero_pad_left(&zero_padded, key_len, data_);
336 if (error != KM_ERROR_OK)
337 return error;
338 to_encrypt = zero_padded.get();
339 }
340 bytes_encrypted = RSA_private_encrypt(key_len, to_encrypt, output->peek_write(), rsa.get(),
341 RSA_NO_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700342 break;
Shawn Willdenc0a63802015-07-29 16:43:17 -0600343 }
Shawn Willdenf90f2352014-12-18 23:01:15 -0700344 case KM_PAD_RSA_PKCS1_1_5_SIGN:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600345 // Does PKCS1 padding without digesting even make sense? Dunno. We'll support it.
Shawn Willdenc0a63802015-07-29 16:43:17 -0600346 if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead > key_len) {
Shawn Willdend5303052015-06-22 05:25:59 -0600347 LOG_E("Input too long: cannot sign %u-byte message with PKCS1 padding with %u-bit key",
348 data_.available_read(), EVP_PKEY_size(rsa_key_) * 8);
349 return KM_ERROR_INVALID_INPUT_LENGTH;
350 }
Shawn Willdenf90f2352014-12-18 23:01:15 -0700351 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600352 output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700353 break;
Shawn Willdenc0a63802015-07-29 16:43:17 -0600354
Shawn Willdenf90f2352014-12-18 23:01:15 -0700355 default:
356 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
357 }
Shawn Willden61902362014-12-18 10:33:24 -0700358
Shawn Willdenf90f2352014-12-18 23:01:15 -0700359 if (bytes_encrypted <= 0)
Shawn Willden0f906ec2015-06-20 09:16:30 -0600360 return TranslateLastOpenSslError();
361 if (!output->advance_write(bytes_encrypted))
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600362 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600363 return KM_ERROR_OK;
364}
365
Shawn Willdenf90f2352014-12-18 23:01:15 -0700366keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600367 size_t siglen;
368 if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
369 return TranslateLastOpenSslError();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700370
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600371 if (!output->Reinitialize(siglen))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700372 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
373
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600374 if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
375 return TranslateLastOpenSslError();
Shawn Willden0f906ec2015-06-20 09:16:30 -0600376 if (!output->advance_write(siglen))
377 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600378
Shawn Willdenf90f2352014-12-18 23:01:15 -0700379 return KM_ERROR_OK;
380}
381
Shawn Willden7d05d882015-07-10 14:03:14 -0600382keymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& input_params,
383 AuthorizationSet* output_params) {
384 keymaster_error_t error = RsaDigestingOperation::Begin(input_params, output_params);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600385 if (error != KM_ERROR_OK)
386 return error;
387
388 if (digest_ == KM_DIGEST_NONE)
389 return KM_ERROR_OK;
390
391 EVP_PKEY_CTX* pkey_ctx;
392 if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
393 return TranslateLastOpenSslError();
Shawn Willdenb6179f42016-01-26 11:47:34 -0700394 return SetRsaPaddingInEvpContext(pkey_ctx, false /* signing */);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600395}
396
397keymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600398 const Buffer& input, AuthorizationSet* output_params,
399 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600400 if (digest_ == KM_DIGEST_NONE)
401 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600402 return RsaOperation::Update(additional_params, input, output_params, output,
403 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600404
405 if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
406 return TranslateLastOpenSslError();
407 *input_consumed = input.available_read();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700408 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700409}
410
Shawn Willden6bfbff02015-02-06 19:48:24 -0700411keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600412 const Buffer& signature,
413 AuthorizationSet* /* output_params */,
414 Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700415 if (digest_ == KM_DIGEST_NONE)
416 return VerifyUndigested(signature);
417 else
418 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700419}
420
Shawn Willdenf90f2352014-12-18 23:01:15 -0700421keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600422 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
423 if (!rsa.get())
424 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700425
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600426 size_t key_len = RSA_size(rsa.get());
Shawn Willdenf90f2352014-12-18 23:01:15 -0700427 int openssl_padding;
428 switch (padding_) {
429 case KM_PAD_NONE:
Shawn Willdenc0a63802015-07-29 16:43:17 -0600430 if (data_.available_read() > key_len)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700431 return KM_ERROR_INVALID_INPUT_LENGTH;
Shawn Willdenc0a63802015-07-29 16:43:17 -0600432 if (key_len != signature.available_read())
Shawn Willdenf90f2352014-12-18 23:01:15 -0700433 return KM_ERROR_VERIFICATION_FAILED;
434 openssl_padding = RSA_NO_PADDING;
435 break;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700436 case KM_PAD_RSA_PKCS1_1_5_SIGN:
Shawn Willdend5303052015-06-22 05:25:59 -0600437 if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead > key_len) {
438 LOG_E("Input too long: cannot verify %u-byte message with PKCS1 padding && %u-bit key",
439 data_.available_read(), key_len * 8);
440 return KM_ERROR_INVALID_INPUT_LENGTH;
441 }
Shawn Willdenf90f2352014-12-18 23:01:15 -0700442 openssl_padding = RSA_PKCS1_PADDING;
443 break;
444 default:
445 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
446 }
447
Shawn Willden0f906ec2015-06-20 09:16:30 -0600448 UniquePtr<uint8_t[]> decrypted_data(new (std::nothrow) uint8_t[key_len]);
449 if (!decrypted_data.get())
450 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700451 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600452 decrypted_data.get(), rsa.get(), openssl_padding);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700453 if (bytes_decrypted < 0)
454 return KM_ERROR_VERIFICATION_FAILED;
455
Shawn Willdenc0a63802015-07-29 16:43:17 -0600456 const uint8_t* compare_pos = decrypted_data.get();
457 size_t bytes_to_compare = bytes_decrypted;
458 uint8_t zero_check_result = 0;
459 if (padding_ == KM_PAD_NONE && data_.available_read() < bytes_to_compare) {
460 // If the data is short, for "unpadded" signing we zero-pad to the left. So during
461 // verification we should have zeros on the left of the decrypted data. Do a constant-time
462 // check.
463 const uint8_t* zero_end = compare_pos + bytes_to_compare - data_.available_read();
464 while (compare_pos < zero_end)
465 zero_check_result |= *compare_pos++;
466 bytes_to_compare = data_.available_read();
467 }
468 if (memcmp_s(compare_pos, data_.peek_read(), bytes_to_compare) != 0 || zero_check_result != 0)
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600469 return KM_ERROR_VERIFICATION_FAILED;
470 return KM_ERROR_OK;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600471}
472
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600473keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
474 if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
475 return KM_ERROR_VERIFICATION_FAILED;
476 return KM_ERROR_OK;
477}
478
Shawn Willden7d05d882015-07-10 14:03:14 -0600479keymaster_error_t RsaCryptOperation::SetOaepDigestIfRequired(EVP_PKEY_CTX* pkey_ctx) {
480 if (padding() != KM_PAD_RSA_OAEP)
481 return KM_ERROR_OK;
482
483 assert(digest_algorithm_ != nullptr);
484 if (!EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, digest_algorithm_))
485 return TranslateLastOpenSslError();
486
487 // MGF1 MD is always SHA1.
488 if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha1()))
489 return TranslateLastOpenSslError();
490
491 return KM_ERROR_OK;
492}
493
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600494int RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
495 *error = KM_ERROR_OK;
496 switch (padding_) {
Shawn Willden30160842015-06-01 08:31:00 -0600497 case KM_PAD_NONE:
498 return RSA_NO_PADDING;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600499 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
500 return RSA_PKCS1_PADDING;
501 case KM_PAD_RSA_OAEP:
502 return RSA_PKCS1_OAEP_PADDING;
503 default:
504 return -1;
505 }
506}
507
508struct EVP_PKEY_CTX_Delete {
509 void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
510};
Shawn Willden4200f212014-12-02 07:01:21 -0700511
Shawn Willden6bfbff02015-02-06 19:48:24 -0700512keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600513 const Buffer& /* signature */,
514 AuthorizationSet* /* output_params */,
515 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700516 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700517
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600518 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
519 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
520 if (!ctx.get())
521 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700522
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600523 if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
524 return TranslateLastOpenSslError();
Shawn Willden4200f212014-12-02 07:01:21 -0700525
Shawn Willdenb6179f42016-01-26 11:47:34 -0700526 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get(), false /* signing */);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600527 if (error != KM_ERROR_OK)
528 return error;
Shawn Willden7d05d882015-07-10 14:03:14 -0600529 error = SetOaepDigestIfRequired(ctx.get());
530 if (error != KM_ERROR_OK)
531 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700532
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600533 size_t outlen;
534 if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
535 data_.available_read()) <= 0)
536 return TranslateLastOpenSslError();
537
538 if (!output->Reinitialize(outlen))
539 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
540
Shawn Willdenc0a63802015-07-29 16:43:17 -0600541 const uint8_t* to_encrypt = data_.peek_read();
542 size_t to_encrypt_len = data_.available_read();
543 UniquePtr<uint8_t[]> zero_padded;
544 if (padding_ == KM_PAD_NONE && to_encrypt_len < outlen) {
545 keymaster_error_t error = zero_pad_left(&zero_padded, outlen, data_);
546 if (error != KM_ERROR_OK)
547 return error;
548 to_encrypt = zero_padded.get();
549 to_encrypt_len = outlen;
550 }
551
552 if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, to_encrypt, to_encrypt_len) <= 0)
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600553 return TranslateLastOpenSslError();
Shawn Willden0f906ec2015-06-20 09:16:30 -0600554 if (!output->advance_write(outlen))
555 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden4200f212014-12-02 07:01:21 -0700556
557 return KM_ERROR_OK;
558}
559
Shawn Willden6bfbff02015-02-06 19:48:24 -0700560keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600561 const Buffer& /* signature */,
562 AuthorizationSet* /* output_params */,
563 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700564 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700565
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600566 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
567 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
568 if (!ctx.get())
569 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700570
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600571 if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
572 return TranslateLastOpenSslError();
573
Shawn Willdenb6179f42016-01-26 11:47:34 -0700574 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get(), false /* signing */);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600575 if (error != KM_ERROR_OK)
576 return error;
Shawn Willden7d05d882015-07-10 14:03:14 -0600577 error = SetOaepDigestIfRequired(ctx.get());
578 if (error != KM_ERROR_OK)
579 return error;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600580
581 size_t outlen;
582 if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
583 data_.available_read()) <= 0)
584 return TranslateLastOpenSslError();
585
586 if (!output->Reinitialize(outlen))
587 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
588
Shawn Willdenc0a63802015-07-29 16:43:17 -0600589 const uint8_t* to_decrypt = data_.peek_read();
590 size_t to_decrypt_len = data_.available_read();
591 UniquePtr<uint8_t[]> zero_padded;
592 if (padding_ == KM_PAD_NONE && to_decrypt_len < outlen) {
593 keymaster_error_t error = zero_pad_left(&zero_padded, outlen, data_);
594 if (error != KM_ERROR_OK)
595 return error;
596 to_decrypt = zero_padded.get();
597 to_decrypt_len = outlen;
598 }
599
600 if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, to_decrypt, to_decrypt_len) <= 0)
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600601 return TranslateLastOpenSslError();
Shawn Willden0f906ec2015-06-20 09:16:30 -0600602 if (!output->advance_write(outlen))
603 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden4200f212014-12-02 07:01:21 -0700604
605 return KM_ERROR_OK;
606}
607
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600608} // namespace keymaster