Source release 19.1.0
This commit is contained in:
@@ -5,8 +5,11 @@
|
||||
|
||||
#include "oemcrypto_provisioning_test.h"
|
||||
|
||||
#include "bcc_validator.h"
|
||||
#include "device_info_validator.h"
|
||||
#include "log.h"
|
||||
#include "platform.h"
|
||||
#include "signed_csr_payload_validator.h"
|
||||
#include "test_sleep.h"
|
||||
|
||||
namespace wvoec {
|
||||
@@ -67,24 +70,6 @@ TEST_F(OEMCryptoKeyboxTest, ProductionKeyboxValid) {
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid());
|
||||
}
|
||||
|
||||
// This tests GenerateDerivedKeys with an 8k context.
|
||||
TEST_F(OEMCryptoKeyboxTest, GenerateDerivedKeysFromKeyboxLargeBuffer) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
const size_t max_size = GetResourceValue(kLargeMessageSize);
|
||||
vector<uint8_t> mac_context(max_size);
|
||||
vector<uint8_t> enc_context(max_size);
|
||||
// Stripe the data so the two vectors are not identical, and not all zeroes.
|
||||
for (size_t i = 0; i < max_size; i++) {
|
||||
mac_context[i] = i % 0x100;
|
||||
enc_context[i] = (3 * i) % 0x100;
|
||||
}
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||
OEMCrypto_GenerateDerivedKeys(
|
||||
s.session_id(), mac_context.data(), mac_context.size(),
|
||||
enc_context.data(), enc_context.size()));
|
||||
}
|
||||
|
||||
// This verifies that the device really does claim to have a certificate.
|
||||
// It should be filtered out for devices that have a keybox.
|
||||
TEST_F(OEMCryptoProv30Test, DeviceClaimsOEMCertificate) {
|
||||
@@ -164,7 +149,6 @@ TEST_F(OEMCryptoProv30Test, GetCertOnlyAPI16) {
|
||||
// Derive keys from the session key -- this should use the DRM Cert's key.
|
||||
// It should NOT use the OEM Private key because that key should not have
|
||||
// been loaded.
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateDerivedKeysFromSessionKey());
|
||||
// Now fill a message and try to load it.
|
||||
LicenseRoundTrip license_messages(&s);
|
||||
license_messages.set_control(0);
|
||||
@@ -251,6 +235,9 @@ TEST_F(OEMCryptoProv40Test, GetBootCertificateChainSuccess) {
|
||||
additional_signature.data(),
|
||||
&additional_signature_size),
|
||||
OEMCrypto_SUCCESS);
|
||||
util::BccValidator validator;
|
||||
EXPECT_EQ(util::CborMessageStatus::kCborParseOk, validator.Parse(bcc));
|
||||
EXPECT_EQ(util::CborMessageStatus::kCborValidateOk, validator.Validate());
|
||||
}
|
||||
|
||||
// Verifies that short buffer error returns when the buffer is short.
|
||||
@@ -363,6 +350,9 @@ TEST_F(OEMCryptoProv40Test, GenerateCertificateKeyPairsAreDifferent) {
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoProv40Test, GetDeviceInformationAPI18) {
|
||||
if (wvoec::global_features.api_version < 18) {
|
||||
GTEST_SKIP() << "Test for versions 18 and up only.";
|
||||
}
|
||||
std::vector<uint8_t> device_info;
|
||||
size_t device_info_length = 0;
|
||||
OEMCryptoResult sts =
|
||||
@@ -374,24 +364,26 @@ TEST_F(OEMCryptoProv40Test, GetDeviceInformationAPI18) {
|
||||
OEMCrypto_GetDeviceInformation(device_info.data(), &device_info_length),
|
||||
OEMCrypto_SUCCESS);
|
||||
EXPECT_NE(device_info_length, 0uL);
|
||||
device_info.resize(device_info_length);
|
||||
constexpr int kDeviceVersion = 3;
|
||||
util::DeviceInfoValidator validator(kDeviceVersion);
|
||||
EXPECT_EQ(util::CborMessageStatus::kCborParseOk,
|
||||
validator.Parse(device_info));
|
||||
validator.Validate();
|
||||
EXPECT_EQ(util::CborMessageStatus::kCborValidateOk, validator.Validate());
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoProv40Test, GetDeviceSignedCsrPayloadAPI18) {
|
||||
std::vector<uint8_t> challenge(64, 0xaa);
|
||||
// TODO: add cppbor support for oemcrypto tests for all targets. Before that,
|
||||
// use hex values which are equivalent of the commented cppbor statement.
|
||||
// std::vector<uint8_t> device_info = cppbor::Map()
|
||||
// .add("manufacturer", "google")
|
||||
// .add("fused", 0)
|
||||
// .add("other", "ignored")
|
||||
// .canonicalize()
|
||||
// .encode();
|
||||
//
|
||||
std::vector<uint8_t> device_info = {
|
||||
0xa3, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x0, 0x65, 0x6f, 0x74,
|
||||
0x68, 0x65, 0x72, 0x67, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64,
|
||||
0x6c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72,
|
||||
0x65, 0x72, 0x66, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65};
|
||||
if (wvoec::global_features.api_version < 18) {
|
||||
GTEST_SKIP() << "Test for versions 18 and up only.";
|
||||
}
|
||||
const std::vector<uint8_t> challenge(64, 0xaa);
|
||||
const std::vector<uint8_t> device_info = cppbor::Map()
|
||||
.add("manufacturer", "google")
|
||||
.add("fused", 0)
|
||||
.add("other", "ignored")
|
||||
.canonicalize()
|
||||
.encode();
|
||||
std::vector<uint8_t> signed_csr_payload;
|
||||
size_t signed_csr_payload_length = 0;
|
||||
OEMCryptoResult sts = OEMCrypto_GetDeviceSignedCsrPayload(
|
||||
@@ -407,17 +399,22 @@ TEST_F(OEMCryptoProv40Test, GetDeviceSignedCsrPayloadAPI18) {
|
||||
&signed_csr_payload_length),
|
||||
OEMCrypto_SUCCESS);
|
||||
EXPECT_NE(signed_csr_payload_length, 0uL);
|
||||
util::SignedCsrPayloadValidator validator;
|
||||
EXPECT_EQ(util::CborMessageStatus::kCborParseOk,
|
||||
validator.Parse(signed_csr_payload));
|
||||
EXPECT_EQ(util::CborMessageStatus::kCborValidateOk, validator.Validate());
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoProv40Test, GetDeviceSignedCsrPayloadInvalid) {
|
||||
std::vector<uint8_t> signed_csr_payload;
|
||||
size_t signed_csr_payload_length = 0;
|
||||
std::vector<uint8_t> challenge(64, 0xaa);
|
||||
std::vector<uint8_t> device_info = {
|
||||
0xa3, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x0, 0x65, 0x6f, 0x74,
|
||||
0x68, 0x65, 0x72, 0x67, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64,
|
||||
0x6c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72,
|
||||
0x65, 0x72, 0x66, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65};
|
||||
const std::vector<uint8_t> challenge(64, 0xaa);
|
||||
const std::vector<uint8_t> device_info = cppbor::Map()
|
||||
.add("manufacturer", "google")
|
||||
.add("fused", 0)
|
||||
.add("other", "ignored")
|
||||
.canonicalize()
|
||||
.encode();
|
||||
std::vector<uint8_t> challenge_empty;
|
||||
OEMCryptoResult sts = OEMCrypto_GetDeviceSignedCsrPayload(
|
||||
challenge_empty.data(), challenge_empty.size(), device_info.data(),
|
||||
@@ -427,7 +424,7 @@ TEST_F(OEMCryptoProv40Test, GetDeviceSignedCsrPayloadInvalid) {
|
||||
ASSERT_EQ(sts, OEMCrypto_ERROR_INVALID_CONTEXT);
|
||||
|
||||
// Oversized challenge
|
||||
std::vector<uint8_t> challenge_long(65, 0xaa);
|
||||
const std::vector<uint8_t> challenge_long(65, 0xaa);
|
||||
sts = OEMCrypto_GetDeviceSignedCsrPayload(
|
||||
challenge_long.data(), challenge_long.size(), device_info.data(),
|
||||
device_info.size(), signed_csr_payload.data(),
|
||||
@@ -693,6 +690,9 @@ TEST_F(OEMCryptoLoadsCertificate, ForbidRSASignatureForDRMKey2) {
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertificate, PrepAndSignLicenseRequestCounterAPI18) {
|
||||
if (wvoec::global_features.api_version < 18) {
|
||||
GTEST_SKIP() << "Test for versions 18 and up only.";
|
||||
}
|
||||
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
|
||||
// provisioning 4. Disabled here temporarily.
|
||||
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
|
||||
@@ -736,14 +736,8 @@ TEST_F(OEMCryptoLoadsCertificate, SignProvisioningRequest) {
|
||||
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
|
||||
}
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
if (global_features.provisioning_method == OEMCrypto_OEMCertificate) {
|
||||
s.LoadOEMCert(true);
|
||||
} else {
|
||||
EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox);
|
||||
s.GenerateDerivedKeysFromKeybox(keybox_);
|
||||
}
|
||||
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.PrepareSession(keybox_));
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
|
||||
}
|
||||
|
||||
@@ -755,16 +749,10 @@ TEST_F(OEMCryptoLoadsCertificate, SignLargeProvisioningRequestAPI16) {
|
||||
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
|
||||
}
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
if (global_features.provisioning_method == OEMCrypto_OEMCertificate) {
|
||||
s.LoadOEMCert(true);
|
||||
} else {
|
||||
EXPECT_EQ(global_features.provisioning_method, OEMCrypto_Keybox);
|
||||
s.GenerateDerivedKeysFromKeybox(keybox_);
|
||||
}
|
||||
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
|
||||
const size_t max_size = GetResourceValue(kLargeMessageSize);
|
||||
provisioning_messages.set_message_size(max_size);
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.PrepareSession(keybox_));
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
|
||||
}
|
||||
|
||||
@@ -779,7 +767,7 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvision) {
|
||||
}
|
||||
Session s;
|
||||
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
|
||||
provisioning_messages.PrepareSession(keybox_);
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.PrepareSession(keybox_));
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
|
||||
@@ -913,6 +901,9 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange5Prov30_API16) {
|
||||
// TODO(b/144186970): This test should also run on Prov 3.0 devices.
|
||||
TEST_F(OEMCryptoLoadsCertificate,
|
||||
CertificateProvisionBadSignatureKeyboxTestAPI16) {
|
||||
if (global_features.provisioning_method != OEMCrypto_Keybox) {
|
||||
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
|
||||
}
|
||||
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
|
||||
// provisioning 4. Disabled here temporarily.
|
||||
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
|
||||
@@ -977,6 +968,9 @@ TEST_F(OEMCryptoLoadsCertificate,
|
||||
if (global_features.provisioning_method != OEMCrypto_Keybox) {
|
||||
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
|
||||
}
|
||||
if (global_features.provisioning_method != OEMCrypto_Keybox) {
|
||||
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
|
||||
}
|
||||
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
|
||||
// provisioning 4. Disabled here temporarily.
|
||||
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
|
||||
@@ -1243,141 +1237,4 @@ TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) {
|
||||
<< "Supported certificates is only " << OEMCrypto_SupportedCertificates();
|
||||
}
|
||||
|
||||
// This test is not run by default, because it takes a long time and
|
||||
// is used to measure RSA performance, not test functionality.
|
||||
TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
|
||||
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
|
||||
// provisioning 4. Disabled here temporarily.
|
||||
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
|
||||
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
|
||||
}
|
||||
const std::chrono::milliseconds kTestDuration(5000);
|
||||
OEMCryptoResult sts;
|
||||
std::chrono::steady_clock clock;
|
||||
wvutil::TestSleep::Sleep(kShortSleep); // Make sure we are not nonce limited.
|
||||
|
||||
auto start_time = clock.now();
|
||||
int count = 15;
|
||||
for (int i = 0; i < count; i++) { // Only 20 nonce available.
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
}
|
||||
auto delta_time = clock.now() - start_time;
|
||||
const double provision_time =
|
||||
delta_time / std::chrono::milliseconds(1) / count;
|
||||
|
||||
Session session;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
start_time = clock.now();
|
||||
count = 0;
|
||||
while (clock.now() - start_time < kTestDuration) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
const size_t size = 50;
|
||||
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, kSign_RSASSA_PSS);
|
||||
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
|
||||
ASSERT_NE(static_cast<size_t>(0), signature_length);
|
||||
|
||||
if (ShouldGenerateCorpus()) {
|
||||
const std::string file_name =
|
||||
GetFileName("oemcrypto_generate_rsa_signature_fuzz_seed_corpus");
|
||||
OEMCrypto_Generate_RSA_Signature_Fuzz fuzzed_structure;
|
||||
fuzzed_structure.padding_scheme = kSign_RSASSA_PSS;
|
||||
fuzzed_structure.signature_length = signature_length;
|
||||
// Cipher mode and algorithm.
|
||||
AppendToFile(file_name, reinterpret_cast<const char*>(&fuzzed_structure),
|
||||
sizeof(fuzzed_structure));
|
||||
AppendToFile(file_name,
|
||||
reinterpret_cast<const char*>(licenseRequest.data()),
|
||||
licenseRequest.size());
|
||||
}
|
||||
|
||||
std::vector<uint8_t> signature(signature_length, 0);
|
||||
sts = OEMCrypto_GenerateRSASignature(
|
||||
s.session_id(), licenseRequest.data(), licenseRequest.size(),
|
||||
signature.data(), &signature_length, kSign_RSASSA_PSS);
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
count++;
|
||||
}
|
||||
delta_time = clock.now() - start_time;
|
||||
const double license_request_time =
|
||||
delta_time / std::chrono::milliseconds(1) / count;
|
||||
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
vector<uint8_t> session_key;
|
||||
vector<uint8_t> 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);
|
||||
|
||||
enc_session_key = wvutil::a2b_hex(
|
||||
"7789c619aa3b9fa3c0a53f57a4abc6"
|
||||
"02157c8aa57e3c6fb450b0bea22667fb"
|
||||
"0c3200f9d9d618e397837c720dc2dadf"
|
||||
"486f33590744b2a4e54ca134ae7dbf74"
|
||||
"434c2fcf6b525f3e132262f05ea3b3c1"
|
||||
"198595c0e52b573335b2e8a3debd0d0d"
|
||||
"d0306f8fcdde4e76476be71342957251"
|
||||
"e1688c9ca6c1c34ed056d3b989394160"
|
||||
"cf6937e5ce4d39cc73d11a2e93da21a2"
|
||||
"fa019d246c852fe960095b32f120c3c2"
|
||||
"7085f7b64aac344a68d607c0768676ce"
|
||||
"d4c5b2d057f7601921b453a451e1dea0"
|
||||
"843ebfef628d9af2784d68e86b730476"
|
||||
"e136dfe19989de4be30a4e7878efcde5"
|
||||
"ad2b1254f80c0c5dd3cf111b56572217"
|
||||
"b9f58fc1dacbf74b59d354a1e62cfa0e"
|
||||
"bf");
|
||||
start_time = clock.now();
|
||||
while (clock.now() - start_time < kTestDuration) {
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||
OEMCrypto_DeriveKeysFromSessionKey(
|
||||
s.session_id(), enc_session_key.data(),
|
||||
enc_session_key.size(), mac_context.data(),
|
||||
mac_context.size(), enc_context.data(), enc_context.size()));
|
||||
count++;
|
||||
}
|
||||
delta_time = clock.now() - start_time;
|
||||
const double derive_keys_time =
|
||||
delta_time / std::chrono::milliseconds(1) / count;
|
||||
|
||||
OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel();
|
||||
printf(
|
||||
"PERF:head, security, provision (ms), lic req(ms), derive "
|
||||
"keys(ms)\n");
|
||||
printf("PERF:stat, %u, %8.3f, %8.3f, %8.3f\n",
|
||||
static_cast<unsigned int>(level), provision_time, license_request_time,
|
||||
derive_keys_time);
|
||||
}
|
||||
|
||||
// Test DeriveKeysFromSessionKey using the maximum size for the HMAC context.
|
||||
TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) {
|
||||
vector<uint8_t> session_key;
|
||||
vector<uint8_t> enc_session_key;
|
||||
ASSERT_TRUE(session_.GenerateSessionKey(&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);
|
||||
// Stripe the data so the two vectors are not identical, and not all zeroes.
|
||||
for (size_t i = 0; i < max_size; i++) {
|
||||
mac_context[i] = i % 0x100;
|
||||
enc_context[i] = (3 * i) % 0x100;
|
||||
}
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||
OEMCrypto_DeriveKeysFromSessionKey(
|
||||
session_.session_id(), enc_session_key.data(),
|
||||
enc_session_key.size(), mac_context.data(), mac_context.size(),
|
||||
enc_context.data(), enc_context.size()));
|
||||
}
|
||||
|
||||
} // namespace wvoec
|
||||
|
||||
Reference in New Issue
Block a user