Updated OEMCrypto tests to use DRM key objects.

[ Merge of http://go/wvgerrit/147275 ]

Swapped out use of OpenSSL/BoringSSL RSA and EC_KEY to use OEMCrypto
reference utility classes RsaPublicKey/EccPublicKey.  This enables
further test development with ECC keys, and removes duplicate OpenSSL/
BoringSSL code.

For Android makefiles, only the minimally required files have been
added.

Bug: 205902021
Bug: 236317198
Test: run_prov30_test run_prov40_test oemcrypto_test
Change-Id: I64491018e8ffb69bf986083e3aae446eb9e5cf39
This commit is contained in:
Alex Dale
2022-06-16 19:56:56 -07:00
parent 2a371dce54
commit bfa2d782bd
7 changed files with 252 additions and 314 deletions

View File

@@ -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 += \

View File

@@ -310,12 +310,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_);
}
}
@@ -324,7 +324,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);
@@ -565,11 +565,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_);
}
@@ -1403,17 +1403,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() {
@@ -1493,10 +1486,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);
@@ -1621,12 +1615,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);
@@ -1658,199 +1651,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) {

View File

@@ -8,8 +8,6 @@
// OEMCrypto unit tests
//
#include <gtest/gtest.h>
#include <openssl/ec.h>
#include <openssl/rsa.h>
#include <time.h>
#include <string>
@@ -20,7 +18,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"
@@ -558,38 +558,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.
@@ -663,21 +690,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.

View File

@@ -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

View File

@@ -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));
}
@@ -5330,7 +5323,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) {
@@ -5764,14 +5757,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,
@@ -5780,9 +5769,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());
@@ -5823,9 +5811,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());
@@ -5894,12 +5882,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,
@@ -5907,9 +5892,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());
@@ -5943,10 +5928,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
@@ -6020,7 +6005,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_);
@@ -6059,10 +6044,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());
@@ -6100,15 +6082,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);
@@ -6155,7 +6134,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);
@@ -6175,7 +6154,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);
@@ -6195,7 +6174,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);
@@ -6215,7 +6194,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);
@@ -6239,10 +6218,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);
@@ -6269,20 +6245,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);
@@ -6295,26 +6267,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);
@@ -6361,10 +6329,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;
@@ -6388,7 +6353,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) {
@@ -6397,10 +6361,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;
@@ -6610,10 +6571,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.
@@ -6645,8 +6603,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);
@@ -6655,9 +6613,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));
}
};