blob: df077474233524d688a49d5cc13112e4e2762dec [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:
39 virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_RSA, purpose()); }
40 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;
45 bool GetAndValidateDigest(const Key& key, keymaster_digest_t* digest,
46 keymaster_error_t* error) const;
47 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
64bool RsaOperationFactory::GetAndValidateDigest(const Key& key, keymaster_digest_t* digest,
65 keymaster_error_t* error) const {
66 *error = KM_ERROR_UNSUPPORTED_DIGEST;
Shawn Willden0bd61a82015-04-13 19:09:32 -070067 if (!key.authorizations().GetTagValue(TAG_DIGEST, digest) &&
68 !key.authorizations().GetTagValue(TAG_DIGEST_OLD, digest))
69 return false;
70
71 if (!supported(*digest))
Shawn Willden63ac0432014-12-29 14:07:08 -070072 return false;
73
Shawn Willdend92591d2014-12-30 18:19:10 -070074 *error = KM_ERROR_OK;
75 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070076}
77
78/* static */
79RSA* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
80 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
81 assert(rsa_key);
82 if (!rsa_key || !rsa_key->key()) {
83 *error = KM_ERROR_UNKNOWN_ERROR;
84 return NULL;
85 }
Shawn Willden28eed512015-02-25 19:16:36 -070086 RSA_up_ref(rsa_key->key());
87 return rsa_key->key();
Shawn Willden63ac0432014-12-29 14:07:08 -070088}
89
Shawn Willden61902362014-12-18 10:33:24 -070090static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_DIGEST_SHA_2_256};
Shawn Willdenf90f2352014-12-18 23:01:15 -070091static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
92 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070093
94/**
95 * Abstract base for RSA operations that digest their input (signing and verification). This class
96 * does most of the work of creation of RSA digesting operations, delegating only the actual
97 * operation instantiation.
98 */
99class RsaDigestingOperationFactory : public RsaOperationFactory {
100 public:
Shawn Willden3ed6d062015-04-15 13:39:38 -0600101 virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
102 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700103
104 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
105 *digest_count = array_length(supported_digests);
106 return supported_digests;
107 }
108
109 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
110 *padding_mode_count = array_length(supported_sig_padding);
111 return supported_sig_padding;
112 }
113
114 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700115 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
116 RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700117};
118
Shawn Willden3ed6d062015-04-15 13:39:38 -0600119Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
120 const AuthorizationSet& /* begin_params */,
121 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700122 keymaster_padding_t padding;
123 keymaster_digest_t digest;
124 RSA* rsa;
125 if (!GetAndValidateDigest(key, &digest, error) ||
126 !GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
127 return NULL;
128
Shawn Willden567a4a02014-12-31 12:14:46 -0700129 Operation* op = InstantiateOperation(digest, padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700130 if (!op)
131 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
132 return op;
133}
134
135static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
136 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
137
138/**
139 * Abstract base for en/de-crypting RSA operation factories. This class does most of the work of
140 * creating such operations, delegating only the actual operation instantiation.
141 */
142class RsaCryptingOperationFactory : public RsaOperationFactory {
143 public:
Shawn Willden3ed6d062015-04-15 13:39:38 -0600144 virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
145 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700146
147 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
148 *padding_mode_count = array_length(supported_crypt_padding);
149 return supported_crypt_padding;
150 }
151
152 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
153 *digest_count = 0;
154 return NULL;
155 }
156
157 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700158 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700159};
160
Shawn Willden3ed6d062015-04-15 13:39:38 -0600161Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
162 const AuthorizationSet& /* begin_params */,
163 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700164 keymaster_padding_t padding;
165 RSA* rsa;
166 if (!GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
167 return NULL;
168
Shawn Willden567a4a02014-12-31 12:14:46 -0700169 Operation* op = InstantiateOperation(padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700170 if (!op)
171 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
172 return op;
173}
174
175/**
176 * Concrete factory for RSA signing operations.
177 */
178class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
179 public:
180 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700181 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
182 RSA* key) {
183 return new RsaSignOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700184 }
185};
186static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
187
188/**
189 * Concrete factory for RSA signing operations.
190 */
191class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
192 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700193 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
194 RSA* key) {
195 return new RsaVerifyOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700196 }
197};
198static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
199
200/**
201 * Concrete factory for RSA signing operations.
202 */
203class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
204 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700205 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
206 return new RsaEncryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700207 }
208};
209static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
210
211/**
212 * Concrete factory for RSA signing operations.
213 */
214class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
215 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700216 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
217 return new RsaDecryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700218 }
219};
220
221static OperationFactoryRegistry::Registration<RsaDecryptionOperationFactory> decrypt_registration;
222
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600223struct RSA_Delete {
224 void operator()(RSA* p) const { RSA_free(p); }
225};
226
227RsaOperation::~RsaOperation() {
228 if (rsa_key_ != NULL)
229 RSA_free(rsa_key_);
230}
231
Shawn Willden6bfbff02015-02-06 19:48:24 -0700232keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
233 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700234 size_t* input_consumed) {
235 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600236 switch (purpose()) {
237 default:
238 return KM_ERROR_UNIMPLEMENTED;
239 case KM_PURPOSE_SIGN:
240 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700241 case KM_PURPOSE_ENCRYPT:
242 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700243 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600244 }
245}
246
Shawn Willdenb7361132014-12-08 08:15:14 -0700247keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
248 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600249 if (!data_.reserve(data_.available_read() + input.available_read()) ||
250 !data_.write(input.peek_read(), input.available_read()))
251 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700252 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600253 return KM_ERROR_OK;
254}
255
Shawn Willden61902362014-12-18 10:33:24 -0700256RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
257 keymaster_padding_t padding, RSA* key)
258 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
259 EVP_MD_CTX_init(&digest_ctx_);
260}
261RsaDigestingOperation::~RsaDigestingOperation() {
262 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700263 memset_s(digest_buf_, 0, sizeof(digest_buf_));
Shawn Willden61902362014-12-18 10:33:24 -0700264}
265
266keymaster_error_t RsaDigestingOperation::Begin(const AuthorizationSet& /* input_params */,
267 AuthorizationSet* /* output_params */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700268 if (require_digest() && digest_ == KM_DIGEST_NONE)
269 return KM_ERROR_INCOMPATIBLE_DIGEST;
270 return InitDigest();
271}
Shawn Willden61902362014-12-18 10:33:24 -0700272
Shawn Willdenf90f2352014-12-18 23:01:15 -0700273keymaster_error_t RsaDigestingOperation::Update(const AuthorizationSet& additional_params,
274 const Buffer& input, Buffer* output,
275 size_t* input_consumed) {
276 if (digest_ == KM_DIGEST_NONE)
277 return RsaOperation::Update(additional_params, input, output, input_consumed);
278 else
279 return UpdateDigest(input, input_consumed);
280}
281
282keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden61902362014-12-18 10:33:24 -0700283 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700284 case KM_DIGEST_NONE:
285 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700286 case KM_DIGEST_SHA_2_256:
287 digest_algorithm_ = EVP_sha256();
288 break;
289 default:
290 return KM_ERROR_UNSUPPORTED_DIGEST;
291 }
292
293 if (!EVP_DigestInit_ex(&digest_ctx_, digest_algorithm_, NULL /* engine */)) {
294 int err = ERR_get_error();
295 LOG_E("Failed to initialize digest: %d %s", err, ERR_error_string(err, NULL));
296 return KM_ERROR_UNKNOWN_ERROR;
297 }
Shawn Willden61902362014-12-18 10:33:24 -0700298 return KM_ERROR_OK;
299}
300
Shawn Willdenf90f2352014-12-18 23:01:15 -0700301keymaster_error_t RsaDigestingOperation::UpdateDigest(const Buffer& input, size_t* input_consumed) {
Shawn Willden61902362014-12-18 10:33:24 -0700302 if (!EVP_DigestUpdate(&digest_ctx_, input.peek_read(), input.available_read())) {
303 int err = ERR_get_error();
304 LOG_E("Failed to update digest: %d %s", err, ERR_error_string(err, NULL));
305 return KM_ERROR_UNKNOWN_ERROR;
306 }
307 *input_consumed = input.available_read();
308 return KM_ERROR_OK;
309}
310
Shawn Willdenf90f2352014-12-18 23:01:15 -0700311keymaster_error_t RsaDigestingOperation::FinishDigest(unsigned* digest_size) {
Shawn Willden61902362014-12-18 10:33:24 -0700312 assert(digest_algorithm_ != NULL);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700313 if (!EVP_DigestFinal_ex(&digest_ctx_, digest_buf_, digest_size)) {
Shawn Willden61902362014-12-18 10:33:24 -0700314 int err = ERR_get_error();
315 LOG_E("Failed to finalize digest: %d %s", err, ERR_error_string(err, NULL));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700316 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700317 }
318 assert(*digest_size == static_cast<unsigned>(EVP_MD_size(digest_algorithm_)));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700319 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700320}
321
Shawn Willden6bfbff02015-02-06 19:48:24 -0700322keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
323 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700324 assert(output);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600325 output->Reinitialize(RSA_size(rsa_key_));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700326 if (digest_ == KM_DIGEST_NONE)
327 return SignUndigested(output);
328 else
329 return SignDigested(output);
330}
Shawn Willden61902362014-12-18 10:33:24 -0700331
Shawn Willdenf90f2352014-12-18 23:01:15 -0700332keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
333 int bytes_encrypted;
334 switch (padding_) {
335 case KM_PAD_NONE:
336 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
337 output->peek_write(), rsa_key_, RSA_NO_PADDING);
338 break;
339 case KM_PAD_RSA_PKCS1_1_5_SIGN:
340 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
341 output->peek_write(), rsa_key_, RSA_PKCS1_PADDING);
342 break;
343 default:
344 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
345 }
Shawn Willden61902362014-12-18 10:33:24 -0700346
Shawn Willdenf90f2352014-12-18 23:01:15 -0700347 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600348 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600349 output->advance_write(bytes_encrypted);
350 return KM_ERROR_OK;
351}
352
Shawn Willdenf90f2352014-12-18 23:01:15 -0700353keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
354 unsigned digest_size = 0;
355 keymaster_error_t error = FinishDigest(&digest_size);
356 if (error != KM_ERROR_OK)
357 return error;
358
359 UniquePtr<uint8_t[]> padded_digest;
360 switch (padding_) {
361 case KM_PAD_NONE:
362 return PrivateEncrypt(digest_buf_, digest_size, RSA_NO_PADDING, output);
363 case KM_PAD_RSA_PKCS1_1_5_SIGN:
364 return PrivateEncrypt(digest_buf_, digest_size, RSA_PKCS1_PADDING, output);
365 case KM_PAD_RSA_PSS:
366 // OpenSSL doesn't verify that the key is large enough for the digest size. This can cause
367 // a segfault in some cases, and in others can result in a unsafely-small salt.
Shawn Willden2c242002015-02-27 07:01:02 -0700368 if ((unsigned)RSA_size(rsa_key_) < MIN_PSS_SALT_LEN + digest_size)
369 // TODO(swillden): Add a better return code for this.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700370 return KM_ERROR_INCOMPATIBLE_DIGEST;
371
372 if ((error = PssPadDigest(&padded_digest)) != KM_ERROR_OK)
373 return error;
374 return PrivateEncrypt(padded_digest.get(), RSA_size(rsa_key_), RSA_NO_PADDING, output);
375 default:
376 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
377 }
Shawn Willden61902362014-12-18 10:33:24 -0700378}
379
Shawn Willdenf90f2352014-12-18 23:01:15 -0700380keymaster_error_t RsaSignOperation::PssPadDigest(UniquePtr<uint8_t[]>* padded_digest) {
381 padded_digest->reset(new uint8_t[RSA_size(rsa_key_)]);
382 if (!padded_digest->get())
383 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
384
Adam Langleyadb0f332015-03-05 19:57:29 -0800385 if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa_key_, padded_digest->get(), digest_buf_,
386 digest_algorithm_, NULL,
387 -2 /* Indicates maximum salt length */)) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700388 LOG_E("%s", "Failed to apply PSS padding");
Shawn Willden61902362014-12-18 10:33:24 -0700389 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700390 }
391 return KM_ERROR_OK;
392}
393
394keymaster_error_t RsaSignOperation::PrivateEncrypt(uint8_t* to_encrypt, size_t len,
395 int openssl_padding, Buffer* output) {
396 int bytes_encrypted =
397 RSA_private_encrypt(len, to_encrypt, output->peek_write(), rsa_key_, openssl_padding);
398 if (bytes_encrypted <= 0)
399 return KM_ERROR_UNKNOWN_ERROR;
400 output->advance_write(bytes_encrypted);
401 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700402}
403
Shawn Willden6bfbff02015-02-06 19:48:24 -0700404keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
405 const Buffer& signature, Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700406 if (digest_ == KM_DIGEST_NONE)
407 return VerifyUndigested(signature);
408 else
409 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700410}
411
Shawn Willdenf90f2352014-12-18 23:01:15 -0700412keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
413 return DecryptAndMatch(signature, data_.peek_read(), data_.available_read());
Shawn Willden61902362014-12-18 10:33:24 -0700414}
415
Shawn Willdenf90f2352014-12-18 23:01:15 -0700416keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
Shawn Willden61902362014-12-18 10:33:24 -0700417 unsigned digest_size = 0;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700418 keymaster_error_t error = FinishDigest(&digest_size);
419 if (error != KM_ERROR_OK)
420 return error;
421 return DecryptAndMatch(signature, digest_buf_, digest_size);
422}
Shawn Willden61902362014-12-18 10:33:24 -0700423
Shawn Willdenf90f2352014-12-18 23:01:15 -0700424keymaster_error_t RsaVerifyOperation::DecryptAndMatch(const Buffer& signature,
425 const uint8_t* to_match, size_t len) {
426#ifdef OPENSSL_IS_BORINGSSL
427 size_t key_len = RSA_size(rsa_key_);
428#else
429 size_t key_len = (size_t)RSA_size(rsa_key_);
430#endif
431
432 int openssl_padding;
433 switch (padding_) {
434 case KM_PAD_NONE:
435 if (len != key_len)
436 return KM_ERROR_INVALID_INPUT_LENGTH;
437 if (len != signature.available_read())
438 return KM_ERROR_VERIFICATION_FAILED;
439 openssl_padding = RSA_NO_PADDING;
440 break;
441 case KM_PAD_RSA_PSS: // Do a raw decrypt for PSS
442 openssl_padding = RSA_NO_PADDING;
443 break;
444 case KM_PAD_RSA_PKCS1_1_5_SIGN:
445 openssl_padding = RSA_PKCS1_PADDING;
446 break;
447 default:
448 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
449 }
450
451 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
452 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
453 decrypted_data.get(), rsa_key_, openssl_padding);
454 if (bytes_decrypted < 0)
455 return KM_ERROR_VERIFICATION_FAILED;
456
457 if (padding_ == KM_PAD_RSA_PSS &&
Adam Langleyadb0f332015-03-05 19:57:29 -0800458 RSA_verify_PKCS1_PSS_mgf1(rsa_key_, to_match, digest_algorithm_, NULL, decrypted_data.get(),
459 -2 /* salt length recovered from signature */))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700460 return KM_ERROR_OK;
461 else if (padding_ != KM_PAD_RSA_PSS && memcmp_s(decrypted_data.get(), to_match, len) == 0)
Shawn Willden61902362014-12-18 10:33:24 -0700462 return KM_ERROR_OK;
463
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600464 return KM_ERROR_VERIFICATION_FAILED;
465}
466
Shawn Willden4200f212014-12-02 07:01:21 -0700467const int OAEP_PADDING_OVERHEAD = 41;
468const int PKCS1_PADDING_OVERHEAD = 11;
469
Shawn Willden6bfbff02015-02-06 19:48:24 -0700470keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
471 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700472 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700473 int openssl_padding;
474
475#if defined(OPENSSL_IS_BORINGSSL)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700476 size_t key_len = RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700477#else
Shawn Willdenf90f2352014-12-18 23:01:15 -0700478 size_t key_len = (size_t)RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700479#endif
480
Shawn Willdenf90f2352014-12-18 23:01:15 -0700481 size_t message_size = data_.available_read();
Shawn Willden4200f212014-12-02 07:01:21 -0700482 switch (padding_) {
483 case KM_PAD_RSA_OAEP:
484 openssl_padding = RSA_PKCS1_OAEP_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700485 if (message_size + OAEP_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700486 LOG_E("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700487 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700488 return KM_ERROR_INVALID_INPUT_LENGTH;
489 }
490 break;
491 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
492 openssl_padding = RSA_PKCS1_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700493 if (message_size + PKCS1_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700494 LOG_E("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700495 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700496 return KM_ERROR_INVALID_INPUT_LENGTH;
497 }
498 break;
499 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700500 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700501 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
502 }
503
504 output->Reinitialize(RSA_size(rsa_key_));
505 int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(),
506 output->peek_write(), rsa_key_, openssl_padding);
507
508 if (bytes_encrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700509 LOG_E("Error %d encrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700510 return KM_ERROR_UNKNOWN_ERROR;
511 }
512 assert(bytes_encrypted == RSA_size(rsa_key_));
513 output->advance_write(bytes_encrypted);
514
515 return KM_ERROR_OK;
516}
517
Shawn Willden6bfbff02015-02-06 19:48:24 -0700518keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
519 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700520 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700521 int openssl_padding;
522 switch (padding_) {
523 case KM_PAD_RSA_OAEP:
524 openssl_padding = RSA_PKCS1_OAEP_PADDING;
525 break;
526 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
527 openssl_padding = RSA_PKCS1_PADDING;
528 break;
529 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700530 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700531 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
532 }
533
534 output->Reinitialize(RSA_size(rsa_key_));
535 int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(),
536 output->peek_write(), rsa_key_, openssl_padding);
537
538 if (bytes_decrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700539 LOG_E("Error %d decrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700540 return KM_ERROR_UNKNOWN_ERROR;
541 }
542 output->advance_write(bytes_decrypted);
543
544 return KM_ERROR_OK;
545}
546
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600547} // namespace keymaster