blob: a5ad6f7931792490a120b30e2caef84695f30415 [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 Willden4749c432015-05-04 14:59:29 -060022#include <openssl/mem.h>
Shawn Willden0a4df7e2014-08-28 16:09:05 -060023
Shawn Willden567a4a02014-12-31 12:14:46 -070024#include <keymaster/logger.h>
25
26#include "openssl_err.h"
Shawn Willden0a4df7e2014-08-28 16:09:05 -060027#include "openssl_utils.h"
Shawn Willden63ac0432014-12-29 14:07:08 -070028#include "rsa_key.h"
Shawn Willden0a4df7e2014-08-28 16:09:05 -060029
30namespace keymaster {
31
Shawn Willdenf90f2352014-12-18 23:01:15 -070032static const int MIN_PSS_SALT_LEN = 8 /* salt len */ + 2 /* overhead */;
33
Shawn Willden63ac0432014-12-29 14:07:08 -070034/**
35 * Abstract base for all RSA operation factories. This class exists mainly to centralize some code
36 * common to all RSA operation factories.
37 */
38class RsaOperationFactory : public OperationFactory {
39 public:
40 virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_RSA, purpose()); }
41 virtual keymaster_purpose_t purpose() const = 0;
42
43 protected:
44 bool GetAndValidatePadding(const Key& key, keymaster_padding_t* padding,
45 keymaster_error_t* error) const;
46 bool GetAndValidateDigest(const Key& key, keymaster_digest_t* digest,
47 keymaster_error_t* error) const;
48 static RSA* GetRsaKey(const Key& key, keymaster_error_t* error);
49};
50
51bool RsaOperationFactory::GetAndValidatePadding(const Key& key, keymaster_padding_t* padding,
52 keymaster_error_t* error) const {
53 *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
Shawn Willdend9d7acf2015-02-25 17:37:20 -070054 if (!key.authorizations().GetTagValue(TAG_PADDING, padding) &&
55 !key.authorizations().GetTagValue(TAG_PADDING_OLD, padding))
56 return false;
57
58 if (!supported(*padding))
Shawn Willden63ac0432014-12-29 14:07:08 -070059 return false;
60
Shawn Willdend92591d2014-12-30 18:19:10 -070061 *error = KM_ERROR_OK;
62 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070063}
64
65bool RsaOperationFactory::GetAndValidateDigest(const Key& key, keymaster_digest_t* digest,
66 keymaster_error_t* error) const {
67 *error = KM_ERROR_UNSUPPORTED_DIGEST;
Shawn Willden0bd61a82015-04-13 19:09:32 -070068 if (!key.authorizations().GetTagValue(TAG_DIGEST, digest) &&
69 !key.authorizations().GetTagValue(TAG_DIGEST_OLD, digest))
70 return false;
71
72 if (!supported(*digest))
Shawn Willden63ac0432014-12-29 14:07:08 -070073 return false;
74
Shawn Willdend92591d2014-12-30 18:19:10 -070075 *error = KM_ERROR_OK;
76 return true;
Shawn Willden63ac0432014-12-29 14:07:08 -070077}
78
79/* static */
80RSA* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
81 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
82 assert(rsa_key);
83 if (!rsa_key || !rsa_key->key()) {
84 *error = KM_ERROR_UNKNOWN_ERROR;
85 return NULL;
86 }
Shawn Willden28eed512015-02-25 19:16:36 -070087 RSA_up_ref(rsa_key->key());
88 return rsa_key->key();
Shawn Willden63ac0432014-12-29 14:07:08 -070089}
90
Shawn Willden61902362014-12-18 10:33:24 -070091static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE, KM_DIGEST_SHA_2_256};
Shawn Willdenf90f2352014-12-18 23:01:15 -070092static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
93 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070094
95/**
96 * Abstract base for RSA operations that digest their input (signing and verification). This class
97 * does most of the work of creation of RSA digesting operations, delegating only the actual
98 * operation instantiation.
99 */
100class RsaDigestingOperationFactory : public RsaOperationFactory {
101 public:
Shawn Willden3ed6d062015-04-15 13:39:38 -0600102 virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
103 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700104
105 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
106 *digest_count = array_length(supported_digests);
107 return supported_digests;
108 }
109
110 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
111 *padding_mode_count = array_length(supported_sig_padding);
112 return supported_sig_padding;
113 }
114
115 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700116 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
117 RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700118};
119
Shawn Willden3ed6d062015-04-15 13:39:38 -0600120Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
121 const AuthorizationSet& /* begin_params */,
122 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700123 keymaster_padding_t padding;
124 keymaster_digest_t digest;
125 RSA* rsa;
126 if (!GetAndValidateDigest(key, &digest, error) ||
127 !GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
128 return NULL;
129
Shawn Willden567a4a02014-12-31 12:14:46 -0700130 Operation* op = InstantiateOperation(digest, padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700131 if (!op)
132 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
133 return op;
134}
135
136static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_RSA_OAEP,
137 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
138
139/**
140 * Abstract base for en/de-crypting RSA operation factories. This class does most of the work of
141 * creating such operations, delegating only the actual operation instantiation.
142 */
143class RsaCryptingOperationFactory : public RsaOperationFactory {
144 public:
Shawn Willden3ed6d062015-04-15 13:39:38 -0600145 virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
146 keymaster_error_t* error);
Shawn Willden63ac0432014-12-29 14:07:08 -0700147
148 virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
149 *padding_mode_count = array_length(supported_crypt_padding);
150 return supported_crypt_padding;
151 }
152
153 virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
154 *digest_count = 0;
155 return NULL;
156 }
157
158 private:
Shawn Willden567a4a02014-12-31 12:14:46 -0700159 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
Shawn Willden63ac0432014-12-29 14:07:08 -0700160};
161
Shawn Willden3ed6d062015-04-15 13:39:38 -0600162Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
163 const AuthorizationSet& /* begin_params */,
164 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700165 keymaster_padding_t padding;
166 RSA* rsa;
167 if (!GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
168 return NULL;
169
Shawn Willden567a4a02014-12-31 12:14:46 -0700170 Operation* op = InstantiateOperation(padding, rsa);
Shawn Willden63ac0432014-12-29 14:07:08 -0700171 if (!op)
172 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
173 return op;
174}
175
176/**
177 * Concrete factory for RSA signing operations.
178 */
179class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
180 public:
181 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700182 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
183 RSA* key) {
184 return new RsaSignOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700185 }
186};
187static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
188
189/**
190 * Concrete factory for RSA signing operations.
191 */
192class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
193 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700194 virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
195 RSA* key) {
196 return new RsaVerifyOperation(digest, padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700197 }
198};
199static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
200
201/**
202 * Concrete factory for RSA signing operations.
203 */
204class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
205 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700206 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
207 return new RsaEncryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700208 }
209};
210static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
211
212/**
213 * Concrete factory for RSA signing operations.
214 */
215class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
216 virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
Shawn Willden567a4a02014-12-31 12:14:46 -0700217 virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
218 return new RsaDecryptOperation(padding, key);
Shawn Willden63ac0432014-12-29 14:07:08 -0700219 }
220};
221
222static OperationFactoryRegistry::Registration<RsaDecryptionOperationFactory> decrypt_registration;
223
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600224struct RSA_Delete {
225 void operator()(RSA* p) const { RSA_free(p); }
226};
227
228RsaOperation::~RsaOperation() {
229 if (rsa_key_ != NULL)
230 RSA_free(rsa_key_);
231}
232
Shawn Willden6bfbff02015-02-06 19:48:24 -0700233keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
234 const Buffer& input, Buffer* /* output */,
Shawn Willdenb7361132014-12-08 08:15:14 -0700235 size_t* input_consumed) {
236 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600237 switch (purpose()) {
238 default:
239 return KM_ERROR_UNIMPLEMENTED;
240 case KM_PURPOSE_SIGN:
241 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700242 case KM_PURPOSE_ENCRYPT:
243 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700244 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600245 }
246}
247
Shawn Willdenb7361132014-12-08 08:15:14 -0700248keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
249 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600250 if (!data_.reserve(data_.available_read() + input.available_read()) ||
251 !data_.write(input.peek_read(), input.available_read()))
252 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700253 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600254 return KM_ERROR_OK;
255}
256
Shawn Willden61902362014-12-18 10:33:24 -0700257RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
258 keymaster_padding_t padding, RSA* key)
259 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
260 EVP_MD_CTX_init(&digest_ctx_);
261}
262RsaDigestingOperation::~RsaDigestingOperation() {
263 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700264 memset_s(digest_buf_, 0, sizeof(digest_buf_));
Shawn Willden61902362014-12-18 10:33:24 -0700265}
266
267keymaster_error_t RsaDigestingOperation::Begin(const AuthorizationSet& /* input_params */,
268 AuthorizationSet* /* output_params */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700269 if (require_digest() && digest_ == KM_DIGEST_NONE)
270 return KM_ERROR_INCOMPATIBLE_DIGEST;
271 return InitDigest();
272}
Shawn Willden61902362014-12-18 10:33:24 -0700273
Shawn Willdenf90f2352014-12-18 23:01:15 -0700274keymaster_error_t RsaDigestingOperation::Update(const AuthorizationSet& additional_params,
275 const Buffer& input, Buffer* output,
276 size_t* input_consumed) {
277 if (digest_ == KM_DIGEST_NONE)
278 return RsaOperation::Update(additional_params, input, output, input_consumed);
279 else
280 return UpdateDigest(input, input_consumed);
281}
282
283keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden61902362014-12-18 10:33:24 -0700284 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700285 case KM_DIGEST_NONE:
286 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700287 case KM_DIGEST_SHA_2_256:
288 digest_algorithm_ = EVP_sha256();
289 break;
290 default:
291 return KM_ERROR_UNSUPPORTED_DIGEST;
292 }
293
294 if (!EVP_DigestInit_ex(&digest_ctx_, digest_algorithm_, NULL /* engine */)) {
295 int err = ERR_get_error();
296 LOG_E("Failed to initialize digest: %d %s", err, ERR_error_string(err, NULL));
297 return KM_ERROR_UNKNOWN_ERROR;
298 }
Shawn Willden61902362014-12-18 10:33:24 -0700299 return KM_ERROR_OK;
300}
301
Shawn Willdenf90f2352014-12-18 23:01:15 -0700302keymaster_error_t RsaDigestingOperation::UpdateDigest(const Buffer& input, size_t* input_consumed) {
Shawn Willden61902362014-12-18 10:33:24 -0700303 if (!EVP_DigestUpdate(&digest_ctx_, input.peek_read(), input.available_read())) {
304 int err = ERR_get_error();
305 LOG_E("Failed to update digest: %d %s", err, ERR_error_string(err, NULL));
306 return KM_ERROR_UNKNOWN_ERROR;
307 }
308 *input_consumed = input.available_read();
309 return KM_ERROR_OK;
310}
311
Shawn Willdenf90f2352014-12-18 23:01:15 -0700312keymaster_error_t RsaDigestingOperation::FinishDigest(unsigned* digest_size) {
Shawn Willden61902362014-12-18 10:33:24 -0700313 assert(digest_algorithm_ != NULL);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700314 if (!EVP_DigestFinal_ex(&digest_ctx_, digest_buf_, digest_size)) {
Shawn Willden61902362014-12-18 10:33:24 -0700315 int err = ERR_get_error();
316 LOG_E("Failed to finalize digest: %d %s", err, ERR_error_string(err, NULL));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700317 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700318 }
319 assert(*digest_size == static_cast<unsigned>(EVP_MD_size(digest_algorithm_)));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700320 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700321}
322
Shawn Willden6bfbff02015-02-06 19:48:24 -0700323keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
324 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700325 assert(output);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600326 output->Reinitialize(RSA_size(rsa_key_));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700327 if (digest_ == KM_DIGEST_NONE)
328 return SignUndigested(output);
329 else
330 return SignDigested(output);
331}
Shawn Willden61902362014-12-18 10:33:24 -0700332
Shawn Willdenf90f2352014-12-18 23:01:15 -0700333keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
334 int bytes_encrypted;
335 switch (padding_) {
336 case KM_PAD_NONE:
337 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
338 output->peek_write(), rsa_key_, RSA_NO_PADDING);
339 break;
340 case KM_PAD_RSA_PKCS1_1_5_SIGN:
341 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
342 output->peek_write(), rsa_key_, RSA_PKCS1_PADDING);
343 break;
344 default:
345 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
346 }
Shawn Willden61902362014-12-18 10:33:24 -0700347
Shawn Willdenf90f2352014-12-18 23:01:15 -0700348 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600349 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600350 output->advance_write(bytes_encrypted);
351 return KM_ERROR_OK;
352}
353
Shawn Willdenf90f2352014-12-18 23:01:15 -0700354keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
355 unsigned digest_size = 0;
356 keymaster_error_t error = FinishDigest(&digest_size);
357 if (error != KM_ERROR_OK)
358 return error;
359
360 UniquePtr<uint8_t[]> padded_digest;
361 switch (padding_) {
362 case KM_PAD_NONE:
363 return PrivateEncrypt(digest_buf_, digest_size, RSA_NO_PADDING, output);
364 case KM_PAD_RSA_PKCS1_1_5_SIGN:
365 return PrivateEncrypt(digest_buf_, digest_size, RSA_PKCS1_PADDING, output);
366 case KM_PAD_RSA_PSS:
367 // OpenSSL doesn't verify that the key is large enough for the digest size. This can cause
368 // a segfault in some cases, and in others can result in a unsafely-small salt.
Shawn Willden2c242002015-02-27 07:01:02 -0700369 if ((unsigned)RSA_size(rsa_key_) < MIN_PSS_SALT_LEN + digest_size)
370 // TODO(swillden): Add a better return code for this.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700371 return KM_ERROR_INCOMPATIBLE_DIGEST;
372
373 if ((error = PssPadDigest(&padded_digest)) != KM_ERROR_OK)
374 return error;
375 return PrivateEncrypt(padded_digest.get(), RSA_size(rsa_key_), RSA_NO_PADDING, output);
376 default:
377 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
378 }
Shawn Willden61902362014-12-18 10:33:24 -0700379}
380
Shawn Willdenf90f2352014-12-18 23:01:15 -0700381keymaster_error_t RsaSignOperation::PssPadDigest(UniquePtr<uint8_t[]>* padded_digest) {
382 padded_digest->reset(new uint8_t[RSA_size(rsa_key_)]);
383 if (!padded_digest->get())
384 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
385
Adam Langleyadb0f332015-03-05 19:57:29 -0800386 if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa_key_, padded_digest->get(), digest_buf_,
387 digest_algorithm_, NULL,
388 -2 /* Indicates maximum salt length */)) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700389 LOG_E("%s", "Failed to apply PSS padding");
Shawn Willden61902362014-12-18 10:33:24 -0700390 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700391 }
392 return KM_ERROR_OK;
393}
394
395keymaster_error_t RsaSignOperation::PrivateEncrypt(uint8_t* to_encrypt, size_t len,
396 int openssl_padding, Buffer* output) {
397 int bytes_encrypted =
398 RSA_private_encrypt(len, to_encrypt, output->peek_write(), rsa_key_, openssl_padding);
399 if (bytes_encrypted <= 0)
400 return KM_ERROR_UNKNOWN_ERROR;
401 output->advance_write(bytes_encrypted);
402 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700403}
404
Shawn Willden6bfbff02015-02-06 19:48:24 -0700405keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
406 const Buffer& signature, Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700407 if (digest_ == KM_DIGEST_NONE)
408 return VerifyUndigested(signature);
409 else
410 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700411}
412
Shawn Willdenf90f2352014-12-18 23:01:15 -0700413keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
414 return DecryptAndMatch(signature, data_.peek_read(), data_.available_read());
Shawn Willden61902362014-12-18 10:33:24 -0700415}
416
Shawn Willdenf90f2352014-12-18 23:01:15 -0700417keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
Shawn Willden61902362014-12-18 10:33:24 -0700418 unsigned digest_size = 0;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700419 keymaster_error_t error = FinishDigest(&digest_size);
420 if (error != KM_ERROR_OK)
421 return error;
422 return DecryptAndMatch(signature, digest_buf_, digest_size);
423}
Shawn Willden61902362014-12-18 10:33:24 -0700424
Shawn Willdenf90f2352014-12-18 23:01:15 -0700425keymaster_error_t RsaVerifyOperation::DecryptAndMatch(const Buffer& signature,
426 const uint8_t* to_match, size_t len) {
427#ifdef OPENSSL_IS_BORINGSSL
428 size_t key_len = RSA_size(rsa_key_);
429#else
430 size_t key_len = (size_t)RSA_size(rsa_key_);
431#endif
432
433 int openssl_padding;
434 switch (padding_) {
435 case KM_PAD_NONE:
436 if (len != key_len)
437 return KM_ERROR_INVALID_INPUT_LENGTH;
438 if (len != signature.available_read())
439 return KM_ERROR_VERIFICATION_FAILED;
440 openssl_padding = RSA_NO_PADDING;
441 break;
442 case KM_PAD_RSA_PSS: // Do a raw decrypt for PSS
443 openssl_padding = RSA_NO_PADDING;
444 break;
445 case KM_PAD_RSA_PKCS1_1_5_SIGN:
446 openssl_padding = RSA_PKCS1_PADDING;
447 break;
448 default:
449 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
450 }
451
452 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
453 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
454 decrypted_data.get(), rsa_key_, openssl_padding);
455 if (bytes_decrypted < 0)
456 return KM_ERROR_VERIFICATION_FAILED;
457
458 if (padding_ == KM_PAD_RSA_PSS &&
Adam Langleyadb0f332015-03-05 19:57:29 -0800459 RSA_verify_PKCS1_PSS_mgf1(rsa_key_, to_match, digest_algorithm_, NULL, decrypted_data.get(),
460 -2 /* salt length recovered from signature */))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700461 return KM_ERROR_OK;
Shawn Willden4749c432015-05-04 14:59:29 -0600462 else if (padding_ != KM_PAD_RSA_PSS && CRYPTO_memcmp(decrypted_data.get(), to_match, len) == 0)
Shawn Willden61902362014-12-18 10:33:24 -0700463 return KM_ERROR_OK;
464
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600465 return KM_ERROR_VERIFICATION_FAILED;
466}
467
Shawn Willden4200f212014-12-02 07:01:21 -0700468const int OAEP_PADDING_OVERHEAD = 41;
469const int PKCS1_PADDING_OVERHEAD = 11;
470
Shawn Willden6bfbff02015-02-06 19:48:24 -0700471keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
472 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700473 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700474 int openssl_padding;
475
476#if defined(OPENSSL_IS_BORINGSSL)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700477 size_t key_len = RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700478#else
Shawn Willdenf90f2352014-12-18 23:01:15 -0700479 size_t key_len = (size_t)RSA_size(rsa_key_);
Shawn Willden4200f212014-12-02 07:01:21 -0700480#endif
481
Shawn Willdenf90f2352014-12-18 23:01:15 -0700482 size_t message_size = data_.available_read();
Shawn Willden4200f212014-12-02 07:01:21 -0700483 switch (padding_) {
484 case KM_PAD_RSA_OAEP:
485 openssl_padding = RSA_PKCS1_OAEP_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700486 if (message_size + OAEP_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700487 LOG_E("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700488 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700489 return KM_ERROR_INVALID_INPUT_LENGTH;
490 }
491 break;
492 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
493 openssl_padding = RSA_PKCS1_PADDING;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700494 if (message_size + PKCS1_PADDING_OVERHEAD >= key_len) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700495 LOG_E("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
Shawn Willdenf90f2352014-12-18 23:01:15 -0700496 data_.available_read(), key_len);
Shawn Willden4200f212014-12-02 07:01:21 -0700497 return KM_ERROR_INVALID_INPUT_LENGTH;
498 }
499 break;
500 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700501 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700502 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
503 }
504
505 output->Reinitialize(RSA_size(rsa_key_));
506 int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(),
507 output->peek_write(), rsa_key_, openssl_padding);
508
509 if (bytes_encrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700510 LOG_E("Error %d encrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700511 return KM_ERROR_UNKNOWN_ERROR;
512 }
513 assert(bytes_encrypted == RSA_size(rsa_key_));
514 output->advance_write(bytes_encrypted);
515
516 return KM_ERROR_OK;
517}
518
Shawn Willden6bfbff02015-02-06 19:48:24 -0700519keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
520 const Buffer& /* signature */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700521 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700522 int openssl_padding;
523 switch (padding_) {
524 case KM_PAD_RSA_OAEP:
525 openssl_padding = RSA_PKCS1_OAEP_PADDING;
526 break;
527 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
528 openssl_padding = RSA_PKCS1_PADDING;
529 break;
530 default:
Shawn Willden567a4a02014-12-31 12:14:46 -0700531 LOG_E("Padding mode %d not supported", padding_);
Shawn Willden4200f212014-12-02 07:01:21 -0700532 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
533 }
534
535 output->Reinitialize(RSA_size(rsa_key_));
536 int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(),
537 output->peek_write(), rsa_key_, openssl_padding);
538
539 if (bytes_decrypted < 0) {
Shawn Willden567a4a02014-12-31 12:14:46 -0700540 LOG_E("Error %d decrypting data with RSA", ERR_get_error());
Shawn Willden4200f212014-12-02 07:01:21 -0700541 return KM_ERROR_UNKNOWN_ERROR;
542 }
543 output->advance_write(bytes_decrypted);
544
545 return KM_ERROR_OK;
546}
547
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600548} // namespace keymaster