rsa_operation.cpp revision bfd9ed7f5c50cdfa310cb0f21c7706e99b780738
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 3163ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden/* static */ 322bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn WilldenEVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) { 3363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden const RsaKey* rsa_key = static_cast<const RsaKey*>(&key); 3463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden assert(rsa_key); 3563ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden if (!rsa_key || !rsa_key->key()) { 3663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 372bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return nullptr; 3863ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden } 392bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden 402bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); 412bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (!rsa_key->InternalToEvp(pkey.get())) { 422bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 432bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return nullptr; 442bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden } 452bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return pkey.release(); 4663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden} 4763ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 482bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenstatic const keymaster_digest_t supported_digests[] = { 492bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224, 502bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512}; 51f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenstatic const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN, 52f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden KM_PAD_RSA_PSS}; 5363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 540629810b145187575bc26c910dded0d24c64569dShawn Willdenconst keymaster_digest_t* 550629810b145187575bc26c910dded0d24c64569dShawn WilldenRsaDigestingOperationFactory::SupportedDigests(size_t* digest_count) const { 560629810b145187575bc26c910dded0d24c64569dShawn Willden *digest_count = array_length(supported_digests); 570629810b145187575bc26c910dded0d24c64569dShawn Willden return supported_digests; 580629810b145187575bc26c910dded0d24c64569dShawn Willden} 5963ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 600629810b145187575bc26c910dded0d24c64569dShawn Willdenconst keymaster_padding_t* 610629810b145187575bc26c910dded0d24c64569dShawn WilldenRsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const { 620629810b145187575bc26c910dded0d24c64569dShawn Willden *padding_mode_count = array_length(supported_sig_padding); 630629810b145187575bc26c910dded0d24c64569dShawn Willden return supported_sig_padding; 640629810b145187575bc26c910dded0d24c64569dShawn Willden} 6563ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 663ed6d06a378c29deacb1fb9cc33b599b309c3a52Shawn WilldenOperation* RsaDigestingOperationFactory::CreateOperation(const Key& key, 67226746bfb5f79857145d5f3ebdfd6f49b6c114acShawn Willden const AuthorizationSet& begin_params, 683ed6d06a378c29deacb1fb9cc33b599b309c3a52Shawn Willden keymaster_error_t* error) { 6963ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden keymaster_padding_t padding; 7063ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden keymaster_digest_t digest; 71226746bfb5f79857145d5f3ebdfd6f49b6c114acShawn Willden if (!GetAndValidateDigest(begin_params, key, &digest, error) || 722bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden !GetAndValidatePadding(begin_params, key, &padding, error)) 732bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return nullptr; 7463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 752bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error)); 762bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (!rsa.get()) 772bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return nullptr; 782bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden 792bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden Operation* op = InstantiateOperation(digest, padding, rsa.release()); 8063ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden if (!op) 8163ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 8263ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden return op; 8363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden} 8463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 8530160842424ee43690247a0ec4e2858d2bb5d694Shawn Willdenstatic const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP, 8663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden KM_PAD_RSA_PKCS1_1_5_ENCRYPT}; 8763ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 883ed6d06a378c29deacb1fb9cc33b599b309c3a52Shawn WilldenOperation* RsaCryptingOperationFactory::CreateOperation(const Key& key, 893ad5f05e1ae2ca4beb1d0b2104c742de869841bcShawn Willden const AuthorizationSet& begin_params, 903ed6d06a378c29deacb1fb9cc33b599b309c3a52Shawn Willden keymaster_error_t* error) { 9163ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden keymaster_padding_t padding; 922bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (!GetAndValidatePadding(begin_params, key, &padding, error)) 932bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return nullptr; 942bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden 952bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error)); 962bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (!rsa.get()) 972bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return nullptr; 9863ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 992bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden Operation* op = InstantiateOperation(padding, rsa.release()); 10063ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden if (!op) 10163ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 10263ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden return op; 10363ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden} 10463ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 1050629810b145187575bc26c910dded0d24c64569dShawn Willdenconst keymaster_padding_t* 1060629810b145187575bc26c910dded0d24c64569dShawn WilldenRsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const { 1070629810b145187575bc26c910dded0d24c64569dShawn Willden *padding_mode_count = array_length(supported_crypt_padding); 1080629810b145187575bc26c910dded0d24c64569dShawn Willden return supported_crypt_padding; 1090629810b145187575bc26c910dded0d24c64569dShawn Willden} 11063ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 1110629810b145187575bc26c910dded0d24c64569dShawn Willdenconst keymaster_digest_t* 1120629810b145187575bc26c910dded0d24c64569dShawn WilldenRsaCryptingOperationFactory::SupportedDigests(size_t* digest_count) const { 1130629810b145187575bc26c910dded0d24c64569dShawn Willden *digest_count = 0; 1140629810b145187575bc26c910dded0d24c64569dShawn Willden return NULL; 1150629810b145187575bc26c910dded0d24c64569dShawn Willden} 11663ac043f81f8e2a15bbadcb6628b92096295ab6aShawn Willden 1170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenRsaOperation::~RsaOperation() { 1180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (rsa_key_ != NULL) 1192bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden EVP_PKEY_free(rsa_key_); 1200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1226bfbff0020bb964a736e30d717b338e3e3973a36Shawn Willdenkeymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */, 123ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden const Buffer& input, AuthorizationSet* /* output_params */, 124ded8e7d0ad241fc0a930dbebbd9f2e2bf4e929a2Shawn Willden Buffer* /* output */, size_t* input_consumed) { 125b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden assert(input_consumed); 1260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (purpose()) { 1270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 1280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNIMPLEMENTED; 1290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_SIGN: 1300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_VERIFY: 1314200f211057551c02e909fe88e5a92dae7a36597Shawn Willden case KM_PURPOSE_ENCRYPT: 1324200f211057551c02e909fe88e5a92dae7a36597Shawn Willden case KM_PURPOSE_DECRYPT: 133b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden return StoreData(input, input_consumed); 1340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 137b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willdenkeymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) { 138b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden assert(input_consumed); 1390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!data_.reserve(data_.available_read() + input.available_read()) || 1400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden !data_.write(input.peek_read(), input.available_read())) 1410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 142b7361134bff4d3d7ef1d5a3c60e50c9952dc2b56Shawn Willden *input_consumed = input.available_read(); 1430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 1440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1462bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenkeymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx) { 1472bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden keymaster_error_t error; 1482bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden int openssl_padding = GetOpensslPadding(&error); 1492bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (error != KM_ERROR_OK) 1502bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return error; 1512bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden 1522bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, openssl_padding) <= 0) 1532bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return TranslateLastOpenSslError(); 1542bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return KM_ERROR_OK; 1552bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden} 1562bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden 15761902366cc912daacb84dd84c9bada95718e19b7Shawn WilldenRsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest, 1582bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden keymaster_padding_t padding, EVP_PKEY* key) 15961902366cc912daacb84dd84c9bada95718e19b7Shawn Willden : RsaOperation(purpose, padding, key), digest_(digest), digest_algorithm_(NULL) { 16061902366cc912daacb84dd84c9bada95718e19b7Shawn Willden EVP_MD_CTX_init(&digest_ctx_); 16161902366cc912daacb84dd84c9bada95718e19b7Shawn Willden} 16261902366cc912daacb84dd84c9bada95718e19b7Shawn WilldenRsaDigestingOperation::~RsaDigestingOperation() { 16361902366cc912daacb84dd84c9bada95718e19b7Shawn Willden EVP_MD_CTX_cleanup(&digest_ctx_); 164f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden} 16561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden 166f90f235636cc3cbfb393e5006b673aef00df825aShawn Willdenkeymaster_error_t RsaDigestingOperation::InitDigest() { 1672bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (digest_ == KM_DIGEST_NONE) { 1682bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (require_digest()) 1692bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return KM_ERROR_INCOMPATIBLE_DIGEST; 1702bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return KM_ERROR_OK; 1712bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden } 1722bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden 17361902366cc912daacb84dd84c9bada95718e19b7Shawn Willden switch (digest_) { 174f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden case KM_DIGEST_NONE: 175f90f235636cc3cbfb393e5006b673aef00df825aShawn Willden return KM_ERROR_OK; 1762bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden case KM_DIGEST_MD5: 1772bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden digest_algorithm_ = EVP_md5(); 1782bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return KM_ERROR_OK; 1792bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden case KM_DIGEST_SHA1: 1802bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden digest_algorithm_ = EVP_sha1(); 1812bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return KM_ERROR_OK; 1822bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden case KM_DIGEST_SHA_2_224: 1832bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden digest_algorithm_ = EVP_sha224(); 1842bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return KM_ERROR_OK; 18561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden case KM_DIGEST_SHA_2_256: 18661902366cc912daacb84dd84c9bada95718e19b7Shawn Willden digest_algorithm_ = EVP_sha256(); 1872bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return KM_ERROR_OK; 1882bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden case KM_DIGEST_SHA_2_384: 1892bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden digest_algorithm_ = EVP_sha384(); 1902bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return KM_ERROR_OK; 1912bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden case KM_DIGEST_SHA_2_512: 1922bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden digest_algorithm_ = EVP_sha512(); 1932bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return KM_ERROR_OK; 19461902366cc912daacb84dd84c9bada95718e19b7Shawn Willden default: 19561902366cc912daacb84dd84c9bada95718e19b7Shawn Willden return KM_ERROR_UNSUPPORTED_DIGEST; 19661902366cc912daacb84dd84c9bada95718e19b7Shawn Willden } 1972bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden} 19861902366cc912daacb84dd84c9bada95718e19b7Shawn Willden 1992bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenconst size_t PSS_OVERHEAD = 2; 2002bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenconst size_t MIN_SALT_SIZE = 8; 2012bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden 2022bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willdenint RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) { 2032bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden *error = KM_ERROR_OK; 2042bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden switch (padding_) { 2052bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden case KM_PAD_NONE: 2062bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return RSA_NO_PADDING; 2072bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden case KM_PAD_RSA_PKCS1_1_5_SIGN: 2082bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden 2092bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return RSA_PKCS1_PADDING; 2102bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden case KM_PAD_RSA_PSS: 2112bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (digest_ == KM_DIGEST_NONE) { 2122bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE; 2132bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden return -1; 2142bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden } 2152bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden if (EVP_MD_size(digest_algorithm_) + PSS_OVERHEAD + MIN_SALT_SIZE > 2162bf4ad32f195bd734e4d7e7d4ac52c051f182fbfShawn Willden (size_t)EVP_PKEY_size(rsa_key_)) { 217bfd9ed7f5c50cdfa310cb0f21c7706e99b780738Shawn Willden LOG_E("%d-byte digest cannot be used with %d-byte RSA key in PSS padding mode", 218bfd9ed7f5c50cdfa310cb0f21c7706e99b780738Shawn Willden EVP_MD_size(digest_algorithm_), 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