blob: fac3ae785129eca110e4dd2421a63445819b5bda [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 Willden63ac0432014-12-29 14:07:08 -070031/* static */
Shawn Willden2bf4ad32015-06-01 07:33:51 -060032EVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070033 const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
34 assert(rsa_key);
35 if (!rsa_key || !rsa_key->key()) {
36 *error = KM_ERROR_UNKNOWN_ERROR;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060037 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070038 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -060039
40 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
41 if (!rsa_key->InternalToEvp(pkey.get())) {
42 *error = KM_ERROR_UNKNOWN_ERROR;
43 return nullptr;
44 }
45 return pkey.release();
Shawn Willden63ac0432014-12-29 14:07:08 -070046}
47
Shawn Willden2bf4ad32015-06-01 07:33:51 -060048static const keymaster_digest_t supported_digests[] = {
49 KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
50 KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
Shawn Willdenf90f2352014-12-18 23:01:15 -070051static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
52 KM_PAD_RSA_PSS};
Shawn Willden63ac0432014-12-29 14:07:08 -070053
Shawn Willden06298102015-05-25 23:12:48 -060054const keymaster_digest_t*
55RsaDigestingOperationFactory::SupportedDigests(size_t* digest_count) const {
56 *digest_count = array_length(supported_digests);
57 return supported_digests;
58}
Shawn Willden63ac0432014-12-29 14:07:08 -070059
Shawn Willden06298102015-05-25 23:12:48 -060060const keymaster_padding_t*
61RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
62 *padding_mode_count = array_length(supported_sig_padding);
63 return supported_sig_padding;
64}
Shawn Willden63ac0432014-12-29 14:07:08 -070065
Shawn Willden3ed6d062015-04-15 13:39:38 -060066Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
Shawn Willden226746b2015-05-08 11:36:56 -060067 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060068 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070069 keymaster_padding_t padding;
70 keymaster_digest_t digest;
Shawn Willden226746b2015-05-08 11:36:56 -060071 if (!GetAndValidateDigest(begin_params, key, &digest, error) ||
Shawn Willden2bf4ad32015-06-01 07:33:51 -060072 !GetAndValidatePadding(begin_params, key, &padding, error))
73 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070074
Shawn Willden2bf4ad32015-06-01 07:33:51 -060075 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
76 if (!rsa.get())
77 return nullptr;
78
79 Operation* op = InstantiateOperation(digest, padding, rsa.release());
Shawn Willden63ac0432014-12-29 14:07:08 -070080 if (!op)
81 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
82 return op;
83}
84
Shawn Willden30160842015-06-01 08:31:00 -060085static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
Shawn Willden63ac0432014-12-29 14:07:08 -070086 KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
87
Shawn Willden3ed6d062015-04-15 13:39:38 -060088Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
Shawn Willden3ad5f052015-05-08 14:05:13 -060089 const AuthorizationSet& begin_params,
Shawn Willden3ed6d062015-04-15 13:39:38 -060090 keymaster_error_t* error) {
Shawn Willden63ac0432014-12-29 14:07:08 -070091 keymaster_padding_t padding;
Shawn Willden2bf4ad32015-06-01 07:33:51 -060092 if (!GetAndValidatePadding(begin_params, key, &padding, error))
93 return nullptr;
Shawn Willden63ac0432014-12-29 14:07:08 -070094
Shawn Willden2bf4ad32015-06-01 07:33:51 -060095 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
96 if (!rsa.get())
97 return nullptr;
98
99 Operation* op = InstantiateOperation(padding, rsa.release());
Shawn Willden63ac0432014-12-29 14:07:08 -0700100 if (!op)
101 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
102 return op;
103}
104
Shawn Willden06298102015-05-25 23:12:48 -0600105const keymaster_padding_t*
106RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
107 *padding_mode_count = array_length(supported_crypt_padding);
108 return supported_crypt_padding;
109}
Shawn Willden63ac0432014-12-29 14:07:08 -0700110
Shawn Willden06298102015-05-25 23:12:48 -0600111const keymaster_digest_t*
112RsaCryptingOperationFactory::SupportedDigests(size_t* digest_count) const {
113 *digest_count = 0;
114 return NULL;
115}
Shawn Willden63ac0432014-12-29 14:07:08 -0700116
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600117RsaOperation::~RsaOperation() {
118 if (rsa_key_ != NULL)
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600119 EVP_PKEY_free(rsa_key_);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600120}
121
Shawn Willden6bfbff02015-02-06 19:48:24 -0700122keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600123 const Buffer& input, AuthorizationSet* /* output_params */,
124 Buffer* /* output */, size_t* input_consumed) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700125 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600126 switch (purpose()) {
127 default:
128 return KM_ERROR_UNIMPLEMENTED;
129 case KM_PURPOSE_SIGN:
130 case KM_PURPOSE_VERIFY:
Shawn Willden4200f212014-12-02 07:01:21 -0700131 case KM_PURPOSE_ENCRYPT:
132 case KM_PURPOSE_DECRYPT:
Shawn Willdenb7361132014-12-08 08:15:14 -0700133 return StoreData(input, input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600134 }
135}
136
Shawn Willdenb7361132014-12-08 08:15:14 -0700137keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
138 assert(input_consumed);
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600139 if (!data_.reserve(data_.available_read() + input.available_read()) ||
140 !data_.write(input.peek_read(), input.available_read()))
141 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willdenb7361132014-12-08 08:15:14 -0700142 *input_consumed = input.available_read();
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600143 return KM_ERROR_OK;
144}
145
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600146keymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx) {
147 keymaster_error_t error;
148 int openssl_padding = GetOpensslPadding(&error);
149 if (error != KM_ERROR_OK)
150 return error;
151
152 if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, openssl_padding) <= 0)
153 return TranslateLastOpenSslError();
154 return KM_ERROR_OK;
155}
156
Shawn Willden61902362014-12-18 10:33:24 -0700157RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600158 keymaster_padding_t padding, EVP_PKEY* key)
Shawn Willden61902362014-12-18 10:33:24 -0700159 : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
160 EVP_MD_CTX_init(&digest_ctx_);
161}
162RsaDigestingOperation::~RsaDigestingOperation() {
163 EVP_MD_CTX_cleanup(&digest_ctx_);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700164}
165
166keymaster_error_t RsaDigestingOperation::InitDigest() {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600167 if (digest_ == KM_DIGEST_NONE) {
168 if (require_digest())
169 return KM_ERROR_INCOMPATIBLE_DIGEST;
170 return KM_ERROR_OK;
171 }
172
Shawn Willden61902362014-12-18 10:33:24 -0700173 switch (digest_) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700174 case KM_DIGEST_NONE:
175 return KM_ERROR_OK;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600176 case KM_DIGEST_MD5:
177 digest_algorithm_ = EVP_md5();
178 return KM_ERROR_OK;
179 case KM_DIGEST_SHA1:
180 digest_algorithm_ = EVP_sha1();
181 return KM_ERROR_OK;
182 case KM_DIGEST_SHA_2_224:
183 digest_algorithm_ = EVP_sha224();
184 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700185 case KM_DIGEST_SHA_2_256:
186 digest_algorithm_ = EVP_sha256();
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600187 return KM_ERROR_OK;
188 case KM_DIGEST_SHA_2_384:
189 digest_algorithm_ = EVP_sha384();
190 return KM_ERROR_OK;
191 case KM_DIGEST_SHA_2_512:
192 digest_algorithm_ = EVP_sha512();
193 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700194 default:
195 return KM_ERROR_UNSUPPORTED_DIGEST;
196 }
Shawn Willden61902362014-12-18 10:33:24 -0700197}
198
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600199const size_t PSS_OVERHEAD = 2;
200const size_t MIN_SALT_SIZE = 8;
201
202int RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) {
203 *error = KM_ERROR_OK;
204 switch (padding_) {
205 case KM_PAD_NONE:
206 return RSA_NO_PADDING;
207 case KM_PAD_RSA_PKCS1_1_5_SIGN:
208
209 return RSA_PKCS1_PADDING;
210 case KM_PAD_RSA_PSS:
211 if (digest_ == KM_DIGEST_NONE) {
212 *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
213 return -1;
214 }
215 if (EVP_MD_size(digest_algorithm_) + PSS_OVERHEAD + MIN_SALT_SIZE >
216 (size_t)EVP_PKEY_size(rsa_key_)) {
217 *error = KM_ERROR_INCOMPATIBLE_DIGEST;
218 return -1;
219 }
220 return RSA_PKCS1_PSS_PADDING;
221 default:
222 return -1;
Shawn Willden61902362014-12-18 10:33:24 -0700223 }
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600224}
225
226keymaster_error_t RsaSignOperation::Begin(const AuthorizationSet& /* input_params */,
227 AuthorizationSet* /* output_params */) {
228 keymaster_error_t error = InitDigest();
229 if (error != KM_ERROR_OK)
230 return error;
231
232 if (digest_ == KM_DIGEST_NONE)
233 return KM_ERROR_OK;
234
235 EVP_PKEY_CTX* pkey_ctx;
236 if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
237 rsa_key_) != 1)
238 return TranslateLastOpenSslError();
239 return SetRsaPaddingInEvpContext(pkey_ctx);
240}
241
242keymaster_error_t RsaSignOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600243 const Buffer& input, AuthorizationSet* output_params,
244 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600245 if (digest_ == KM_DIGEST_NONE)
246 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600247 return RsaOperation::Update(additional_params, input, output_params, output,
248 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600249
250 if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
251 return TranslateLastOpenSslError();
Shawn Willden61902362014-12-18 10:33:24 -0700252 *input_consumed = input.available_read();
253 return KM_ERROR_OK;
254}
255
Shawn Willden6bfbff02015-02-06 19:48:24 -0700256keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600257 const Buffer& /* signature */,
258 AuthorizationSet* /* output_params */, Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700259 assert(output);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600260
Shawn Willdenf90f2352014-12-18 23:01:15 -0700261 if (digest_ == KM_DIGEST_NONE)
262 return SignUndigested(output);
263 else
264 return SignDigested(output);
265}
Shawn Willden61902362014-12-18 10:33:24 -0700266
Shawn Willdenf90f2352014-12-18 23:01:15 -0700267keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600268 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
269 if (!rsa.get())
270 return TranslateLastOpenSslError();
271
272 if (!output->Reinitialize(RSA_size(rsa.get())))
273 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
274
Shawn Willdenf90f2352014-12-18 23:01:15 -0700275 int bytes_encrypted;
276 switch (padding_) {
277 case KM_PAD_NONE:
278 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600279 output->peek_write(), rsa.get(), RSA_NO_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700280 break;
281 case KM_PAD_RSA_PKCS1_1_5_SIGN:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600282 // Does PKCS1 padding without digesting even make sense? Dunno. We'll support it.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700283 bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600284 output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700285 break;
286 default:
287 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
288 }
Shawn Willden61902362014-12-18 10:33:24 -0700289
Shawn Willdenf90f2352014-12-18 23:01:15 -0700290 if (bytes_encrypted <= 0)
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600291 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600292 output->advance_write(bytes_encrypted);
293 return KM_ERROR_OK;
294}
295
Shawn Willdenf90f2352014-12-18 23:01:15 -0700296keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600297 size_t siglen;
298 if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
299 return TranslateLastOpenSslError();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700300
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600301 if (!output->Reinitialize(siglen))
Shawn Willdenf90f2352014-12-18 23:01:15 -0700302 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
303
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600304 if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
305 return TranslateLastOpenSslError();
306 output->advance_write(siglen);
307
Shawn Willdenf90f2352014-12-18 23:01:15 -0700308 return KM_ERROR_OK;
309}
310
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600311keymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
312 AuthorizationSet* /* output_params */) {
313 keymaster_error_t error = InitDigest();
314 if (error != KM_ERROR_OK)
315 return error;
316
317 if (digest_ == KM_DIGEST_NONE)
318 return KM_ERROR_OK;
319
320 EVP_PKEY_CTX* pkey_ctx;
321 if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
322 return TranslateLastOpenSslError();
323 return SetRsaPaddingInEvpContext(pkey_ctx);
324}
325
326keymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600327 const Buffer& input, AuthorizationSet* output_params,
328 Buffer* output, size_t* input_consumed) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600329 if (digest_ == KM_DIGEST_NONE)
330 // Just buffer the data.
Shawn Willdended8e7d2015-06-01 15:29:12 -0600331 return RsaOperation::Update(additional_params, input, output_params, output,
332 input_consumed);
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600333
334 if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
335 return TranslateLastOpenSslError();
336 *input_consumed = input.available_read();
Shawn Willdenf90f2352014-12-18 23:01:15 -0700337 return KM_ERROR_OK;
Shawn Willden61902362014-12-18 10:33:24 -0700338}
339
Shawn Willden6bfbff02015-02-06 19:48:24 -0700340keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600341 const Buffer& signature,
342 AuthorizationSet* /* output_params */,
343 Buffer* /* output */) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700344 if (digest_ == KM_DIGEST_NONE)
345 return VerifyUndigested(signature);
346 else
347 return VerifyDigested(signature);
Shawn Willden61902362014-12-18 10:33:24 -0700348}
349
Shawn Willdenf90f2352014-12-18 23:01:15 -0700350keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600351 UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
352 if (!rsa.get())
353 return KM_ERROR_UNKNOWN_ERROR;
Shawn Willden61902362014-12-18 10:33:24 -0700354
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600355 size_t key_len = RSA_size(rsa.get());
Shawn Willdenf90f2352014-12-18 23:01:15 -0700356 int openssl_padding;
357 switch (padding_) {
358 case KM_PAD_NONE:
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600359 if (data_.available_read() != key_len)
Shawn Willdenf90f2352014-12-18 23:01:15 -0700360 return KM_ERROR_INVALID_INPUT_LENGTH;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600361 if (data_.available_read() != signature.available_read())
Shawn Willdenf90f2352014-12-18 23:01:15 -0700362 return KM_ERROR_VERIFICATION_FAILED;
363 openssl_padding = RSA_NO_PADDING;
364 break;
Shawn Willdenf90f2352014-12-18 23:01:15 -0700365 case KM_PAD_RSA_PKCS1_1_5_SIGN:
366 openssl_padding = RSA_PKCS1_PADDING;
367 break;
368 default:
369 return KM_ERROR_UNSUPPORTED_PADDING_MODE;
370 }
371
372 UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
373 int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600374 decrypted_data.get(), rsa.get(), openssl_padding);
Shawn Willdenf90f2352014-12-18 23:01:15 -0700375 if (bytes_decrypted < 0)
376 return KM_ERROR_VERIFICATION_FAILED;
377
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600378 if (memcmp_s(decrypted_data.get(), data_.peek_read(), data_.available_read()) != 0)
379 return KM_ERROR_VERIFICATION_FAILED;
380 return KM_ERROR_OK;
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600381}
382
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600383keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
384 if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
385 return KM_ERROR_VERIFICATION_FAILED;
386 return KM_ERROR_OK;
387}
388
389int RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
390 *error = KM_ERROR_OK;
391 switch (padding_) {
Shawn Willden30160842015-06-01 08:31:00 -0600392 case KM_PAD_NONE:
393 return RSA_NO_PADDING;
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600394 case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
395 return RSA_PKCS1_PADDING;
396 case KM_PAD_RSA_OAEP:
397 return RSA_PKCS1_OAEP_PADDING;
398 default:
399 return -1;
400 }
401}
402
403struct EVP_PKEY_CTX_Delete {
404 void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
405};
Shawn Willden4200f212014-12-02 07:01:21 -0700406
Shawn Willden6bfbff02015-02-06 19:48:24 -0700407keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600408 const Buffer& /* signature */,
409 AuthorizationSet* /* output_params */,
410 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700411 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700412
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600413 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
414 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
415 if (!ctx.get())
416 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700417
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600418 if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
419 return TranslateLastOpenSslError();
Shawn Willden4200f212014-12-02 07:01:21 -0700420
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600421 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
422 if (error != KM_ERROR_OK)
423 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700424
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600425 size_t outlen;
426 if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
427 data_.available_read()) <= 0)
428 return TranslateLastOpenSslError();
429
430 if (!output->Reinitialize(outlen))
431 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
432
433 if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
434 data_.available_read()) <= 0)
435 return TranslateLastOpenSslError();
436 output->advance_write(outlen);
Shawn Willden4200f212014-12-02 07:01:21 -0700437
438 return KM_ERROR_OK;
439}
440
Shawn Willden6bfbff02015-02-06 19:48:24 -0700441keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
Shawn Willdended8e7d2015-06-01 15:29:12 -0600442 const Buffer& /* signature */,
443 AuthorizationSet* /* output_params */,
444 Buffer* output) {
Shawn Willdenb7361132014-12-08 08:15:14 -0700445 assert(output);
Shawn Willden4200f212014-12-02 07:01:21 -0700446
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600447 UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
448 EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
449 if (!ctx.get())
450 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
Shawn Willden4200f212014-12-02 07:01:21 -0700451
Shawn Willden2bf4ad32015-06-01 07:33:51 -0600452 if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
453 return TranslateLastOpenSslError();
454
455 keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
456 if (error != KM_ERROR_OK)
457 return error;
458
459 size_t outlen;
460 if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
461 data_.available_read()) <= 0)
462 return TranslateLastOpenSslError();
463
464 if (!output->Reinitialize(outlen))
465 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
466
467 if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
468 data_.available_read()) <= 0)
469 return TranslateLastOpenSslError();
470 output->advance_write(outlen);
Shawn Willden4200f212014-12-02 07:01:21 -0700471
472 return KM_ERROR_OK;
473}
474
Shawn Willden0a4df7e2014-08-28 16:09:05 -0600475} // namespace keymaster