blob: b52f98824ef2fb74c7f0542599cee0b413447d5d [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 Willdend92591d2014-12-30 18:19:10 -070067 if (!key.authorizations().GetTagValue(TAG_DIGEST, digest) || !supported(*digest))
Shawn Willden63ac0432014-12-29 14:07:08 -070068 return false;
69
Shawn Willdend92591d2014-12-30 18:19:10 -070070 *error = KM_ERROR_OK;
71 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070072}
73
74/* static */
75RSA* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
76 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
77 assert(rsa_key);
78 if (!rsa_key || !rsa_key->key()) {
79 *error = KM_ERROR_UNKNOWN_ERROR;
80 return NULL;
81 }
Shawn Willden28eed512015-02-25 19:16:36 -070082 RSA_up_ref(rsa_key->key());
83 return rsa_key->key();
Shawn Willden63ac0432014-12-29 14:07:08 -070084}
85
Shawn Willden61902362014-12-18 10:33:24 -070086static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_DIGEST_SHA_2_256};
Shawn Willdenf90f2352014-12-18 23:01:15 -070087static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
88 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070089
90/**
91 * Abstract base for RSA operations that digest their input (signing and verification). This class
92 * does most of the work of creation of RSA digesting operations, delegating only the actual
93 * operation instantiation.
94 */
95class RsaDigestingOperationFactory : public RsaOperationFactory {
96 public:
Shawn Willden567a4a02014-12-31 12:14:46 -070097 virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -070098
99 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
100 *digest_count = array_length(supported_digests);
101 return supported_digests;
102 }
103
104 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
105 *padding_mode_count = array_length(supported_sig_padding);
106 return supported_sig_padding;
107 }
108
109 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700110 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
111 RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700112};
113
Shawn Willden567a4a02014-12-31 12:14:46 -0700114Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700115 keymaster_padding_t padding;
116 keymaster_digest_t digest;
117 RSA* rsa;
118 if (!GetAndValidateDigest(key, &digest, error) ||
119 !GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
120 return NULL;
121
Shawn Willden567a4a02014-12-31 12:14:46 -0700122 Operation* op = InstantiateOperation(digest, padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700123 if (!op)
124 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
125 return op;
126}
127
128static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
129 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
130
131/**
132 * Abstract base for en/de-crypting RSA operation factories. This class does most of the work of
133 * creating such operations, delegating only the actual operation instantiation.
134 */
135class RsaCryptingOperationFactory : public RsaOperationFactory {
136 public:
Shawn Willden567a4a02014-12-31 12:14:46 -0700137 virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700138
139 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
140 *padding_mode_count = array_length(supported_crypt_padding);
141 return supported_crypt_padding;
142 }
143
144 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
145 *digest_count = 0;
146 return NULL;
147 }
148
149 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700150 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700151};
152
Shawn Willden567a4a02014-12-31 12:14:46 -0700153Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700154 keymaster_padding_t padding;
155 RSA* rsa;
156 if (!GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
157 return NULL;
158
Shawn Willden567a4a02014-12-31 12:14:46 -0700159 Operation* op = InstantiateOperation(padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700160 if (!op)
161 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
162 return op;
163}
164
165/**
166 * Concrete factory for RSA signing operations.
167 */
168class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
169 public:
170 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700171 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
172 RSA* key) {
173 return new RsaSignOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700174 }
175};
176static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
177
178/**
179 * Concrete factory for RSA signing operations.
180 */
181class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
182 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700183 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
184 RSA* key) {
185 return new RsaVerifyOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700186 }
187};
188static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
189
190/**
191 * Concrete factory for RSA signing operations.
192 */
193class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
194 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700195 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
196 return new RsaEncryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700197 }
198};
199static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
200
201/**
202 * Concrete factory for RSA signing operations.
203 */
204class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
205 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700206 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
207 return new RsaDecryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700208 }
209};
210
211static OperationFactoryRegistry::Registration<RsaDecryptionOperationFactory> decrypt_registration;
212
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600213struct RSA_Delete {
214 void operator()(RSA* p) const { RSA_free(p); }
215};
216
217RsaOperation::~RsaOperation() {
218 if (rsa_key_ != NULL)
219 RSA_free(rsa_key_);
220}
221
Shawn Willden6bfbff02015-02-06 19:48:24 -0700222keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
223 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700224 size_t* input_consumed) {
225 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600226 switch (purpose()) {
227 default:
228 return KM_ERROR_UNIMPLEMENTED;
229 case KM_PURPOSE_SIGN:
230 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700231 case KM_PURPOSE_ENCRYPT:
232 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700233 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600234 }
235}
236
Shawn Willdenb7361132014-12-08 08:15:14 -0700237keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
238 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600239 if (!data_.reserve(data_.available_read() + input.available_read()) ||
240 !data_.write(input.peek_read(), input.available_read()))
241 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700242 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600243 return KM_ERROR_OK;
244}
245
Shawn Willden61902362014-12-18 10:33:24 -0700246RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
247 keymaster_padding_t padding, RSA* key)
248 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
249 EVP_MD_CTX_init(&digest_ctx_);
250}
251RsaDigestingOperation::~RsaDigestingOperation() {
252 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700253 memset_s(digest_buf_, 0, sizeof(digest_buf_));
Shawn Willden61902362014-12-18 10:33:24 -0700254}
255
256keymaster_error_t RsaDigestingOperation::Begin(const AuthorizationSet& /* input_params */,
257 AuthorizationSet* /* output_params */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700258 if (require_digest() && digest_ == KM_DIGEST_NONE)
259 return KM_ERROR_INCOMPATIBLE_DIGEST;
260 return InitDigest();
261}
Shawn Willden61902362014-12-18 10:33:24 -0700262
Shawn Willdenf90f2352014-12-18 23:01:15 -0700263keymaster_error_t RsaDigestingOperation::Update(const AuthorizationSet& additional_params,
264 const Buffer& input, Buffer* output,
265 size_t* input_consumed) {
266 if (digest_ == KM_DIGEST_NONE)
267 return RsaOperation::Update(additional_params, input, output, input_consumed);
268 else
269 return UpdateDigest(input, input_consumed);
270}
271
272keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden61902362014-12-18 10:33:24 -0700273 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700274 case KM_DIGEST_NONE:
275 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700276 case KM_DIGEST_SHA_2_256:
277 digest_algorithm_ = EVP_sha256();
278 break;
279 default:
280 return KM_ERROR_UNSUPPORTED_DIGEST;
281 }
282
283 if (!EVP_DigestInit_ex(&digest_ctx_, digest_algorithm_, NULL /* engine */)) {
284 int err = ERR_get_error();
285 LOG_E("Failed to initialize digest: %d %s", err, ERR_error_string(err, NULL));
286 return KM_ERROR_UNKNOWN_ERROR;
287 }
Shawn Willden61902362014-12-18 10:33:24 -0700288 return KM_ERROR_OK;
289}
290
Shawn Willdenf90f2352014-12-18 23:01:15 -0700291keymaster_error_t RsaDigestingOperation::UpdateDigest(const Buffer& input, size_t* input_consumed) {
Shawn Willden61902362014-12-18 10:33:24 -0700292 if (!EVP_DigestUpdate(&digest_ctx_, input.peek_read(), input.available_read())) {
293 int err = ERR_get_error();
294 LOG_E("Failed to update digest: %d %s", err, ERR_error_string(err, NULL));
295 return KM_ERROR_UNKNOWN_ERROR;
296 }
297 *input_consumed = input.available_read();
298 return KM_ERROR_OK;
299}
300
Shawn Willdenf90f2352014-12-18 23:01:15 -0700301keymaster_error_t RsaDigestingOperation::FinishDigest(unsigned* digest_size) {
Shawn Willden61902362014-12-18 10:33:24 -0700302 assert(digest_algorithm_ != NULL);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700303 if (!EVP_DigestFinal_ex(&digest_ctx_, digest_buf_, digest_size)) {
Shawn Willden61902362014-12-18 10:33:24 -0700304 int err = ERR_get_error();
305 LOG_E("Failed to finalize digest: %d %s", err, ERR_error_string(err, NULL));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700306 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700307 }
308 assert(*digest_size == static_cast<unsigned>(EVP_MD_size(digest_algorithm_)));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700309 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700310}
311
Shawn Willden6bfbff02015-02-06 19:48:24 -0700312keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
313 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700314 assert(output);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600315 output->Reinitialize(RSA_size(rsa_key_));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700316 if (digest_ == KM_DIGEST_NONE)
317 return SignUndigested(output);
318 else
319 return SignDigested(output);
320}
Shawn Willden61902362014-12-18 10:33:24 -0700321
Shawn Willdenf90f2352014-12-18 23:01:15 -0700322keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
323 int bytes_encrypted;
324 switch (padding_) {
325 case KM_PAD_NONE:
326 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
327 output->peek_write(), rsa_key_, RSA_NO_PADDING);
328 break;
329 case KM_PAD_RSA_PKCS1_1_5_SIGN:
330 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
331 output->peek_write(), rsa_key_, RSA_PKCS1_PADDING);
332 break;
333 default:
334 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
335 }
Shawn Willden61902362014-12-18 10:33:24 -0700336
Shawn Willdenf90f2352014-12-18 23:01:15 -0700337 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600338 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600339 output->advance_write(bytes_encrypted);
340 return KM_ERROR_OK;
341}
342
Shawn Willdenf90f2352014-12-18 23:01:15 -0700343keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
344 unsigned digest_size = 0;
345 keymaster_error_t error = FinishDigest(&digest_size);
346 if (error != KM_ERROR_OK)
347 return error;
348
349 UniquePtr<uint8_t[]> padded_digest;
350 switch (padding_) {
351 case KM_PAD_NONE:
352 return PrivateEncrypt(digest_buf_, digest_size, RSA_NO_PADDING, output);
353 case KM_PAD_RSA_PKCS1_1_5_SIGN:
354 return PrivateEncrypt(digest_buf_, digest_size, RSA_PKCS1_PADDING, output);
355 case KM_PAD_RSA_PSS:
356 // OpenSSL doesn't verify that the key is large enough for the digest size. This can cause
357 // a segfault in some cases, and in others can result in a unsafely-small salt.
Shawn Willden2c242002015-02-27 07:01:02 -0700358 if ((unsigned)RSA_size(rsa_key_) < MIN_PSS_SALT_LEN + digest_size)
359 // TODO(swillden): Add a better return code for this.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700360 return KM_ERROR_INCOMPATIBLE_DIGEST;
361
362 if ((error = PssPadDigest(&padded_digest)) != KM_ERROR_OK)
363 return error;
364 return PrivateEncrypt(padded_digest.get(), RSA_size(rsa_key_), RSA_NO_PADDING, output);
365 default:
366 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
367 }
Shawn Willden61902362014-12-18 10:33:24 -0700368}
369
Shawn Willdenf90f2352014-12-18 23:01:15 -0700370keymaster_error_t RsaSignOperation::PssPadDigest(UniquePtr<uint8_t[]>* padded_digest) {
371 padded_digest->reset(new uint8_t[RSA_size(rsa_key_)]);
372 if (!padded_digest->get())
373 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
374
Adam Langleyadb0f332015-03-05 19:57:29 -0800375 if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa_key_, padded_digest->get(), digest_buf_,
376 digest_algorithm_, NULL,
377 -2 /* Indicates maximum salt length */)) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700378 LOG_E("%s", "Failed to apply PSS padding");
Shawn Willden61902362014-12-18 10:33:24 -0700379 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700380 }
381 return KM_ERROR_OK;
382}
383
384keymaster_error_t RsaSignOperation::PrivateEncrypt(uint8_t* to_encrypt, size_t len,
385 int openssl_padding, Buffer* output) {
386 int bytes_encrypted =
387 RSA_private_encrypt(len, to_encrypt, output->peek_write(), rsa_key_, openssl_padding);
388 if (bytes_encrypted <= 0)
389 return KM_ERROR_UNKNOWN_ERROR;
390 output->advance_write(bytes_encrypted);
391 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700392}
393
Shawn Willden6bfbff02015-02-06 19:48:24 -0700394keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
395 const Buffer& signature, Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700396 if (digest_ == KM_DIGEST_NONE)
397 return VerifyUndigested(signature);
398 else
399 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700400}
401
Shawn Willdenf90f2352014-12-18 23:01:15 -0700402keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
403 return DecryptAndMatch(signature, data_.peek_read(), data_.available_read());
Shawn Willden61902362014-12-18 10:33:24 -0700404}
405
Shawn Willdenf90f2352014-12-18 23:01:15 -0700406keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
Shawn Willden61902362014-12-18 10:33:24 -0700407 unsigned digest_size = 0;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700408 keymaster_error_t error = FinishDigest(&digest_size);
409 if (error != KM_ERROR_OK)
410 return error;
411 return DecryptAndMatch(signature, digest_buf_, digest_size);
412}
Shawn Willden61902362014-12-18 10:33:24 -0700413
Shawn Willdenf90f2352014-12-18 23:01:15 -0700414keymaster_error_t RsaVerifyOperation::DecryptAndMatch(const Buffer& signature,
415 const uint8_t* to_match, size_t len) {
416#ifdef OPENSSL_IS_BORINGSSL
417 size_t key_len = RSA_size(rsa_key_);
418#else
419 size_t key_len = (size_t)RSA_size(rsa_key_);
420#endif
421
422 int openssl_padding;
423 switch (padding_) {
424 case KM_PAD_NONE:
425 if (len != key_len)
426 return KM_ERROR_INVALID_INPUT_LENGTH;
427 if (len != signature.available_read())
428 return KM_ERROR_VERIFICATION_FAILED;
429 openssl_padding = RSA_NO_PADDING;
430 break;
431 case KM_PAD_RSA_PSS: // Do a raw decrypt for PSS
432 openssl_padding = RSA_NO_PADDING;
433 break;
434 case KM_PAD_RSA_PKCS1_1_5_SIGN:
435 openssl_padding = RSA_PKCS1_PADDING;
436 break;
437 default:
438 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
439 }
440
441 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
442 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
443 decrypted_data.get(), rsa_key_, openssl_padding);
444 if (bytes_decrypted < 0)
445 return KM_ERROR_VERIFICATION_FAILED;
446
447 if (padding_ == KM_PAD_RSA_PSS &&
Adam Langleyadb0f332015-03-05 19:57:29 -0800448 RSA_verify_PKCS1_PSS_mgf1(rsa_key_, to_match, digest_algorithm_, NULL, decrypted_data.get(),
449 -2 /* salt length recovered from signature */))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700450 return KM_ERROR_OK;
451 else if (padding_ != KM_PAD_RSA_PSS && memcmp_s(decrypted_data.get(), to_match, len) == 0)
Shawn Willden61902362014-12-18 10:33:24 -0700452 return KM_ERROR_OK;
453
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600454 return KM_ERROR_VERIFICATION_FAILED;
455}
456
Shawn Willden4200f212014-12-02 07:01:21 -0700457const int OAEP_PADDING_OVERHEAD = 41;
458const int PKCS1_PADDING_OVERHEAD = 11;
459
Shawn Willden6bfbff02015-02-06 19:48:24 -0700460keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
461 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700462 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700463 int openssl_padding;
464
465#if defined(OPENSSL_IS_BORINGSSL)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700466 size_t key_len = RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700467#else
Shawn Willdenf90f2352014-12-18 23:01:15 -0700468 size_t key_len = (size_t)RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700469#endif
470
Shawn Willdenf90f2352014-12-18 23:01:15 -0700471 size_t message_size = data_.available_read();
Shawn Willden4200f212014-12-02 07:01:21 -0700472 switch (padding_) {
473 case KM_PAD_RSA_OAEP:
474 openssl_padding = RSA_PKCS1_OAEP_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700475 if (message_size + OAEP_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700476 LOG_E("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700477 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700478 return KM_ERROR_INVALID_INPUT_LENGTH;
479 }
480 break;
481 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
482 openssl_padding = RSA_PKCS1_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700483 if (message_size + PKCS1_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700484 LOG_E("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700485 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700486 return KM_ERROR_INVALID_INPUT_LENGTH;
487 }
488 break;
489 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700490 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700491 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
492 }
493
494 output->Reinitialize(RSA_size(rsa_key_));
495 int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(),
496 output->peek_write(), rsa_key_, openssl_padding);
497
498 if (bytes_encrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700499 LOG_E("Error %d encrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700500 return KM_ERROR_UNKNOWN_ERROR;
501 }
502 assert(bytes_encrypted == RSA_size(rsa_key_));
503 output->advance_write(bytes_encrypted);
504
505 return KM_ERROR_OK;
506}
507
Shawn Willden6bfbff02015-02-06 19:48:24 -0700508keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
509 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700510 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700511 int openssl_padding;
512 switch (padding_) {
513 case KM_PAD_RSA_OAEP:
514 openssl_padding = RSA_PKCS1_OAEP_PADDING;
515 break;
516 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
517 openssl_padding = RSA_PKCS1_PADDING;
518 break;
519 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700520 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700521 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
522 }
523
524 output->Reinitialize(RSA_size(rsa_key_));
525 int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(),
526 output->peek_write(), rsa_key_, openssl_padding);
527
528 if (bytes_decrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700529 LOG_E("Error %d decrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700530 return KM_ERROR_UNKNOWN_ERROR;
531 }
532 output->advance_write(bytes_decrypted);
533
534 return KM_ERROR_OK;
535}
536
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600537} // namespace keymaster