Merge "Updated OEMCrypto tests to use DRM key objects."
This commit is contained in:
@@ -44,6 +44,8 @@ LOCAL_SRC_FILES := \
|
||||
../../oemcrypto/test/oec_device_features.cpp \
|
||||
../../oemcrypto/test/oec_key_deriver.cpp \
|
||||
../../oemcrypto/test/oec_session_util.cpp \
|
||||
../../oemcrypto/util/src/oemcrypto_ecc_key.cpp \
|
||||
../../oemcrypto/util/src/oemcrypto_rsa_key.cpp \
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/android/cdm/test \
|
||||
@@ -58,6 +60,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/test/fuzz_tests \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/odk/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/odk/kdo/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/util/include \
|
||||
|
||||
LOCAL_C_INCLUDES += external/protobuf/src
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ LOCAL_SRC_FILES := \
|
||||
../../oemcrypto/test/oec_device_features.cpp \
|
||||
../../oemcrypto/test/oec_key_deriver.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 \
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
@@ -49,6 +51,7 @@ LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/test/fuzz_tests \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/odk/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/odk/kdo/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/util/include \
|
||||
|
||||
LOCAL_C_INCLUDES += external/protobuf/src
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ LOCAL_SRC_FILES:= \
|
||||
oemcrypto_test_main.cpp \
|
||||
ota_keybox_test.cpp \
|
||||
../../cdm/util/test/test_sleep.cpp \
|
||||
../util/src/oemcrypto_ecc_key.cpp \
|
||||
../util/src/oemcrypto_rsa_key.cpp \
|
||||
../util/src/wvcrc.cpp \
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
|
||||
@@ -309,12 +309,12 @@ void ProvisioningRoundTrip::PrepareSession(
|
||||
OEMCrypto_BootCertificateChain) {
|
||||
// TODO(chelu): change this to CSR provisioning.
|
||||
session_->LoadOEMCert(true);
|
||||
session_->GenerateRSASessionKey(&message_key_, &encrypted_message_key_);
|
||||
session_->GenerateRsaSessionKey(&message_key_, &encrypted_message_key_);
|
||||
encryptor_.set_enc_key(message_key_);
|
||||
} else {
|
||||
EXPECT_EQ(global_features.provisioning_method, OEMCrypto_OEMCertificate);
|
||||
session_->LoadOEMCert(true);
|
||||
session_->GenerateRSASessionKey(&message_key_, &encrypted_message_key_);
|
||||
session_->GenerateRsaSessionKey(&message_key_, &encrypted_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,
|
||||
size_t /* core_message_length */) {
|
||||
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);
|
||||
} else {
|
||||
EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox);
|
||||
@@ -564,11 +564,11 @@ void LicenseRoundTrip::VerifyRequestSignature(
|
||||
if (global_features.api_version < 17) {
|
||||
const std::vector<uint8_t> subdata(data.begin() + core_message_length,
|
||||
data.end());
|
||||
session()->VerifyRSASignature(subdata, generated_signature.data(),
|
||||
session()->VerifyRsaSignature(subdata, generated_signature.data(),
|
||||
generated_signature.size(), kSign_RSASSA_PSS);
|
||||
SHA256(data.data(), core_message_length, request_hash_);
|
||||
} else {
|
||||
session()->VerifyRSASignature(data, generated_signature.data(),
|
||||
session()->VerifyRsaSignature(data, generated_signature.data(),
|
||||
generated_signature.size(), kSign_RSASSA_PSS);
|
||||
SHA256(data.data(), core_message_length, request_hash_);
|
||||
}
|
||||
@@ -1422,17 +1422,10 @@ OEMCryptoResult RenewalRoundTrip::LoadResponse(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 (public_rsa_) RSA_free(public_rsa_);
|
||||
if (public_ec_) EC_KEY_free(public_ec_);
|
||||
}
|
||||
|
||||
void Session::open() {
|
||||
@@ -1512,10 +1505,11 @@ void Session::GenerateDerivedKeysFromSessionKey() {
|
||||
// Uses test certificate.
|
||||
vector<uint8_t> 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
|
||||
// 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> 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));
|
||||
ASSERT_TRUE(pubkey.NotNull());
|
||||
if (i == 0) {
|
||||
public_rsa_ = EVP_PKEY_get1_RSA(pubkey.get());
|
||||
if (!public_rsa_) {
|
||||
cerr << "d2i_RSAPrivateKey failed.\n";
|
||||
dump_boringssl_error();
|
||||
ASSERT_TRUE(nullptr != public_rsa_);
|
||||
}
|
||||
public_rsa_ =
|
||||
util::RsaPublicKey::FromSslHandle(EVP_PKEY_get0_RSA(pubkey.get()));
|
||||
ASSERT_TRUE(public_rsa_)
|
||||
<< "Failed to extract public RSA key from OEM certificate";
|
||||
return;
|
||||
}
|
||||
if (verify_cert) {
|
||||
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) {
|
||||
if (rsa_key == nullptr) {
|
||||
rsa_key = kTestRSAPKCS8PrivateKeyInfo2_2048;
|
||||
rsa_key_length = sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048);
|
||||
}
|
||||
uint8_t* p = const_cast<uint8_t*>(rsa_key);
|
||||
boringssl_ptr<BIO, BIO_vfree> bio(
|
||||
BIO_new_mem_buf(p, static_cast<int>(rsa_key_length)));
|
||||
ASSERT_TRUE(bio.NotNull());
|
||||
boringssl_ptr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> pkcs8_pki(
|
||||
d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), nullptr));
|
||||
ASSERT_TRUE(pkcs8_pki.NotNull());
|
||||
boringssl_ptr<EVP_PKEY, EVP_PKEY_free> evp(EVP_PKCS82PKEY(pkcs8_pki.get()));
|
||||
ASSERT_TRUE(evp.NotNull());
|
||||
if (public_rsa_) RSA_free(public_rsa_);
|
||||
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.
|
||||
void Session::SetTestRsaPublicKey() {
|
||||
public_ec_.reset();
|
||||
public_rsa_ = util::RsaPublicKey::LoadPrivateKeyInfo(
|
||||
kTestRSAPKCS8PrivateKeyInfo2_2048,
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048));
|
||||
ASSERT_TRUE(public_rsa_) << "Could not parse test RSA public key #2";
|
||||
}
|
||||
|
||||
void Session::SetPublicKeyFromPrivateKeyInfo(OEMCrypto_PrivateKeyType key_type,
|
||||
const uint8_t* buffer,
|
||||
size_t length) {
|
||||
switch (key_type) {
|
||||
case OEMCrypto_RSA_Private_Key:
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
SetRsaPublicKeyFromPrivateKeyInfo(buffer, length));
|
||||
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] ";
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
case OEMCrypto_ECC_Private_Key:
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
SetEccPublicKeyFromPrivateKeyInfo(buffer, length));
|
||||
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) {
|
||||
if (public_rsa_) {
|
||||
RSA_free(public_rsa_);
|
||||
public_rsa_ = nullptr;
|
||||
}
|
||||
if (public_ec_) {
|
||||
EC_KEY_free(public_ec_);
|
||||
public_ec_ = nullptr;
|
||||
}
|
||||
public_ec_ = d2i_EC_PUBKEY(nullptr, &buffer, length);
|
||||
if (!public_ec_) {
|
||||
cout << "d2i_RSAPrivateKey failed. ";
|
||||
dump_boringssl_error();
|
||||
FAIL() << "Could not parse public RSA key.";
|
||||
}
|
||||
switch (EC_KEY_check_key(public_ec_)) {
|
||||
case 1: // valid.
|
||||
void Session::SetRsaPublicKeyFromPrivateKeyInfo(const uint8_t* buffer,
|
||||
size_t length) {
|
||||
public_ec_.reset();
|
||||
public_rsa_ = util::RsaPublicKey::LoadPrivateKeyInfo(buffer, length);
|
||||
ASSERT_TRUE(public_rsa_) << "Could not parse RSA public key";
|
||||
}
|
||||
|
||||
void Session::SetEccPublicKeyFromPrivateKeyInfo(const uint8_t* buffer,
|
||||
size_t length) {
|
||||
public_rsa_.reset();
|
||||
public_ec_ = util::EccPublicKey::LoadPrivateKeyInfo(buffer, length);
|
||||
ASSERT_TRUE(public_ec_) << "Could not parse ECC public key";
|
||||
}
|
||||
|
||||
void Session::SetPublicKeyFromSubjectPublicKey(
|
||||
OEMCrypto_PrivateKeyType key_type, const uint8_t* buffer, size_t length) {
|
||||
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;
|
||||
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,
|
||||
size_t message_length,
|
||||
const uint8_t* signature,
|
||||
size_t signature_length) {
|
||||
boringssl_ptr<EVP_MD_CTX, EVP_MD_CTX_free> md_ctx(EVP_MD_CTX_new());
|
||||
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::SetRsaPublicKeyFromSubjectPublicKey(const uint8_t* buffer,
|
||||
size_t length) {
|
||||
public_ec_.reset();
|
||||
public_rsa_ = util::RsaPublicKey::Load(buffer, length);
|
||||
ASSERT_TRUE(public_rsa_) << "Could not parse RSA public key";
|
||||
}
|
||||
|
||||
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,
|
||||
size_t signature_length,
|
||||
RSA_Padding_Scheme padding_scheme) {
|
||||
ASSERT_NE(public_rsa_, nullptr) << "No public RSA key loaded in test code.";
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(RSA_size(public_rsa_)), signature_length)
|
||||
<< "Signature size is wrong. " << signature_length << ", should be "
|
||||
<< RSA_size(public_rsa_);
|
||||
|
||||
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.";
|
||||
ASSERT_TRUE(public_rsa_) << "No public RSA key loaded in test code";
|
||||
if (padding_scheme != kSign_RSASSA_PSS &&
|
||||
padding_scheme != kSign_PKCS1_Block1) {
|
||||
FAIL() << "Padding scheme not supported: " << padding_scheme;
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
*session_key = wvutil::a2b_hex("6fa479c731d2770b6a61a5d1420bb9d1");
|
||||
enc_session_key->assign(RSA_size(public_rsa_), 0);
|
||||
int status = RSA_public_encrypt(
|
||||
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();
|
||||
*enc_session_key = public_rsa_->EncryptSessionKey(*session_key);
|
||||
if (enc_session_key->empty()) {
|
||||
return false;
|
||||
}
|
||||
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,
|
||||
OEMCrypto_LoadDRMPrivateKey(session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key.data(),
|
||||
wrapped_rsa_key.size()));
|
||||
OEMCrypto_LoadDRMPrivateKey(session_id(), key_type,
|
||||
wrapped_drm_key.data(),
|
||||
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) {
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// OEMCrypto unit tests
|
||||
//
|
||||
#include <gtest/gtest.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <string>
|
||||
@@ -21,7 +19,9 @@
|
||||
#include "odk.h"
|
||||
#include "oec_device_features.h"
|
||||
#include "oec_key_deriver.h"
|
||||
#include "oemcrypto_ecc_key.h"
|
||||
#include "oemcrypto_fuzz_structs.h"
|
||||
#include "oemcrypto_rsa_key.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "pst_report.h"
|
||||
|
||||
@@ -571,38 +571,65 @@ class Session {
|
||||
void RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
|
||||
size_t message_size, const std::vector<uint8_t>& signature,
|
||||
vector<uint8_t>* wrapped_key, bool force);
|
||||
// Loads the specified RSA public key into public_rsa_. If rsa_key is null,
|
||||
// the default test key is loaded.
|
||||
void PreparePublicKey(const uint8_t* rsa_key = nullptr,
|
||||
size_t rsa_key_length = 0);
|
||||
// Loads the default test RSA public key into public_rsa_.
|
||||
void SetTestRsaPublicKey();
|
||||
// Loads the specified DRM public key into the appropriate key.
|
||||
// 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_.
|
||||
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_.
|
||||
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
|
||||
// |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,
|
||||
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
|
||||
// OEMCrypto_DeriveKeysFromSessionKey or OEMCrypto_RewrapDeviceRSAKey30.
|
||||
// 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);
|
||||
// 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
|
||||
// message. If force is true, we assert that the key loads successfully.
|
||||
void RewrapRSAKey30(const struct RSAPrivateKeyMessage& encrypted,
|
||||
const std::vector<uint8_t>& encrypted_message_key,
|
||||
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 InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key);
|
||||
|
||||
void LoadWrappedDrmKey(OEMCrypto_PrivateKeyType key_type,
|
||||
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.
|
||||
// If status is null, we expect success, otherwise status is set to the
|
||||
// return value.
|
||||
@@ -676,21 +703,21 @@ class Session {
|
||||
OEMCryptoResult actual_select_result,
|
||||
OEMCryptoResult actual_decryt_result);
|
||||
|
||||
bool open_;
|
||||
bool forced_session_id_;
|
||||
OEMCrypto_SESSION session_id_;
|
||||
bool open_ = false;
|
||||
bool forced_session_id_ = false;
|
||||
OEMCrypto_SESSION session_id_ = 0;
|
||||
KeyDeriver key_deriver_;
|
||||
uint32_t nonce_;
|
||||
uint32_t nonce_ = 0;
|
||||
// Only one of RSA or EC should be set.
|
||||
RSA* public_rsa_ = nullptr;
|
||||
EC_KEY* public_ec_ = nullptr;
|
||||
std::unique_ptr<util::RsaPublicKey> public_rsa_;
|
||||
std::unique_ptr<util::EccPublicKey> public_ec_;
|
||||
vector<uint8_t> pst_report_buffer_;
|
||||
MessageData license_ = {};
|
||||
|
||||
vector<uint8_t> encrypted_usage_entry_;
|
||||
uint32_t usage_entry_number_;
|
||||
uint32_t usage_entry_number_ = 0;
|
||||
string pst_;
|
||||
};
|
||||
}; // class Session
|
||||
|
||||
// Used for OEMCrypto Fuzzing: Convert byte to a valid boolean to avoid errors
|
||||
// generated by msan.
|
||||
|
||||
@@ -92,12 +92,11 @@ void SessionUtil::InstallTestRSAKey(Session* s) {
|
||||
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
|
||||
// returned.
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||
OEMCrypto_LoadDRMPrivateKey(s->session_id(), key_type,
|
||||
wrapped_private_key.data(),
|
||||
wrapped_private_key_size));
|
||||
wrapped_private_key.resize(wrapped_private_key_size);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -108,10 +107,10 @@ void SessionUtil::InstallTestRSAKey(Session* s) {
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
|
||||
}
|
||||
// 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.
|
||||
ASSERT_NO_FATAL_FAILURE(s->PreparePublicKey());
|
||||
ASSERT_NO_FATAL_FAILURE(s->SetTestRsaPublicKey());
|
||||
}
|
||||
|
||||
} // namespace wvoec
|
||||
|
||||
@@ -1214,8 +1214,8 @@ TEST_F(OEMCryptoProv30Test, GetCertOnlyAPI16) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
// Install the DRM Cert's RSA key.
|
||||
ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetTestRsaPublicKey());
|
||||
// Request the OEM Cert. -- This should NOT load the OEM Private key.
|
||||
vector<uint8_t> public_cert;
|
||||
size_t public_cert_length = 0;
|
||||
@@ -1247,8 +1247,8 @@ TEST_F(OEMCryptoProv30Test, OEMCryptoMemoryGetOEMPublicCertForHugeCertLength) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
// Install the DRM Cert's RSA key.
|
||||
ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetTestRsaPublicKey());
|
||||
|
||||
auto oemcrypto_function = [](size_t 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);
|
||||
wrapped_private_key.resize(wrapped_private_key_size);
|
||||
// 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.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);
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetPublicKeyFromSubjectPublicKey(
|
||||
key_type, public_key.data(), public_key_size));
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Verify public_key_signature2 with public_key1.
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromSubjectPublicKey(
|
||||
public_key1.data(), public_key1.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.SetRsaPublicKey(public_key1.data(), public_key1.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.VerifyRSASignature(public_key2, public_key_signature2.data(),
|
||||
s.VerifyRsaSignature(public_key2, public_key_signature2.data(),
|
||||
public_key_signature2.size(), kSign_RSASSA_PSS));
|
||||
}
|
||||
|
||||
@@ -5363,7 +5356,7 @@ TEST_F(OEMCryptoLoadsCertificate, LoadRSASessionKey) {
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
|
||||
Session s;
|
||||
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) {
|
||||
@@ -5797,14 +5790,10 @@ TEST_F(OEMCryptoLoadsCertificate,
|
||||
|
||||
// Test that a wrapped RSA key can be loaded.
|
||||
TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) {
|
||||
OEMCryptoResult sts;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(),
|
||||
wrapped_rsa_key_.size());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertificate,
|
||||
@@ -5813,9 +5802,8 @@ TEST_F(OEMCryptoLoadsCertificate,
|
||||
auto oemcrypto_function = [&](size_t wrapped_rsa_key_length) {
|
||||
Session s;
|
||||
s.open();
|
||||
vector<uint8_t> wrapped_rsa_key_buffer(wrapped_rsa_key_length);
|
||||
memcpy(wrapped_rsa_key_buffer.data(), wrapped_rsa_key_.data(),
|
||||
wrapped_rsa_key_.size());
|
||||
vector<uint8_t> wrapped_rsa_key_buffer = wrapped_rsa_key_;
|
||||
wrapped_rsa_key_buffer.resize(wrapped_rsa_key_length);
|
||||
OEMCryptoResult result = OEMCrypto_LoadDRMPrivateKey(
|
||||
s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_buffer.data(), wrapped_rsa_key_buffer.size());
|
||||
@@ -5856,9 +5844,9 @@ class OEMCryptoLoadsCertVariousKeys : public OEMCryptoLoadsCertificate {
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
|
||||
LicenseRoundTrip license_messages(&s);
|
||||
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
|
||||
// until after s2 uses its key.
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s1.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||
OEMCrypto_LoadDRMPrivateKey(
|
||||
s1.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(), wrapped_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
|
||||
Session s2; // Session s2 uses a different rsa key.
|
||||
encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo4_2048,
|
||||
@@ -5940,9 +5925,9 @@ TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) {
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo4_2048));
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
|
||||
ASSERT_NO_FATAL_FAILURE(s2.open());
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s2.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s2.InstallRSASessionTestKey(wrapped_rsa_key_));
|
||||
ASSERT_NO_FATAL_FAILURE(s2.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s2.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
LicenseRoundTrip license_messages2(&s2);
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse());
|
||||
@@ -5976,10 +5961,10 @@ TEST_F(OEMCryptoLoadsCertificate, TestMaxDRMKeys) {
|
||||
kTestRSAPKCS8PrivateKeys_2048[key_index].end());
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
|
||||
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()));
|
||||
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
|
||||
@@ -6053,7 +6038,7 @@ class OEMCryptoUsesCertificate : public OEMCryptoLoadsCertificate {
|
||||
ASSERT_NO_FATAL_FAILURE(session_.open());
|
||||
if (global_features.derive_key_method ==
|
||||
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()));
|
||||
} else {
|
||||
InstallTestRSAKey(&session_);
|
||||
@@ -6092,10 +6077,7 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
|
||||
while (clock.now() - start_time < kTestDuration) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(),
|
||||
wrapped_rsa_key_.size());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
const size_t size = 50;
|
||||
vector<uint8_t> licenseRequest(size);
|
||||
GetRandBytes(licenseRequest.data(), licenseRequest.size());
|
||||
@@ -6133,15 +6115,12 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
|
||||
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||
OEMCrypto_LoadDRMPrivateKey(
|
||||
s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(), wrapped_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
vector<uint8_t> session_key;
|
||||
vector<uint8_t> enc_session_key;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_TRUE(s.GenerateRSASessionKey(&session_key, &enc_session_key));
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_TRUE(s.GenerateRsaSessionKey(&session_key, &enc_session_key));
|
||||
vector<uint8_t> mac_context;
|
||||
vector<uint8_t> enc_context;
|
||||
s.FillDefaultContext(&mac_context, &enc_context);
|
||||
@@ -6188,7 +6167,7 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
|
||||
TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) {
|
||||
vector<uint8_t> 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);
|
||||
vector<uint8_t> mac_context(max_size);
|
||||
vector<uint8_t> enc_context(max_size);
|
||||
@@ -6208,7 +6187,7 @@ TEST_F(OEMCryptoUsesCertificate,
|
||||
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeMacContext) {
|
||||
vector<uint8_t> 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> enc_context;
|
||||
session_.FillDefaultContext(&mac_context, &enc_context);
|
||||
@@ -6228,7 +6207,7 @@ TEST_F(OEMCryptoUsesCertificate,
|
||||
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncContext) {
|
||||
vector<uint8_t> 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> enc_context;
|
||||
session_.FillDefaultContext(&mac_context, &enc_context);
|
||||
@@ -6248,7 +6227,7 @@ TEST_F(OEMCryptoUsesCertificate,
|
||||
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncSessionKey) {
|
||||
vector<uint8_t> 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> enc_context;
|
||||
session_.FillDefaultContext(&mac_context, &enc_context);
|
||||
@@ -6272,10 +6251,7 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
|
||||
OEMCryptoResult sts;
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(),
|
||||
wrapped_rsa_key_.size());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
|
||||
// Sign a Message
|
||||
vector<uint8_t> licenseRequest(size);
|
||||
@@ -6302,20 +6278,16 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
|
||||
}
|
||||
|
||||
void TestSignature(RSA_Padding_Scheme scheme, size_t size) {
|
||||
OEMCryptoResult sts;
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(),
|
||||
wrapped_rsa_key_.size());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
|
||||
vector<uint8_t> licenseRequest(size);
|
||||
GetRandBytes(licenseRequest.data(), licenseRequest.size());
|
||||
size_t signature_length = 0;
|
||||
sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(),
|
||||
licenseRequest.size(), nullptr,
|
||||
&signature_length, scheme);
|
||||
OEMCryptoResult sts = OEMCrypto_GenerateRSASignature(
|
||||
s.session_id(), licenseRequest.data(), licenseRequest.size(), nullptr,
|
||||
&signature_length, scheme);
|
||||
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
|
||||
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
|
||||
<< ", size=" << size;
|
||||
signature.resize(signature_length);
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature(
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature(
|
||||
licenseRequest, signature.data(), signature_length, scheme));
|
||||
}
|
||||
|
||||
void DisallowDeriveKeys() {
|
||||
OEMCryptoResult sts;
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(),
|
||||
wrapped_rsa_key_.size());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
s.GenerateNonce();
|
||||
vector<uint8_t> session_key;
|
||||
vector<uint8_t> enc_session_key;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_TRUE(s.GenerateRSASessionKey(&session_key, &enc_session_key));
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_TRUE(s.GenerateRsaSessionKey(&session_key, &enc_session_key));
|
||||
vector<uint8_t> mac_context;
|
||||
vector<uint8_t> enc_context;
|
||||
s.FillDefaultContext(&mac_context, &enc_context);
|
||||
@@ -6394,10 +6362,7 @@ TEST_F(OEMCryptoLoadsCertificateAlternates,
|
||||
if (key_loaded_) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(),
|
||||
wrapped_rsa_key_.size());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
|
||||
vector<uint8_t> message_buffer(10);
|
||||
size_t signature_length = 0;
|
||||
@@ -6421,7 +6386,6 @@ TEST_F(OEMCryptoLoadsCertificateAlternates,
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertificateAlternates,
|
||||
OEMCryptoMemoryGenerateRSASignatureForHugeSignatureLength) {
|
||||
OEMCryptoResult sts;
|
||||
LoadWithAllowedSchemes(kSign_PKCS1_Block1, false);
|
||||
// If the device is a cast receiver, then this scheme is required.
|
||||
if (global_features.cast_receiver) {
|
||||
@@ -6430,10 +6394,7 @@ TEST_F(OEMCryptoLoadsCertificateAlternates,
|
||||
if (key_loaded_) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(),
|
||||
wrapped_rsa_key_.size());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
|
||||
vector<uint8_t> message_buffer(50);
|
||||
vector<uint8_t> signature;
|
||||
@@ -6643,10 +6604,7 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates {
|
||||
OEMCryptoResult sts;
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
sts = OEMCrypto_LoadDRMPrivateKey(s.session_id(), OEMCrypto_RSA_Private_Key,
|
||||
wrapped_rsa_key_.data(),
|
||||
wrapped_rsa_key_.size());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_rsa_key_));
|
||||
|
||||
// The application will compute the SHA-1 Hash of the message, so this
|
||||
// test must do that also.
|
||||
@@ -6678,8 +6636,8 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates {
|
||||
<< "Failed to sign with padding scheme=" << (int)scheme
|
||||
<< ", size=" << message.size();
|
||||
signature.resize(signature_length);
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
|
||||
// Verify that the signature matches the official test vector.
|
||||
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
|
||||
// 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));
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature(
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature(
|
||||
digest, correct_signature.data(), correct_signature.size(), scheme));
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user