Merge "Updated OEMCrypto tests to use DRM key objects."

This commit is contained in:
Alex Dale
2022-06-21 20:52:08 +00:00
committed by Android (Google) Code Review
7 changed files with 252 additions and 314 deletions

View File

@@ -44,6 +44,8 @@ LOCAL_SRC_FILES := \
../../oemcrypto/test/oec_device_features.cpp \ ../../oemcrypto/test/oec_device_features.cpp \
../../oemcrypto/test/oec_key_deriver.cpp \ ../../oemcrypto/test/oec_key_deriver.cpp \
../../oemcrypto/test/oec_session_util.cpp \ ../../oemcrypto/test/oec_session_util.cpp \
../../oemcrypto/util/src/oemcrypto_ecc_key.cpp \
../../oemcrypto/util/src/oemcrypto_rsa_key.cpp \
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := \
vendor/widevine/libwvdrmengine/android/cdm/test \ vendor/widevine/libwvdrmengine/android/cdm/test \
@@ -58,6 +60,7 @@ LOCAL_C_INCLUDES := \
vendor/widevine/libwvdrmengine/oemcrypto/test/fuzz_tests \ vendor/widevine/libwvdrmengine/oemcrypto/test/fuzz_tests \
vendor/widevine/libwvdrmengine/oemcrypto/odk/include \ vendor/widevine/libwvdrmengine/oemcrypto/odk/include \
vendor/widevine/libwvdrmengine/oemcrypto/odk/kdo/include \ vendor/widevine/libwvdrmengine/oemcrypto/odk/kdo/include \
vendor/widevine/libwvdrmengine/oemcrypto/util/include \
LOCAL_C_INCLUDES += external/protobuf/src LOCAL_C_INCLUDES += external/protobuf/src

View File

@@ -34,6 +34,8 @@ LOCAL_SRC_FILES := \
../../oemcrypto/test/oec_device_features.cpp \ ../../oemcrypto/test/oec_device_features.cpp \
../../oemcrypto/test/oec_key_deriver.cpp \ ../../oemcrypto/test/oec_key_deriver.cpp \
../../oemcrypto/test/oec_session_util.cpp \ ../../oemcrypto/test/oec_session_util.cpp \
../../oemcrypto/util/src/oemcrypto_ecc_key.cpp \
../../oemcrypto/util/src/oemcrypto_rsa_key.cpp \
../util/test/test_sleep.cpp \ ../util/test/test_sleep.cpp \
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := \
@@ -49,6 +51,7 @@ LOCAL_C_INCLUDES := \
vendor/widevine/libwvdrmengine/oemcrypto/test/fuzz_tests \ vendor/widevine/libwvdrmengine/oemcrypto/test/fuzz_tests \
vendor/widevine/libwvdrmengine/oemcrypto/odk/include \ vendor/widevine/libwvdrmengine/oemcrypto/odk/include \
vendor/widevine/libwvdrmengine/oemcrypto/odk/kdo/include \ vendor/widevine/libwvdrmengine/oemcrypto/odk/kdo/include \
vendor/widevine/libwvdrmengine/oemcrypto/util/include \
LOCAL_C_INCLUDES += external/protobuf/src LOCAL_C_INCLUDES += external/protobuf/src

View File

@@ -29,6 +29,8 @@ LOCAL_SRC_FILES:= \
oemcrypto_test_main.cpp \ oemcrypto_test_main.cpp \
ota_keybox_test.cpp \ ota_keybox_test.cpp \
../../cdm/util/test/test_sleep.cpp \ ../../cdm/util/test/test_sleep.cpp \
../util/src/oemcrypto_ecc_key.cpp \
../util/src/oemcrypto_rsa_key.cpp \
../util/src/wvcrc.cpp \ ../util/src/wvcrc.cpp \
LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES += \

View File

@@ -309,12 +309,12 @@ void ProvisioningRoundTrip::PrepareSession(
OEMCrypto_BootCertificateChain) { OEMCrypto_BootCertificateChain) {
// TODO(chelu): change this to CSR provisioning. // TODO(chelu): change this to CSR provisioning.
session_->LoadOEMCert(true); session_->LoadOEMCert(true);
session_->GenerateRSASessionKey(&message_key_, &encrypted_message_key_); session_->GenerateRsaSessionKey(&message_key_, &encrypted_message_key_);
encryptor_.set_enc_key(message_key_); encryptor_.set_enc_key(message_key_);
} else { } else {
EXPECT_EQ(global_features.provisioning_method, OEMCrypto_OEMCertificate); EXPECT_EQ(global_features.provisioning_method, OEMCrypto_OEMCertificate);
session_->LoadOEMCert(true); session_->LoadOEMCert(true);
session_->GenerateRSASessionKey(&message_key_, &encrypted_message_key_); session_->GenerateRsaSessionKey(&message_key_, &encrypted_message_key_);
encryptor_.set_enc_key(message_key_); encryptor_.set_enc_key(message_key_);
} }
} }
@@ -323,7 +323,7 @@ void ProvisioningRoundTrip::VerifyRequestSignature(
const vector<uint8_t>& data, const vector<uint8_t>& generated_signature, const vector<uint8_t>& data, const vector<uint8_t>& generated_signature,
size_t /* core_message_length */) { size_t /* core_message_length */) {
if (global_features.provisioning_method == OEMCrypto_OEMCertificate) { if (global_features.provisioning_method == OEMCrypto_OEMCertificate) {
session()->VerifyRSASignature(data, generated_signature.data(), session()->VerifyRsaSignature(data, generated_signature.data(),
generated_signature.size(), kSign_RSASSA_PSS); generated_signature.size(), kSign_RSASSA_PSS);
} else { } else {
EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox); EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox);
@@ -564,11 +564,11 @@ void LicenseRoundTrip::VerifyRequestSignature(
if (global_features.api_version < 17) { if (global_features.api_version < 17) {
const std::vector<uint8_t> subdata(data.begin() + core_message_length, const std::vector<uint8_t> subdata(data.begin() + core_message_length,
data.end()); data.end());
session()->VerifyRSASignature(subdata, generated_signature.data(), session()->VerifyRsaSignature(subdata, generated_signature.data(),
generated_signature.size(), kSign_RSASSA_PSS); generated_signature.size(), kSign_RSASSA_PSS);
SHA256(data.data(), core_message_length, request_hash_); SHA256(data.data(), core_message_length, request_hash_);
} else { } else {
session()->VerifyRSASignature(data, generated_signature.data(), session()->VerifyRsaSignature(data, generated_signature.data(),
generated_signature.size(), kSign_RSASSA_PSS); generated_signature.size(), kSign_RSASSA_PSS);
SHA256(data.data(), core_message_length, request_hash_); SHA256(data.data(), core_message_length, request_hash_);
} }
@@ -1422,17 +1422,10 @@ OEMCryptoResult RenewalRoundTrip::LoadResponse(Session* session) {
} }
} }
Session::Session() Session::Session() {}
: open_(false),
forced_session_id_(false),
session_id_(0),
nonce_(0),
public_rsa_(nullptr) {}
Session::~Session() { Session::~Session() {
if (!forced_session_id_ && open_) close(); if (!forced_session_id_ && open_) close();
if (public_rsa_) RSA_free(public_rsa_);
if (public_ec_) EC_KEY_free(public_ec_);
} }
void Session::open() { void Session::open() {
@@ -1512,10 +1505,11 @@ void Session::GenerateDerivedKeysFromSessionKey() {
// Uses test certificate. // Uses test certificate.
vector<uint8_t> session_key; vector<uint8_t> session_key;
vector<uint8_t> enc_session_key; vector<uint8_t> enc_session_key;
ASSERT_NE(public_rsa_, nullptr) << "No public RSA key loaded in test code."; ASSERT_TRUE(public_rsa_ || public_ec_)
<< "No public RSA/ECC key loaded in test code";
// A failure here probably indicates that there is something wrong with the // A failure here probably indicates that there is something wrong with the
// test program and its dependency on BoringSSL. // test program and its dependency on BoringSSL.
ASSERT_TRUE(GenerateRSASessionKey(&session_key, &enc_session_key)); ASSERT_TRUE(GenerateRsaSessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context; vector<uint8_t> mac_context;
vector<uint8_t> enc_context; vector<uint8_t> enc_context;
FillDefaultContext(&mac_context, &enc_context); FillDefaultContext(&mac_context, &enc_context);
@@ -1640,12 +1634,11 @@ void Session::LoadOEMCert(bool verify_cert) {
boringssl_ptr<EVP_PKEY, EVP_PKEY_free> pubkey(X509_get_pubkey(x509_cert)); boringssl_ptr<EVP_PKEY, EVP_PKEY_free> pubkey(X509_get_pubkey(x509_cert));
ASSERT_TRUE(pubkey.NotNull()); ASSERT_TRUE(pubkey.NotNull());
if (i == 0) { if (i == 0) {
public_rsa_ = EVP_PKEY_get1_RSA(pubkey.get()); public_rsa_ =
if (!public_rsa_) { util::RsaPublicKey::FromSslHandle(EVP_PKEY_get0_RSA(pubkey.get()));
cerr << "d2i_RSAPrivateKey failed.\n"; ASSERT_TRUE(public_rsa_)
dump_boringssl_error(); << "Failed to extract public RSA key from OEM certificate";
ASSERT_TRUE(nullptr != public_rsa_); return;
}
} }
if (verify_cert) { if (verify_cert) {
vector<char> buffer(80); vector<char> buffer(80);
@@ -1677,199 +1670,152 @@ void Session::LoadOEMCert(bool verify_cert) {
} }
} }
void Session::PreparePublicKey(const uint8_t* rsa_key, size_t rsa_key_length) { void Session::SetTestRsaPublicKey() {
if (rsa_key == nullptr) { public_ec_.reset();
rsa_key = kTestRSAPKCS8PrivateKeyInfo2_2048; public_rsa_ = util::RsaPublicKey::LoadPrivateKeyInfo(
rsa_key_length = sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048); kTestRSAPKCS8PrivateKeyInfo2_2048,
} sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048));
uint8_t* p = const_cast<uint8_t*>(rsa_key); ASSERT_TRUE(public_rsa_) << "Could not parse test RSA public key #2";
boringssl_ptr<BIO, BIO_vfree> bio( }
BIO_new_mem_buf(p, static_cast<int>(rsa_key_length)));
ASSERT_TRUE(bio.NotNull()); void Session::SetPublicKeyFromPrivateKeyInfo(OEMCrypto_PrivateKeyType key_type,
boringssl_ptr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> pkcs8_pki( const uint8_t* buffer,
d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), nullptr)); size_t length) {
ASSERT_TRUE(pkcs8_pki.NotNull()); switch (key_type) {
boringssl_ptr<EVP_PKEY, EVP_PKEY_free> evp(EVP_PKCS82PKEY(pkcs8_pki.get())); case OEMCrypto_RSA_Private_Key:
ASSERT_TRUE(evp.NotNull()); ASSERT_NO_FATAL_FAILURE(
if (public_rsa_) RSA_free(public_rsa_); SetRsaPublicKeyFromPrivateKeyInfo(buffer, length));
public_rsa_ = EVP_PKEY_get1_RSA(evp.get());
if (!public_rsa_) {
cerr << "d2i_RSAPrivateKey failed. ";
dump_boringssl_error();
FAIL() << "Could not parse public RSA key.";
}
switch (RSA_check_key(public_rsa_)) {
case 1: // valid.
return; return;
case 0: // not valid. case OEMCrypto_ECC_Private_Key:
dump_boringssl_error(); ASSERT_NO_FATAL_FAILURE(
FAIL() << "[rsa key not valid] "; SetEccPublicKeyFromPrivateKeyInfo(buffer, length));
default: // -1 == check failed.
dump_boringssl_error();
FAIL() << "[error checking rsa key] ";
}
}
void Session::SetRsaPublicKey(const uint8_t* buffer, size_t length) {
if (public_rsa_) {
RSA_free(public_rsa_);
public_rsa_ = nullptr;
}
if (public_ec_) {
EC_KEY_free(public_ec_);
public_ec_ = nullptr;
}
public_rsa_ = d2i_RSA_PUBKEY(nullptr, &buffer, length);
if (!public_rsa_) {
cout << "d2i_RSAPrivateKey failed. ";
dump_boringssl_error();
FAIL() << "Could not parse public RSA key.";
}
switch (RSA_check_key(public_rsa_)) {
case 1: // valid.
return; return;
case 0: // not valid.
dump_boringssl_error();
FAIL() << "[rsa key not valid] ";
default: // -1 == check failed.
dump_boringssl_error();
FAIL() << "[error checking rsa key] ";
} }
FAIL() << "Unknown key type: " << static_cast<int>(key_type);
} }
void Session::SetEcPublicKey(const uint8_t* buffer, size_t length) { void Session::SetRsaPublicKeyFromPrivateKeyInfo(const uint8_t* buffer,
if (public_rsa_) { size_t length) {
RSA_free(public_rsa_); public_ec_.reset();
public_rsa_ = nullptr; public_rsa_ = util::RsaPublicKey::LoadPrivateKeyInfo(buffer, length);
} ASSERT_TRUE(public_rsa_) << "Could not parse RSA public key";
if (public_ec_) { }
EC_KEY_free(public_ec_);
public_ec_ = nullptr; void Session::SetEccPublicKeyFromPrivateKeyInfo(const uint8_t* buffer,
} size_t length) {
public_ec_ = d2i_EC_PUBKEY(nullptr, &buffer, length); public_rsa_.reset();
if (!public_ec_) { public_ec_ = util::EccPublicKey::LoadPrivateKeyInfo(buffer, length);
cout << "d2i_RSAPrivateKey failed. "; ASSERT_TRUE(public_ec_) << "Could not parse ECC public key";
dump_boringssl_error(); }
FAIL() << "Could not parse public RSA key.";
} void Session::SetPublicKeyFromSubjectPublicKey(
switch (EC_KEY_check_key(public_ec_)) { OEMCrypto_PrivateKeyType key_type, const uint8_t* buffer, size_t length) {
case 1: // valid. switch (key_type) {
case OEMCrypto_RSA_Private_Key:
ASSERT_NO_FATAL_FAILURE(
SetRsaPublicKeyFromSubjectPublicKey(buffer, length));
return;
case OEMCrypto_ECC_Private_Key:
ASSERT_NO_FATAL_FAILURE(
SetEccPublicKeyFromSubjectPublicKey(buffer, length));
return; return;
case 0: // not valid.
default:
dump_boringssl_error();
FAIL() << "[ec key not valid] ";
} }
FAIL() << "Unknown key type: " << static_cast<int>(key_type);
} }
bool Session::VerifyPSSSignature(EVP_PKEY* pkey, const uint8_t* message, void Session::SetRsaPublicKeyFromSubjectPublicKey(const uint8_t* buffer,
size_t message_length, size_t length) {
const uint8_t* signature, public_ec_.reset();
size_t signature_length) { public_rsa_ = util::RsaPublicKey::Load(buffer, length);
boringssl_ptr<EVP_MD_CTX, EVP_MD_CTX_free> md_ctx(EVP_MD_CTX_new()); ASSERT_TRUE(public_rsa_) << "Could not parse RSA public key";
EVP_PKEY_CTX* pkey_ctx = nullptr;
if (EVP_DigestVerifyInit(md_ctx.get(), &pkey_ctx, EVP_sha1(),
nullptr /* no ENGINE */, pkey) != 1) {
LOGE("EVP_DigestVerifyInit failed in VerifyPSSSignature");
goto err;
}
if (EVP_PKEY_CTX_set_signature_md(pkey_ctx,
const_cast<EVP_MD*>(EVP_sha1())) != 1) {
LOGE("EVP_PKEY_CTX_set_signature_md failed in VerifyPSSSignature");
goto err;
}
if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) {
LOGE("EVP_PKEY_CTX_set_rsa_padding failed in VerifyPSSSignature");
goto err;
}
if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, SHA_DIGEST_LENGTH) != 1) {
LOGE("EVP_PKEY_CTX_set_rsa_pss_saltlen failed in VerifyPSSSignature");
goto err;
}
if (EVP_DigestVerifyUpdate(md_ctx.get(), message, message_length) != 1) {
LOGE("EVP_DigestVerifyUpdate failed in VerifyPSSSignature");
goto err;
}
if (EVP_DigestVerifyFinal(md_ctx.get(), const_cast<uint8_t*>(signature),
signature_length) != 1) {
LOGE(
"EVP_DigestVerifyFinal failed in VerifyPSSSignature. (Probably a bad "
"signature.)");
goto err;
}
return true;
err:
dump_boringssl_error();
return false;
} }
void Session::VerifyRSASignature(const vector<uint8_t>& message, void Session::SetEccPublicKeyFromSubjectPublicKey(const uint8_t* buffer,
size_t length) {
public_rsa_.reset();
public_ec_ = util::EccPublicKey::Load(buffer, length);
ASSERT_TRUE(public_ec_) << "Could not parse ECC public key";
}
void Session::VerifyRsaSignature(const vector<uint8_t>& message,
const uint8_t* signature, const uint8_t* signature,
size_t signature_length, size_t signature_length,
RSA_Padding_Scheme padding_scheme) { RSA_Padding_Scheme padding_scheme) {
ASSERT_NE(public_rsa_, nullptr) << "No public RSA key loaded in test code."; ASSERT_TRUE(public_rsa_) << "No public RSA key loaded in test code";
if (padding_scheme != kSign_RSASSA_PSS &&
ASSERT_EQ(static_cast<size_t>(RSA_size(public_rsa_)), signature_length) padding_scheme != kSign_PKCS1_Block1) {
<< "Signature size is wrong. " << signature_length << ", should be " FAIL() << "Padding scheme not supported: " << padding_scheme;
<< RSA_size(public_rsa_); return;
if (padding_scheme == kSign_RSASSA_PSS) {
boringssl_ptr<EVP_PKEY, EVP_PKEY_free> pkey(EVP_PKEY_new());
ASSERT_EQ(1, EVP_PKEY_set1_RSA(pkey.get(), public_rsa_));
const bool ok =
VerifyPSSSignature(pkey.get(), message.data(), message.size(),
signature, signature_length);
EXPECT_TRUE(ok) << "PSS signature check failed.";
} else if (padding_scheme == kSign_PKCS1_Block1) {
vector<uint8_t> padded_digest(signature_length);
int size;
// RSA_public_decrypt decrypts the signature, and then verifies that
// it was padded with RSA PKCS1 padding.
size = RSA_public_decrypt(static_cast<int>(signature_length), signature,
padded_digest.data(), public_rsa_,
RSA_PKCS1_PADDING);
EXPECT_GT(size, 0);
padded_digest.resize(size);
EXPECT_EQ(message, padded_digest);
} else {
EXPECT_TRUE(false) << "Padding scheme not supported.";
} }
const util::RsaSignatureAlgorithm algorithm =
padding_scheme == kSign_RSASSA_PSS ? util::kRsaPssDefault
: util::kRsaPkcs1Cast;
const OEMCryptoResult result = public_rsa_->VerifySignature(
message.data(), message.size(), signature, signature_length, algorithm);
ASSERT_EQ(result, OEMCrypto_SUCCESS) << "RSA signature check failed";
} }
bool Session::GenerateRSASessionKey(vector<uint8_t>* session_key, void Session::VerifyEccSignature(const vector<uint8_t>& message,
const uint8_t* signature,
size_t signature_length) {
ASSERT_TRUE(public_ec_) << "No public ECC key loaded in test code";
const OEMCryptoResult result = public_ec_->VerifySignature(
message.data(), message.size(), signature, signature_length);
ASSERT_EQ(result, OEMCrypto_SUCCESS) << "ECC signature check failed";
}
bool Session::GenerateRsaSessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* enc_session_key) { vector<uint8_t>* enc_session_key) {
if (!public_rsa_) { if (!public_rsa_) {
cerr << "No public RSA key loaded in test code.\n"; cerr << "No public RSA key loaded in test code\n";
return false; return false;
} }
*session_key = wvutil::a2b_hex("6fa479c731d2770b6a61a5d1420bb9d1"); *session_key = wvutil::a2b_hex("6fa479c731d2770b6a61a5d1420bb9d1");
enc_session_key->assign(RSA_size(public_rsa_), 0); *enc_session_key = public_rsa_->EncryptSessionKey(*session_key);
int status = RSA_public_encrypt( if (enc_session_key->empty()) {
static_cast<int>(session_key->size()), &(session_key->front()),
&(enc_session_key->front()), public_rsa_, RSA_PKCS1_OAEP_PADDING);
int size = static_cast<int>(RSA_size(public_rsa_));
if (status != size) {
cerr << "GenerateRSASessionKey error encrypting session key.\n";
dump_boringssl_error();
return false; return false;
} }
return true; return true;
} }
void Session::InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key) { bool Session::GenerateEccSessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* ecdh_public_key_data) {
if (!public_ec_) {
cerr << "No public ECC key loaded in test code\n";
return false;
}
auto ephemeral_key = util::EccPrivateKey::New(public_ec_->curve());
if (!ephemeral_key) {
return false;
}
*session_key = ephemeral_key->DeriveSessionKey(*public_ec_);
if (session_key->empty()) {
return false;
}
*ecdh_public_key_data = ephemeral_key->SerializeAsPublicKey();
if (ecdh_public_key_data->empty()) {
session_key->clear();
return false;
}
return true;
}
void Session::LoadWrappedDrmKey(OEMCrypto_PrivateKeyType key_type,
const vector<uint8_t>& wrapped_drm_key) {
ASSERT_EQ(OEMCrypto_SUCCESS, ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadDRMPrivateKey(session_id(), OEMCrypto_RSA_Private_Key, OEMCrypto_LoadDRMPrivateKey(session_id(), key_type,
wrapped_rsa_key.data(), wrapped_drm_key.data(),
wrapped_rsa_key.size())); wrapped_drm_key.size()));
}
void Session::LoadWrappedRsaDrmKey(const vector<uint8_t>& wrapped_rsa_key) {
ASSERT_NO_FATAL_FAILURE(
LoadWrappedDrmKey(OEMCrypto_RSA_Private_Key, wrapped_rsa_key));
}
void Session::LoadWrappedEccDrmKey(const vector<uint8_t>& wrapped_ecc_key) {
ASSERT_NO_FATAL_FAILURE(
LoadWrappedDrmKey(OEMCrypto_ECC_Private_Key, wrapped_ecc_key));
} }
void Session::CreateNewUsageEntry(OEMCryptoResult* status) { void Session::CreateNewUsageEntry(OEMCryptoResult* status) {

View File

@@ -8,8 +8,6 @@
// OEMCrypto unit tests // OEMCrypto unit tests
// //
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <openssl/ec.h>
#include <openssl/rsa.h>
#include <time.h> #include <time.h>
#include <string> #include <string>
@@ -21,7 +19,9 @@
#include "odk.h" #include "odk.h"
#include "oec_device_features.h" #include "oec_device_features.h"
#include "oec_key_deriver.h" #include "oec_key_deriver.h"
#include "oemcrypto_ecc_key.h"
#include "oemcrypto_fuzz_structs.h" #include "oemcrypto_fuzz_structs.h"
#include "oemcrypto_rsa_key.h"
#include "oemcrypto_types.h" #include "oemcrypto_types.h"
#include "pst_report.h" #include "pst_report.h"
@@ -571,38 +571,65 @@ class Session {
void RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted, void RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
size_t message_size, const std::vector<uint8_t>& signature, size_t message_size, const std::vector<uint8_t>& signature,
vector<uint8_t>* wrapped_key, bool force); vector<uint8_t>* wrapped_key, bool force);
// Loads the specified RSA public key into public_rsa_. If rsa_key is null, // Loads the default test RSA public key into public_rsa_.
// the default test key is loaded. void SetTestRsaPublicKey();
void PreparePublicKey(const uint8_t* rsa_key = nullptr, // Loads the specified DRM public key into the appropriate key.
size_t rsa_key_length = 0); // The provided key is serialized as an ASN.1 DER encoded PrivateKeyInfo.
void SetPublicKeyFromPrivateKeyInfo(OEMCrypto_PrivateKeyType key_type,
const uint8_t* buffer, size_t length);
// Loads the specified RSA public key into public_rsa_. // Loads the specified RSA public key into public_rsa_.
void SetRsaPublicKey(const uint8_t* buffer, size_t length); // The provided key is serialized as an ASN.1 DER encoded PrivateKeyInfo.
void SetRsaPublicKeyFromPrivateKeyInfo(const uint8_t* buffer, size_t length);
// Loads the specified EC public key into public_ec_. // Loads the specified EC public key into public_ec_.
void SetEcPublicKey(const uint8_t* buffer, size_t length); // The provided key is serialized as an ASN.1 DER encoded PrivateKeyInfo.
void SetEccPublicKeyFromPrivateKeyInfo(const uint8_t* buffer, size_t length);
// Loads the specified DRM public key into the appropriate key.
// The provided key is serialized as an ASN.1 DER encoded SubjectPublicKey.
void SetPublicKeyFromSubjectPublicKey(OEMCrypto_PrivateKeyType key_type,
const uint8_t* buffer, size_t length);
// Loads the specified RSA public key into public_rsa_.
// The provided key is serialized as an ASN.1 DER encoded SubjectPublicKey.
void SetRsaPublicKeyFromSubjectPublicKey(const uint8_t* buffer,
size_t length);
// Loads the specified EC public key into public_ec_.
// The provided key is serialized as an ASN.1 DER encoded SubjectPublicKey.
void SetEccPublicKeyFromSubjectPublicKey(const uint8_t* buffer,
size_t length);
// Verifies the given signature is from the given message and RSA key, pkey.
static bool VerifyPSSSignature(EVP_PKEY* pkey, const uint8_t* message,
size_t message_length,
const uint8_t* signature,
size_t signature_length);
// Verify that the message was signed by the private key associated with // Verify that the message was signed by the private key associated with
// |public_rsa_| using the specified padding scheme. // |public_rsa_| using the specified padding scheme.
void VerifyRSASignature(const vector<uint8_t>& message, void VerifyRsaSignature(const vector<uint8_t>& message,
const uint8_t* signature, size_t signature_length, const uint8_t* signature, size_t signature_length,
RSA_Padding_Scheme padding_scheme); RSA_Padding_Scheme padding_scheme);
// Verify that the message was signed by the private key associated with
// |public_ecc_| using Widevine ECDSA.
void VerifyEccSignature(const vector<uint8_t>& message,
const uint8_t* signature, size_t signature_length);
// Encrypts a known session key with public_rsa_ for use in future calls to // Encrypts a known session key with public_rsa_ for use in future calls to
// OEMCrypto_DeriveKeysFromSessionKey or OEMCrypto_RewrapDeviceRSAKey30. // OEMCrypto_DeriveKeysFromSessionKey or OEMCrypto_RewrapDeviceRSAKey30.
// The unencrypted session key is stored in session_key. // The unencrypted session key is stored in session_key.
bool GenerateRSASessionKey(vector<uint8_t>* session_key, bool GenerateRsaSessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* enc_session_key); vector<uint8_t>* enc_session_key);
// Derives a session key with public_ec_ and a ephemeral "server" ECC key
// for use in future calls to OEMCrypto_DeriveKeysFromSessionKey.
// The unencrypted session key is stored in session_key.
bool GenerateEccSessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* ecdh_public_key_data);
// Calls OEMCrypto_RewrapDeviceRSAKey30 with the given provisioning response // Calls OEMCrypto_RewrapDeviceRSAKey30 with the given provisioning response
// message. If force is true, we assert that the key loads successfully. // message. If force is true, we assert that the key loads successfully.
void RewrapRSAKey30(const struct RSAPrivateKeyMessage& encrypted, void RewrapRSAKey30(const struct RSAPrivateKeyMessage& encrypted,
const std::vector<uint8_t>& encrypted_message_key, const std::vector<uint8_t>& encrypted_message_key,
vector<uint8_t>* wrapped_key, bool force); vector<uint8_t>* wrapped_key, bool force);
// Loads the specified wrapped_rsa_key into OEMCrypto, and then runs
// GenerateDerivedKeysFromSessionKey to install known encryption and mac keys. void LoadWrappedDrmKey(OEMCrypto_PrivateKeyType key_type,
void InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key); const vector<uint8_t>& wrapped_drm_key);
// Loads the specified wrapped_rsa_key into OEMCrypto.
void LoadWrappedRsaDrmKey(const vector<uint8_t>& wrapped_rsa_key);
// Loads the specified wrapped_ecc_key into OEMCrypto.
void LoadWrappedEccDrmKey(const vector<uint8_t>& wrapped_ecc_key);
// Creates a new usage entry, and keeps track of the index. // Creates a new usage entry, and keeps track of the index.
// If status is null, we expect success, otherwise status is set to the // If status is null, we expect success, otherwise status is set to the
// return value. // return value.
@@ -676,21 +703,21 @@ class Session {
OEMCryptoResult actual_select_result, OEMCryptoResult actual_select_result,
OEMCryptoResult actual_decryt_result); OEMCryptoResult actual_decryt_result);
bool open_; bool open_ = false;
bool forced_session_id_; bool forced_session_id_ = false;
OEMCrypto_SESSION session_id_; OEMCrypto_SESSION session_id_ = 0;
KeyDeriver key_deriver_; KeyDeriver key_deriver_;
uint32_t nonce_; uint32_t nonce_ = 0;
// Only one of RSA or EC should be set. // Only one of RSA or EC should be set.
RSA* public_rsa_ = nullptr; std::unique_ptr<util::RsaPublicKey> public_rsa_;
EC_KEY* public_ec_ = nullptr; std::unique_ptr<util::EccPublicKey> public_ec_;
vector<uint8_t> pst_report_buffer_; vector<uint8_t> pst_report_buffer_;
MessageData license_ = {}; MessageData license_ = {};
vector<uint8_t> encrypted_usage_entry_; vector<uint8_t> encrypted_usage_entry_;
uint32_t usage_entry_number_; uint32_t usage_entry_number_ = 0;
string pst_; string pst_;
}; }; // class Session
// Used for OEMCrypto Fuzzing: Convert byte to a valid boolean to avoid errors // Used for OEMCrypto Fuzzing: Convert byte to a valid boolean to avoid errors
// generated by msan. // generated by msan.

View File

@@ -92,12 +92,11 @@ void SessionUtil::InstallTestRSAKey(Session* s) {
wrapped_private_key.data(), &wrapped_private_key_size, &key_type)); wrapped_private_key.data(), &wrapped_private_key_size, &key_type));
// Assume the public key has been verified by the server and the DRM cert is // Assume the public key has been verified by the server and the DRM cert is
// returned. // returned.
ASSERT_EQ(OEMCrypto_SUCCESS, wrapped_private_key.resize(wrapped_private_key_size);
OEMCrypto_LoadDRMPrivateKey(s->session_id(), key_type,
wrapped_private_key.data(),
wrapped_private_key_size));
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(
s->SetRsaPublicKey(public_key.data(), public_key_size)); s->LoadWrappedDrmKey(key_type, wrapped_private_key));
ASSERT_NO_FATAL_FAILURE(s->SetPublicKeyFromSubjectPublicKey(
key_type, public_key.data(), public_key_size));
return; return;
} }
@@ -108,10 +107,10 @@ void SessionUtil::InstallTestRSAKey(Session* s) {
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
} }
// Load the wrapped rsa test key. // Load the wrapped rsa test key.
ASSERT_NO_FATAL_FAILURE(s->InstallRSASessionTestKey(wrapped_rsa_key_)); ASSERT_NO_FATAL_FAILURE(s->LoadWrappedRsaDrmKey(wrapped_rsa_key_));
} }
// Test RSA key should be loaded. // Test RSA key should be loaded.
ASSERT_NO_FATAL_FAILURE(s->PreparePublicKey()); ASSERT_NO_FATAL_FAILURE(s->SetTestRsaPublicKey());
} }
} // namespace wvoec } // namespace wvoec

View File

@@ -1214,8 +1214,8 @@ TEST_F(OEMCryptoProv30Test, GetCertOnlyAPI16) {
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
// Install the DRM Cert's RSA key. // Install the DRM Cert's RSA key.
ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_)); ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey()); ASSERT_NO_FATAL_FAILURE(s.SetTestRsaPublicKey());
// Request the OEM Cert. -- This should NOT load the OEM Private key. // Request the OEM Cert. -- This should NOT load the OEM Private key.
vector<uint8_t> public_cert; vector<uint8_t> public_cert;
size_t public_cert_length = 0; size_t public_cert_length = 0;
@@ -1247,8 +1247,8 @@ TEST_F(OEMCryptoProv30Test, OEMCryptoMemoryGetOEMPublicCertForHugeCertLength) {
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
// Install the DRM Cert's RSA key. // Install the DRM Cert's RSA key.
ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_)); ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey()); ASSERT_NO_FATAL_FAILURE(s.SetTestRsaPublicKey());
auto oemcrypto_function = [](size_t input_length) { auto oemcrypto_function = [](size_t input_length) {
size_t public_cert_length = input_length; size_t public_cert_length = input_length;
@@ -1355,15 +1355,8 @@ TEST_F(OEMCryptoProv40Test, GenerateCertificateKeyPairSuccess) {
public_key_signature.resize(public_key_signature_size); public_key_signature.resize(public_key_signature_size);
wrapped_private_key.resize(wrapped_private_key_size); wrapped_private_key.resize(wrapped_private_key_size);
// Parse the public key generated to make sure it is correctly formatted. // Parse the public key generated to make sure it is correctly formatted.
if (key_type == OEMCrypto_PrivateKeyType::OEMCrypto_RSA_Private_Key) { ASSERT_NO_FATAL_FAILURE(s.SetPublicKeyFromSubjectPublicKey(
ASSERT_NO_FATAL_FAILURE( key_type, public_key.data(), public_key_size));
s.SetRsaPublicKey(public_key.data(), public_key_size));
} else if (key_type == OEMCrypto_PrivateKeyType::OEMCrypto_ECC_Private_Key) {
ASSERT_NO_FATAL_FAILURE(
s.SetEcPublicKey(public_key.data(), public_key_size));
} else {
FAIL() << "Unknown private key type: " << static_cast<int>(key_type);
}
} }
// Verifies the generated key pairs are different on each call. // Verifies the generated key pairs are different on each call.
@@ -1522,10 +1515,10 @@ TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeyCanBeUsed) {
wrapped_private_key2.resize(wrapped_private_key_size2); wrapped_private_key2.resize(wrapped_private_key_size2);
// Verify public_key_signature2 with public_key1. // Verify public_key_signature2 with public_key1.
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromSubjectPublicKey(
public_key1.data(), public_key1.size()));
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(
s.SetRsaPublicKey(public_key1.data(), public_key1.size())); s.VerifyRsaSignature(public_key2, public_key_signature2.data(),
ASSERT_NO_FATAL_FAILURE(
s.VerifyRSASignature(public_key2, public_key_signature2.data(),
public_key_signature2.size(), kSign_RSASSA_PSS)); public_key_signature2.size(), kSign_RSASSA_PSS));
} }
@@ -5363,7 +5356,7 @@ TEST_F(OEMCryptoLoadsCertificate, LoadRSASessionKey) {
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_)); ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
} }
TEST_F(OEMCryptoLoadsCertificate, SignProvisioningRequest) { TEST_F(OEMCryptoLoadsCertificate, SignProvisioningRequest) {
@@ -5797,14 +5790,10 @@ TEST_F(OEMCryptoLoadsCertificate,
// Test that a wrapped RSA key can be loaded. // Test that a wrapped RSA key can be loaded.
TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) { TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) {
OEMCryptoResult sts;
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
wrapped_rsa_key_.data(),
wrapped_rsa_key_.size());
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
} }
TEST_F(OEMCryptoLoadsCertificate, TEST_F(OEMCryptoLoadsCertificate,
@@ -5813,9 +5802,8 @@ TEST_F(OEMCryptoLoadsCertificate,
auto oemcrypto_function = [&](size_t wrapped_rsa_key_length) { auto oemcrypto_function = [&](size_t wrapped_rsa_key_length) {
Session s; Session s;
s.open(); s.open();
vector<uint8_t> wrapped_rsa_key_buffer(wrapped_rsa_key_length); vector<uint8_t> wrapped_rsa_key_buffer = wrapped_rsa_key_;
memcpy(wrapped_rsa_key_buffer.data(), wrapped_rsa_key_.data(), wrapped_rsa_key_buffer.resize(wrapped_rsa_key_length);
wrapped_rsa_key_.size());
OEMCryptoResult result = OEMCrypto_LoadDRMPrivateKey( OEMCryptoResult result = OEMCrypto_LoadDRMPrivateKey(
s.session_id(), OEMCrypto_RSA_Private_Key, s.session_id(), OEMCrypto_RSA_Private_Key,
wrapped_rsa_key_buffer.data(), wrapped_rsa_key_buffer.size()); wrapped_rsa_key_buffer.data(), wrapped_rsa_key_buffer.size());
@@ -5856,9 +5844,9 @@ class OEMCryptoLoadsCertVariousKeys : public OEMCryptoLoadsCertificate {
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); encoded_rsa_key_.data(), encoded_rsa_key_.size()));
ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_)); ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
LicenseRoundTrip license_messages(&s); LicenseRoundTrip license_messages(&s);
ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest()); ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest());
@@ -5927,12 +5915,9 @@ TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) {
Session s1; // Session s1 loads the default rsa key, but doesn't use it Session s1; // Session s1 loads the default rsa key, but doesn't use it
// until after s2 uses its key. // until after s2 uses its key.
ASSERT_NO_FATAL_FAILURE(s1.open()); ASSERT_NO_FATAL_FAILURE(s1.open());
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(s1.SetRsaPublicKeyFromPrivateKeyInfo(
s1.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); encoded_rsa_key_.data(), encoded_rsa_key_.size()));
ASSERT_EQ(OEMCrypto_SUCCESS, ASSERT_NO_FATAL_FAILURE(s1.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
OEMCrypto_LoadDRMPrivateKey(
s1.session_id(), OEMCrypto_RSA_Private_Key,
wrapped_rsa_key_.data(), wrapped_rsa_key_.size()));
Session s2; // Session s2 uses a different rsa key. Session s2; // Session s2 uses a different rsa key.
encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo4_2048, encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo4_2048,
@@ -5940,9 +5925,9 @@ TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) {
sizeof(kTestRSAPKCS8PrivateKeyInfo4_2048)); sizeof(kTestRSAPKCS8PrivateKeyInfo4_2048));
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
ASSERT_NO_FATAL_FAILURE(s2.open()); ASSERT_NO_FATAL_FAILURE(s2.open());
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(s2.SetRsaPublicKeyFromPrivateKeyInfo(
s2.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); encoded_rsa_key_.data(), encoded_rsa_key_.size()));
ASSERT_NO_FATAL_FAILURE(s2.InstallRSASessionTestKey(wrapped_rsa_key_)); ASSERT_NO_FATAL_FAILURE(s2.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
LicenseRoundTrip license_messages2(&s2); LicenseRoundTrip license_messages2(&s2);
ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest()); ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse()); ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse());
@@ -5976,10 +5961,10 @@ TEST_F(OEMCryptoLoadsCertificate, TestMaxDRMKeys) {
kTestRSAPKCS8PrivateKeys_2048[key_index].end()); kTestRSAPKCS8PrivateKeys_2048[key_index].end());
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey()); ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
ASSERT_NO_FATAL_FAILURE(sessions[i]->open()); ASSERT_NO_FATAL_FAILURE(sessions[i]->open());
ASSERT_NO_FATAL_FAILURE(sessions[i]->PreparePublicKey( ASSERT_NO_FATAL_FAILURE(sessions[i]->SetRsaPublicKeyFromPrivateKeyInfo(
encoded_rsa_key_.data(), encoded_rsa_key_.size())); encoded_rsa_key_.data(), encoded_rsa_key_.size()));
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(
sessions[i]->InstallRSASessionTestKey(wrapped_rsa_key_)); sessions[i]->LoadWrappedRsaDrmKey(wrapped_rsa_key_));
} }
// Attempts to load one more key than the kMaxTotalDRMPrivateKeys // Attempts to load one more key than the kMaxTotalDRMPrivateKeys
@@ -6053,7 +6038,7 @@ class OEMCryptoUsesCertificate : public OEMCryptoLoadsCertificate {
ASSERT_NO_FATAL_FAILURE(session_.open()); ASSERT_NO_FATAL_FAILURE(session_.open());
if (global_features.derive_key_method == if (global_features.derive_key_method ==
DeviceFeatures::LOAD_TEST_RSA_KEY) { DeviceFeatures::LOAD_TEST_RSA_KEY) {
ASSERT_NO_FATAL_FAILURE(session_.PreparePublicKey( ASSERT_NO_FATAL_FAILURE(session_.SetRsaPublicKeyFromPrivateKeyInfo(
encoded_rsa_key_.data(), encoded_rsa_key_.size())); encoded_rsa_key_.data(), encoded_rsa_key_.size()));
} else { } else {
InstallTestRSAKey(&session_); InstallTestRSAKey(&session_);
@@ -6092,10 +6077,7 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
while (clock.now() - start_time < kTestDuration) { while (clock.now() - start_time < kTestDuration) {
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
wrapped_rsa_key_.data(),
wrapped_rsa_key_.size());
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
const size_t size = 50; const size_t size = 50;
vector<uint8_t> licenseRequest(size); vector<uint8_t> licenseRequest(size);
GetRandBytes(licenseRequest.data(), licenseRequest.size()); GetRandBytes(licenseRequest.data(), licenseRequest.size());
@@ -6133,15 +6115,12 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_EQ(OEMCrypto_SUCCESS, ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
OEMCrypto_LoadDRMPrivateKey(
s.session_id(), OEMCrypto_RSA_Private_Key,
wrapped_rsa_key_.data(), wrapped_rsa_key_.size()));
vector<uint8_t> session_key; vector<uint8_t> session_key;
vector<uint8_t> enc_session_key; vector<uint8_t> enc_session_key;
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); encoded_rsa_key_.data(), encoded_rsa_key_.size()));
ASSERT_TRUE(s.GenerateRSASessionKey(&session_key, &enc_session_key)); ASSERT_TRUE(s.GenerateRsaSessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context; vector<uint8_t> mac_context;
vector<uint8_t> enc_context; vector<uint8_t> enc_context;
s.FillDefaultContext(&mac_context, &enc_context); s.FillDefaultContext(&mac_context, &enc_context);
@@ -6188,7 +6167,7 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) { TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) {
vector<uint8_t> session_key; vector<uint8_t> session_key;
vector<uint8_t> enc_session_key; vector<uint8_t> enc_session_key;
ASSERT_TRUE(session_.GenerateRSASessionKey(&session_key, &enc_session_key)); ASSERT_TRUE(session_.GenerateRsaSessionKey(&session_key, &enc_session_key));
const size_t max_size = GetResourceValue(kLargeMessageSize); const size_t max_size = GetResourceValue(kLargeMessageSize);
vector<uint8_t> mac_context(max_size); vector<uint8_t> mac_context(max_size);
vector<uint8_t> enc_context(max_size); vector<uint8_t> enc_context(max_size);
@@ -6208,7 +6187,7 @@ TEST_F(OEMCryptoUsesCertificate,
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeMacContext) { OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeMacContext) {
vector<uint8_t> session_key; vector<uint8_t> session_key;
vector<uint8_t> enc_session_key; vector<uint8_t> enc_session_key;
ASSERT_TRUE(session_.GenerateRSASessionKey(&session_key, &enc_session_key)); ASSERT_TRUE(session_.GenerateRsaSessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context; vector<uint8_t> mac_context;
vector<uint8_t> enc_context; vector<uint8_t> enc_context;
session_.FillDefaultContext(&mac_context, &enc_context); session_.FillDefaultContext(&mac_context, &enc_context);
@@ -6228,7 +6207,7 @@ TEST_F(OEMCryptoUsesCertificate,
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncContext) { OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncContext) {
vector<uint8_t> session_key; vector<uint8_t> session_key;
vector<uint8_t> enc_session_key; vector<uint8_t> enc_session_key;
ASSERT_TRUE(session_.GenerateRSASessionKey(&session_key, &enc_session_key)); ASSERT_TRUE(session_.GenerateRsaSessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context; vector<uint8_t> mac_context;
vector<uint8_t> enc_context; vector<uint8_t> enc_context;
session_.FillDefaultContext(&mac_context, &enc_context); session_.FillDefaultContext(&mac_context, &enc_context);
@@ -6248,7 +6227,7 @@ TEST_F(OEMCryptoUsesCertificate,
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncSessionKey) { OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncSessionKey) {
vector<uint8_t> session_key; vector<uint8_t> session_key;
vector<uint8_t> enc_session_key; vector<uint8_t> enc_session_key;
ASSERT_TRUE(session_.GenerateRSASessionKey(&session_key, &enc_session_key)); ASSERT_TRUE(session_.GenerateRsaSessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context; vector<uint8_t> mac_context;
vector<uint8_t> enc_context; vector<uint8_t> enc_context;
session_.FillDefaultContext(&mac_context, &enc_context); session_.FillDefaultContext(&mac_context, &enc_context);
@@ -6272,10 +6251,7 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
OEMCryptoResult sts; OEMCryptoResult sts;
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
wrapped_rsa_key_.data(),
wrapped_rsa_key_.size());
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
// Sign a Message // Sign a Message
vector<uint8_t> licenseRequest(size); vector<uint8_t> licenseRequest(size);
@@ -6302,19 +6278,15 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
} }
void TestSignature(RSA_Padding_Scheme scheme, size_t size) { void TestSignature(RSA_Padding_Scheme scheme, size_t size) {
OEMCryptoResult sts;
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
wrapped_rsa_key_.data(),
wrapped_rsa_key_.size());
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> licenseRequest(size); vector<uint8_t> licenseRequest(size);
GetRandBytes(licenseRequest.data(), licenseRequest.size()); GetRandBytes(licenseRequest.data(), licenseRequest.size());
size_t signature_length = 0; size_t signature_length = 0;
sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(), OEMCryptoResult sts = OEMCrypto_GenerateRSASignature(
licenseRequest.size(), nullptr, s.session_id(), licenseRequest.data(), licenseRequest.size(), nullptr,
&signature_length, scheme); &signature_length, scheme);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
ASSERT_NE(static_cast<size_t>(0), signature_length); ASSERT_NE(static_cast<size_t>(0), signature_length);
@@ -6328,26 +6300,22 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
<< "Failed to sign with padding scheme=" << (int)scheme << "Failed to sign with padding scheme=" << (int)scheme
<< ", size=" << size; << ", size=" << size;
signature.resize(signature_length); signature.resize(signature_length);
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); encoded_rsa_key_.data(), encoded_rsa_key_.size()));
ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature( ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature(
licenseRequest, signature.data(), signature_length, scheme)); licenseRequest, signature.data(), signature_length, scheme));
} }
void DisallowDeriveKeys() { void DisallowDeriveKeys() {
OEMCryptoResult sts;
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
wrapped_rsa_key_.data(),
wrapped_rsa_key_.size());
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
s.GenerateNonce(); s.GenerateNonce();
vector<uint8_t> session_key; vector<uint8_t> session_key;
vector<uint8_t> enc_session_key; vector<uint8_t> enc_session_key;
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); encoded_rsa_key_.data(), encoded_rsa_key_.size()));
ASSERT_TRUE(s.GenerateRSASessionKey(&session_key, &enc_session_key)); ASSERT_TRUE(s.GenerateRsaSessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context; vector<uint8_t> mac_context;
vector<uint8_t> enc_context; vector<uint8_t> enc_context;
s.FillDefaultContext(&mac_context, &enc_context); s.FillDefaultContext(&mac_context, &enc_context);
@@ -6394,10 +6362,7 @@ TEST_F(OEMCryptoLoadsCertificateAlternates,
if (key_loaded_) { if (key_loaded_) {
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
wrapped_rsa_key_.data(),
wrapped_rsa_key_.size());
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> message_buffer(10); vector<uint8_t> message_buffer(10);
size_t signature_length = 0; size_t signature_length = 0;
@@ -6421,7 +6386,6 @@ TEST_F(OEMCryptoLoadsCertificateAlternates,
TEST_F(OEMCryptoLoadsCertificateAlternates, TEST_F(OEMCryptoLoadsCertificateAlternates,
OEMCryptoMemoryGenerateRSASignatureForHugeSignatureLength) { OEMCryptoMemoryGenerateRSASignatureForHugeSignatureLength) {
OEMCryptoResult sts;
LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false);
// If the device is a cast receiver, then this scheme is required. // If the device is a cast receiver, then this scheme is required.
if (global_features.cast_receiver) { if (global_features.cast_receiver) {
@@ -6430,10 +6394,7 @@ TEST_F(OEMCryptoLoadsCertificateAlternates,
if (key_loaded_) { if (key_loaded_) {
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
wrapped_rsa_key_.data(),
wrapped_rsa_key_.size());
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> message_buffer(50); vector<uint8_t> message_buffer(50);
vector<uint8_t> signature; vector<uint8_t> signature;
@@ -6643,10 +6604,7 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates {
OEMCryptoResult sts; OEMCryptoResult sts;
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(s.open());
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key, ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
wrapped_rsa_key_.data(),
wrapped_rsa_key_.size());
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
// The application will compute the SHA-1 Hash of the message, so this // The application will compute the SHA-1 Hash of the message, so this
// test must do that also. // test must do that also.
@@ -6678,8 +6636,8 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates {
<< "Failed to sign with padding scheme=" << (int)scheme << "Failed to sign with padding scheme=" << (int)scheme
<< ", size=" << message.size(); << ", size=" << message.size();
signature.resize(signature_length); signature.resize(signature_length);
ASSERT_NO_FATAL_FAILURE( ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); encoded_rsa_key_.data(), encoded_rsa_key_.size()));
// Verify that the signature matches the official test vector. // Verify that the signature matches the official test vector.
ASSERT_EQ(correct_signature.size(), signature_length); ASSERT_EQ(correct_signature.size(), signature_length);
@@ -6688,9 +6646,9 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates {
// Also verify that our verification algorithm agrees. This is not needed // Also verify that our verification algorithm agrees. This is not needed
// to test OEMCrypto, but it does verify that this test is valid. // to test OEMCrypto, but it does verify that this test is valid.
ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature(digest, signature.data(), ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature(digest, signature.data(),
signature_length, scheme)); signature_length, scheme));
ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature( ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature(
digest, correct_signature.data(), correct_signature.size(), scheme)); digest, correct_signature.data(), correct_signature.size(), scheme));
} }
}; };