blob: 17a3f2fcc7edf508557c239eb262edd64b06fec0 [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/**
34 * Abstract base for all RSA operation factories. This class exists mainly to centralize some code
35 * common to all RSA operation factories.
36 */
37class RsaOperationFactory : public OperationFactory {
38 public:
Shawn Willden226746b2015-05-08 11:36:56 -060039 KeyType registry_key() const override { return KeyType(KM_ALGORITHM_RSA, purpose()); }
Shawn Willden63ac0432014-12-29 14:07:08 -070040 virtual keymaster_purpose_t purpose() const = 0;
41
42 protected:
43 bool GetAndValidatePadding(const Key& key, keymaster_padding_t* padding,
44 keymaster_error_t* error) const;
Shawn Willden226746b2015-05-08 11:36:56 -060045 bool GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
46 keymaster_digest_t* digest, keymaster_error_t* error) const;
Shawn Willden63ac0432014-12-29 14:07:08 -070047 static RSA* GetRsaKey(const Key& key, keymaster_error_t* error);
48};
49
50bool RsaOperationFactory::GetAndValidatePadding(const Key& key, keymaster_padding_t* padding,
51 keymaster_error_t* error) const {
52 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
Shawn Willdend9d7acf2015-02-25 17:37:20 -070053 if (!key.authorizations().GetTagValue(TAG_PADDING, padding) &&
54 !key.authorizations().GetTagValue(TAG_PADDING_OLD, padding))
55 return false;
56
57 if (!supported(*padding))
Shawn Willden63ac0432014-12-29 14:07:08 -070058 return false;
59
Shawn Willdend92591d2014-12-30 18:19:10 -070060 *error = KM_ERROR_OK;
61 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070062}
63
Shawn Willden226746b2015-05-08 11:36:56 -060064bool RsaOperationFactory::GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
65 keymaster_digest_t* digest,
Shawn Willden63ac0432014-12-29 14:07:08 -070066 keymaster_error_t* error) const {
67 *error = KM_ERROR_UNSUPPORTED_DIGEST;
Shawn Willden226746b2015-05-08 11:36:56 -060068 if (!begin_params.GetTagValue(TAG_DIGEST, digest)) {
69 LOG_E("%d digests specified in begin params", begin_params.GetTagCount(TAG_DIGEST));
Shawn Willden0bd61a82015-04-13 19:09:32 -070070 return false;
Shawn Willden226746b2015-05-08 11:36:56 -060071 } else if (!supported(*digest)) {
72 LOG_E("Digest %d not supported", *digest);
Shawn Willden63ac0432014-12-29 14:07:08 -070073 return false;
Shawn Willden226746b2015-05-08 11:36:56 -060074 } else if (!key.authorizations().Contains(TAG_DIGEST, *digest) &&
75 !key.authorizations().Contains(TAG_DIGEST_OLD, *digest)) {
76 LOG_E("Digest %d was specified, but not authorized by key", *digest);
77 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
78 return false;
79 }
Shawn Willdend92591d2014-12-30 18:19:10 -070080 *error = KM_ERROR_OK;
81 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070082}
83
84/* static */
85RSA* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
86 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
87 assert(rsa_key);
88 if (!rsa_key || !rsa_key->key()) {
89 *error = KM_ERROR_UNKNOWN_ERROR;
90 return NULL;
91 }
Shawn Willden28eed512015-02-25 19:16:36 -070092 RSA_up_ref(rsa_key->key());
93 return rsa_key->key();
Shawn Willden63ac0432014-12-29 14:07:08 -070094}
95
Shawn Willden61902362014-12-18 10:33:24 -070096static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_DIGEST_SHA_2_256};
Shawn Willdenf90f2352014-12-18 23:01:15 -070097static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
98 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070099
100/**
101 * Abstract base for RSA operations that digest their input (signing and verification). This class
102 * does most of the work of creation of RSA digesting operations, delegating only the actual
103 * operation instantiation.
104 */
105class RsaDigestingOperationFactory : public RsaOperationFactory {
106 public:
Shawn Willden3ed6d062015-04-15 13:39:38 -0600107 virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
108 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700109
110 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
111 *digest_count = array_length(supported_digests);
112 return supported_digests;
113 }
114
115 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
116 *padding_mode_count = array_length(supported_sig_padding);
117 return supported_sig_padding;
118 }
119
120 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700121 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
122 RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700123};
124
Shawn Willden3ed6d062015-04-15 13:39:38 -0600125Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
Shawn Willden226746b2015-05-08 11:36:56 -0600126 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -0600127 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700128 keymaster_padding_t padding;
129 keymaster_digest_t digest;
130 RSA* rsa;
Shawn Willden226746b2015-05-08 11:36:56 -0600131 if (!GetAndValidateDigest(begin_params, key, &digest, error) ||
Shawn Willden63ac0432014-12-29 14:07:08 -0700132 !GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
133 return NULL;
134
Shawn Willden567a4a02014-12-31 12:14:46 -0700135 Operation* op = InstantiateOperation(digest, padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700136 if (!op)
137 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
138 return op;
139}
140
141static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
142 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
143
144/**
145 * Abstract base for en/de-crypting RSA operation factories. This class does most of the work of
146 * creating such operations, delegating only the actual operation instantiation.
147 */
148class RsaCryptingOperationFactory : public RsaOperationFactory {
149 public:
Shawn Willden3ed6d062015-04-15 13:39:38 -0600150 virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
151 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700152
153 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
154 *padding_mode_count = array_length(supported_crypt_padding);
155 return supported_crypt_padding;
156 }
157
158 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
159 *digest_count = 0;
160 return NULL;
161 }
162
163 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700164 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700165};
166
Shawn Willden3ed6d062015-04-15 13:39:38 -0600167Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
168 const AuthorizationSet& /* begin_params */,
169 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700170 keymaster_padding_t padding;
171 RSA* rsa;
172 if (!GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
173 return NULL;
174
Shawn Willden567a4a02014-12-31 12:14:46 -0700175 Operation* op = InstantiateOperation(padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700176 if (!op)
177 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
178 return op;
179}
180
181/**
182 * Concrete factory for RSA signing operations.
183 */
184class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
185 public:
186 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700187 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
188 RSA* key) {
189 return new RsaSignOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700190 }
191};
192static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
193
194/**
195 * Concrete factory for RSA signing operations.
196 */
197class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
198 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700199 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
200 RSA* key) {
201 return new RsaVerifyOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700202 }
203};
204static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
205
206/**
207 * Concrete factory for RSA signing operations.
208 */
209class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
210 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700211 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
212 return new RsaEncryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700213 }
214};
215static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
216
217/**
218 * Concrete factory for RSA signing operations.
219 */
220class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
221 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700222 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
223 return new RsaDecryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700224 }
225};
226
227static OperationFactoryRegistry::Registration<RsaDecryptionOperationFactory> decrypt_registration;
228
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600229struct RSA_Delete {
230 void operator()(RSA* p) const { RSA_free(p); }
231};
232
233RsaOperation::~RsaOperation() {
234 if (rsa_key_ != NULL)
235 RSA_free(rsa_key_);
236}
237
Shawn Willden6bfbff02015-02-06 19:48:24 -0700238keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
239 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700240 size_t* input_consumed) {
241 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600242 switch (purpose()) {
243 default:
244 return KM_ERROR_UNIMPLEMENTED;
245 case KM_PURPOSE_SIGN:
246 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700247 case KM_PURPOSE_ENCRYPT:
248 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700249 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600250 }
251}
252
Shawn Willdenb7361132014-12-08 08:15:14 -0700253keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
254 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600255 if (!data_.reserve(data_.available_read() + input.available_read()) ||
256 !data_.write(input.peek_read(), input.available_read()))
257 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700258 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600259 return KM_ERROR_OK;
260}
261
Shawn Willden61902362014-12-18 10:33:24 -0700262RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
263 keymaster_padding_t padding, RSA* key)
264 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
265 EVP_MD_CTX_init(&digest_ctx_);
266}
267RsaDigestingOperation::~RsaDigestingOperation() {
268 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700269 memset_s(digest_buf_, 0, sizeof(digest_buf_));
Shawn Willden61902362014-12-18 10:33:24 -0700270}
271
272keymaster_error_t RsaDigestingOperation::Begin(const AuthorizationSet& /* input_params */,
273 AuthorizationSet* /* output_params */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700274 if (require_digest() && digest_ == KM_DIGEST_NONE)
275 return KM_ERROR_INCOMPATIBLE_DIGEST;
276 return InitDigest();
277}
Shawn Willden61902362014-12-18 10:33:24 -0700278
Shawn Willdenf90f2352014-12-18 23:01:15 -0700279keymaster_error_t RsaDigestingOperation::Update(const AuthorizationSet& additional_params,
280 const Buffer& input, Buffer* output,
281 size_t* input_consumed) {
282 if (digest_ == KM_DIGEST_NONE)
283 return RsaOperation::Update(additional_params, input, output, input_consumed);
284 else
285 return UpdateDigest(input, input_consumed);
286}
287
288keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden61902362014-12-18 10:33:24 -0700289 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700290 case KM_DIGEST_NONE:
291 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700292 case KM_DIGEST_SHA_2_256:
293 digest_algorithm_ = EVP_sha256();
294 break;
295 default:
296 return KM_ERROR_UNSUPPORTED_DIGEST;
297 }
298
299 if (!EVP_DigestInit_ex(&digest_ctx_, digest_algorithm_, NULL /* engine */)) {
300 int err = ERR_get_error();
301 LOG_E("Failed to initialize digest: %d %s", err, ERR_error_string(err, NULL));
302 return KM_ERROR_UNKNOWN_ERROR;
303 }
Shawn Willden61902362014-12-18 10:33:24 -0700304 return KM_ERROR_OK;
305}
306
Shawn Willdenf90f2352014-12-18 23:01:15 -0700307keymaster_error_t RsaDigestingOperation::UpdateDigest(const Buffer& input, size_t* input_consumed) {
Shawn Willden61902362014-12-18 10:33:24 -0700308 if (!EVP_DigestUpdate(&digest_ctx_, input.peek_read(), input.available_read())) {
309 int err = ERR_get_error();
310 LOG_E("Failed to update digest: %d %s", err, ERR_error_string(err, NULL));
311 return KM_ERROR_UNKNOWN_ERROR;
312 }
313 *input_consumed = input.available_read();
314 return KM_ERROR_OK;
315}
316
Shawn Willdenf90f2352014-12-18 23:01:15 -0700317keymaster_error_t RsaDigestingOperation::FinishDigest(unsigned* digest_size) {
Shawn Willden61902362014-12-18 10:33:24 -0700318 assert(digest_algorithm_ != NULL);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700319 if (!EVP_DigestFinal_ex(&digest_ctx_, digest_buf_, digest_size)) {
Shawn Willden61902362014-12-18 10:33:24 -0700320 int err = ERR_get_error();
321 LOG_E("Failed to finalize digest: %d %s", err, ERR_error_string(err, NULL));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700322 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700323 }
324 assert(*digest_size == static_cast<unsigned>(EVP_MD_size(digest_algorithm_)));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700325 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700326}
327
Shawn Willden6bfbff02015-02-06 19:48:24 -0700328keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
329 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700330 assert(output);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600331 output->Reinitialize(RSA_size(rsa_key_));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700332 if (digest_ == KM_DIGEST_NONE)
333 return SignUndigested(output);
334 else
335 return SignDigested(output);
336}
Shawn Willden61902362014-12-18 10:33:24 -0700337
Shawn Willdenf90f2352014-12-18 23:01:15 -0700338keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
339 int bytes_encrypted;
340 switch (padding_) {
341 case KM_PAD_NONE:
342 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
343 output->peek_write(), rsa_key_, RSA_NO_PADDING);
344 break;
345 case KM_PAD_RSA_PKCS1_1_5_SIGN:
346 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
347 output->peek_write(), rsa_key_, RSA_PKCS1_PADDING);
348 break;
349 default:
350 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
351 }
Shawn Willden61902362014-12-18 10:33:24 -0700352
Shawn Willdenf90f2352014-12-18 23:01:15 -0700353 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600354 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600355 output->advance_write(bytes_encrypted);
356 return KM_ERROR_OK;
357}
358
Shawn Willdenf90f2352014-12-18 23:01:15 -0700359keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
360 unsigned digest_size = 0;
361 keymaster_error_t error = FinishDigest(&digest_size);
362 if (error != KM_ERROR_OK)
363 return error;
364
365 UniquePtr<uint8_t[]> padded_digest;
366 switch (padding_) {
367 case KM_PAD_NONE:
368 return PrivateEncrypt(digest_buf_, digest_size, RSA_NO_PADDING, output);
369 case KM_PAD_RSA_PKCS1_1_5_SIGN:
370 return PrivateEncrypt(digest_buf_, digest_size, RSA_PKCS1_PADDING, output);
371 case KM_PAD_RSA_PSS:
372 // OpenSSL doesn't verify that the key is large enough for the digest size. This can cause
373 // a segfault in some cases, and in others can result in a unsafely-small salt.
Shawn Willden2c242002015-02-27 07:01:02 -0700374 if ((unsigned)RSA_size(rsa_key_) < MIN_PSS_SALT_LEN + digest_size)
375 // TODO(swillden): Add a better return code for this.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700376 return KM_ERROR_INCOMPATIBLE_DIGEST;
377
378 if ((error = PssPadDigest(&padded_digest)) != KM_ERROR_OK)
379 return error;
380 return PrivateEncrypt(padded_digest.get(), RSA_size(rsa_key_), RSA_NO_PADDING, output);
381 default:
382 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
383 }
Shawn Willden61902362014-12-18 10:33:24 -0700384}
385
Shawn Willdenf90f2352014-12-18 23:01:15 -0700386keymaster_error_t RsaSignOperation::PssPadDigest(UniquePtr<uint8_t[]>* padded_digest) {
387 padded_digest->reset(new uint8_t[RSA_size(rsa_key_)]);
388 if (!padded_digest->get())
389 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
390
Adam Langleyadb0f332015-03-05 19:57:29 -0800391 if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa_key_, padded_digest->get(), digest_buf_,
392 digest_algorithm_, NULL,
393 -2 /* Indicates maximum salt length */)) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700394 LOG_E("%s", "Failed to apply PSS padding");
Shawn Willden61902362014-12-18 10:33:24 -0700395 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700396 }
397 return KM_ERROR_OK;
398}
399
400keymaster_error_t RsaSignOperation::PrivateEncrypt(uint8_t* to_encrypt, size_t len,
401 int openssl_padding, Buffer* output) {
402 int bytes_encrypted =
403 RSA_private_encrypt(len, to_encrypt, output->peek_write(), rsa_key_, openssl_padding);
404 if (bytes_encrypted <= 0)
405 return KM_ERROR_UNKNOWN_ERROR;
406 output->advance_write(bytes_encrypted);
407 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700408}
409
Shawn Willden6bfbff02015-02-06 19:48:24 -0700410keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
411 const Buffer& signature, Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700412 if (digest_ == KM_DIGEST_NONE)
413 return VerifyUndigested(signature);
414 else
415 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700416}
417
Shawn Willdenf90f2352014-12-18 23:01:15 -0700418keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
419 return DecryptAndMatch(signature, data_.peek_read(), data_.available_read());
Shawn Willden61902362014-12-18 10:33:24 -0700420}
421
Shawn Willdenf90f2352014-12-18 23:01:15 -0700422keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
Shawn Willden61902362014-12-18 10:33:24 -0700423 unsigned digest_size = 0;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700424 keymaster_error_t error = FinishDigest(&digest_size);
425 if (error != KM_ERROR_OK)
426 return error;
427 return DecryptAndMatch(signature, digest_buf_, digest_size);
428}
Shawn Willden61902362014-12-18 10:33:24 -0700429
Shawn Willdenf90f2352014-12-18 23:01:15 -0700430keymaster_error_t RsaVerifyOperation::DecryptAndMatch(const Buffer& signature,
431 const uint8_t* to_match, size_t len) {
432#ifdef OPENSSL_IS_BORINGSSL
433 size_t key_len = RSA_size(rsa_key_);
434#else
435 size_t key_len = (size_t)RSA_size(rsa_key_);
436#endif
437
438 int openssl_padding;
439 switch (padding_) {
440 case KM_PAD_NONE:
441 if (len != key_len)
442 return KM_ERROR_INVALID_INPUT_LENGTH;
443 if (len != signature.available_read())
444 return KM_ERROR_VERIFICATION_FAILED;
445 openssl_padding = RSA_NO_PADDING;
446 break;
447 case KM_PAD_RSA_PSS: // Do a raw decrypt for PSS
448 openssl_padding = RSA_NO_PADDING;
449 break;
450 case KM_PAD_RSA_PKCS1_1_5_SIGN:
451 openssl_padding = RSA_PKCS1_PADDING;
452 break;
453 default:
454 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
455 }
456
457 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
458 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
459 decrypted_data.get(), rsa_key_, openssl_padding);
460 if (bytes_decrypted < 0)
461 return KM_ERROR_VERIFICATION_FAILED;
462
463 if (padding_ == KM_PAD_RSA_PSS &&
Adam Langleyadb0f332015-03-05 19:57:29 -0800464 RSA_verify_PKCS1_PSS_mgf1(rsa_key_, to_match, digest_algorithm_, NULL, decrypted_data.get(),
465 -2 /* salt length recovered from signature */))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700466 return KM_ERROR_OK;
Shawn Willden197d9af2015-05-09 12:48:16 +0000467 else if (padding_ != KM_PAD_RSA_PSS && memcmp_s(decrypted_data.get(), to_match, len) == 0)
Shawn Willden61902362014-12-18 10:33:24 -0700468 return KM_ERROR_OK;
469
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600470 return KM_ERROR_VERIFICATION_FAILED;
471}
472
Shawn Willden4200f212014-12-02 07:01:21 -0700473const int OAEP_PADDING_OVERHEAD = 41;
474const int PKCS1_PADDING_OVERHEAD = 11;
475
Shawn Willden6bfbff02015-02-06 19:48:24 -0700476keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
477 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700478 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700479 int openssl_padding;
480
481#if defined(OPENSSL_IS_BORINGSSL)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700482 size_t key_len = RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700483#else
Shawn Willdenf90f2352014-12-18 23:01:15 -0700484 size_t key_len = (size_t)RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700485#endif
486
Shawn Willdenf90f2352014-12-18 23:01:15 -0700487 size_t message_size = data_.available_read();
Shawn Willden4200f212014-12-02 07:01:21 -0700488 switch (padding_) {
489 case KM_PAD_RSA_OAEP:
490 openssl_padding = RSA_PKCS1_OAEP_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700491 if (message_size + OAEP_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700492 LOG_E("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700493 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700494 return KM_ERROR_INVALID_INPUT_LENGTH;
495 }
496 break;
497 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
498 openssl_padding = RSA_PKCS1_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700499 if (message_size + PKCS1_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700500 LOG_E("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700501 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700502 return KM_ERROR_INVALID_INPUT_LENGTH;
503 }
504 break;
505 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700506 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700507 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
508 }
509
510 output->Reinitialize(RSA_size(rsa_key_));
511 int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(),
512 output->peek_write(), rsa_key_, openssl_padding);
513
514 if (bytes_encrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700515 LOG_E("Error %d encrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700516 return KM_ERROR_UNKNOWN_ERROR;
517 }
518 assert(bytes_encrypted == RSA_size(rsa_key_));
519 output->advance_write(bytes_encrypted);
520
521 return KM_ERROR_OK;
522}
523
Shawn Willden6bfbff02015-02-06 19:48:24 -0700524keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
525 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700526 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700527 int openssl_padding;
528 switch (padding_) {
529 case KM_PAD_RSA_OAEP:
530 openssl_padding = RSA_PKCS1_OAEP_PADDING;
531 break;
532 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
533 openssl_padding = RSA_PKCS1_PADDING;
534 break;
535 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700536 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700537 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
538 }
539
540 output->Reinitialize(RSA_size(rsa_key_));
541 int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(),
542 output->peek_write(), rsa_key_, openssl_padding);
543
544 if (bytes_decrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700545 LOG_E("Error %d decrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700546 return KM_ERROR_UNKNOWN_ERROR;
547 }
548 output->advance_write(bytes_decrypted);
549
550 return KM_ERROR_OK;
551}
552
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600553} // namespace keymaster