rsa_operation.cpp revision 4200f211057551c02e909fe88e5a92dae7a36597
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 174200f211057551c02e909fe88e5a92dae7a36597Shawn Willden#include <limits.h> 184200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 194200f211057551c02e909fe88e5a92dae7a36597Shawn Willden#include <openssl/err.h> 205f42dbae89434cfb2bd0cd00061b1096b3fd02b5Shawn Willden#include <openssl/evp.h> 214200f211057551c02e909fe88e5a92dae7a36597Shawn Willden#include <openssl/rsa.h> 220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "rsa_operation.h" 240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "openssl_utils.h" 250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdennamespace keymaster { 270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenstruct RSA_Delete { 290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden void operator()(RSA* p) const { RSA_free(p); } 300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden}; 310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenRsaOperation::~RsaOperation() { 330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (rsa_key_ != NULL) 340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden RSA_free(rsa_key_); 350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 375da34d2f205623a05ca503d5c192a020b7740be1Shawn Willdenkeymaster_error_t RsaOperation::Update(const Buffer& input, Buffer* /* output */) { 380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (purpose()) { 390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNIMPLEMENTED; 410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_SIGN: 420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_VERIFY: 434200f211057551c02e909fe88e5a92dae7a36597Shawn Willden case KM_PURPOSE_ENCRYPT: 444200f211057551c02e909fe88e5a92dae7a36597Shawn Willden case KM_PURPOSE_DECRYPT: 455da34d2f205623a05ca503d5c192a020b7740be1Shawn Willden return StoreData(input); 460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 495da34d2f205623a05ca503d5c192a020b7740be1Shawn Willdenkeymaster_error_t RsaOperation::StoreData(const Buffer& input) { 500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!data_.reserve(data_.available_read() + input.available_read()) || 510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden !data_.write(input.peek_read(), input.available_read())) 520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t RsaSignOperation::Finish(const Buffer& /* signature */, Buffer* output) { 570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden output->Reinitialize(RSA_size(rsa_key_)); 580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden int bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(), 590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden output->peek_write(), rsa_key_, RSA_NO_PADDING); 600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (bytes_encrypted < 0) 610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden assert(bytes_encrypted == RSA_size(rsa_key_)); 630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden output->advance_write(bytes_encrypted); 640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t RsaVerifyOperation::Finish(const Buffer& signature, Buffer* /* output */) { 68f2aefdfc5adcc0a59bd51a7e4ec5ab92a513171cAdam Langley#if defined(OPENSSL_IS_BORINGSSL) 694200f211057551c02e909fe88e5a92dae7a36597Shawn Willden size_t message_size = data_.available_read(); 70f2aefdfc5adcc0a59bd51a7e4ec5ab92a513171cAdam Langley#else 714200f211057551c02e909fe88e5a92dae7a36597Shawn Willden if (data_.available_read() > INT_MAX) 720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_INVALID_INPUT_LENGTH; 734200f211057551c02e909fe88e5a92dae7a36597Shawn Willden int message_size = (int)data_.available_read(); 74f2aefdfc5adcc0a59bd51a7e4ec5ab92a513171cAdam Langley#endif 75f2aefdfc5adcc0a59bd51a7e4ec5ab92a513171cAdam Langley 764200f211057551c02e909fe88e5a92dae7a36597Shawn Willden if (message_size != RSA_size(rsa_key_)) 774200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_INVALID_INPUT_LENGTH; 784200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (data_.available_read() != signature.available_read()) 800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_VERIFICATION_FAILED; 810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<uint8_t[]> decrypted_data(new uint8_t[RSA_size(rsa_key_)]); 830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(), 840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden decrypted_data.get(), rsa_key_, RSA_NO_PADDING); 850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (bytes_decrypted < 0) 860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden assert(bytes_decrypted == RSA_size(rsa_key_)); 880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (memcmp_s(decrypted_data.get(), data_.peek_read(), data_.available_read()) == 0) 900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_VERIFICATION_FAILED; 920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 944200f211057551c02e909fe88e5a92dae7a36597Shawn Willdenconst int OAEP_PADDING_OVERHEAD = 41; 954200f211057551c02e909fe88e5a92dae7a36597Shawn Willdenconst int PKCS1_PADDING_OVERHEAD = 11; 964200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 974200f211057551c02e909fe88e5a92dae7a36597Shawn Willdenkeymaster_error_t RsaEncryptOperation::Finish(const Buffer& /* signature */, Buffer* output) { 984200f211057551c02e909fe88e5a92dae7a36597Shawn Willden int openssl_padding; 994200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1004200f211057551c02e909fe88e5a92dae7a36597Shawn Willden#if defined(OPENSSL_IS_BORINGSSL) 1014200f211057551c02e909fe88e5a92dae7a36597Shawn Willden size_t message_size = data_.available_read(); 1024200f211057551c02e909fe88e5a92dae7a36597Shawn Willden#else 1034200f211057551c02e909fe88e5a92dae7a36597Shawn Willden if (data_.available_read() > INT_MAX) 1044200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_INVALID_INPUT_LENGTH; 1054200f211057551c02e909fe88e5a92dae7a36597Shawn Willden int message_size = (int)data_.available_read(); 1064200f211057551c02e909fe88e5a92dae7a36597Shawn Willden#endif 1074200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1084200f211057551c02e909fe88e5a92dae7a36597Shawn Willden switch (padding_) { 1094200f211057551c02e909fe88e5a92dae7a36597Shawn Willden case KM_PAD_RSA_OAEP: 1104200f211057551c02e909fe88e5a92dae7a36597Shawn Willden openssl_padding = RSA_PKCS1_OAEP_PADDING; 1114200f211057551c02e909fe88e5a92dae7a36597Shawn Willden if (message_size >= RSA_size(rsa_key_) - OAEP_PADDING_OVERHEAD) { 1124200f211057551c02e909fe88e5a92dae7a36597Shawn Willden logger().error("Cannot encrypt %d bytes with %d-byte key and OAEP padding", 1134200f211057551c02e909fe88e5a92dae7a36597Shawn Willden data_.available_read(), RSA_size(rsa_key_)); 1144200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_INVALID_INPUT_LENGTH; 1154200f211057551c02e909fe88e5a92dae7a36597Shawn Willden } 1164200f211057551c02e909fe88e5a92dae7a36597Shawn Willden break; 1174200f211057551c02e909fe88e5a92dae7a36597Shawn Willden case KM_PAD_RSA_PKCS1_1_5_ENCRYPT: 1184200f211057551c02e909fe88e5a92dae7a36597Shawn Willden openssl_padding = RSA_PKCS1_PADDING; 1194200f211057551c02e909fe88e5a92dae7a36597Shawn Willden if (message_size >= RSA_size(rsa_key_) - PKCS1_PADDING_OVERHEAD) { 1204200f211057551c02e909fe88e5a92dae7a36597Shawn Willden logger().error("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding", 1214200f211057551c02e909fe88e5a92dae7a36597Shawn Willden data_.available_read(), RSA_size(rsa_key_)); 1224200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_INVALID_INPUT_LENGTH; 1234200f211057551c02e909fe88e5a92dae7a36597Shawn Willden } 1244200f211057551c02e909fe88e5a92dae7a36597Shawn Willden break; 1254200f211057551c02e909fe88e5a92dae7a36597Shawn Willden default: 1264200f211057551c02e909fe88e5a92dae7a36597Shawn Willden logger().error("Padding mode %d not supported", padding_); 1274200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_UNSUPPORTED_PADDING_MODE; 1284200f211057551c02e909fe88e5a92dae7a36597Shawn Willden } 1294200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1304200f211057551c02e909fe88e5a92dae7a36597Shawn Willden output->Reinitialize(RSA_size(rsa_key_)); 1314200f211057551c02e909fe88e5a92dae7a36597Shawn Willden int bytes_encrypted = RSA_public_encrypt(data_.available_read(), data_.peek_read(), 1324200f211057551c02e909fe88e5a92dae7a36597Shawn Willden output->peek_write(), rsa_key_, openssl_padding); 1334200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1344200f211057551c02e909fe88e5a92dae7a36597Shawn Willden if (bytes_encrypted < 0) { 1354200f211057551c02e909fe88e5a92dae7a36597Shawn Willden logger().error("Error %d encrypting data with RSA", ERR_get_error()); 1364200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 1374200f211057551c02e909fe88e5a92dae7a36597Shawn Willden } 1384200f211057551c02e909fe88e5a92dae7a36597Shawn Willden assert(bytes_encrypted == RSA_size(rsa_key_)); 1394200f211057551c02e909fe88e5a92dae7a36597Shawn Willden output->advance_write(bytes_encrypted); 1404200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1414200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_OK; 1424200f211057551c02e909fe88e5a92dae7a36597Shawn Willden} 1434200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1444200f211057551c02e909fe88e5a92dae7a36597Shawn Willdenkeymaster_error_t RsaDecryptOperation::Finish(const Buffer& /* signature */, Buffer* output) { 1454200f211057551c02e909fe88e5a92dae7a36597Shawn Willden int openssl_padding; 1464200f211057551c02e909fe88e5a92dae7a36597Shawn Willden switch (padding_) { 1474200f211057551c02e909fe88e5a92dae7a36597Shawn Willden case KM_PAD_RSA_OAEP: 1484200f211057551c02e909fe88e5a92dae7a36597Shawn Willden openssl_padding = RSA_PKCS1_OAEP_PADDING; 1494200f211057551c02e909fe88e5a92dae7a36597Shawn Willden break; 1504200f211057551c02e909fe88e5a92dae7a36597Shawn Willden case KM_PAD_RSA_PKCS1_1_5_ENCRYPT: 1514200f211057551c02e909fe88e5a92dae7a36597Shawn Willden openssl_padding = RSA_PKCS1_PADDING; 1524200f211057551c02e909fe88e5a92dae7a36597Shawn Willden break; 1534200f211057551c02e909fe88e5a92dae7a36597Shawn Willden default: 1544200f211057551c02e909fe88e5a92dae7a36597Shawn Willden logger().error("Padding mode %d not supported", padding_); 1554200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_UNSUPPORTED_PADDING_MODE; 1564200f211057551c02e909fe88e5a92dae7a36597Shawn Willden } 1574200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1584200f211057551c02e909fe88e5a92dae7a36597Shawn Willden output->Reinitialize(RSA_size(rsa_key_)); 1594200f211057551c02e909fe88e5a92dae7a36597Shawn Willden int bytes_decrypted = RSA_private_decrypt(data_.available_read(), data_.peek_read(), 1604200f211057551c02e909fe88e5a92dae7a36597Shawn Willden output->peek_write(), rsa_key_, openssl_padding); 1614200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1624200f211057551c02e909fe88e5a92dae7a36597Shawn Willden if (bytes_decrypted < 0) { 1634200f211057551c02e909fe88e5a92dae7a36597Shawn Willden logger().error("Error %d decrypting data with RSA", ERR_get_error()); 1644200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 1654200f211057551c02e909fe88e5a92dae7a36597Shawn Willden } 1664200f211057551c02e909fe88e5a92dae7a36597Shawn Willden output->advance_write(bytes_decrypted); 1674200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1684200f211057551c02e909fe88e5a92dae7a36597Shawn Willden return KM_ERROR_OK; 1694200f211057551c02e909fe88e5a92dae7a36597Shawn Willden} 1704200f211057551c02e909fe88e5a92dae7a36597Shawn Willden 1710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} // namespace keymaster 172