blob: a4a2b6da251cc564bf7557f54b9311cbd7d0d25d [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:
Shawn Willden3ad5f052015-05-08 14:05:13 -060043 bool GetAndValidatePadding(const AuthorizationSet& begin_params, const Key& key,
44 keymaster_padding_t* padding, 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
Shawn Willden3ad5f052015-05-08 14:05:13 -060050bool RsaOperationFactory::GetAndValidatePadding(const AuthorizationSet& begin_params,
51 const Key& key, keymaster_padding_t* padding,
Shawn Willden63ac0432014-12-29 14:07:08 -070052 keymaster_error_t* error) const {
53 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
Shawn Willden3ad5f052015-05-08 14:05:13 -060054 if (!begin_params.GetTagValue(TAG_PADDING, padding)) {
55 LOG_E("%d padding modes specified in begin params", begin_params.GetTagCount(TAG_PADDING));
Shawn Willdend9d7acf2015-02-25 17:37:20 -070056 return false;
Shawn Willden3ad5f052015-05-08 14:05:13 -060057 } else if (!supported(*padding)) {
58 LOG_E("Padding mode %d not supported", *padding);
Shawn Willden63ac0432014-12-29 14:07:08 -070059 return false;
Shawn Willden3ad5f052015-05-08 14:05:13 -060060 } else if (!key.authorizations().Contains(TAG_PADDING, *padding) &&
61 !key.authorizations().Contains(TAG_PADDING_OLD, *padding)) {
62 LOG_E("Padding mode %d was specified, but not authorized by key", *padding);
63 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
64 return false;
65 }
Shawn Willden63ac0432014-12-29 14:07:08 -070066
Shawn Willdend92591d2014-12-30 18:19:10 -070067 *error = KM_ERROR_OK;
68 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070069}
70
Shawn Willden226746b2015-05-08 11:36:56 -060071bool RsaOperationFactory::GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
72 keymaster_digest_t* digest,
Shawn Willden63ac0432014-12-29 14:07:08 -070073 keymaster_error_t* error) const {
74 *error = KM_ERROR_UNSUPPORTED_DIGEST;
Shawn Willden226746b2015-05-08 11:36:56 -060075 if (!begin_params.GetTagValue(TAG_DIGEST, digest)) {
76 LOG_E("%d digests specified in begin params", begin_params.GetTagCount(TAG_DIGEST));
Shawn Willden0bd61a82015-04-13 19:09:32 -070077 return false;
Shawn Willden226746b2015-05-08 11:36:56 -060078 } else if (!supported(*digest)) {
79 LOG_E("Digest %d not supported", *digest);
Shawn Willden63ac0432014-12-29 14:07:08 -070080 return false;
Shawn Willden226746b2015-05-08 11:36:56 -060081 } else if (!key.authorizations().Contains(TAG_DIGEST, *digest) &&
82 !key.authorizations().Contains(TAG_DIGEST_OLD, *digest)) {
83 LOG_E("Digest %d was specified, but not authorized by key", *digest);
84 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
85 return false;
86 }
Shawn Willdend92591d2014-12-30 18:19:10 -070087 *error = KM_ERROR_OK;
88 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070089}
90
91/* static */
92RSA* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
93 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
94 assert(rsa_key);
95 if (!rsa_key || !rsa_key->key()) {
96 *error = KM_ERROR_UNKNOWN_ERROR;
97 return NULL;
98 }
Shawn Willden28eed512015-02-25 19:16:36 -070099 RSA_up_ref(rsa_key->key());
100 return rsa_key->key();
Shawn Willden63ac0432014-12-29 14:07:08 -0700101}
102
Shawn Willden61902362014-12-18 10:33:24 -0700103static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_DIGEST_SHA_2_256};
Shawn Willdenf90f2352014-12-18 23:01:15 -0700104static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
105 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -0700106
107/**
108 * Abstract base for RSA operations that digest their input (signing and verification). This class
109 * does most of the work of creation of RSA digesting operations, delegating only the actual
110 * operation instantiation.
111 */
112class RsaDigestingOperationFactory : public RsaOperationFactory {
113 public:
Shawn Willden3ed6d062015-04-15 13:39:38 -0600114 virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
115 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700116
117 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
118 *digest_count = array_length(supported_digests);
119 return supported_digests;
120 }
121
122 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
123 *padding_mode_count = array_length(supported_sig_padding);
124 return supported_sig_padding;
125 }
126
127 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700128 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
129 RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700130};
131
Shawn Willden3ed6d062015-04-15 13:39:38 -0600132Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
Shawn Willden226746b2015-05-08 11:36:56 -0600133 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -0600134 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700135 keymaster_padding_t padding;
136 keymaster_digest_t digest;
137 RSA* rsa;
Shawn Willden226746b2015-05-08 11:36:56 -0600138 if (!GetAndValidateDigest(begin_params, key, &digest, error) ||
Shawn Willden3ad5f052015-05-08 14:05:13 -0600139 !GetAndValidatePadding(begin_params, key, &padding, error) ||
140 !(rsa = GetRsaKey(key, error)))
Shawn Willden63ac0432014-12-29 14:07:08 -0700141 return NULL;
142
Shawn Willden567a4a02014-12-31 12:14:46 -0700143 Operation* op = InstantiateOperation(digest, padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700144 if (!op)
145 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
146 return op;
147}
148
149static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
150 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
151
152/**
153 * Abstract base for en/de-crypting RSA operation factories. This class does most of the work of
154 * creating such operations, delegating only the actual operation instantiation.
155 */
156class RsaCryptingOperationFactory : public RsaOperationFactory {
157 public:
Shawn Willden3ed6d062015-04-15 13:39:38 -0600158 virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
159 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700160
161 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
162 *padding_mode_count = array_length(supported_crypt_padding);
163 return supported_crypt_padding;
164 }
165
166 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
167 *digest_count = 0;
168 return NULL;
169 }
170
171 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700172 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700173};
174
Shawn Willden3ed6d062015-04-15 13:39:38 -0600175Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
Shawn Willden3ad5f052015-05-08 14:05:13 -0600176 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -0600177 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700178 keymaster_padding_t padding;
179 RSA* rsa;
Shawn Willden3ad5f052015-05-08 14:05:13 -0600180 if (!GetAndValidatePadding(begin_params, key, &padding, error) ||
181 !(rsa = GetRsaKey(key, error)))
Shawn Willden63ac0432014-12-29 14:07:08 -0700182 return NULL;
183
Shawn Willden567a4a02014-12-31 12:14:46 -0700184 Operation* op = InstantiateOperation(padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700185 if (!op)
186 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
187 return op;
188}
189
190/**
191 * Concrete factory for RSA signing operations.
192 */
193class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
194 public:
195 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700196 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
197 RSA* key) {
198 return new RsaSignOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700199 }
200};
201static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
202
203/**
204 * Concrete factory for RSA signing operations.
205 */
206class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
207 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700208 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
209 RSA* key) {
210 return new RsaVerifyOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700211 }
212};
213static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
214
215/**
216 * Concrete factory for RSA signing operations.
217 */
218class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
219 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700220 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
221 return new RsaEncryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700222 }
223};
224static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
225
226/**
227 * Concrete factory for RSA signing operations.
228 */
229class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
230 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700231 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
232 return new RsaDecryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700233 }
234};
235
236static OperationFactoryRegistry::Registration<RsaDecryptionOperationFactory> decrypt_registration;
237
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600238struct RSA_Delete {
239 void operator()(RSA* p) const { RSA_free(p); }
240};
241
242RsaOperation::~RsaOperation() {
243 if (rsa_key_ != NULL)
244 RSA_free(rsa_key_);
245}
246
Shawn Willden6bfbff02015-02-06 19:48:24 -0700247keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
248 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700249 size_t* input_consumed) {
250 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600251 switch (purpose()) {
252 default:
253 return KM_ERROR_UNIMPLEMENTED;
254 case KM_PURPOSE_SIGN:
255 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700256 case KM_PURPOSE_ENCRYPT:
257 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700258 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600259 }
260}
261
Shawn Willdenb7361132014-12-08 08:15:14 -0700262keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
263 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600264 if (!data_.reserve(data_.available_read() + input.available_read()) ||
265 !data_.write(input.peek_read(), input.available_read()))
266 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700267 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600268 return KM_ERROR_OK;
269}
270
Shawn Willden61902362014-12-18 10:33:24 -0700271RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
272 keymaster_padding_t padding, RSA* key)
273 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
274 EVP_MD_CTX_init(&digest_ctx_);
275}
276RsaDigestingOperation::~RsaDigestingOperation() {
277 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700278 memset_s(digest_buf_, 0, sizeof(digest_buf_));
Shawn Willden61902362014-12-18 10:33:24 -0700279}
280
281keymaster_error_t RsaDigestingOperation::Begin(const AuthorizationSet& /* input_params */,
282 AuthorizationSet* /* output_params */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700283 if (require_digest() && digest_ == KM_DIGEST_NONE)
284 return KM_ERROR_INCOMPATIBLE_DIGEST;
285 return InitDigest();
286}
Shawn Willden61902362014-12-18 10:33:24 -0700287
Shawn Willdenf90f2352014-12-18 23:01:15 -0700288keymaster_error_t RsaDigestingOperation::Update(const AuthorizationSet& additional_params,
289 const Buffer& input, Buffer* output,
290 size_t* input_consumed) {
291 if (digest_ == KM_DIGEST_NONE)
292 return RsaOperation::Update(additional_params, input, output, input_consumed);
293 else
294 return UpdateDigest(input, input_consumed);
295}
296
297keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden61902362014-12-18 10:33:24 -0700298 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700299 case KM_DIGEST_NONE:
300 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700301 case KM_DIGEST_SHA_2_256:
302 digest_algorithm_ = EVP_sha256();
303 break;
304 default:
305 return KM_ERROR_UNSUPPORTED_DIGEST;
306 }
307
308 if (!EVP_DigestInit_ex(&digest_ctx_, digest_algorithm_, NULL /* engine */)) {
309 int err = ERR_get_error();
310 LOG_E("Failed to initialize digest: %d %s", err, ERR_error_string(err, NULL));
311 return KM_ERROR_UNKNOWN_ERROR;
312 }
Shawn Willden61902362014-12-18 10:33:24 -0700313 return KM_ERROR_OK;
314}
315
Shawn Willdenf90f2352014-12-18 23:01:15 -0700316keymaster_error_t RsaDigestingOperation::UpdateDigest(const Buffer& input, size_t* input_consumed) {
Shawn Willden61902362014-12-18 10:33:24 -0700317 if (!EVP_DigestUpdate(&digest_ctx_, input.peek_read(), input.available_read())) {
318 int err = ERR_get_error();
319 LOG_E("Failed to update digest: %d %s", err, ERR_error_string(err, NULL));
320 return KM_ERROR_UNKNOWN_ERROR;
321 }
322 *input_consumed = input.available_read();
323 return KM_ERROR_OK;
324}
325
Shawn Willdenf90f2352014-12-18 23:01:15 -0700326keymaster_error_t RsaDigestingOperation::FinishDigest(unsigned* digest_size) {
Shawn Willden61902362014-12-18 10:33:24 -0700327 assert(digest_algorithm_ != NULL);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700328 if (!EVP_DigestFinal_ex(&digest_ctx_, digest_buf_, digest_size)) {
Shawn Willden61902362014-12-18 10:33:24 -0700329 int err = ERR_get_error();
330 LOG_E("Failed to finalize digest: %d %s", err, ERR_error_string(err, NULL));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700331 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700332 }
333 assert(*digest_size == static_cast<unsigned>(EVP_MD_size(digest_algorithm_)));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700334 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700335}
336
Shawn Willden6bfbff02015-02-06 19:48:24 -0700337keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
338 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700339 assert(output);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600340 output->Reinitialize(RSA_size(rsa_key_));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700341 if (digest_ == KM_DIGEST_NONE)
342 return SignUndigested(output);
343 else
344 return SignDigested(output);
345}
Shawn Willden61902362014-12-18 10:33:24 -0700346
Shawn Willdenf90f2352014-12-18 23:01:15 -0700347keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
348 int bytes_encrypted;
349 switch (padding_) {
350 case KM_PAD_NONE:
351 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
352 output->peek_write(), rsa_key_, RSA_NO_PADDING);
353 break;
354 case KM_PAD_RSA_PKCS1_1_5_SIGN:
355 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
356 output->peek_write(), rsa_key_, RSA_PKCS1_PADDING);
357 break;
358 default:
359 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
360 }
Shawn Willden61902362014-12-18 10:33:24 -0700361
Shawn Willdenf90f2352014-12-18 23:01:15 -0700362 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600363 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600364 output->advance_write(bytes_encrypted);
365 return KM_ERROR_OK;
366}
367
Shawn Willdenf90f2352014-12-18 23:01:15 -0700368keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
369 unsigned digest_size = 0;
370 keymaster_error_t error = FinishDigest(&digest_size);
371 if (error != KM_ERROR_OK)
372 return error;
373
374 UniquePtr<uint8_t[]> padded_digest;
375 switch (padding_) {
376 case KM_PAD_NONE:
Shawn Willden3ad5f052015-05-08 14:05:13 -0600377 LOG_E("Digesting requires padding", 0);
378 return KM_ERROR_INCOMPATIBLE_PADDING_MODE;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700379 case KM_PAD_RSA_PKCS1_1_5_SIGN:
380 return PrivateEncrypt(digest_buf_, digest_size, RSA_PKCS1_PADDING, output);
381 case KM_PAD_RSA_PSS:
382 // OpenSSL doesn't verify that the key is large enough for the digest size. This can cause
383 // a segfault in some cases, and in others can result in a unsafely-small salt.
Shawn Willden3ad5f052015-05-08 14:05:13 -0600384 if ((unsigned)RSA_size(rsa_key_) < MIN_PSS_SALT_LEN + digest_size) {
385 LOG_E("%d-byte too small for PSS padding and %d-byte digest", RSA_size(rsa_key_),
386 digest_size);
Shawn Willden2c242002015-02-27 07:01:02 -0700387 // TODO(swillden): Add a better return code for this.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700388 return KM_ERROR_INCOMPATIBLE_DIGEST;
Shawn Willden3ad5f052015-05-08 14:05:13 -0600389 }
Shawn Willdenf90f2352014-12-18 23:01:15 -0700390
391 if ((error = PssPadDigest(&padded_digest)) != KM_ERROR_OK)
392 return error;
393 return PrivateEncrypt(padded_digest.get(), RSA_size(rsa_key_), RSA_NO_PADDING, output);
394 default:
395 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
396 }
Shawn Willden61902362014-12-18 10:33:24 -0700397}
398
Shawn Willdenf90f2352014-12-18 23:01:15 -0700399keymaster_error_t RsaSignOperation::PssPadDigest(UniquePtr<uint8_t[]>* padded_digest) {
400 padded_digest->reset(new uint8_t[RSA_size(rsa_key_)]);
401 if (!padded_digest->get())
402 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
403
Adam Langleyadb0f332015-03-05 19:57:29 -0800404 if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa_key_, padded_digest->get(), digest_buf_,
405 digest_algorithm_, NULL,
406 -2 /* Indicates maximum salt length */)) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700407 LOG_E("%s", "Failed to apply PSS padding");
Shawn Willden61902362014-12-18 10:33:24 -0700408 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700409 }
410 return KM_ERROR_OK;
411}
412
413keymaster_error_t RsaSignOperation::PrivateEncrypt(uint8_t* to_encrypt, size_t len,
414 int openssl_padding, Buffer* output) {
415 int bytes_encrypted =
416 RSA_private_encrypt(len, to_encrypt, output->peek_write(), rsa_key_, openssl_padding);
417 if (bytes_encrypted <= 0)
418 return KM_ERROR_UNKNOWN_ERROR;
419 output->advance_write(bytes_encrypted);
420 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700421}
422
Shawn Willden6bfbff02015-02-06 19:48:24 -0700423keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
424 const Buffer& signature, Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700425 if (digest_ == KM_DIGEST_NONE)
426 return VerifyUndigested(signature);
427 else
428 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700429}
430
Shawn Willdenf90f2352014-12-18 23:01:15 -0700431keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
432 return DecryptAndMatch(signature, data_.peek_read(), data_.available_read());
Shawn Willden61902362014-12-18 10:33:24 -0700433}
434
Shawn Willdenf90f2352014-12-18 23:01:15 -0700435keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
Shawn Willden61902362014-12-18 10:33:24 -0700436 unsigned digest_size = 0;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700437 keymaster_error_t error = FinishDigest(&digest_size);
438 if (error != KM_ERROR_OK)
439 return error;
440 return DecryptAndMatch(signature, digest_buf_, digest_size);
441}
Shawn Willden61902362014-12-18 10:33:24 -0700442
Shawn Willdenf90f2352014-12-18 23:01:15 -0700443keymaster_error_t RsaVerifyOperation::DecryptAndMatch(const Buffer& signature,
444 const uint8_t* to_match, size_t len) {
445#ifdef OPENSSL_IS_BORINGSSL
446 size_t key_len = RSA_size(rsa_key_);
447#else
448 size_t key_len = (size_t)RSA_size(rsa_key_);
449#endif
450
451 int openssl_padding;
452 switch (padding_) {
453 case KM_PAD_NONE:
454 if (len != key_len)
455 return KM_ERROR_INVALID_INPUT_LENGTH;
456 if (len != signature.available_read())
457 return KM_ERROR_VERIFICATION_FAILED;
458 openssl_padding = RSA_NO_PADDING;
459 break;
460 case KM_PAD_RSA_PSS: // Do a raw decrypt for PSS
461 openssl_padding = RSA_NO_PADDING;
462 break;
463 case KM_PAD_RSA_PKCS1_1_5_SIGN:
464 openssl_padding = RSA_PKCS1_PADDING;
465 break;
466 default:
467 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
468 }
469
470 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
471 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
472 decrypted_data.get(), rsa_key_, openssl_padding);
473 if (bytes_decrypted < 0)
474 return KM_ERROR_VERIFICATION_FAILED;
475
476 if (padding_ == KM_PAD_RSA_PSS &&
Adam Langleyadb0f332015-03-05 19:57:29 -0800477 RSA_verify_PKCS1_PSS_mgf1(rsa_key_, to_match, digest_algorithm_, NULL, decrypted_data.get(),
478 -2 /* salt length recovered from signature */))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700479 return KM_ERROR_OK;
Shawn Willden197d9af2015-05-09 12:48:16 +0000480 else if (padding_ != KM_PAD_RSA_PSS && memcmp_s(decrypted_data.get(), to_match, len) == 0)
Shawn Willden61902362014-12-18 10:33:24 -0700481 return KM_ERROR_OK;
482
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600483 return KM_ERROR_VERIFICATION_FAILED;
484}
485
Shawn Willden4200f212014-12-02 07:01:21 -0700486const int OAEP_PADDING_OVERHEAD = 41;
487const int PKCS1_PADDING_OVERHEAD = 11;
488
Shawn Willden6bfbff02015-02-06 19:48:24 -0700489keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
490 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700491 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700492 int openssl_padding;
493
494#if defined(OPENSSL_IS_BORINGSSL)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700495 size_t key_len = RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700496#else
Shawn Willdenf90f2352014-12-18 23:01:15 -0700497 size_t key_len = (size_t)RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700498#endif
499
Shawn Willdenf90f2352014-12-18 23:01:15 -0700500 size_t message_size = data_.available_read();
Shawn Willden4200f212014-12-02 07:01:21 -0700501 switch (padding_) {
502 case KM_PAD_RSA_OAEP:
503 openssl_padding = RSA_PKCS1_OAEP_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700504 if (message_size + OAEP_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700505 LOG_E("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700506 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700507 return KM_ERROR_INVALID_INPUT_LENGTH;
508 }
509 break;
510 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
511 openssl_padding = RSA_PKCS1_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700512 if (message_size + PKCS1_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700513 LOG_E("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700514 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700515 return KM_ERROR_INVALID_INPUT_LENGTH;
516 }
517 break;
518 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700519 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700520 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
521 }
522
523 output->Reinitialize(RSA_size(rsa_key_));
524 int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(),
525 output->peek_write(), rsa_key_, openssl_padding);
526
527 if (bytes_encrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700528 LOG_E("Error %d encrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700529 return KM_ERROR_UNKNOWN_ERROR;
530 }
Shawn Willden67380a92015-05-13 12:07:50 -0600531 assert(bytes_encrypted == (int)RSA_size(rsa_key_));
Shawn Willden4200f212014-12-02 07:01:21 -0700532 output->advance_write(bytes_encrypted);
533
534 return KM_ERROR_OK;
535}
536
Shawn Willden6bfbff02015-02-06 19:48:24 -0700537keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
538 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700539 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700540 int openssl_padding;
541 switch (padding_) {
542 case KM_PAD_RSA_OAEP:
543 openssl_padding = RSA_PKCS1_OAEP_PADDING;
544 break;
545 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
546 openssl_padding = RSA_PKCS1_PADDING;
547 break;
548 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700549 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700550 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
551 }
552
553 output->Reinitialize(RSA_size(rsa_key_));
554 int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(),
555 output->peek_write(), rsa_key_, openssl_padding);
556
557 if (bytes_decrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700558 LOG_E("Error %d decrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700559 return KM_ERROR_UNKNOWN_ERROR;
560 }
561 output->advance_write(bytes_decrypted);
562
563 return KM_ERROR_OK;
564}
565
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600566} // namespace keymaster