blob: 3c4209a7b13e29445d82f44b9ac85483b07c0e6d [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 Willden567a4a02014-12-31 12:14:46 -0700101 virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700102
103 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
104 *digest_count = array_length(supported_digests);
105 return supported_digests;
106 }
107
108 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
109 *padding_mode_count = array_length(supported_sig_padding);
110 return supported_sig_padding;
111 }
112
113 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700114 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
115 RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700116};
117
Shawn Willden567a4a02014-12-31 12:14:46 -0700118Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700119 keymaster_padding_t padding;
120 keymaster_digest_t digest;
121 RSA* rsa;
122 if (!GetAndValidateDigest(key, &digest, error) ||
123 !GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
124 return NULL;
125
Shawn Willden567a4a02014-12-31 12:14:46 -0700126 Operation* op = InstantiateOperation(digest, padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700127 if (!op)
128 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
129 return op;
130}
131
132static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
133 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
134
135/**
136 * Abstract base for en/de-crypting RSA operation factories. This class does most of the work of
137 * creating such operations, delegating only the actual operation instantiation.
138 */
139class RsaCryptingOperationFactory : public RsaOperationFactory {
140 public:
Shawn Willden567a4a02014-12-31 12:14:46 -0700141 virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700142
143 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
144 *padding_mode_count = array_length(supported_crypt_padding);
145 return supported_crypt_padding;
146 }
147
148 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
149 *digest_count = 0;
150 return NULL;
151 }
152
153 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700154 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700155};
156
Shawn Willden567a4a02014-12-31 12:14:46 -0700157Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700158 keymaster_padding_t padding;
159 RSA* rsa;
160 if (!GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
161 return NULL;
162
Shawn Willden567a4a02014-12-31 12:14:46 -0700163 Operation* op = InstantiateOperation(padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700164 if (!op)
165 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
166 return op;
167}
168
169/**
170 * Concrete factory for RSA signing operations.
171 */
172class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
173 public:
174 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700175 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
176 RSA* key) {
177 return new RsaSignOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700178 }
179};
180static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
181
182/**
183 * Concrete factory for RSA signing operations.
184 */
185class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
186 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
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 RsaVerifyOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700190 }
191};
192static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
193
194/**
195 * Concrete factory for RSA signing operations.
196 */
197class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
198 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700199 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
200 return new RsaEncryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700201 }
202};
203static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
204
205/**
206 * Concrete factory for RSA signing operations.
207 */
208class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
209 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700210 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
211 return new RsaDecryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700212 }
213};
214
215static OperationFactoryRegistry::Registration<RsaDecryptionOperationFactory> decrypt_registration;
216
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600217struct RSA_Delete {
218 void operator()(RSA* p) const { RSA_free(p); }
219};
220
221RsaOperation::~RsaOperation() {
222 if (rsa_key_ != NULL)
223 RSA_free(rsa_key_);
224}
225
Shawn Willden6bfbff02015-02-06 19:48:24 -0700226keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
227 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700228 size_t* input_consumed) {
229 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600230 switch (purpose()) {
231 default:
232 return KM_ERROR_UNIMPLEMENTED;
233 case KM_PURPOSE_SIGN:
234 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700235 case KM_PURPOSE_ENCRYPT:
236 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700237 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600238 }
239}
240
Shawn Willdenb7361132014-12-08 08:15:14 -0700241keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
242 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600243 if (!data_.reserve(data_.available_read() + input.available_read()) ||
244 !data_.write(input.peek_read(), input.available_read()))
245 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700246 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600247 return KM_ERROR_OK;
248}
249
Shawn Willden61902362014-12-18 10:33:24 -0700250RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
251 keymaster_padding_t padding, RSA* key)
252 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
253 EVP_MD_CTX_init(&digest_ctx_);
254}
255RsaDigestingOperation::~RsaDigestingOperation() {
256 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700257 memset_s(digest_buf_, 0, sizeof(digest_buf_));
Shawn Willden61902362014-12-18 10:33:24 -0700258}
259
260keymaster_error_t RsaDigestingOperation::Begin(const AuthorizationSet& /* input_params */,
261 AuthorizationSet* /* output_params */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700262 if (require_digest() && digest_ == KM_DIGEST_NONE)
263 return KM_ERROR_INCOMPATIBLE_DIGEST;
264 return InitDigest();
265}
Shawn Willden61902362014-12-18 10:33:24 -0700266
Shawn Willdenf90f2352014-12-18 23:01:15 -0700267keymaster_error_t RsaDigestingOperation::Update(const AuthorizationSet& additional_params,
268 const Buffer& input, Buffer* output,
269 size_t* input_consumed) {
270 if (digest_ == KM_DIGEST_NONE)
271 return RsaOperation::Update(additional_params, input, output, input_consumed);
272 else
273 return UpdateDigest(input, input_consumed);
274}
275
276keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden61902362014-12-18 10:33:24 -0700277 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700278 case KM_DIGEST_NONE:
279 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700280 case KM_DIGEST_SHA_2_256:
281 digest_algorithm_ = EVP_sha256();
282 break;
283 default:
284 return KM_ERROR_UNSUPPORTED_DIGEST;
285 }
286
287 if (!EVP_DigestInit_ex(&digest_ctx_, digest_algorithm_, NULL /* engine */)) {
288 int err = ERR_get_error();
289 LOG_E("Failed to initialize digest: %d %s", err, ERR_error_string(err, NULL));
290 return KM_ERROR_UNKNOWN_ERROR;
291 }
Shawn Willden61902362014-12-18 10:33:24 -0700292 return KM_ERROR_OK;
293}
294
Shawn Willdenf90f2352014-12-18 23:01:15 -0700295keymaster_error_t RsaDigestingOperation::UpdateDigest(const Buffer& input, size_t* input_consumed) {
Shawn Willden61902362014-12-18 10:33:24 -0700296 if (!EVP_DigestUpdate(&digest_ctx_, input.peek_read(), input.available_read())) {
297 int err = ERR_get_error();
298 LOG_E("Failed to update digest: %d %s", err, ERR_error_string(err, NULL));
299 return KM_ERROR_UNKNOWN_ERROR;
300 }
301 *input_consumed = input.available_read();
302 return KM_ERROR_OK;
303}
304
Shawn Willdenf90f2352014-12-18 23:01:15 -0700305keymaster_error_t RsaDigestingOperation::FinishDigest(unsigned* digest_size) {
Shawn Willden61902362014-12-18 10:33:24 -0700306 assert(digest_algorithm_ != NULL);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700307 if (!EVP_DigestFinal_ex(&digest_ctx_, digest_buf_, digest_size)) {
Shawn Willden61902362014-12-18 10:33:24 -0700308 int err = ERR_get_error();
309 LOG_E("Failed to finalize digest: %d %s", err, ERR_error_string(err, NULL));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700310 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700311 }
312 assert(*digest_size == static_cast<unsigned>(EVP_MD_size(digest_algorithm_)));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700313 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700314}
315
Shawn Willden6bfbff02015-02-06 19:48:24 -0700316keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
317 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700318 assert(output);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600319 output->Reinitialize(RSA_size(rsa_key_));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700320 if (digest_ == KM_DIGEST_NONE)
321 return SignUndigested(output);
322 else
323 return SignDigested(output);
324}
Shawn Willden61902362014-12-18 10:33:24 -0700325
Shawn Willdenf90f2352014-12-18 23:01:15 -0700326keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
327 int bytes_encrypted;
328 switch (padding_) {
329 case KM_PAD_NONE:
330 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
331 output->peek_write(), rsa_key_, RSA_NO_PADDING);
332 break;
333 case KM_PAD_RSA_PKCS1_1_5_SIGN:
334 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
335 output->peek_write(), rsa_key_, RSA_PKCS1_PADDING);
336 break;
337 default:
338 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
339 }
Shawn Willden61902362014-12-18 10:33:24 -0700340
Shawn Willdenf90f2352014-12-18 23:01:15 -0700341 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600342 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600343 output->advance_write(bytes_encrypted);
344 return KM_ERROR_OK;
345}
346
Shawn Willdenf90f2352014-12-18 23:01:15 -0700347keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
348 unsigned digest_size = 0;
349 keymaster_error_t error = FinishDigest(&digest_size);
350 if (error != KM_ERROR_OK)
351 return error;
352
353 UniquePtr<uint8_t[]> padded_digest;
354 switch (padding_) {
355 case KM_PAD_NONE:
356 return PrivateEncrypt(digest_buf_, digest_size, RSA_NO_PADDING, output);
357 case KM_PAD_RSA_PKCS1_1_5_SIGN:
358 return PrivateEncrypt(digest_buf_, digest_size, RSA_PKCS1_PADDING, output);
359 case KM_PAD_RSA_PSS:
360 // OpenSSL doesn't verify that the key is large enough for the digest size. This can cause
361 // a segfault in some cases, and in others can result in a unsafely-small salt.
Shawn Willden2c242002015-02-27 07:01:02 -0700362 if ((unsigned)RSA_size(rsa_key_) < MIN_PSS_SALT_LEN + digest_size)
363 // TODO(swillden): Add a better return code for this.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700364 return KM_ERROR_INCOMPATIBLE_DIGEST;
365
366 if ((error = PssPadDigest(&padded_digest)) != KM_ERROR_OK)
367 return error;
368 return PrivateEncrypt(padded_digest.get(), RSA_size(rsa_key_), RSA_NO_PADDING, output);
369 default:
370 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
371 }
Shawn Willden61902362014-12-18 10:33:24 -0700372}
373
Shawn Willdenf90f2352014-12-18 23:01:15 -0700374keymaster_error_t RsaSignOperation::PssPadDigest(UniquePtr<uint8_t[]>* padded_digest) {
375 padded_digest->reset(new uint8_t[RSA_size(rsa_key_)]);
376 if (!padded_digest->get())
377 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
378
Adam Langleyadb0f332015-03-05 19:57:29 -0800379 if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa_key_, padded_digest->get(), digest_buf_,
380 digest_algorithm_, NULL,
381 -2 /* Indicates maximum salt length */)) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700382 LOG_E("%s", "Failed to apply PSS padding");
Shawn Willden61902362014-12-18 10:33:24 -0700383 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700384 }
385 return KM_ERROR_OK;
386}
387
388keymaster_error_t RsaSignOperation::PrivateEncrypt(uint8_t* to_encrypt, size_t len,
389 int openssl_padding, Buffer* output) {
390 int bytes_encrypted =
391 RSA_private_encrypt(len, to_encrypt, output->peek_write(), rsa_key_, openssl_padding);
392 if (bytes_encrypted <= 0)
393 return KM_ERROR_UNKNOWN_ERROR;
394 output->advance_write(bytes_encrypted);
395 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700396}
397
Shawn Willden6bfbff02015-02-06 19:48:24 -0700398keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
399 const Buffer& signature, Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700400 if (digest_ == KM_DIGEST_NONE)
401 return VerifyUndigested(signature);
402 else
403 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700404}
405
Shawn Willdenf90f2352014-12-18 23:01:15 -0700406keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
407 return DecryptAndMatch(signature, data_.peek_read(), data_.available_read());
Shawn Willden61902362014-12-18 10:33:24 -0700408}
409
Shawn Willdenf90f2352014-12-18 23:01:15 -0700410keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
Shawn Willden61902362014-12-18 10:33:24 -0700411 unsigned digest_size = 0;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700412 keymaster_error_t error = FinishDigest(&digest_size);
413 if (error != KM_ERROR_OK)
414 return error;
415 return DecryptAndMatch(signature, digest_buf_, digest_size);
416}
Shawn Willden61902362014-12-18 10:33:24 -0700417
Shawn Willdenf90f2352014-12-18 23:01:15 -0700418keymaster_error_t RsaVerifyOperation::DecryptAndMatch(const Buffer& signature,
419 const uint8_t* to_match, size_t len) {
420#ifdef OPENSSL_IS_BORINGSSL
421 size_t key_len = RSA_size(rsa_key_);
422#else
423 size_t key_len = (size_t)RSA_size(rsa_key_);
424#endif
425
426 int openssl_padding;
427 switch (padding_) {
428 case KM_PAD_NONE:
429 if (len != key_len)
430 return KM_ERROR_INVALID_INPUT_LENGTH;
431 if (len != signature.available_read())
432 return KM_ERROR_VERIFICATION_FAILED;
433 openssl_padding = RSA_NO_PADDING;
434 break;
435 case KM_PAD_RSA_PSS: // Do a raw decrypt for PSS
436 openssl_padding = RSA_NO_PADDING;
437 break;
438 case KM_PAD_RSA_PKCS1_1_5_SIGN:
439 openssl_padding = RSA_PKCS1_PADDING;
440 break;
441 default:
442 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
443 }
444
445 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
446 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
447 decrypted_data.get(), rsa_key_, openssl_padding);
448 if (bytes_decrypted < 0)
449 return KM_ERROR_VERIFICATION_FAILED;
450
451 if (padding_ == KM_PAD_RSA_PSS &&
Adam Langleyadb0f332015-03-05 19:57:29 -0800452 RSA_verify_PKCS1_PSS_mgf1(rsa_key_, to_match, digest_algorithm_, NULL, decrypted_data.get(),
453 -2 /* salt length recovered from signature */))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700454 return KM_ERROR_OK;
455 else if (padding_ != KM_PAD_RSA_PSS && memcmp_s(decrypted_data.get(), to_match, len) == 0)
Shawn Willden61902362014-12-18 10:33:24 -0700456 return KM_ERROR_OK;
457
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600458 return KM_ERROR_VERIFICATION_FAILED;
459}
460
Shawn Willden4200f212014-12-02 07:01:21 -0700461const int OAEP_PADDING_OVERHEAD = 41;
462const int PKCS1_PADDING_OVERHEAD = 11;
463
Shawn Willden6bfbff02015-02-06 19:48:24 -0700464keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
465 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700466 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700467 int openssl_padding;
468
469#if defined(OPENSSL_IS_BORINGSSL)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700470 size_t key_len = RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700471#else
Shawn Willdenf90f2352014-12-18 23:01:15 -0700472 size_t key_len = (size_t)RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700473#endif
474
Shawn Willdenf90f2352014-12-18 23:01:15 -0700475 size_t message_size = data_.available_read();
Shawn Willden4200f212014-12-02 07:01:21 -0700476 switch (padding_) {
477 case KM_PAD_RSA_OAEP:
478 openssl_padding = RSA_PKCS1_OAEP_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700479 if (message_size + OAEP_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700480 LOG_E("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700481 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700482 return KM_ERROR_INVALID_INPUT_LENGTH;
483 }
484 break;
485 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
486 openssl_padding = RSA_PKCS1_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700487 if (message_size + PKCS1_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700488 LOG_E("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700489 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700490 return KM_ERROR_INVALID_INPUT_LENGTH;
491 }
492 break;
493 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700494 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700495 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
496 }
497
498 output->Reinitialize(RSA_size(rsa_key_));
499 int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(),
500 output->peek_write(), rsa_key_, openssl_padding);
501
502 if (bytes_encrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700503 LOG_E("Error %d encrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700504 return KM_ERROR_UNKNOWN_ERROR;
505 }
506 assert(bytes_encrypted == RSA_size(rsa_key_));
507 output->advance_write(bytes_encrypted);
508
509 return KM_ERROR_OK;
510}
511
Shawn Willden6bfbff02015-02-06 19:48:24 -0700512keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
513 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700514 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700515 int openssl_padding;
516 switch (padding_) {
517 case KM_PAD_RSA_OAEP:
518 openssl_padding = RSA_PKCS1_OAEP_PADDING;
519 break;
520 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
521 openssl_padding = RSA_PKCS1_PADDING;
522 break;
523 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700524 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700525 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
526 }
527
528 output->Reinitialize(RSA_size(rsa_key_));
529 int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(),
530 output->peek_write(), rsa_key_, openssl_padding);
531
532 if (bytes_decrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700533 LOG_E("Error %d decrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700534 return KM_ERROR_UNKNOWN_ERROR;
535 }
536 output->advance_write(bytes_decrypted);
537
538 return KM_ERROR_OK;
539}
540
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600541} // namespace keymaster