summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Krahn <dkrahn@google.com>2015-12-16 19:02:13 -0800
committerDarren Krahn <dkrahn@google.com>2015-12-16 19:49:07 -0800
commitee93b5e81e62fdc0053c74ad565957354e540a99 (patch)
tree87aa4ab5d4dddeed66ea2de352e64f99359a4a84
parent5cb93f016cff70190b89577ca3e8416ce3fd888a (diff)
downloadtpm-ee93b5e81e62fdc0053c74ad565957354e540a99.tar.gz
trunks: Port to boringssl.
Use the EVP interface instead of RSA functions directly when encrypting salt. BUG=26191810 Change-Id: I45f0497b60941452ca4407732fee0a297b9780ca
-rw-r--r--trunks/error_codes.h1
-rw-r--r--trunks/session_manager_impl.cc121
-rw-r--r--trunks/trunks_client_test.cc29
3 files changed, 92 insertions, 59 deletions
diff --git a/trunks/error_codes.h b/trunks/error_codes.h
index dd3b5b4..4b8d61a 100644
--- a/trunks/error_codes.h
+++ b/trunks/error_codes.h
@@ -40,6 +40,7 @@ const TPM_RC TRUNKS_RC_ENCRYPTION_FAILED = kTrunksErrorBase + 2;
const TPM_RC TRUNKS_RC_READ_ERROR = kTrunksErrorBase + 3;
const TPM_RC TRUNKS_RC_WRITE_ERROR = kTrunksErrorBase + 4;
const TPM_RC TRUNKS_RC_IPC_ERROR = kTrunksErrorBase + 5;
+const TPM_RC TRUNKS_RC_SESSION_SETUP_ERROR = kTrunksErrorBase + 6;
const TPM_RC TCTI_RC_TRY_AGAIN = kTctiErrorBase + 1;
const TPM_RC TCTI_RC_GENERAL_FAILURE = kTctiErrorBase + 2;
diff --git a/trunks/session_manager_impl.cc b/trunks/session_manager_impl.cc
index b71c4ee..f1a648f 100644
--- a/trunks/session_manager_impl.cc
+++ b/trunks/session_manager_impl.cc
@@ -20,8 +20,10 @@
#include <base/logging.h>
#include <base/stl_util.h>
+#include <crypto/openssl_util.h>
#include <crypto/scoped_openssl_types.h>
#include <openssl/err.h>
+#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
@@ -31,13 +33,25 @@
namespace {
const size_t kWellKnownExponent = 0x10001;
+
+std::string GetOpenSSLError() {
+ BIO* bio = BIO_new(BIO_s_mem());
+ ERR_print_errors(bio);
+ char* data = nullptr;
+ int data_len = BIO_get_mem_data(bio, &data);
+ std::string error_string(data, data_len);
+ BIO_free(bio);
+ return error_string;
+}
} // namespace
namespace trunks {
SessionManagerImpl::SessionManagerImpl(const TrunksFactory& factory)
: factory_(factory),
- session_handle_(kUninitializedHandle) {}
+ session_handle_(kUninitializedHandle) {
+ crypto::EnsureOpenSSLInit();
+}
SessionManagerImpl::~SessionManagerImpl() {
CloseSession();
@@ -75,7 +89,7 @@ TPM_RC SessionManagerImpl::StartSession(
std::string encrypted_salt;
TPM_RC salt_result = EncryptSalt(salt, &encrypted_salt);
if (salt_result != TPM_RC_SUCCESS) {
- LOG(ERROR) << "Error encrypting salt.";
+ LOG(ERROR) << "Error encrypting salt: " << GetErrorString(salt_result);
return salt_result;
}
@@ -139,71 +153,64 @@ TPM_RC SessionManagerImpl::EncryptSalt(const std::string& salt,
TPM2B_NAME qualified_name;
TPM2B_PUBLIC public_data;
public_data.public_area.unique.rsa.size = 0;
- // The TPM2 Command below needs no authorization. Therefore we can simply
- // use the empty string for all the Key names, and pullptr for the
- // authorization delegate.
TPM_RC result = factory_.GetTpm()->ReadPublicSync(
- kSaltingKey, "", // SaltingKey name.
- &public_data, &out_name, &qualified_name, nullptr); // No authorization
+ kSaltingKey, "" /*object_handle_name (not used)*/, &public_data,
+ &out_name, &qualified_name, nullptr /*authorization_delegate*/);
if (result != TPM_RC_SUCCESS) {
- LOG(ERROR) << "Error fetching salting key public info.";
+ LOG(ERROR) << "Error fetching salting key public info: "
+ << GetErrorString(result);
return result;
}
- crypto::ScopedRSA salting_rsa(RSA_new());
- salting_rsa.get()->e = BN_new();
- if (!salting_rsa.get()->e) {
- LOG(ERROR) << "Error creating exponent for RSA.";
- return TPM_RC_FAILURE;
+ crypto::ScopedRSA salting_key_rsa(RSA_new());
+ salting_key_rsa->e = BN_new();
+ if (!salting_key_rsa->e) {
+ LOG(ERROR) << "Error creating exponent for RSA: " << GetOpenSSLError();
+ return TRUNKS_RC_SESSION_SETUP_ERROR;
}
- BN_set_word(salting_rsa.get()->e, kWellKnownExponent);
- salting_rsa.get()->n = BN_bin2bn(public_data.public_area.unique.rsa.buffer,
- public_data.public_area.unique.rsa.size,
- nullptr);
- if (!salting_rsa.get()->n) {
- LOG(ERROR) << "Error setting public area of rsa key.";
- return TPM_RC_FAILURE;
+ BN_set_word(salting_key_rsa->e, kWellKnownExponent);
+ salting_key_rsa->n =
+ BN_bin2bn(public_data.public_area.unique.rsa.buffer,
+ public_data.public_area.unique.rsa.size, nullptr);
+ if (!salting_key_rsa->n) {
+ LOG(ERROR) << "Error setting public area of rsa key: " << GetOpenSSLError();
+ return TRUNKS_RC_SESSION_SETUP_ERROR;
+ }
+ crypto::ScopedEVP_PKEY salting_key(EVP_PKEY_new());
+ if (!EVP_PKEY_set1_RSA(salting_key.get(), salting_key_rsa.get())) {
+ LOG(ERROR) << "Error setting up EVP_PKEY: " << GetOpenSSLError();
+ return TRUNKS_RC_SESSION_SETUP_ERROR;
}
// Label for RSAES-OAEP. Defined in TPM2.0 Part1 Architecture,
// Appendix B.10.2.
- unsigned char oaep_param[7] = {'S', 'E', 'C', 'R', 'E', 'T', '\0'};
- const EVP_MD* sha256_md = EVP_sha256();
- std::string padded_input(RSA_size(salting_rsa.get()), 0);
- int rsa_result = RSA_padding_add_PKCS1_OAEP_mgf1(
- reinterpret_cast<unsigned char*>(string_as_array(&padded_input)),
- padded_input.size(),
- reinterpret_cast<const unsigned char*>(salt.c_str()),
- salt.size(),
- oaep_param,
- arraysize(oaep_param),
- sha256_md,
- sha256_md);
- if (!rsa_result) {
- unsigned long err = ERR_get_error(); // NOLINT openssl types
- ERR_load_ERR_strings();
- ERR_load_crypto_strings();
- LOG(ERROR) << "EncryptSalt Error: " << err
- << ": " << ERR_lib_error_string(err)
- << ", " << ERR_func_error_string(err)
- << ", " << ERR_reason_error_string(err);
- return TPM_RC_FAILURE;
+ const size_t kOaepLabelSize = 7;
+ const char kOaepLabelValue[] = "SECRET\0";
+ // EVP_PKEY_CTX_set0_rsa_oaep_label takes ownership so we need to malloc.
+ uint8_t* oaep_label = static_cast<uint8_t*>(OPENSSL_malloc(kOaepLabelSize));
+ memcpy(oaep_label, kOaepLabelValue, kOaepLabelSize);
+ crypto::ScopedEVP_PKEY_CTX salt_encrypt_context(
+ EVP_PKEY_CTX_new(salting_key.get(), nullptr));
+ if (!EVP_PKEY_encrypt_init(salt_encrypt_context.get()) ||
+ !EVP_PKEY_CTX_set_rsa_padding(salt_encrypt_context.get(),
+ RSA_PKCS1_OAEP_PADDING) ||
+ !EVP_PKEY_CTX_set_rsa_oaep_md(salt_encrypt_context.get(), EVP_sha256()) ||
+ !EVP_PKEY_CTX_set_rsa_mgf1_md(salt_encrypt_context.get(), EVP_sha256()) ||
+ !EVP_PKEY_CTX_set0_rsa_oaep_label(salt_encrypt_context.get(), oaep_label,
+ kOaepLabelSize)) {
+ LOG(ERROR) << "Error setting up salt encrypt context: "
+ << GetOpenSSLError();
+ return TRUNKS_RC_SESSION_SETUP_ERROR;
}
- encrypted_salt->resize(padded_input.size());
- rsa_result = RSA_public_encrypt(
- padded_input.size(),
- reinterpret_cast<unsigned char*>(string_as_array(&padded_input)),
- reinterpret_cast<unsigned char*>(string_as_array(encrypted_salt)),
- salting_rsa.get(),
- RSA_NO_PADDING);
- if (rsa_result == -1) {
- unsigned long err = ERR_get_error(); // NOLINT openssl types
- ERR_load_ERR_strings();
- ERR_load_crypto_strings();
- LOG(ERROR) << "EncryptSalt Error: " << err
- << ": " << ERR_lib_error_string(err)
- << ", " << ERR_func_error_string(err)
- << ", " << ERR_reason_error_string(err);
- return TPM_RC_FAILURE;
+ size_t out_length = EVP_PKEY_size(salting_key.get());
+ encrypted_salt->resize(out_length);
+ if (!EVP_PKEY_encrypt(
+ salt_encrypt_context.get(),
+ reinterpret_cast<uint8_t*>(string_as_array(encrypted_salt)),
+ &out_length, reinterpret_cast<const uint8_t*>(salt.data()),
+ salt.size())) {
+ LOG(ERROR) << "Error encrypting salt: " << GetOpenSSLError();
+ return TRUNKS_RC_SESSION_SETUP_ERROR;
}
+ encrypted_salt->resize(out_length);
return TPM_RC_SUCCESS;
}
diff --git a/trunks/trunks_client_test.cc b/trunks/trunks_client_test.cc
index 73b8a0c..cd7de4e 100644
--- a/trunks/trunks_client_test.cc
+++ b/trunks/trunks_client_test.cc
@@ -24,6 +24,7 @@
#include <base/logging.h>
#include <base/stl_util.h>
+#include <crypto/openssl_util.h>
#include <crypto/scoped_openssl_types.h>
#include <crypto/sha2.h>
#include <openssl/bn.h>
@@ -40,9 +41,25 @@
#include "trunks/tpm_utility.h"
#include "trunks/trunks_factory_impl.h"
+namespace {
+
+std::string GetOpenSSLError() {
+ BIO* bio = BIO_new(BIO_s_mem());
+ ERR_print_errors(bio);
+ char* data = nullptr;
+ int data_len = BIO_get_mem_data(bio, &data);
+ std::string error_string(data, data_len);
+ BIO_free(bio);
+ return error_string;
+}
+
+} // namespace
+
namespace trunks {
-TrunksClientTest::TrunksClientTest() : factory_(new TrunksFactoryImpl()) {}
+TrunksClientTest::TrunksClientTest() : factory_(new TrunksFactoryImpl()) {
+ crypto::EnsureOpenSSLInit();
+}
TrunksClientTest::TrunksClientTest(scoped_ptr<TrunksFactory> factory)
: factory_(factory.Pass()) {}
@@ -970,8 +987,16 @@ bool TrunksClientTest::PerformRSAEncrpytAndDecrpyt(
void TrunksClientTest::GenerateRSAKeyPair(std::string* modulus,
std::string* prime_factor,
std::string* public_key) {
+#ifdef OPENSSL_IS_BORINGSSL
+ crypto::ScopedRSA rsa(RSA_new());
+ crypto::ScopedBIGNUM exponent(BN_new());
+ CHECK(BN_set_word(exponent.get(), RSA_F4));
+ CHECK(RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr))
+ << "Failed to generate RSA key: " << GetOpenSSLError();
+#else
crypto::ScopedRSA rsa(RSA_generate_key(2048, 0x10001, nullptr, nullptr));
CHECK(rsa.get());
+#endif
modulus->resize(BN_num_bytes(rsa.get()->n), 0);
BN_bn2bin(rsa.get()->n,
reinterpret_cast<unsigned char*>(string_as_array(modulus)));
@@ -1049,7 +1074,7 @@ bool TrunksClientTest::SignAndVerify(const ScopedKeyHandle& key_handle,
return false;
}
if (!VerifyRSASignature(public_key, data_to_sign, signature)) {
- LOG(ERROR) << "Signature verification failed.";
+ LOG(ERROR) << "Signature verification failed: " << GetOpenSSLError();
return false;
}
return true;