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 210f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden#include <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 310c0a63805e4f21e46cc533ec0938306ca997c9a2dShawn Willden dest->reset(new 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