10a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/*
20a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * Copyright 2014 The Android Open Source Project
30a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *
40a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * Licensed under the Apache License, Version 2.0 (the "License");
50a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * you may not use this file except in compliance with the License.
60a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * You may obtain a copy of the License at
70a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *
80a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *      http://www.apache.org/licenses/LICENSE-2.0
90a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *
100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * Unless required by applicable law or agreed to in writing, software
110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * distributed under the License is distributed on an "AS IS" BASIS,
120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * See the License for the specific language governing permissions and
140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * limitations under the License.
150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden */
160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
1763ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden#include "rsa_operation.h"
1863ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
194200f211057551c02e909fe88e5a92dae7a36597Shawn Willden#include <limits.h>
204200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
21f38a002624126ca837865826f948edc9100d6e8aJanis Danisevskis#include <keymaster/new>
220f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden
234200f211057551c02e909fe88e5a92dae7a36597Shawn Willden#include <openssl/err.h>
240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
25567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden#include <keymaster/logger.h>
26567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden
27567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden#include "openssl_err.h"
280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "openssl_utils.h"
2963ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden#include "rsa_key.h"
300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdennamespace keymaster {
320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
33d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willdenconst size_t kPssOverhead = 2;
34d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden
35d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden// Overhead for PKCS#1 v1.5 signature padding of undigested messages.  Digested messages have
36d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden// additional overhead, for the digest algorithmIdentifier required by PKCS#1.
37d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willdenconst size_t kPkcs1UndigestedSignaturePaddingOverhead = 11;
38d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden
3963ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden/* static */
402bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn WilldenEVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
4163ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
4263ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    assert(rsa_key);
4363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    if (!rsa_key || !rsa_key->key()) {
4463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden        *error = KM_ERROR_UNKNOWN_ERROR;
452bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
4663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    }
472bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
482bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
492bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!rsa_key->InternalToEvp(pkey.get())) {
502bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        *error = KM_ERROR_UNKNOWN_ERROR;
512bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
522bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    }
532bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return pkey.release();
5463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden}
5563ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
562bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenstatic const keymaster_digest_t supported_digests[] = {
572bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    KM_DIGEST_NONE,      KM_DIGEST_MD5,       KM_DIGEST_SHA1,     KM_DIGEST_SHA_2_224,
582bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
5963ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
600afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willdenconst keymaster_digest_t* RsaOperationFactory::SupportedDigests(size_t* digest_count) const {
610629810b145187575bc26c910dded0d24c64569dShawn Willden    *digest_count = array_length(supported_digests);
620629810b145187575bc26c910dded0d24c64569dShawn Willden    return supported_digests;
630629810b145187575bc26c910dded0d24c64569dShawn Willden}
6463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
650afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn WilldenRsaOperation* RsaOperationFactory::CreateRsaOperation(const Key& key,
660afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                                                      const AuthorizationSet& begin_params,
670afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                                                      keymaster_error_t* error) {
6863ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    keymaster_padding_t padding;
690afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    if (!GetAndValidatePadding(begin_params, key, &padding, error))
702bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
712bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
720afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    bool require_digest = (purpose() == KM_PURPOSE_SIGN || purpose() == KM_PURPOSE_VERIFY ||
730afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                           padding == KM_PAD_RSA_OAEP);
7463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
757d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    keymaster_digest_t digest = KM_DIGEST_NONE;
760afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    if (require_digest && !GetAndValidateDigest(begin_params, key, &digest, error))
770afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden        return nullptr;
782bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
792bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
802bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!rsa.get())
812bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
8263ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
830afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    RsaOperation* op = InstantiateOperation(digest, padding, rsa.release());
8463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    if (!op)
8563ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
8663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    return op;
8763ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden}
8863ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
890afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willdenstatic const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
900afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                                                            KM_PAD_RSA_PSS};
910afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willdenconst keymaster_padding_t*
920afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn WilldenRsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
930afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    *padding_mode_count = array_length(supported_sig_padding);
940afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    return supported_sig_padding;
950afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden}
960afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden
970afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn WilldenRsaOperation* RsaCryptingOperationFactory::CreateRsaOperation(const Key& key,
980afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                                                              const AuthorizationSet& begin_params,
990afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                                                              keymaster_error_t* error) {
1000afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    UniquePtr<RsaOperation> op(RsaOperationFactory::CreateRsaOperation(key, begin_params, error));
1010afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    if (op.get()) {
1020afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden        switch (op->padding()) {
1030afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden        case KM_PAD_NONE:
1040afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden        case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
1050afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden            if (op->digest() != KM_DIGEST_NONE) {
1060afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                *error = KM_ERROR_INCOMPATIBLE_DIGEST;
1070afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                return nullptr;
1080afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden            }
1090afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden            break;
1100afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden
1110afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden        case KM_PAD_RSA_OAEP:
1120afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden            if (op->digest() == KM_DIGEST_NONE) {
1130afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                *error = KM_ERROR_INCOMPATIBLE_DIGEST;
1140afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                return nullptr;
1150afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden            }
1160afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden            break;
1170afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden
1180afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden        default:
1190afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden            *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
1200afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden            return nullptr;
1210afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden        }
1220afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    }
1230afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    return op.release();
1240afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden}
1250afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden
1260afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willdenstatic const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
1270afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                                                              KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
1280629810b145187575bc26c910dded0d24c64569dShawn Willdenconst keymaster_padding_t*
1290629810b145187575bc26c910dded0d24c64569dShawn WilldenRsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
1300629810b145187575bc26c910dded0d24c64569dShawn Willden    *padding_mode_count = array_length(supported_crypt_padding);
1310629810b145187575bc26c910dded0d24c64569dShawn Willden    return supported_crypt_padding;
1320629810b145187575bc26c910dded0d24c64569dShawn Willden}
13363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
1340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenRsaOperation::~RsaOperation() {
1350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    if (rsa_key_ != NULL)
1362bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        EVP_PKEY_free(rsa_key_);
1370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
1380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
1397d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willdenkeymaster_error_t RsaOperation::Begin(const AuthorizationSet& /* input_params */,
1407d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden                                      AuthorizationSet* /* output_params */) {
1417d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    return InitDigest();
1427d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden}
1437d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden
1446bfbff0020bb964a736e30d717b338e3e3973a36Shawn Willdenkeymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
145ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                       const Buffer& input, AuthorizationSet* /* output_params */,
146ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                       Buffer* /* output */, size_t* input_consumed) {
147b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    assert(input_consumed);
1480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    switch (purpose()) {
1490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    default:
1500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden        return KM_ERROR_UNIMPLEMENTED;
1510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    case KM_PURPOSE_SIGN:
1520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    case KM_PURPOSE_VERIFY:
1534200f211057551c02e909fe88e5a92dae7a36597Shawn Willden    case KM_PURPOSE_ENCRYPT:
1544200f211057551c02e909fe88e5a92dae7a36597Shawn Willden    case KM_PURPOSE_DECRYPT:
155b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden        return StoreData(input, input_consumed);
1560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    }
1570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
1580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
159b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willdenkeymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
160b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    assert(input_consumed);
161d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden
162d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden    if (!data_.reserve(EVP_PKEY_size(rsa_key_)))
1630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
164d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden    // If the write fails, it's because input length exceeds key size.
165d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden    if (!data_.write(input.peek_read(), input.available_read())) {
1662101e9e8215cce6da36d8d7382486737b68e8c93Shawn Willden        LOG_E("Input too long: cannot operate on %u bytes of data with %u-byte RSA key",
1672101e9e8215cce6da36d8d7382486737b68e8c93Shawn Willden              input.available_read() + data_.available_read(), EVP_PKEY_size(rsa_key_));
168d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden        return KM_ERROR_INVALID_INPUT_LENGTH;
169d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden    }
170d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden
171b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    *input_consumed = input.available_read();
1720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    return KM_ERROR_OK;
1730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
1740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
175b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willdenkeymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx, bool signing) {
1762bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    keymaster_error_t error;
1772bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    int openssl_padding = GetOpensslPadding(&error);
1782bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
1792bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
1802bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
1812bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, openssl_padding) <= 0)
1822bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
183b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden
184b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden    if (signing && openssl_padding == RSA_PKCS1_PSS_PADDING) {
185b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden        // Also need to set the length of the salt used in the padding generation.  We set it equal
186b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden        // to the length of the selected digest.
187b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden        assert(digest_algorithm_);
188b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden        if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(digest_algorithm_)) <= 0)
189b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden            return TranslateLastOpenSslError();
190b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden    }
191b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden
1922bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return KM_ERROR_OK;
1932bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden}
1942bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
1950afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willdenkeymaster_error_t RsaOperation::InitDigest() {
1962bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE) {
1972bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        if (require_digest())
1982bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            return KM_ERROR_INCOMPATIBLE_DIGEST;
1992bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
2002bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    }
2012bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
20261902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    switch (digest_) {
203f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    case KM_DIGEST_NONE:
204f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return KM_ERROR_OK;
2052bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_MD5:
2062bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_md5();
2072bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
2082bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_SHA1:
2092bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_sha1();
2102bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
2112bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_SHA_2_224:
2122bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_sha224();
2132bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
21461902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    case KM_DIGEST_SHA_2_256:
21561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden        digest_algorithm_ = EVP_sha256();
2162bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
2172bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_SHA_2_384:
2182bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_sha384();
2192bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
2202bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_SHA_2_512:
2212bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_sha512();
2222bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
22361902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    default:
22461902366cc912daacb84dd84c9bada95718e19b7Shawn Willden        return KM_ERROR_UNSUPPORTED_DIGEST;
22561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    }
2262bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden}
22761902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
2280afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn WilldenRsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
2290afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden                                             keymaster_padding_t padding, EVP_PKEY* key)
2300afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    : RsaOperation(purpose, digest, padding, key) {
2310afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    EVP_MD_CTX_init(&digest_ctx_);
2320afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden}
2330afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn WilldenRsaDigestingOperation::~RsaDigestingOperation() {
2340afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden    EVP_MD_CTX_cleanup(&digest_ctx_);
2350afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden}
2360afa3c8a03fc817279bdf0f46abe3dc7a3fd53e1Shawn Willden
2372bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenint RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) {
2382bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    *error = KM_ERROR_OK;
2392bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    switch (padding_) {
2402bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_NONE:
2412bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_NO_PADDING;
2422bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_RSA_PKCS1_1_5_SIGN:
2432bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_PKCS1_PADDING;
2442bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_RSA_PSS:
2452bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        if (digest_ == KM_DIGEST_NONE) {
2462bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
2472bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            return -1;
2482bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        }
249b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden        if (EVP_MD_size(digest_algorithm_) * 2 + kPssOverhead > (size_t)EVP_PKEY_size(rsa_key_)) {
250d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden            LOG_E("Input too long: %d-byte digest cannot be used with %d-byte RSA key in PSS "
251d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden                  "padding mode",
252bfd9ed7f5c50cdfa310cb0f21c7706e99b780738Shawn Willden                  EVP_MD_size(digest_algorithm_), EVP_PKEY_size(rsa_key_));
2532bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            *error = KM_ERROR_INCOMPATIBLE_DIGEST;
2542bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            return -1;
2552bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        }
2562bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_PKCS1_PSS_PADDING;
2572bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    default:
2582bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return -1;
25961902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    }
26061902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
26161902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
2627d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willdenkeymaster_error_t RsaSignOperation::Begin(const AuthorizationSet& input_params,
2637d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden                                          AuthorizationSet* output_params) {
2647d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    keymaster_error_t error = RsaDigestingOperation::Begin(input_params, output_params);
2652bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
2662bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
2672bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
2682bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE)
2692bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
2702bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
2712bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    EVP_PKEY_CTX* pkey_ctx;
2722bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
2732bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                           rsa_key_) != 1)
2742bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
275b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden    return SetRsaPaddingInEvpContext(pkey_ctx, true /* signing */);
27661902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
27761902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
2782bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaSignOperation::Update(const AuthorizationSet& additional_params,
279ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                           const Buffer& input, AuthorizationSet* output_params,
280ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                           Buffer* output, size_t* input_consumed) {
2812bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE)
2822bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        // Just buffer the data.
283ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden        return RsaOperation::Update(additional_params, input, output_params, output,
284ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                    input_consumed);
2852bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
2862bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
2872bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
2882bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    *input_consumed = input.available_read();
289f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    return KM_ERROR_OK;
29061902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
29161902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
292cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willdenkeymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& additional_params,
293cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden                                           const Buffer& input, const Buffer& /* signature */,
294ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                           AuthorizationSet* /* output_params */, Buffer* output) {
295b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    assert(output);
2962bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
297cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    keymaster_error_t error = UpdateForFinish(additional_params, input);
298cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    if (error != KM_ERROR_OK)
299cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden        return error;
300cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden
301f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    if (digest_ == KM_DIGEST_NONE)
302f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return SignUndigested(output);
303f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    else
304f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return SignDigested(output);
305f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden}
30661902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
307c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willdenstatic keymaster_error_t zero_pad_left(UniquePtr<uint8_t[]>* dest, size_t padded_len, Buffer& src) {
308c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    assert(padded_len > src.available_read());
309c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden
310f38a002624126ca837865826f948edc9100d6e8aJanis Danisevskis    dest->reset(new(std::nothrow) uint8_t[padded_len]);
311c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    if (!dest->get())
312c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
313c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden
314c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    size_t padding_len = padded_len - src.available_read();
315c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    memset(dest->get(), 0, padding_len);
316c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    if (!src.read(dest->get() + padding_len, src.available_read()))
317c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        return KM_ERROR_UNKNOWN_ERROR;
318c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden
319c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    return KM_ERROR_OK;
320c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden}
321c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden
322f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenkeymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
3232bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
3242bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!rsa.get())
3252bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
3262bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
3272bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!output->Reinitialize(RSA_size(rsa.get())))
3282bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
3292bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
330c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    size_t key_len = EVP_PKEY_size(rsa_key_);
331f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    int bytes_encrypted;
332f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    switch (padding_) {
333c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    case KM_PAD_NONE: {
334c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        const uint8_t* to_encrypt = data_.peek_read();
335c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        UniquePtr<uint8_t[]> zero_padded;
336c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        if (data_.available_read() > key_len) {
337c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden            return KM_ERROR_INVALID_INPUT_LENGTH;
338c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        } else if (data_.available_read() < key_len) {
339c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden            keymaster_error_t error = zero_pad_left(&zero_padded, key_len, data_);
340c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden            if (error != KM_ERROR_OK)
341c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden                return error;
342c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden            to_encrypt = zero_padded.get();
343c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        }
344c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        bytes_encrypted = RSA_private_encrypt(key_len, to_encrypt, output->peek_write(), rsa.get(),
345c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden                                              RSA_NO_PADDING);
346f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        break;
347c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    }
348f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    case KM_PAD_RSA_PKCS1_1_5_SIGN:
3492bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        // Does PKCS1 padding without digesting even make sense?  Dunno.  We'll support it.
350c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead > key_len) {
351d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden            LOG_E("Input too long: cannot sign %u-byte message with PKCS1 padding with %u-bit key",
352d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden                  data_.available_read(), EVP_PKEY_size(rsa_key_) * 8);
353d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden            return KM_ERROR_INVALID_INPUT_LENGTH;
354d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden        }
355f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
3562bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                                              output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
357f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        break;
358c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden
359f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    default:
360f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return KM_ERROR_UNSUPPORTED_PADDING_MODE;
361f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    }
36261902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
363f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    if (bytes_encrypted <= 0)
3640f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden        return TranslateLastOpenSslError();
3650f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden    if (!output->advance_write(bytes_encrypted))
3660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden        return KM_ERROR_UNKNOWN_ERROR;
3670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    return KM_ERROR_OK;
3680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
3690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
370f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenkeymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
3712bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    size_t siglen;
3722bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
3732bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
374f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden
3752bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!output->Reinitialize(siglen))
3762bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
377f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden
3782bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
3792bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
3800f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden    if (!output->advance_write(siglen))
3810f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden        return KM_ERROR_UNKNOWN_ERROR;
3822bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
3832bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return KM_ERROR_OK;
38461902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
38561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
3867d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willdenkeymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& input_params,
3877d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden                                            AuthorizationSet* output_params) {
3887d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    keymaster_error_t error = RsaDigestingOperation::Begin(input_params, output_params);
3892bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
3902bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
391f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden
3922bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE)
3932bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
3942bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
3952bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    EVP_PKEY_CTX* pkey_ctx;
3962bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
3972bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
398b6179f4bec118299e89ce1b6ef6480570880afd9Shawn Willden    return SetRsaPaddingInEvpContext(pkey_ctx, false /* signing */);
399f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden}
400f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden
4012bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
402ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                             const Buffer& input, AuthorizationSet* output_params,
403ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                             Buffer* output, size_t* input_consumed) {
4042bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE)
4052bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        // Just buffer the data.
406ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden        return RsaOperation::Update(additional_params, input, output_params, output,
407ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                    input_consumed);
4082bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
4092bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
4102bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
4112bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    *input_consumed = input.available_read();
412f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    return KM_ERROR_OK;
41361902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
41461902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
415cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willdenkeymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& additional_params,
416cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden                                             const Buffer& input, const Buffer& signature,
417ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                             AuthorizationSet* /* output_params */,
418ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                             Buffer* /* output */) {
419cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    keymaster_error_t error = UpdateForFinish(additional_params, input);
420cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    if (error != KM_ERROR_OK)
421cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden        return error;
422cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden
423f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    if (digest_ == KM_DIGEST_NONE)
424f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return VerifyUndigested(signature);
425f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    else
426f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return VerifyDigested(signature);
427f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden}
42861902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
429f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenkeymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
4302bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
4312bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!rsa.get())
4322bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_UNKNOWN_ERROR;
4330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
4342bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    size_t key_len = RSA_size(rsa.get());
435f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    int openssl_padding;
436f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    switch (padding_) {
437f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    case KM_PAD_NONE:
438c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        if (data_.available_read() > key_len)
439f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden            return KM_ERROR_INVALID_INPUT_LENGTH;
440c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        if (key_len != signature.available_read())
441f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden            return KM_ERROR_VERIFICATION_FAILED;
442f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        openssl_padding = RSA_NO_PADDING;
443f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        break;
444f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    case KM_PAD_RSA_PKCS1_1_5_SIGN:
445d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden        if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead > key_len) {
446d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden            LOG_E("Input too long: cannot verify %u-byte message with PKCS1 padding && %u-bit key",
447d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden                  data_.available_read(), key_len * 8);
448d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden            return KM_ERROR_INVALID_INPUT_LENGTH;
449d530305019e1ccc1e30a4f8edeb88db3d126e235Shawn Willden        }
450f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        openssl_padding = RSA_PKCS1_PADDING;
451f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        break;
452f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    default:
453f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return KM_ERROR_UNSUPPORTED_PADDING_MODE;
454f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    }
45561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
4560f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden    UniquePtr<uint8_t[]> decrypted_data(new (std::nothrow) uint8_t[key_len]);
4570f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden    if (!decrypted_data.get())
4580f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
459f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
4602bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                                             decrypted_data.get(), rsa.get(), openssl_padding);
461f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    if (bytes_decrypted < 0)
462f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return KM_ERROR_VERIFICATION_FAILED;
4630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
464c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    const uint8_t* compare_pos = decrypted_data.get();
465c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    size_t bytes_to_compare = bytes_decrypted;
466c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    uint8_t zero_check_result = 0;
467c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    if (padding_ == KM_PAD_NONE && data_.available_read() < bytes_to_compare) {
468c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        // If the data is short, for "unpadded" signing we zero-pad to the left.  So during
469c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        // verification we should have zeros on the left of the decrypted data.  Do a constant-time
470c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        // check.
471c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        const uint8_t* zero_end = compare_pos + bytes_to_compare - data_.available_read();
472c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        while (compare_pos < zero_end)
473c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden            zero_check_result |= *compare_pos++;
474c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        bytes_to_compare = data_.available_read();
475c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    }
476c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    if (memcmp_s(compare_pos, data_.peek_read(), bytes_to_compare) != 0 || zero_check_result != 0)
4772bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_VERIFICATION_FAILED;
4782bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return KM_ERROR_OK;
4792bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden}
4802bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
4812bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
4822bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
4832bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_VERIFICATION_FAILED;
4842bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return KM_ERROR_OK;
4852bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden}
48661902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
4877d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willdenkeymaster_error_t RsaCryptOperation::SetOaepDigestIfRequired(EVP_PKEY_CTX* pkey_ctx) {
4887d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    if (padding() != KM_PAD_RSA_OAEP)
4897d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden        return KM_ERROR_OK;
4907d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden
4917d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    assert(digest_algorithm_ != nullptr);
4927d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    if (!EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, digest_algorithm_))
4937d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden        return TranslateLastOpenSslError();
4947d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden
4957d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    // MGF1 MD is always SHA1.
4967d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha1()))
4977d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden        return TranslateLastOpenSslError();
4987d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden
4997d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    return KM_ERROR_OK;
5007d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden}
5017d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden
5022bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenint RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
5032bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    *error = KM_ERROR_OK;
5042bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    switch (padding_) {
50530160842424ee43690247a0ec4e2858d2bb5d694Shawn Willden    case KM_PAD_NONE:
50630160842424ee43690247a0ec4e2858d2bb5d694Shawn Willden        return RSA_NO_PADDING;
5072bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
5082bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_PKCS1_PADDING;
5092bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_RSA_OAEP:
5102bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_PKCS1_OAEP_PADDING;
5112bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    default:
5122bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return -1;
5132bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    }
5140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
5150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
5162bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenstruct EVP_PKEY_CTX_Delete {
5172bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
5182bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden};
5194200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
520cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willdenkeymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& additional_params,
521cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden                                              const Buffer& input, const Buffer& /* signature */,
522ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              AuthorizationSet* /* output_params */,
523ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              Buffer* output) {
524cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    if (!output)
525cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden        return KM_ERROR_OUTPUT_PARAMETER_NULL;
526cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden
527cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    keymaster_error_t error = UpdateForFinish(additional_params, input);
528cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    if (error != KM_ERROR_OK)
529cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden        return error;
5304200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
5312bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
5322bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
5332bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!ctx.get())
5342bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
5354200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
5362bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
5372bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
5384200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
5395c02b59507262a8ebd8092ee84c39a7fe94bdda2Shawn Willden    error = SetRsaPaddingInEvpContext(ctx.get(), false /* signing */);
5402bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
5412bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
5427d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    error = SetOaepDigestIfRequired(ctx.get());
5437d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    if (error != KM_ERROR_OK)
5447d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden        return error;
5454200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
5462bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    size_t outlen;
5472bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
5482bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                         data_.available_read()) <= 0)
5492bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
5502bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
5512bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!output->Reinitialize(outlen))
5522bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
5532bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
554c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    const uint8_t* to_encrypt = data_.peek_read();
555c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    size_t to_encrypt_len = data_.available_read();
556c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    UniquePtr<uint8_t[]> zero_padded;
557c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    if (padding_ == KM_PAD_NONE && to_encrypt_len < outlen) {
558c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        keymaster_error_t error = zero_pad_left(&zero_padded, outlen, data_);
559c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        if (error != KM_ERROR_OK)
560c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden            return error;
561c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        to_encrypt = zero_padded.get();
562c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        to_encrypt_len = outlen;
563c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    }
564c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden
565c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, to_encrypt, to_encrypt_len) <= 0)
5662bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
5670f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden    if (!output->advance_write(outlen))
5680f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden        return KM_ERROR_UNKNOWN_ERROR;
5694200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
5704200f211057551c02e909fe88e5a92dae7a36597Shawn Willden    return KM_ERROR_OK;
5714200f211057551c02e909fe88e5a92dae7a36597Shawn Willden}
5724200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
573cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willdenkeymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& additional_params,
574cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden                                              const Buffer& input, const Buffer& /* signature */,
575ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              AuthorizationSet* /* output_params */,
576ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              Buffer* output) {
577cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    if (!output)
578cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden        return KM_ERROR_OUTPUT_PARAMETER_NULL;
579cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden
580cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    keymaster_error_t error = UpdateForFinish(additional_params, input);
581cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden    if (error != KM_ERROR_OK)
582cb647fec03f71929fd316d2b8f0750f7b24824f3Shawn Willden        return error;
5834200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
5842bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
5852bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
5862bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!ctx.get())
5872bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
5884200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
5892bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
5902bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
5912bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
5925c02b59507262a8ebd8092ee84c39a7fe94bdda2Shawn Willden    error = SetRsaPaddingInEvpContext(ctx.get(), false /* signing */);
5932bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
5942bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
5957d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    error = SetOaepDigestIfRequired(ctx.get());
5967d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden    if (error != KM_ERROR_OK)
5977d05d88dc44b18e0350f7fe8d28c20f2f643bb80Shawn Willden        return error;
5982bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
5992bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    size_t outlen;
6002bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
6012bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                         data_.available_read()) <= 0)
6022bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
6032bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
6042bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!output->Reinitialize(outlen))
6052bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
6062bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
607c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    const uint8_t* to_decrypt = data_.peek_read();
608c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    size_t to_decrypt_len = data_.available_read();
609c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    UniquePtr<uint8_t[]> zero_padded;
610c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    if (padding_ == KM_PAD_NONE && to_decrypt_len < outlen) {
611c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        keymaster_error_t error = zero_pad_left(&zero_padded, outlen, data_);
612c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        if (error != KM_ERROR_OK)
613c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden            return error;
614c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        to_decrypt = zero_padded.get();
615c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden        to_decrypt_len = outlen;
616c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    }
617c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden
618c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden    if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, to_decrypt, to_decrypt_len) <= 0)
6192bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
6200f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden    if (!output->advance_write(outlen))
6210f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden        return KM_ERROR_UNKNOWN_ERROR;
6224200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
6234200f211057551c02e909fe88e5a92dae7a36597Shawn Willden    return KM_ERROR_OK;
6244200f211057551c02e909fe88e5a92dae7a36597Shawn Willden}
6254200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
6260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}  // namespace keymaster
627