rsa_operation.cpp revision ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2
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
214200f211057551c02e909fe88e5a92dae7a36597Shawn Willden#include <openssl/err.h>
220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
23567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden#include <keymaster/logger.h>
24567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden
25567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden#include "openssl_err.h"
260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "openssl_utils.h"
2763ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden#include "rsa_key.h"
280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdennamespace keymaster {
300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
31f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenstatic const int MIN_PSS_SALT_LEN = 8 /* salt len */ + 2 /* overhead */;
32f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden
3363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden/* static */
342bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn WilldenEVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
3563ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
3663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    assert(rsa_key);
3763ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    if (!rsa_key || !rsa_key->key()) {
3863ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden        *error = KM_ERROR_UNKNOWN_ERROR;
392bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
4063ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    }
412bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
422bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
432bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!rsa_key->InternalToEvp(pkey.get())) {
442bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        *error = KM_ERROR_UNKNOWN_ERROR;
452bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
462bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    }
472bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return pkey.release();
4863ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden}
4963ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
502bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenstatic const keymaster_digest_t supported_digests[] = {
512bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    KM_DIGEST_NONE,      KM_DIGEST_MD5,       KM_DIGEST_SHA1,     KM_DIGEST_SHA_2_224,
522bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
53f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenstatic const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
54f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden                                                            KM_PAD_RSA_PSS};
5563ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
560629810b145187575bc26c910dded0d24c64569dShawn Willdenconst keymaster_digest_t*
570629810b145187575bc26c910dded0d24c64569dShawn WilldenRsaDigestingOperationFactory::SupportedDigests(size_t* digest_count) const {
580629810b145187575bc26c910dded0d24c64569dShawn Willden    *digest_count = array_length(supported_digests);
590629810b145187575bc26c910dded0d24c64569dShawn Willden    return supported_digests;
600629810b145187575bc26c910dded0d24c64569dShawn Willden}
6163ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
620629810b145187575bc26c910dded0d24c64569dShawn Willdenconst keymaster_padding_t*
630629810b145187575bc26c910dded0d24c64569dShawn WilldenRsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
640629810b145187575bc26c910dded0d24c64569dShawn Willden    *padding_mode_count = array_length(supported_sig_padding);
650629810b145187575bc26c910dded0d24c64569dShawn Willden    return supported_sig_padding;
660629810b145187575bc26c910dded0d24c64569dShawn Willden}
6763ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
683ed6d06a378c29deacb1fb9cc33b599b309c3a52Shawn WilldenOperation* RsaDigestingOperationFactory::CreateOperation(const Key& key,
69226746bfb5f79857145d5f3ebdfd6f49b6c114acShawn Willden                                                         const AuthorizationSet& begin_params,
703ed6d06a378c29deacb1fb9cc33b599b309c3a52Shawn Willden                                                         keymaster_error_t* error) {
7163ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    keymaster_padding_t padding;
7263ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    keymaster_digest_t digest;
73226746bfb5f79857145d5f3ebdfd6f49b6c114acShawn Willden    if (!GetAndValidateDigest(begin_params, key, &digest, error) ||
742bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        !GetAndValidatePadding(begin_params, key, &padding, error))
752bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
7663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
772bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
782bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!rsa.get())
792bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
802bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
812bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    Operation* op = InstantiateOperation(digest, padding, rsa.release());
8263ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    if (!op)
8363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
8463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    return op;
8563ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden}
8663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
8730160842424ee43690247a0ec4e2858d2bb5d694Shawn Willdenstatic const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
8863ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden                                                              KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
8963ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
903ed6d06a378c29deacb1fb9cc33b599b309c3a52Shawn WilldenOperation* RsaCryptingOperationFactory::CreateOperation(const Key& key,
913ad5f05e1ae2ca4beb1d0b2104c742de869841bcShawn Willden                                                        const AuthorizationSet& begin_params,
923ed6d06a378c29deacb1fb9cc33b599b309c3a52Shawn Willden                                                        keymaster_error_t* error) {
9363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    keymaster_padding_t padding;
942bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!GetAndValidatePadding(begin_params, key, &padding, error))
952bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
962bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
972bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
982bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!rsa.get())
992bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return nullptr;
10063ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
1012bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    Operation* op = InstantiateOperation(padding, rsa.release());
10263ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    if (!op)
10363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
10463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden    return op;
10563ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden}
10663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
1070629810b145187575bc26c910dded0d24c64569dShawn Willdenconst keymaster_padding_t*
1080629810b145187575bc26c910dded0d24c64569dShawn WilldenRsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
1090629810b145187575bc26c910dded0d24c64569dShawn Willden    *padding_mode_count = array_length(supported_crypt_padding);
1100629810b145187575bc26c910dded0d24c64569dShawn Willden    return supported_crypt_padding;
1110629810b145187575bc26c910dded0d24c64569dShawn Willden}
11263ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
1130629810b145187575bc26c910dded0d24c64569dShawn Willdenconst keymaster_digest_t*
1140629810b145187575bc26c910dded0d24c64569dShawn WilldenRsaCryptingOperationFactory::SupportedDigests(size_t* digest_count) const {
1150629810b145187575bc26c910dded0d24c64569dShawn Willden    *digest_count = 0;
1160629810b145187575bc26c910dded0d24c64569dShawn Willden    return NULL;
1170629810b145187575bc26c910dded0d24c64569dShawn Willden}
11863ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden
1190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenRsaOperation::~RsaOperation() {
1200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    if (rsa_key_ != NULL)
1212bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        EVP_PKEY_free(rsa_key_);
1220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
1230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
1246bfbff0020bb964a736e30d717b338e3e3973a36Shawn Willdenkeymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
125ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                       const Buffer& input, AuthorizationSet* /* output_params */,
126ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                       Buffer* /* output */, size_t* input_consumed) {
127b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    assert(input_consumed);
1280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    switch (purpose()) {
1290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    default:
1300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden        return KM_ERROR_UNIMPLEMENTED;
1310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    case KM_PURPOSE_SIGN:
1320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    case KM_PURPOSE_VERIFY:
1334200f211057551c02e909fe88e5a92dae7a36597Shawn Willden    case KM_PURPOSE_ENCRYPT:
1344200f211057551c02e909fe88e5a92dae7a36597Shawn Willden    case KM_PURPOSE_DECRYPT:
135b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden        return StoreData(input, input_consumed);
1360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    }
1370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
1380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
139b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willdenkeymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
140b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    assert(input_consumed);
1410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    if (!data_.reserve(data_.available_read() + input.available_read()) ||
1420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden        !data_.write(input.peek_read(), input.available_read()))
1430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
144b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    *input_consumed = input.available_read();
1450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    return KM_ERROR_OK;
1460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
1470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
1482bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx) {
1492bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    keymaster_error_t error;
1502bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    int openssl_padding = GetOpensslPadding(&error);
1512bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
1522bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
1532bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
1542bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, openssl_padding) <= 0)
1552bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
1562bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return KM_ERROR_OK;
1572bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden}
1582bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
15961902366cc912daacb84dd84c9bada95718e19b7Shawn WilldenRsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
1602bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                                             keymaster_padding_t padding, EVP_PKEY* key)
16161902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) {
16261902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    EVP_MD_CTX_init(&digest_ctx_);
16361902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
16461902366cc912daacb84dd84c9bada95718e19b7Shawn WilldenRsaDigestingOperation::~RsaDigestingOperation() {
16561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    EVP_MD_CTX_cleanup(&digest_ctx_);
166f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden}
16761902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
168f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenkeymaster_error_t RsaDigestingOperation::InitDigest() {
1692bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE) {
1702bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        if (require_digest())
1712bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            return KM_ERROR_INCOMPATIBLE_DIGEST;
1722bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
1732bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    }
1742bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
17561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    switch (digest_) {
176f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    case KM_DIGEST_NONE:
177f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return KM_ERROR_OK;
1782bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_MD5:
1792bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_md5();
1802bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
1812bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_SHA1:
1822bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_sha1();
1832bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
1842bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_SHA_2_224:
1852bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_sha224();
1862bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
18761902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    case KM_DIGEST_SHA_2_256:
18861902366cc912daacb84dd84c9bada95718e19b7Shawn Willden        digest_algorithm_ = EVP_sha256();
1892bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
1902bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_SHA_2_384:
1912bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_sha384();
1922bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
1932bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_DIGEST_SHA_2_512:
1942bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        digest_algorithm_ = EVP_sha512();
1952bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
19661902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    default:
19761902366cc912daacb84dd84c9bada95718e19b7Shawn Willden        return KM_ERROR_UNSUPPORTED_DIGEST;
19861902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    }
1992bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden}
20061902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
2012bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenconst size_t PSS_OVERHEAD = 2;
2022bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenconst size_t MIN_SALT_SIZE = 8;
2032bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
2042bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenint RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) {
2052bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    *error = KM_ERROR_OK;
2062bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    switch (padding_) {
2072bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_NONE:
2082bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_NO_PADDING;
2092bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_RSA_PKCS1_1_5_SIGN:
2102bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
2112bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_PKCS1_PADDING;
2122bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_RSA_PSS:
2132bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        if (digest_ == KM_DIGEST_NONE) {
2142bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
2152bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            return -1;
2162bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        }
2172bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        if (EVP_MD_size(digest_algorithm_) + PSS_OVERHEAD + MIN_SALT_SIZE >
2182bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            (size_t)EVP_PKEY_size(rsa_key_)) {
2192bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            *error = KM_ERROR_INCOMPATIBLE_DIGEST;
2202bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden            return -1;
2212bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        }
2222bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_PKCS1_PSS_PADDING;
2232bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    default:
2242bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return -1;
22561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden    }
22661902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
22761902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
2282bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaSignOperation::Begin(const AuthorizationSet& /* input_params */,
2292bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                                          AuthorizationSet* /* output_params */) {
2302bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    keymaster_error_t error = InitDigest();
2312bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
2322bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
2332bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
2342bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE)
2352bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
2362bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
2372bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    EVP_PKEY_CTX* pkey_ctx;
2382bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
2392bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                           rsa_key_) != 1)
2402bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
2412bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return SetRsaPaddingInEvpContext(pkey_ctx);
24261902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
24361902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
2442bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaSignOperation::Update(const AuthorizationSet& additional_params,
245ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                           const Buffer& input, AuthorizationSet* output_params,
246ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                           Buffer* output, size_t* input_consumed) {
2472bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE)
2482bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        // Just buffer the data.
249ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden        return RsaOperation::Update(additional_params, input, output_params, output,
250ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                    input_consumed);
2512bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
2522bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
2532bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
2542bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    *input_consumed = input.available_read();
255f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    return KM_ERROR_OK;
25661902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
25761902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
2586bfbff0020bb964a736e30d717b338e3e3973a36Shawn Willdenkeymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& /* additional_params */,
259ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                           const Buffer& /* signature */,
260ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                           AuthorizationSet* /* output_params */, Buffer* output) {
261b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    assert(output);
2622bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
263f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    if (digest_ == KM_DIGEST_NONE)
264f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return SignUndigested(output);
265f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    else
266f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return SignDigested(output);
267f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden}
26861902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
269f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenkeymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
2702bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
2712bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!rsa.get())
2722bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
2732bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
2742bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!output->Reinitialize(RSA_size(rsa.get())))
2752bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
2762bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
277f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    int bytes_encrypted;
278f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    switch (padding_) {
279f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    case KM_PAD_NONE:
280f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
2812bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                                              output->peek_write(), rsa.get(), RSA_NO_PADDING);
282f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        break;
283f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    case KM_PAD_RSA_PKCS1_1_5_SIGN:
2842bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        // Does PKCS1 padding without digesting even make sense?  Dunno.  We'll support it.
285f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
2862bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                                              output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
287f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        break;
288f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    default:
289f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return KM_ERROR_UNSUPPORTED_PADDING_MODE;
290f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    }
29161902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
292f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    if (bytes_encrypted <= 0)
2930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden        return KM_ERROR_UNKNOWN_ERROR;
2940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    output->advance_write(bytes_encrypted);
2950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden    return KM_ERROR_OK;
2960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
2970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
298f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenkeymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
2992bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    size_t siglen;
3002bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
3012bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
302f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden
3032bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!output->Reinitialize(siglen))
3042bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
305f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden
3062bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
3072bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
3082bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    output->advance_write(siglen);
3092bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
3102bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return KM_ERROR_OK;
31161902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
31261902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
3132bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
3142bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                                            AuthorizationSet* /* output_params */) {
3152bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    keymaster_error_t error = InitDigest();
3162bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
3172bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
318f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden
3192bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE)
3202bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_OK;
3212bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
3222bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    EVP_PKEY_CTX* pkey_ctx;
3232bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
3242bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
3252bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return SetRsaPaddingInEvpContext(pkey_ctx);
326f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden}
327f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden
3282bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
329ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                             const Buffer& input, AuthorizationSet* output_params,
330ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                             Buffer* output, size_t* input_consumed) {
3312bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (digest_ == KM_DIGEST_NONE)
3322bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        // Just buffer the data.
333ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden        return RsaOperation::Update(additional_params, input, output_params, output,
334ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                    input_consumed);
3352bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
3362bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
3372bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
3382bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    *input_consumed = input.available_read();
339f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    return KM_ERROR_OK;
34061902366cc912daacb84dd84c9bada95718e19b7Shawn Willden}
34161902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
3426bfbff0020bb964a736e30d717b338e3e3973a36Shawn Willdenkeymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& /* additional_params */,
343ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                             const Buffer& signature,
344ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                             AuthorizationSet* /* output_params */,
345ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                             Buffer* /* output */) {
346f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    if (digest_ == KM_DIGEST_NONE)
347f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return VerifyUndigested(signature);
348f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    else
349f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return VerifyDigested(signature);
350f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden}
35161902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
352f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenkeymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
3532bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
3542bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!rsa.get())
3552bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_UNKNOWN_ERROR;
3560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
3572bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    size_t key_len = RSA_size(rsa.get());
358f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    int openssl_padding;
359f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    switch (padding_) {
360f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    case KM_PAD_NONE:
3612bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        if (data_.available_read() != key_len)
362f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden            return KM_ERROR_INVALID_INPUT_LENGTH;
3632bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        if (data_.available_read() != signature.available_read())
364f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden            return KM_ERROR_VERIFICATION_FAILED;
365f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        openssl_padding = RSA_NO_PADDING;
366f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        break;
367f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    case KM_PAD_RSA_PKCS1_1_5_SIGN:
368f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        openssl_padding = RSA_PKCS1_PADDING;
369f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        break;
370f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    default:
371f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return KM_ERROR_UNSUPPORTED_PADDING_MODE;
372f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    }
37361902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
374f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    UniquePtr<uint8_t[]> decrypted_data(new uint8_t[key_len]);
375f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
3762bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                                             decrypted_data.get(), rsa.get(), openssl_padding);
377f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden    if (bytes_decrypted < 0)
378f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden        return KM_ERROR_VERIFICATION_FAILED;
3790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
3802bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (memcmp_s(decrypted_data.get(), data_.peek_read(), data_.available_read()) != 0)
3812bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_VERIFICATION_FAILED;
3822bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return KM_ERROR_OK;
3832bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden}
3842bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
3852bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
3862bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
3872bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_VERIFICATION_FAILED;
3882bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    return KM_ERROR_OK;
3892bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden}
39061902366cc912daacb84dd84c9bada95718e19b7Shawn Willden
3912bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenint RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
3922bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    *error = KM_ERROR_OK;
3932bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    switch (padding_) {
39430160842424ee43690247a0ec4e2858d2bb5d694Shawn Willden    case KM_PAD_NONE:
39530160842424ee43690247a0ec4e2858d2bb5d694Shawn Willden        return RSA_NO_PADDING;
3962bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
3972bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_PKCS1_PADDING;
3982bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    case KM_PAD_RSA_OAEP:
3992bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return RSA_PKCS1_OAEP_PADDING;
4002bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    default:
4012bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return -1;
4022bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    }
4030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}
4040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden
4052bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenstruct EVP_PKEY_CTX_Delete {
4062bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
4072bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden};
4084200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4096bfbff0020bb964a736e30d717b338e3e3973a36Shawn Willdenkeymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& /* additional_params */,
410ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              const Buffer& /* signature */,
411ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              AuthorizationSet* /* output_params */,
412ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              Buffer* output) {
413b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    assert(output);
4144200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4152bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
4162bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
4172bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!ctx.get())
4182bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
4194200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4202bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
4212bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
4224200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4232bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
4242bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
4252bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
4264200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4272bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    size_t outlen;
4282bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
4292bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                         data_.available_read()) <= 0)
4302bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
4312bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
4322bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!output->Reinitialize(outlen))
4332bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
4342bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
4352bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
4362bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                         data_.available_read()) <= 0)
4372bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
4382bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    output->advance_write(outlen);
4394200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4404200f211057551c02e909fe88e5a92dae7a36597Shawn Willden    return KM_ERROR_OK;
4414200f211057551c02e909fe88e5a92dae7a36597Shawn Willden}
4424200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4436bfbff0020bb964a736e30d717b338e3e3973a36Shawn Willdenkeymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& /* additional_params */,
444ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              const Buffer& /* signature */,
445ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              AuthorizationSet* /* output_params */,
446ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden                                              Buffer* output) {
447b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden    assert(output);
4484200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4492bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
4502bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
4512bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!ctx.get())
4522bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
4534200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4542bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
4552bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
4562bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
4572bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    keymaster_error_t error = SetRsaPaddingInEvpContext(ctx.get());
4582bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (error != KM_ERROR_OK)
4592bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return error;
4602bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
4612bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    size_t outlen;
4622bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
4632bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                         data_.available_read()) <= 0)
4642bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
4652bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
4662bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (!output->Reinitialize(outlen))
4672bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
4682bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden
4692bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, data_.peek_read(),
4702bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden                         data_.available_read()) <= 0)
4712bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden        return TranslateLastOpenSslError();
4722bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden    output->advance_write(outlen);
4734200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4744200f211057551c02e909fe88e5a92dae7a36597Shawn Willden    return KM_ERROR_OK;
4754200f211057551c02e909fe88e5a92dae7a36597Shawn Willden}
4764200f211057551c02e909fe88e5a92dae7a36597Shawn Willden
4770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}  // namespace keymaster
478