blob: fda2e8b295a96bd2df011eaac8efaed216df8108 [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 Willdend92591d2014-12-30 18:19:10 -070053 if (!key.authorizations().GetTagValue(TAG_PADDING, padding) || !supported(*padding))
Shawn Willden63ac0432014-12-29 14:07:08 -070054 return false;
55
Shawn Willdend92591d2014-12-30 18:19:10 -070056 *error = KM_ERROR_OK;
57 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070058}
59
60bool RsaOperationFactory::GetAndValidateDigest(const Key& key, keymaster_digest_t* digest,
61 keymaster_error_t* error) const {
62 *error = KM_ERROR_UNSUPPORTED_DIGEST;
Shawn Willdend92591d2014-12-30 18:19:10 -070063 if (!key.authorizations().GetTagValue(TAG_DIGEST, digest) || !supported(*digest))
Shawn Willden63ac0432014-12-29 14:07:08 -070064 return false;
65
Shawn Willdend92591d2014-12-30 18:19:10 -070066 *error = KM_ERROR_OK;
67 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070068}
69
70/* static */
71RSA* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
72 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
73 assert(rsa_key);
74 if (!rsa_key || !rsa_key->key()) {
75 *error = KM_ERROR_UNKNOWN_ERROR;
76 return NULL;
77 }
Shawn Willden28eed512015-02-25 19:16:36 -070078 RSA_up_ref(rsa_key->key());
79 return rsa_key->key();
Shawn Willden63ac0432014-12-29 14:07:08 -070080}
81
Shawn Willden61902362014-12-18 10:33:24 -070082static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_DIGEST_SHA_2_256};
Shawn Willdenf90f2352014-12-18 23:01:15 -070083static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
84 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070085
86/**
87 * Abstract base for RSA operations that digest their input (signing and verification). This class
88 * does most of the work of creation of RSA digesting operations, delegating only the actual
89 * operation instantiation.
90 */
91class RsaDigestingOperationFactory : public RsaOperationFactory {
92 public:
Shawn Willden567a4a02014-12-31 12:14:46 -070093 virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -070094
95 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
96 *digest_count = array_length(supported_digests);
97 return supported_digests;
98 }
99
100 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
101 *padding_mode_count = array_length(supported_sig_padding);
102 return supported_sig_padding;
103 }
104
105 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700106 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
107 RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700108};
109
Shawn Willden567a4a02014-12-31 12:14:46 -0700110Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700111 keymaster_padding_t padding;
112 keymaster_digest_t digest;
113 RSA* rsa;
114 if (!GetAndValidateDigest(key, &digest, error) ||
115 !GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
116 return NULL;
117
Shawn Willden567a4a02014-12-31 12:14:46 -0700118 Operation* op = InstantiateOperation(digest, padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700119 if (!op)
120 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
121 return op;
122}
123
124static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
125 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
126
127/**
128 * Abstract base for en/de-crypting RSA operation factories. This class does most of the work of
129 * creating such operations, delegating only the actual operation instantiation.
130 */
131class RsaCryptingOperationFactory : public RsaOperationFactory {
132 public:
Shawn Willden567a4a02014-12-31 12:14:46 -0700133 virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700134
135 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
136 *padding_mode_count = array_length(supported_crypt_padding);
137 return supported_crypt_padding;
138 }
139
140 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
141 *digest_count = 0;
142 return NULL;
143 }
144
145 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700146 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700147};
148
Shawn Willden567a4a02014-12-31 12:14:46 -0700149Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700150 keymaster_padding_t padding;
151 RSA* rsa;
152 if (!GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
153 return NULL;
154
Shawn Willden567a4a02014-12-31 12:14:46 -0700155 Operation* op = InstantiateOperation(padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700156 if (!op)
157 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
158 return op;
159}
160
161/**
162 * Concrete factory for RSA signing operations.
163 */
164class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
165 public:
166 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700167 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
168 RSA* key) {
169 return new RsaSignOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700170 }
171};
172static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
173
174/**
175 * Concrete factory for RSA signing operations.
176 */
177class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
178 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700179 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
180 RSA* key) {
181 return new RsaVerifyOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700182 }
183};
184static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
185
186/**
187 * Concrete factory for RSA signing operations.
188 */
189class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
190 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700191 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
192 return new RsaEncryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700193 }
194};
195static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
196
197/**
198 * Concrete factory for RSA signing operations.
199 */
200class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
201 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700202 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
203 return new RsaDecryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700204 }
205};
206
207static OperationFactoryRegistry::Registration<RsaDecryptionOperationFactory> decrypt_registration;
208
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600209struct RSA_Delete {
210 void operator()(RSA* p) const { RSA_free(p); }
211};
212
213RsaOperation::~RsaOperation() {
214 if (rsa_key_ != NULL)
215 RSA_free(rsa_key_);
216}
217
Shawn Willden6bfbff02015-02-06 19:48:24 -0700218keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
219 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700220 size_t* input_consumed) {
221 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600222 switch (purpose()) {
223 default:
224 return KM_ERROR_UNIMPLEMENTED;
225 case KM_PURPOSE_SIGN:
226 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700227 case KM_PURPOSE_ENCRYPT:
228 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700229 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600230 }
231}
232
Shawn Willdenb7361132014-12-08 08:15:14 -0700233keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
234 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600235 if (!data_.reserve(data_.available_read() + input.available_read()) ||
236 !data_.write(input.peek_read(), input.available_read()))
237 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700238 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600239 return KM_ERROR_OK;
240}
241
Shawn Willden61902362014-12-18 10:33:24 -0700242RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
243 keymaster_padding_t padding, RSA* key)
244 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
245 EVP_MD_CTX_init(&digest_ctx_);
246}
247RsaDigestingOperation::~RsaDigestingOperation() {
248 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700249 memset_s(digest_buf_, 0, sizeof(digest_buf_));
Shawn Willden61902362014-12-18 10:33:24 -0700250}
251
252keymaster_error_t RsaDigestingOperation::Begin(const AuthorizationSet& /* input_params */,
253 AuthorizationSet* /* output_params */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700254 if (require_digest() && digest_ == KM_DIGEST_NONE)
255 return KM_ERROR_INCOMPATIBLE_DIGEST;
256 return InitDigest();
257}
Shawn Willden61902362014-12-18 10:33:24 -0700258
Shawn Willdenf90f2352014-12-18 23:01:15 -0700259keymaster_error_t RsaDigestingOperation::Update(const AuthorizationSet& additional_params,
260 const Buffer& input, Buffer* output,
261 size_t* input_consumed) {
262 if (digest_ == KM_DIGEST_NONE)
263 return RsaOperation::Update(additional_params, input, output, input_consumed);
264 else
265 return UpdateDigest(input, input_consumed);
266}
267
268keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden61902362014-12-18 10:33:24 -0700269 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700270 case KM_DIGEST_NONE:
271 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700272 case KM_DIGEST_SHA_2_256:
273 digest_algorithm_ = EVP_sha256();
274 break;
275 default:
276 return KM_ERROR_UNSUPPORTED_DIGEST;
277 }
278
279 if (!EVP_DigestInit_ex(&digest_ctx_, digest_algorithm_, NULL /* engine */)) {
280 int err = ERR_get_error();
281 LOG_E("Failed to initialize digest: %d %s", err, ERR_error_string(err, NULL));
282 return KM_ERROR_UNKNOWN_ERROR;
283 }
Shawn Willden61902362014-12-18 10:33:24 -0700284 return KM_ERROR_OK;
285}
286
Shawn Willdenf90f2352014-12-18 23:01:15 -0700287keymaster_error_t RsaDigestingOperation::UpdateDigest(const Buffer& input, size_t* input_consumed) {
Shawn Willden61902362014-12-18 10:33:24 -0700288 if (!EVP_DigestUpdate(&digest_ctx_, input.peek_read(), input.available_read())) {
289 int err = ERR_get_error();
290 LOG_E("Failed to update digest: %d %s", err, ERR_error_string(err, NULL));
291 return KM_ERROR_UNKNOWN_ERROR;
292 }
293 *input_consumed = input.available_read();
294 return KM_ERROR_OK;
295}
296
Shawn Willdenf90f2352014-12-18 23:01:15 -0700297keymaster_error_t RsaDigestingOperation::FinishDigest(unsigned* digest_size) {
Shawn Willden61902362014-12-18 10:33:24 -0700298 assert(digest_algorithm_ != NULL);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700299 if (!EVP_DigestFinal_ex(&digest_ctx_, digest_buf_, digest_size)) {
Shawn Willden61902362014-12-18 10:33:24 -0700300 int err = ERR_get_error();
301 LOG_E("Failed to finalize digest: %d %s", err, ERR_error_string(err, NULL));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700302 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700303 }
304 assert(*digest_size == static_cast<unsigned>(EVP_MD_size(digest_algorithm_)));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700305 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700306}
307
Shawn Willden6bfbff02015-02-06 19:48:24 -0700308keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
309 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700310 assert(output);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600311 output->Reinitialize(RSA_size(rsa_key_));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700312 if (digest_ == KM_DIGEST_NONE)
313 return SignUndigested(output);
314 else
315 return SignDigested(output);
316}
Shawn Willden61902362014-12-18 10:33:24 -0700317
Shawn Willdenf90f2352014-12-18 23:01:15 -0700318keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
319 int bytes_encrypted;
320 switch (padding_) {
321 case KM_PAD_NONE:
322 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
323 output->peek_write(), rsa_key_, RSA_NO_PADDING);
324 break;
325 case KM_PAD_RSA_PKCS1_1_5_SIGN:
326 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
327 output->peek_write(), rsa_key_, RSA_PKCS1_PADDING);
328 break;
329 default:
330 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
331 }
Shawn Willden61902362014-12-18 10:33:24 -0700332
Shawn Willdenf90f2352014-12-18 23:01:15 -0700333 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600334 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600335 output->advance_write(bytes_encrypted);
336 return KM_ERROR_OK;
337}
338
Shawn Willdenf90f2352014-12-18 23:01:15 -0700339keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
340 unsigned digest_size = 0;
341 keymaster_error_t error = FinishDigest(&digest_size);
342 if (error != KM_ERROR_OK)
343 return error;
344
345 UniquePtr<uint8_t[]> padded_digest;
346 switch (padding_) {
347 case KM_PAD_NONE:
348 return PrivateEncrypt(digest_buf_, digest_size, RSA_NO_PADDING, output);
349 case KM_PAD_RSA_PKCS1_1_5_SIGN:
350 return PrivateEncrypt(digest_buf_, digest_size, RSA_PKCS1_PADDING, output);
351 case KM_PAD_RSA_PSS:
352 // OpenSSL doesn't verify that the key is large enough for the digest size. This can cause
353 // a segfault in some cases, and in others can result in a unsafely-small salt.
Adam Langleyadb0f332015-03-05 19:57:29 -0800354 if ((unsigned) RSA_size(rsa_key_) < MIN_PSS_SALT_LEN + digest_size)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700355 return KM_ERROR_INCOMPATIBLE_DIGEST;
356
357 if ((error = PssPadDigest(&padded_digest)) != KM_ERROR_OK)
358 return error;
359 return PrivateEncrypt(padded_digest.get(), RSA_size(rsa_key_), RSA_NO_PADDING, output);
360 default:
361 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
362 }
Shawn Willden61902362014-12-18 10:33:24 -0700363}
364
Shawn Willdenf90f2352014-12-18 23:01:15 -0700365keymaster_error_t RsaSignOperation::PssPadDigest(UniquePtr<uint8_t[]>* padded_digest) {
366 padded_digest->reset(new uint8_t[RSA_size(rsa_key_)]);
367 if (!padded_digest->get())
368 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
369
Adam Langleyadb0f332015-03-05 19:57:29 -0800370 if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa_key_, padded_digest->get(), digest_buf_,
371 digest_algorithm_, NULL,
372 -2 /* Indicates maximum salt length */)) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700373 LOG_E("%s", "Failed to apply PSS padding");
Shawn Willden61902362014-12-18 10:33:24 -0700374 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700375 }
376 return KM_ERROR_OK;
377}
378
379keymaster_error_t RsaSignOperation::PrivateEncrypt(uint8_t* to_encrypt, size_t len,
380 int openssl_padding, Buffer* output) {
381 int bytes_encrypted =
382 RSA_private_encrypt(len, to_encrypt, output->peek_write(), rsa_key_, openssl_padding);
383 if (bytes_encrypted <= 0)
384 return KM_ERROR_UNKNOWN_ERROR;
385 output->advance_write(bytes_encrypted);
386 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700387}
388
Shawn Willden6bfbff02015-02-06 19:48:24 -0700389keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
390 const Buffer& signature, Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700391 if (digest_ == KM_DIGEST_NONE)
392 return VerifyUndigested(signature);
393 else
394 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700395}
396
Shawn Willdenf90f2352014-12-18 23:01:15 -0700397keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
398 return DecryptAndMatch(signature, data_.peek_read(), data_.available_read());
Shawn Willden61902362014-12-18 10:33:24 -0700399}
400
Shawn Willdenf90f2352014-12-18 23:01:15 -0700401keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
Shawn Willden61902362014-12-18 10:33:24 -0700402 unsigned digest_size = 0;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700403 keymaster_error_t error = FinishDigest(&digest_size);
404 if (error != KM_ERROR_OK)
405 return error;
406 return DecryptAndMatch(signature, digest_buf_, digest_size);
407}
Shawn Willden61902362014-12-18 10:33:24 -0700408
Shawn Willdenf90f2352014-12-18 23:01:15 -0700409keymaster_error_t RsaVerifyOperation::DecryptAndMatch(const Buffer& signature,
410 const uint8_t* to_match, size_t len) {
411#ifdef OPENSSL_IS_BORINGSSL
412 size_t key_len = RSA_size(rsa_key_);
413#else
414 size_t key_len = (size_t)RSA_size(rsa_key_);
415#endif
416
417 int openssl_padding;
418 switch (padding_) {
419 case KM_PAD_NONE:
420 if (len != key_len)
421 return KM_ERROR_INVALID_INPUT_LENGTH;
422 if (len != signature.available_read())
423 return KM_ERROR_VERIFICATION_FAILED;
424 openssl_padding = RSA_NO_PADDING;
425 break;
426 case KM_PAD_RSA_PSS: // Do a raw decrypt for PSS
427 openssl_padding = RSA_NO_PADDING;
428 break;
429 case KM_PAD_RSA_PKCS1_1_5_SIGN:
430 openssl_padding = RSA_PKCS1_PADDING;
431 break;
432 default:
433 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
434 }
435
436 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
437 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
438 decrypted_data.get(), rsa_key_, openssl_padding);
439 if (bytes_decrypted < 0)
440 return KM_ERROR_VERIFICATION_FAILED;
441
442 if (padding_ == KM_PAD_RSA_PSS &&
Adam Langleyadb0f332015-03-05 19:57:29 -0800443 RSA_verify_PKCS1_PSS_mgf1(rsa_key_, to_match, digest_algorithm_, NULL, decrypted_data.get(),
444 -2 /* salt length recovered from signature */))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700445 return KM_ERROR_OK;
446 else if (padding_ != KM_PAD_RSA_PSS && memcmp_s(decrypted_data.get(), to_match, len) == 0)
Shawn Willden61902362014-12-18 10:33:24 -0700447 return KM_ERROR_OK;
448
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600449 return KM_ERROR_VERIFICATION_FAILED;
450}
451
Shawn Willden4200f212014-12-02 07:01:21 -0700452const int OAEP_PADDING_OVERHEAD = 41;
453const int PKCS1_PADDING_OVERHEAD = 11;
454
Shawn Willden6bfbff02015-02-06 19:48:24 -0700455keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
456 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700457 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700458 int openssl_padding;
459
460#if defined(OPENSSL_IS_BORINGSSL)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700461 size_t key_len = RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700462#else
Shawn Willdenf90f2352014-12-18 23:01:15 -0700463 size_t key_len = (size_t)RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700464#endif
465
Shawn Willdenf90f2352014-12-18 23:01:15 -0700466 size_t message_size = data_.available_read();
Shawn Willden4200f212014-12-02 07:01:21 -0700467 switch (padding_) {
468 case KM_PAD_RSA_OAEP:
469 openssl_padding = RSA_PKCS1_OAEP_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700470 if (message_size + OAEP_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700471 LOG_E("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700472 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700473 return KM_ERROR_INVALID_INPUT_LENGTH;
474 }
475 break;
476 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
477 openssl_padding = RSA_PKCS1_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700478 if (message_size + PKCS1_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700479 LOG_E("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700480 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700481 return KM_ERROR_INVALID_INPUT_LENGTH;
482 }
483 break;
484 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700485 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700486 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
487 }
488
489 output->Reinitialize(RSA_size(rsa_key_));
490 int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(),
491 output->peek_write(), rsa_key_, openssl_padding);
492
493 if (bytes_encrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700494 LOG_E("Error %d encrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700495 return KM_ERROR_UNKNOWN_ERROR;
496 }
497 assert(bytes_encrypted == RSA_size(rsa_key_));
498 output->advance_write(bytes_encrypted);
499
500 return KM_ERROR_OK;
501}
502
Shawn Willden6bfbff02015-02-06 19:48:24 -0700503keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
504 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700505 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700506 int openssl_padding;
507 switch (padding_) {
508 case KM_PAD_RSA_OAEP:
509 openssl_padding = RSA_PKCS1_OAEP_PADDING;
510 break;
511 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
512 openssl_padding = RSA_PKCS1_PADDING;
513 break;
514 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700515 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700516 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
517 }
518
519 output->Reinitialize(RSA_size(rsa_key_));
520 int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(),
521 output->peek_write(), rsa_key_, openssl_padding);
522
523 if (bytes_decrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700524 LOG_E("Error %d decrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700525 return KM_ERROR_UNKNOWN_ERROR;
526 }
527 output->advance_write(bytes_decrypted);
528
529 return KM_ERROR_OK;
530}
531
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600532} // namespace keymaster