blob: c99fbfc3bb3a3814ef31d31d555d2fb4676ca9ee [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
Shawn Willden0f906ec2015-06-20 09:16:30 -060021#include <new>
22
Shawn Willden4200f212014-12-02 07:01:21 -070023#include <openssl/err.h>
Shawn Willden0a4df7e2014-08-28 16:09:05 -060024
Shawn Willden567a4a02014-12-31 12:14:46 -070025#include <keymaster/logger.h>
26
27#include "openssl_err.h"
Shawn Willden0a4df7e2014-08-28 16:09:05 -060028#include "openssl_utils.h"
Shawn Willden63ac0432014-12-29 14:07:08 -070029#include "rsa_key.h"
Shawn Willden0a4df7e2014-08-28 16:09:05 -060030
31namespace keymaster {
32
Shawn Willden63ac0432014-12-29 14:07:08 -070033/* static */
Shawn Willden2bf4ad32015-06-01 07:33:51 -060034EVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070035 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
36 assert(rsa_key);
37 if (!rsa_key || !rsa_key->key()) {
38 *error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060039 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070040 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -060041
42 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
43 if (!rsa_key->InternalToEvp(pkey.get())) {
44 *error = KM_ERROR_UNKNOWN_ERROR;
45 return nullptr;
46 }
47 return pkey.release();
Shawn Willden63ac0432014-12-29 14:07:08 -070048}
49
Shawn Willden2bf4ad32015-06-01 07:33:51 -060050static const keymaster_digest_t supported_digests[] = {
51 KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
52 KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
Shawn Willdenf90f2352014-12-18 23:01:15 -070053static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
54 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070055
Shawn Willden06298102015-05-25 23:12:48 -060056const keymaster_digest_t*
57RsaDigestingOperationFactory::SupportedDigests(size_t* digest_count) const {
58 *digest_count = array_length(supported_digests);
59 return supported_digests;
60}
Shawn Willden63ac0432014-12-29 14:07:08 -070061
Shawn Willden06298102015-05-25 23:12:48 -060062const keymaster_padding_t*
63RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
64 *padding_mode_count = array_length(supported_sig_padding);
65 return supported_sig_padding;
66}
Shawn Willden63ac0432014-12-29 14:07:08 -070067
Shawn Willden3ed6d062015-04-15 13:39:38 -060068Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
Shawn Willden226746b2015-05-08 11:36:56 -060069 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060070 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070071 keymaster_padding_t padding;
72 keymaster_digest_t digest;
Shawn Willden226746b2015-05-08 11:36:56 -060073 if (!GetAndValidateDigest(begin_params, key, &digest, error) ||
Shawn Willden2bf4ad32015-06-01 07:33:51 -060074 !GetAndValidatePadding(begin_params, key, &padding, error))
75 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070076
Shawn Willden2bf4ad32015-06-01 07:33:51 -060077 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
78 if (!rsa.get())
79 return nullptr;
80
81 Operation* op = InstantiateOperation(digest, padding, rsa.release());
Shawn Willden63ac0432014-12-29 14:07:08 -070082 if (!op)
83 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
84 return op;
85}
86
Shawn Willden30160842015-06-01 08:31:00 -060087static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
Shawn Willden63ac0432014-12-29 14:07:08 -070088 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
89
Shawn Willden3ed6d062015-04-15 13:39:38 -060090Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
Shawn Willden3ad5f052015-05-08 14:05:13 -060091 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060092 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070093 keymaster_padding_t padding;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060094 if (!GetAndValidatePadding(begin_params, key, &padding, error))
95 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070096
Shawn Willden2bf4ad32015-06-01 07:33:51 -060097 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
98 if (!rsa.get())
99 return nullptr;
100
101 Operation* op = InstantiateOperation(padding, rsa.release());
Shawn Willden63ac0432014-12-29 14:07:08 -0700102 if (!op)
103 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
104 return op;
105}
106
Shawn Willden06298102015-05-25 23:12:48 -0600107const keymaster_padding_t*
108RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
109 *padding_mode_count = array_length(supported_crypt_padding);
110 return supported_crypt_padding;
111}
Shawn Willden63ac0432014-12-29 14:07:08 -0700112
Shawn Willden06298102015-05-25 23:12:48 -0600113const keymaster_digest_t*
114RsaCryptingOperationFactory::SupportedDigests(size_t* digest_count) const {
115 *digest_count = 0;
116 return NULL;
117}
Shawn Willden63ac0432014-12-29 14:07:08 -0700118
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600119RsaOperation::~RsaOperation() {
120 if (rsa_key_ != NULL)
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600121 EVP_PKEY_free(rsa_key_);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600122}
123
Shawn Willden6bfbff02015-02-06 19:48:24 -0700124keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600125 const Buffer& input, AuthorizationSet* /* output_params */,
126 Buffer* /* output */, size_t* input_consumed) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700127 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600128 switch (purpose()) {
129 default:
130 return KM_ERROR_UNIMPLEMENTED;
131 case KM_PURPOSE_SIGN:
132 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700133 case KM_PURPOSE_ENCRYPT:
134 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700135 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600136 }
137}
138
Shawn Willdenb7361132014-12-08 08:15:14 -0700139keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
140 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600141 if (!data_.reserve(data_.available_read() + input.available_read()) ||
142 !data_.write(input.peek_read(), input.available_read()))
143 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700144 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600145 return KM_ERROR_OK;
146}
147
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600148keymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx) {
149 keymaster_error_t error;
150 int openssl_padding = GetOpensslPadding(&error);
151 if (error != KM_ERROR_OK)
152 return error;
153
154 if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, openssl_padding) <= 0)
155 return TranslateLastOpenSslError();
156 return KM_ERROR_OK;
157}
158
Shawn Willden61902362014-12-18 10:33:24 -0700159RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600160 keymaster_padding_t padding, EVP_PKEY* key)
Shawn Willden61902362014-12-18 10:33:24 -0700161 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
162 EVP_MD_CTX_init(&digest_ctx_);
163}
164RsaDigestingOperation::~RsaDigestingOperation() {
165 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700166}
167
168keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600169 if (digest_ == KM_DIGEST_NONE) {
170 if (require_digest())
171 return KM_ERROR_INCOMPATIBLE_DIGEST;
172 return KM_ERROR_OK;
173 }
174
Shawn Willden61902362014-12-18 10:33:24 -0700175 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700176 case KM_DIGEST_NONE:
177 return KM_ERROR_OK;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600178 case KM_DIGEST_MD5:
179 digest_algorithm_ = EVP_md5();
180 return KM_ERROR_OK;
181 case KM_DIGEST_SHA1:
182 digest_algorithm_ = EVP_sha1();
183 return KM_ERROR_OK;
184 case KM_DIGEST_SHA_2_224:
185 digest_algorithm_ = EVP_sha224();
186 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700187 case KM_DIGEST_SHA_2_256:
188 digest_algorithm_ = EVP_sha256();
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600189 return KM_ERROR_OK;
190 case KM_DIGEST_SHA_2_384:
191 digest_algorithm_ = EVP_sha384();
192 return KM_ERROR_OK;
193 case KM_DIGEST_SHA_2_512:
194 digest_algorithm_ = EVP_sha512();
195 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700196 default:
197 return KM_ERROR_UNSUPPORTED_DIGEST;
198 }
Shawn Willden61902362014-12-18 10:33:24 -0700199}
200
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600201const size_t PSS_OVERHEAD = 2;
202const size_t MIN_SALT_SIZE = 8;
203
204int RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) {
205 *error = KM_ERROR_OK;
206 switch (padding_) {
207 case KM_PAD_NONE:
208 return RSA_NO_PADDING;
209 case KM_PAD_RSA_PKCS1_1_5_SIGN:
210
211 return RSA_PKCS1_PADDING;
212 case KM_PAD_RSA_PSS:
213 if (digest_ == KM_DIGEST_NONE) {
214 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
215 return -1;
216 }
217 if (EVP_MD_size(digest_algorithm_) + PSS_OVERHEAD + MIN_SALT_SIZE >
218 (size_t)EVP_PKEY_size(rsa_key_)) {
Shawn Willdenbfd9ed72015-06-11 10:51:12 -0600219 LOG_E("%d-byte digest cannot be used with %d-byte RSA key in PSS padding mode",
220 EVP_MD_size(digest_algorithm_), EVP_PKEY_size(rsa_key_));
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600221 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
222 return -1;
223 }
224 return RSA_PKCS1_PSS_PADDING;
225 default:
226 return -1;
Shawn Willden61902362014-12-18 10:33:24 -0700227 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600228}
229
230keymaster_error_t RsaSignOperation::Begin(const AuthorizationSet& /* input_params */,
231 AuthorizationSet* /* output_params */) {
232 keymaster_error_t error = InitDigest();
233 if (error != KM_ERROR_OK)
234 return error;
235
236 if (digest_ == KM_DIGEST_NONE)
237 return KM_ERROR_OK;
238
239 EVP_PKEY_CTX* pkey_ctx;
240 if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
241 rsa_key_) != 1)
242 return TranslateLastOpenSslError();
243 return SetRsaPaddingInEvpContext(pkey_ctx);
244}
245
246keymaster_error_t RsaSignOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600247 const Buffer& input, AuthorizationSet* output_params,
248 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600249 if (digest_ == KM_DIGEST_NONE)
250 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600251 return RsaOperation::Update(additional_params, input, output_params, output,
252 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600253
254 if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
255 return TranslateLastOpenSslError();
Shawn Willden61902362014-12-18 10:33:24 -0700256 *input_consumed = input.available_read();
257 return KM_ERROR_OK;
258}
259
Shawn Willden6bfbff02015-02-06 19:48:24 -0700260keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600261 const Buffer& /* signature */,
262 AuthorizationSet* /* output_params */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700263 assert(output);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600264
Shawn Willdenf90f2352014-12-18 23:01:15 -0700265 if (digest_ == KM_DIGEST_NONE)
266 return SignUndigested(output);
267 else
268 return SignDigested(output);
269}
Shawn Willden61902362014-12-18 10:33:24 -0700270
Shawn Willdenf90f2352014-12-18 23:01:15 -0700271keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600272 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
273 if (!rsa.get())
274 return TranslateLastOpenSslError();
275
276 if (!output->Reinitialize(RSA_size(rsa.get())))
277 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
278
Shawn Willdenf90f2352014-12-18 23:01:15 -0700279 int bytes_encrypted;
280 switch (padding_) {
281 case KM_PAD_NONE:
282 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600283 output->peek_write(), rsa.get(), RSA_NO_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700284 break;
285 case KM_PAD_RSA_PKCS1_1_5_SIGN:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600286 // Does PKCS1 padding without digesting even make sense? Dunno. We'll support it.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700287 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600288 output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700289 break;
290 default:
291 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
292 }
Shawn Willden61902362014-12-18 10:33:24 -0700293
Shawn Willdenf90f2352014-12-18 23:01:15 -0700294 if (bytes_encrypted <= 0)
Shawn Willden0f906ec2015-06-20 09:16:30 -0600295 return TranslateLastOpenSslError();
296 if (!output->advance_write(bytes_encrypted))
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600297 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600298 return KM_ERROR_OK;
299}
300
Shawn Willdenf90f2352014-12-18 23:01:15 -0700301keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600302 size_t siglen;
303 if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
304 return TranslateLastOpenSslError();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700305
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600306 if (!output->Reinitialize(siglen))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700307 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
308
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600309 if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
310 return TranslateLastOpenSslError();
Shawn Willden0f906ec2015-06-20 09:16:30 -0600311 if (!output->advance_write(siglen))
312 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600313
Shawn Willdenf90f2352014-12-18 23:01:15 -0700314 return KM_ERROR_OK;
315}
316
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600317keymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
318 AuthorizationSet* /* output_params */) {
319 keymaster_error_t error = InitDigest();
320 if (error != KM_ERROR_OK)
321 return error;
322
323 if (digest_ == KM_DIGEST_NONE)
324 return KM_ERROR_OK;
325
326 EVP_PKEY_CTX* pkey_ctx;
327 if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
328 return TranslateLastOpenSslError();
329 return SetRsaPaddingInEvpContext(pkey_ctx);
330}
331
332keymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600333 const Buffer& input, AuthorizationSet* output_params,
334 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600335 if (digest_ == KM_DIGEST_NONE)
336 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600337 return RsaOperation::Update(additional_params, input, output_params, output,
338 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600339
340 if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
341 return TranslateLastOpenSslError();
342 *input_consumed = input.available_read();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700343 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700344}
345
Shawn Willden6bfbff02015-02-06 19:48:24 -0700346keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600347 const Buffer& signature,
348 AuthorizationSet* /* output_params */,
349 Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700350 if (digest_ == KM_DIGEST_NONE)
351 return VerifyUndigested(signature);
352 else
353 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700354}
355
Shawn Willdenf90f2352014-12-18 23:01:15 -0700356keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600357 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
358 if (!rsa.get())
359 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700360
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600361 size_t key_len = RSA_size(rsa.get());
Shawn Willdenf90f2352014-12-18 23:01:15 -0700362 int openssl_padding;
363 switch (padding_) {
364 case KM_PAD_NONE:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600365 if (data_.available_read() != key_len)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700366 return KM_ERROR_INVALID_INPUT_LENGTH;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600367 if (data_.available_read() != signature.available_read())
Shawn Willdenf90f2352014-12-18 23:01:15 -0700368 return KM_ERROR_VERIFICATION_FAILED;
369 openssl_padding = RSA_NO_PADDING;
370 break;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700371 case KM_PAD_RSA_PKCS1_1_5_SIGN:
372 openssl_padding = RSA_PKCS1_PADDING;
373 break;
374 default:
375 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
376 }
377
Shawn Willden0f906ec2015-06-20 09:16:30 -0600378 UniquePtr<uint8_t[]> decrypted_data(new (std::nothrow) uint8_t[key_len]);
379 if (!decrypted_data.get())
380 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700381 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600382 decrypted_data.get(), rsa.get(), openssl_padding);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700383 if (bytes_decrypted < 0)
384 return KM_ERROR_VERIFICATION_FAILED;
385
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600386 if (memcmp_s(decrypted_data.get(), data_.peek_read(), data_.available_read()) != 0)
387 return KM_ERROR_VERIFICATION_FAILED;
388 return KM_ERROR_OK;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600389}
390
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600391keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
392 if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
393 return KM_ERROR_VERIFICATION_FAILED;
394 return KM_ERROR_OK;
395}
396
397int RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
398 *error = KM_ERROR_OK;
399 switch (padding_) {
Shawn Willden30160842015-06-01 08:31:00 -0600400 case KM_PAD_NONE:
401 return RSA_NO_PADDING;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600402 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
403 return RSA_PKCS1_PADDING;
404 case KM_PAD_RSA_OAEP:
405 return RSA_PKCS1_OAEP_PADDING;
406 default:
407 return -1;
408 }
409}
410
411struct EVP_PKEY_CTX_Delete {
412 void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
413};
Shawn Willden4200f212014-12-02 07:01:21 -0700414
Shawn Willden6bfbff02015-02-06 19:48:24 -0700415keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600416 const Buffer& /* signature */,
417 AuthorizationSet* /* output_params */,
418 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700419 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700420
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600421 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
422 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
423 if (!ctx.get())
424 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700425
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600426 if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
427 return TranslateLastOpenSslError();
Shawn Willden4200f212014-12-02 07:01:21 -0700428
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600429 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
430 if (error != KM_ERROR_OK)
431 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700432
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600433 size_t outlen;
434 if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
435 data_.available_read()) <= 0)
436 return TranslateLastOpenSslError();
437
438 if (!output->Reinitialize(outlen))
439 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
440
441 if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
442 data_.available_read()) <= 0)
443 return TranslateLastOpenSslError();
Shawn Willden0f906ec2015-06-20 09:16:30 -0600444 if (!output->advance_write(outlen))
445 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden4200f212014-12-02 07:01:21 -0700446
447 return KM_ERROR_OK;
448}
449
Shawn Willden6bfbff02015-02-06 19:48:24 -0700450keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600451 const Buffer& /* signature */,
452 AuthorizationSet* /* output_params */,
453 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700454 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700455
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600456 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
457 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
458 if (!ctx.get())
459 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700460
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600461 if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
462 return TranslateLastOpenSslError();
463
464 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
465 if (error != KM_ERROR_OK)
466 return error;
467
468 size_t outlen;
469 if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
470 data_.available_read()) <= 0)
471 return TranslateLastOpenSslError();
472
473 if (!output->Reinitialize(outlen))
474 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
475
476 if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
477 data_.available_read()) <= 0)
478 return TranslateLastOpenSslError();
Shawn Willden0f906ec2015-06-20 09:16:30 -0600479 if (!output->advance_write(outlen))
480 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden4200f212014-12-02 07:01:21 -0700481
482 return KM_ERROR_OK;
483}
484
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600485} // namespace keymaster