Files
android/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp
Fred Gylys-Colwell c53047bd1b Document huge buffer tests in separate group
Explain how the huge buffer tests work. In particular, state
that we expect that OEMCrypto returns an error on huge
buffers.

Staged here:
https://developers.devsite.corp.google.com/widevine/drm/client/oemcrypto/v18/oemcrypto-test/group/security

Bug: 300645748
Merged from https://widevine-internal-review.googlesource.com/188034

Change-Id: Iba9d652dfe57df6786b0ab60931f02f8ce9b8180
2024-02-01 13:40:52 -08:00

1899 lines
77 KiB
C++

// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine
// License Agreement.
//
/**
* @mainpage OEMCrypto Unit Tests
*
* The OEMCrypto unit tests are designed to verify that an implementation of
* OEMCrypto is correctly supporting the OEMCrypto API.
*
* @defgroup basic Basic Functionality Tests
* Basic functionality tests.
*
* @defgroup provision Provisioning Tests
* Test for provisioning and certificate key processing. These tests cover
* Provsioning 2.0, 3.0 and 4.0. Tests for the wrong provisioning scheme should
* be skipped.
*
* @defgroup license License Request Tests
* Test for requesting and loading licenses.
*
* @defgroup renewal License Renewal Tests
* Tests for renewing licenses.
*
* @defgroup decrypt Decrypt Tests
* Tests for decrypting content.
*
* @defgroup usage_table Usage Table Tests
* Tests that use the usage table.
*
* @defgroup entitle Entitlement License tests
* Tests for entitlement licenses.
*
* @defgroup cas Conditional Access System Tests
* Tests for OEMCrypto implementations that support MediaCAS.
*
* @defgroup cast Cast Test
* Tests for OEMCrypto implementations that support being a Cast receiver.
*
* @defgroup generic Generic Crypto Tests
* Tests for the Generic Crypto functionality.
*
* @defgroup security Security Tests
* Buffer overflow tests, off-by-one tests, and other security tests.
*
* The way the huge buffer tests work is to create a large buffer and then call
* the API. The test then loops and doubles the buffer until the API returns an
* error. An error is considered a passing test. We expect OEMCrypto to fail
* gracefully on a huge buffer rather than crashing.
*/
#include <ctype.h>
#include <gtest/gtest.h>
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
#include <stdint.h>
#include <algorithm>
#include <chrono>
#include <functional>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "OEMCryptoCENC.h"
#include "clock.h"
#include "log.h"
#include "oec_decrypt_fallback_chain.h"
#include "oec_device_features.h"
#include "oec_extra_test_keys.h"
#include "oec_session_util.h"
#include "oec_test_data.h"
#include "oemcrypto_basic_test.h"
#include "oemcrypto_corpus_generator_helper.h"
#include "oemcrypto_fuzz_structs.h"
#include "oemcrypto_license_test.h"
#include "oemcrypto_provisioning_test.h"
#include "oemcrypto_resource_test.h"
#include "oemcrypto_session_tests_helper.h"
#include "oemcrypto_types.h"
#include "oemcrypto_usage_table_test.h"
#include "platform.h"
#include "string_conversions.h"
#include "test_sleep.h"
#include "wvcrc32.h"
using ::testing::Range;
using ::testing::tuple;
using ::testing::WithParamInterface;
using namespace std;
namespace std { // GTest wants PrintTo to be in the std namespace.
void PrintTo(const tuple<OEMCrypto_CENCEncryptPatternDesc, OEMCryptoCipherMode,
wvoec::OutputType>& param,
ostream* os) {
OEMCrypto_CENCEncryptPatternDesc pattern = ::testing::get<0>(param);
OEMCryptoCipherMode mode = ::testing::get<1>(param);
wvoec::OutputType output = ::testing::get<2>(param);
bool decrypt_inplace = output.decrypt_inplace;
OEMCryptoBufferType type = output.type;
*os << ((mode == OEMCrypto_CipherMode_CENC) ? "CENC mode" : "CBCS mode")
<< ", pattern=(encrypt:" << pattern.encrypt << ", skip:" << pattern.skip
<< ")";
switch (type) {
case OEMCrypto_BufferType_Clear:
*os << ", BufferType = Clear";
break;
case OEMCrypto_BufferType_Secure:
*os << ", BufferType = Secure";
break;
case OEMCrypto_BufferType_Direct:
*os << ", BufferType = Direct";
break;
default:
*os << ", type = <bad type " << type << ">";
break;
}
if (decrypt_inplace) *os << " (in place)";
}
} // namespace std
namespace wvoec {
/// @addtogroup security
/// @{
class OEMCryptoLicenseOverflowTest : public OEMCryptoSessionTests,
public WithParamInterface<uint32_t> {
public:
OEMCryptoLicenseOverflowTest() : license_api_version_(kCurrentAPI) {}
void SetUp() override {
OEMCryptoSessionTests::SetUp();
license_api_version_ = GetParam();
}
void TearDown() override { OEMCryptoSessionTests::TearDown(); }
void TestLoadLicenseForHugeBufferLengths(
const std::function<void(size_t, LicenseRoundTrip*)> f, bool check_status,
bool update_core_message_substring_values) {
auto oemcrypto_function = [&](size_t message_length) {
Session s;
LicenseRoundTrip license_messages(&s);
license_messages.set_api_version(license_api_version_);
s.open();
InstallTestDrmKey(&s);
bool verify_keys_loaded = true;
license_messages.SignAndVerifyRequest();
license_messages.CreateDefaultResponse();
if (update_core_message_substring_values) {
// Make the license message big enough so that updated core message
// substring offset and length values from tests are still able to read
// data from license_message buffer rather than reading some garbage
// data.
license_messages.set_message_size(
sizeof(license_messages.response_data()) + message_length);
}
f(message_length, &license_messages);
if (update_core_message_substring_values) {
// We will be updating offset for these tests, which will cause verify
// keys to fail with an assertion. Hence skipping verification.
verify_keys_loaded = false;
}
license_messages.EncryptAndSignResponse();
OEMCryptoResult result =
license_messages.LoadResponse(&s, verify_keys_loaded);
s.close();
return result;
};
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status);
}
void TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
const std::function<void(size_t, LicenseRoundTrip*)> f) {
Session s;
LicenseRoundTrip license_messages(&s);
license_messages.set_api_version(license_api_version_);
s.open();
InstallTestDrmKey(&s);
license_messages.SignAndVerifyRequest();
license_messages.CreateDefaultResponse();
size_t message_length = sizeof(license_messages.response_data());
f(message_length, &license_messages);
license_messages.EncryptAndSignResponse();
OEMCryptoResult result = license_messages.LoadResponse();
s.close();
// Verifying error is not due to signature failure which can be caused due
// to test code.
ASSERT_NE(OEMCrypto_ERROR_SIGNATURE_FAILURE, result);
ASSERT_NE(OEMCrypto_SUCCESS, result);
}
protected:
uint32_t license_api_version_;
};
// This class is for testing a single license with the default API version
// of 16. Used for buffer overflow tests.
class OEMCryptoMemoryLicenseTest : public OEMCryptoLicenseTestAPI16 {
public:
OEMCryptoMemoryLicenseTest() : entitled_message_(&license_messages_) {}
void SetUp() override {
OEMCryptoLicenseTestAPI16::SetUp();
SetUpEntitledMessage();
entitlement_response_length_ = entitled_message_.entitled_key_data_size();
}
void LoadLicense() {
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
}
void SetUpEntitledMessage() {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
LoadLicense();
entitled_message_.FillKeyArray();
entitled_message_.EncryptContentKey();
uint32_t key_session_id = 0;
OEMCryptoResult sts = OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id);
if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
return;
}
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
entitled_message_.SetEntitledKeySession(key_session_id);
}
void TearDown() override { OEMCryptoLicenseTestAPI16::TearDown(); }
protected:
EntitledMessage entitled_message_;
size_t entitlement_response_length_;
void TestLoadEntitledKeysForHugeBufferLengths(
const std::function<void(size_t, EntitledMessage*)> f,
bool check_status) {
size_t entitled_key_data_size = entitled_message_.entitled_key_data_size();
vector<uint8_t> message(entitled_key_data_size);
memcpy(message.data(), entitled_message_.entitled_key_data(),
entitled_key_data_size);
auto oemcrypto_function = [&](size_t length) {
// Make entitled message big enough so that updated substring offset and
// length fields by core message substring tests can still be able to read
// valid data from entitled message buffer rather than some garbage data.
message.resize(entitled_key_data_size + length);
f(length, &entitled_message_);
return entitled_message_.LoadKeys(message);
};
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, check_status);
}
};
/// @}
/// @addtogroup entitle
/// @{
class OEMCryptoEntitlementLicenseTest : public OEMCryptoLicenseTest {
protected:
void LoadEntitlementLicense() {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
}
};
/** This verifies that entitlement keys and entitled content keys can be loaded.
*/
TEST_P(OEMCryptoEntitlementLicenseTest, LoadEntitlementKeysAPI17) {
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
EntitledMessage entitled_message_2(&license_messages_);
entitled_message_2.FillKeyArray();
entitled_message_2.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_2.LoadKeys(true));
}
TEST_P(OEMCryptoEntitlementLicenseTest, CasOnlyLoadCasKeysAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadCasKeys(
/*load_even=*/true, /*load_odd=*/true, OEMCrypto_SUCCESS));
EntitledMessage entitled_message_2(&license_messages_);
entitled_message_2.FillKeyArray();
entitled_message_2.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_2.LoadCasKeys(
/*load_even=*/true, /*load_odd=*/false, OEMCrypto_SUCCESS));
EntitledMessage entitled_message_3(&license_messages_);
entitled_message_3.FillKeyArray();
entitled_message_3.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_3.LoadCasKeys(
/*load_even=*/false, /*load_odd=*/true, OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_3.LoadCasKeys(
/*load_even=*/false, /*load_odd=*/false, OEMCrypto_SUCCESS));
}
/**
* This verifies that entitled content keys cannot be loaded if we have not yet
* loaded the entitlement keys.
*/
TEST_P(OEMCryptoEntitlementLicenseTest,
LoadEntitlementKeysNoEntitlementKeysAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(false));
}
/**
* This verifies that entitled content keys cannot be loaded if we have loaded
* the wrong entitlement keys.
*/
TEST_P(OEMCryptoEntitlementLicenseTest,
CasOnlyLoadCasKeysNoEntitlementKeysAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadCasKeys(
/*load_even=*/true, /*load_odd=*/true, OEMCrypto_ERROR_INVALID_CONTEXT));
}
/**
* This verifies that entitled content keys cannot be loaded if we have loaded
* the wrong entitlement keys.
*/
TEST_P(OEMCryptoEntitlementLicenseTest,
LoadEntitlementKeysWrongEntitlementKeysAPI17) {
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
const std::string key_id = "no_key";
entitled_message_1.SetEntitlementKeyId(0, key_id);
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(false));
}
TEST_P(OEMCryptoEntitlementLicenseTest,
CasOnlyLoadCasKeysWrongEntitlementKeysAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
const std::string key_id = "no_key";
entitled_message_1.SetEntitlementKeyId(0, key_id);
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadCasKeys(
/*load_even=*/true, /*load_odd=*/true, OEMCrypto_KEY_NOT_ENTITLED));
}
/**
* This verifies that entitled content keys cannot be loaded if we specify an
* entitled key session that has not been created.
*/
TEST_P(OEMCryptoEntitlementLicenseTest,
LoadEntitlementKeysWrongEntitledKeySessionAPI17) {
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
const uint32_t wrong_key_session_id = key_session_id == 0 ? 1 : 0;
entitled_message_1.SetEntitledKeySession(wrong_key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(false));
}
TEST_P(OEMCryptoEntitlementLicenseTest,
CasOnlyLoadCasKeysWrongEntitledKeySessionAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
const uint32_t wrong_key_session_id = key_session_id == 0 ? 1 : 0;
entitled_message_1.SetEntitledKeySession(wrong_key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadCasKeys(
/*load_even=*/true, /*load_odd=*/true,
OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION));
}
/**
* This verifies that entitled content keys cannot be loaded if we specify an
* entitled key session that is actually an oemcrypto session.
*/
TEST_P(OEMCryptoEntitlementLicenseTest,
LoadEntitlementKeysOemcryptoSessionAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
if (session_.session_id() == key_session_id) {
GTEST_SKIP()
<< "Skipping test because entitled and entitlement sessions are both "
<< key_session_id << ".";
}
entitled_message_1.SetEntitledKeySession(session_.session_id());
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(false));
}
TEST_P(OEMCryptoEntitlementLicenseTest,
CasOnlyLoadCasKeysOemcryptoSessionAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(session_.session_id());
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadCasKeys(
/*load_even=*/true, /*load_odd=*/true,
OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION));
}
INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoEntitlementLicenseTest,
Range<uint32_t>(kCoreMessagesAPI, kCurrentAPI + 1));
/// @}
/// @addtogroup security
/// @{
/** Test that LoadEntitledContentKeys fails gracefully on huge buffer. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyIdLength) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t key_id_length, EntitledMessage* entitled_message) {
entitled_message->entitled_key_array()[0].content_key_id.length =
key_id_length;
},
!kCheckStatus);
}
/** Test that LoadEntitledContentKeys fails gracefully on huge buffer. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyIdOffset) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t key_id_offset, EntitledMessage* entitled_message) {
entitled_message->entitled_key_array()[0].content_key_id.offset =
key_id_offset;
},
!kCheckStatus);
}
/** Test that LoadEntitledContentKeys fails gracefully on huge buffer. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyIdLength) {
auto& content_key_id =
entitled_message_.entitled_key_array()[0].content_key_id;
content_key_id.length =
entitlement_response_length_ - content_key_id.offset + 1;
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyIdOffset) {
auto& content_key_id =
entitled_message_.entitled_key_array()[0].content_key_id;
content_key_id.offset =
entitlement_response_length_ - content_key_id.length + 1;
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test that LoadEntitledContentKeys fails gracefully on huge substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringEntitlementKeyIdLength) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t key_id_length, EntitledMessage* entitled_message) {
entitled_message->entitled_key_array()[0].entitlement_key_id.length =
key_id_length;
},
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringEntitlementKeyIdOffset) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t key_id_offset, EntitledMessage* entitled_message) {
entitled_message->entitled_key_array()[0].entitlement_key_id.offset =
key_id_offset;
},
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringEntitlementKeyIdLength) {
auto& entitlement_key_id =
entitled_message_.entitled_key_array()[0].entitlement_key_id;
entitlement_key_id.length =
entitlement_response_length_ - entitlement_key_id.offset + 1;
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringEntitlementKeyIdOffset) {
auto& entitlement_key_id =
entitled_message_.entitled_key_array()[0].entitlement_key_id;
entitlement_key_id.offset =
entitlement_response_length_ - entitlement_key_id.length + 1;
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyDataIvLength) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t content_key_data_iv_length, EntitledMessage* entitled_message) {
entitled_message->entitled_key_array()[0].content_key_data_iv.length =
content_key_data_iv_length;
},
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyDataIvOffset) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t content_key_data_iv_offset, EntitledMessage* entitled_message) {
entitled_message->entitled_key_array()[0].content_key_data_iv.offset =
content_key_data_iv_offset;
},
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyDataIvLength) {
auto& content_key_data_iv =
entitled_message_.entitled_key_array()[0].content_key_data_iv;
content_key_data_iv.length =
entitlement_response_length_ - content_key_data_iv.offset + 1;
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyDataIvOffset) {
auto& content_key_data_iv =
entitled_message_.entitled_key_array()[0].content_key_data_iv;
content_key_data_iv.offset =
entitlement_response_length_ - content_key_data_iv.length + 1;
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyDataLength) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t content_key_data_length, EntitledMessage* entitled_message) {
entitled_message->entitled_key_array()[0].content_key_data.length =
content_key_data_length;
},
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyDataOffset) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t content_key_data_offset, EntitledMessage* entitled_message) {
entitled_message->entitled_key_array()[0].content_key_data.offset =
content_key_data_offset;
},
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyDataLength) {
auto& content_key_data =
entitled_message_.entitled_key_array()[0].content_key_data;
content_key_data.length =
entitlement_response_length_ - content_key_data.offset + 1;
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyDataOffset) {
auto& content_key_data =
entitled_message_.entitled_key_array()[0].content_key_data;
content_key_data.offset =
entitlement_response_length_ - content_key_data.length + 1;
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeEntitlementKeyIdLength) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t key_id_length, EntitledMessage* entitled_message) {
entitled_message->entitled_key_data()->entitlement_key_id_length =
key_id_length;
},
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeContentKeyIdLength) {
TestLoadEntitledKeysForHugeBufferLengths(
[](size_t key_id_length, EntitledMessage* entitled_message) {
entitled_message->entitled_key_data()->content_key_id_length =
key_id_length;
},
!kCheckStatus);
}
/// @}
/// @addtogroup entitle
/// @{
TEST_P(OEMCryptoLicenseTest, GetKeyHandleEntitledKeyAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
uint32_t key_session_id;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
const char* content_key_id = "content_key_id";
entitled_message_1.SetContentKeyId(0, content_key_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
vector<uint8_t> key_handle;
ASSERT_EQ(
OEMCrypto_SUCCESS,
GetKeyHandleIntoVector(
key_session_id, reinterpret_cast<const uint8_t*>(content_key_id),
strlen(content_key_id), OEMCrypto_CipherMode_CENC, key_handle));
}
// SelectEntitledKey should fail if we attempt to select a key that has not been
// loaded. Also, the error should be NO_CONTENT_KEY.
TEST_P(OEMCryptoLicenseTest, SelectKeyEntitledKeyNotThereAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
uint32_t key_session_id;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
const char* content_key_id = "no_key";
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_ERROR_INVALID_CONTEXT, key_session_id,
reinterpret_cast<const uint8_t*>(content_key_id),
strlen(content_key_id)));
}
/**
* Select key with entitlement license fails if the key id is entitlement key
* id.
*/
TEST_P(OEMCryptoLicenseTest, SelectKeyEntitlementKeyAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
uint32_t key_session_id;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
if (session_.session_id() == key_session_id) {
GTEST_SKIP()
<< "Skipping test because entitled and entitlement sessions are both "
<< key_session_id << ".";
}
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_ERROR_INVALID_CONTEXT, session_.session_id(),
session_.license().keys[0].key_id,
session_.license().keys[0].key_id_length));
}
// This verifies that entitled key sessions can be created and removed.
TEST_P(OEMCryptoLicenseTest, EntitledKeySessionsAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
uint32_t key_session_id_1;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id_1));
ASSERT_NE(key_session_id_1, 0u); // 0 is a reserved id number.
uint32_t key_session_id_2;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id_2));
ASSERT_NE(key_session_id_2, 0u); // 0 is a reserved id number.
// Entitled key sessions should have unique ids.
ASSERT_NE(key_session_id_1, key_session_id_2);
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_RemoveEntitledKeySession(key_session_id_1));
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_RemoveEntitledKeySession(key_session_id_2));
}
TEST_P(OEMCryptoLicenseTest,
EntitledKeySessionsCloseWithOEMCryptoSessionAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
uint32_t key_session_id_1;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id_1));
// Close the OEMCrypto session.
session_.close();
// All entitled key sessions associated with the OEMCrypto session should
// already be destroyed.
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_RemoveEntitledKeySession(key_session_id_1));
// Open a new session just for OEMCryptoLicenseTest TearDown.
session_.open();
}
// This verifies that multiple entitled key sessions can be created. They can
// load and select keys independently.
TEST_P(OEMCryptoLicenseTest, EntitledKeySessionMultipleKeySessionsAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
uint32_t key_session_id_1;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id_1));
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id_1);
const char* content_key_id_1 = "content_key_id_1";
entitled_message_1.SetContentKeyId(0, content_key_id_1);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
// We can select content key 1 in entitled key session 1.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_SUCCESS, key_session_id_1,
reinterpret_cast<const uint8_t*>(content_key_id_1),
strlen(content_key_id_1)));
// Create another entitled key session.
uint32_t key_session_id_2;
OEMCryptoResult status = OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id_2);
// For DRM, but not for CAS, we allow there to be only a single entitled
// session.
if (status == OEMCrypto_ERROR_TOO_MANY_SESSIONS) {
GTEST_SKIP()
<< "Skipping test because multiple entitled sessions not supported.";
}
ASSERT_EQ(OEMCrypto_SUCCESS, status);
// Entitled key sessions should have unique ids.
ASSERT_NE(key_session_id_1, key_session_id_2);
EntitledMessage entitled_message_2(&license_messages_);
entitled_message_2.FillKeyArray();
entitled_message_2.SetEntitledKeySession(key_session_id_2);
const char* content_key_id_2 = "content_key_id_2";
entitled_message_2.SetContentKeyId(0, content_key_id_2);
ASSERT_NO_FATAL_FAILURE(entitled_message_2.LoadKeys(true));
// We can select content key 2 in entitled key session 2.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_SUCCESS, key_session_id_2,
reinterpret_cast<const uint8_t*>(content_key_id_2),
strlen(content_key_id_2)));
// Content key id 1 is not in entitled key session 2.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_ERROR_NO_CONTENT_KEY, key_session_id_2,
reinterpret_cast<const uint8_t*>(content_key_id_1),
strlen(content_key_id_1)));
// Content key id 2 is not in entitled key session 1.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_ERROR_NO_CONTENT_KEY, key_session_id_1,
reinterpret_cast<const uint8_t*>(content_key_id_2),
strlen(content_key_id_2)));
}
// This verifies that within an entitled key session, each entitlement key can
// corresponds to only one content key at most.
TEST_P(OEMCryptoLicenseTest,
EntitledKeySessionOneContentKeyPerEntitlementAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
uint32_t key_session_id;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
// Construct and load content keys to entitled key session.
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
const char* content_key_id_1 = "content_key_id_1";
entitled_message_1.SetContentKeyId(0, content_key_id_1);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
// We can select content key 1 in entitled key session.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_SUCCESS, key_session_id,
reinterpret_cast<const uint8_t*>(content_key_id_1),
strlen(content_key_id_1)));
// Load content key with new content id.
const char* content_key_id_2 = "content_key_id_2";
entitled_message_1.SetContentKeyId(0, content_key_id_2);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
// We can select content key 2 in entitled key session.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_SUCCESS, key_session_id,
reinterpret_cast<const uint8_t*>(content_key_id_2),
strlen(content_key_id_2)));
// Content key one is no longer in the entitled key session as they use the
// same entitlement key.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_ERROR_NO_CONTENT_KEY, key_session_id,
reinterpret_cast<const uint8_t*>(content_key_id_1),
strlen(content_key_id_1)));
}
// Decrypt should fail if the license is entitlement license, and the key handle
// is requested from the oemcrypto session (should use entitled key session id
// instead).
TEST_P(OEMCryptoLicenseTest,
RejectOecSessionDecryptWithEntitlementLicenseAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
uint32_t key_session_id;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
// Skip the rest of this test on platforms that do not support separate
// entitlement and entitled sessions.
if (global_features.supports_cas || session_.session_id() != key_session_id) {
// Construct and load content keys to entitled key session.
EntitledMessage entitled_message(&license_messages_);
entitled_message.FillKeyArray();
entitled_message.SetEntitledKeySession(key_session_id);
constexpr char kContentKeyId[] = "content_key_id";
const size_t content_key_id_length = strlen(kContentKeyId);
entitled_message.SetContentKeyId(0, kContentKeyId);
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true));
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptEntitled(
OEMCrypto_SUCCESS, key_session_id,
reinterpret_cast<const uint8_t*>(kContentKeyId),
content_key_id_length));
// Try to get a key handle with the oemcrypto session id.
vector<uint8_t> key_handle;
EXPECT_NE(GetKeyHandleIntoVector(
session_.session_id(),
reinterpret_cast<const uint8_t*>(kContentKeyId),
content_key_id_length, OEMCrypto_CipherMode_CENC, key_handle),
OEMCrypto_SUCCESS);
}
}
// This verifies that an entitled key session can be reassociated to an
// OEMCrypto session.
TEST_P(OEMCryptoEntitlementLicenseTest, ReassociateEntitledKeySessionAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
// Setup an entitled key session in the first OEMCrypto session.
uint32_t key_session_id;
OEMCryptoResult sts = OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
EntitledMessage entitled_message(&license_messages_);
entitled_message.FillKeyArray();
entitled_message.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true));
// Setup another session.
Session session2;
ASSERT_NO_FATAL_FAILURE(session2.open());
ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session2));
// session2 does not have entitlement keys. Re-associating the entitled key
// session to session2 should fail
OEMCryptoResult status = OEMCrypto_ReassociateEntitledKeySession(
key_session_id, session2.session_id());
if (status == OEMCrypto_ERROR_NOT_IMPLEMENTED &&
!global_features.supports_cas) {
GTEST_SKIP() << "Skipping test because "
"OEMCrypto_ReassociateEntitledKeySession not implemented.";
}
EXPECT_NE(OEMCrypto_SUCCESS, status);
// session2 loads the correct entitlement keys.
LicenseRoundTrip license_messages2(&session2);
license_messages2.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages2.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages2.LoadResponse());
// Re-associating to session2 should succeed.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession(
key_session_id, session2.session_id()));
// Now reassociate the entitled key session back to the first OEMCrypto
// session.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession(
key_session_id, session_.session_id()));
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true));
// session3 has unmatched key policies
Session session3;
ASSERT_NO_FATAL_FAILURE(session3.open());
ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session3));
LicenseRoundTrip license_messages3(&session3);
license_messages3.set_license_type(OEMCrypto_EntitlementLicense);
license_messages3.set_control(license_messages_.control() + 1);
ASSERT_NO_FATAL_FAILURE(license_messages3.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages3.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages3.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages3.LoadResponse());
// Re-associating to session3 should fail.
EXPECT_NE(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession(
key_session_id, session3.session_id()));
}
/// @}
/// @addtogroup security
/// @{
/** Test that LoadLicense fails gracefully on huge buffer. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyIdLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t length, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_id.length = length;
license_messages->response_data().keys[0].key_id_length = length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyIdOffset) {
TestLoadLicenseForHugeBufferLengths(
[](size_t offset, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_id.offset = offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyIdLength) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_id = license_messages->core_response().key_array[0].key_id;
key_id.length = response_message_length - key_id.offset + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyIdOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_id = license_messages->core_response().key_array[0].key_id;
key_id.offset = response_message_length - key_id.length + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyDataIvLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t length, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_data_iv.length =
length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyDataIvOffset) {
TestLoadLicenseForHugeBufferLengths(
[](size_t offset, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_data_iv.offset =
offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyDataIvLength) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_data_iv =
license_messages->core_response().key_array[0].key_data_iv;
key_data_iv.length = response_message_length - key_data_iv.offset + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyDataIvOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_data_iv =
license_messages->core_response().key_array[0].key_data_iv;
key_data_iv.offset = response_message_length - key_data_iv.length + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyDataLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t length, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_data.length = length;
license_messages->response_data().keys[0].key_data_length = length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyDataOffset) {
TestLoadLicenseForHugeBufferLengths(
[](size_t offset, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_data.offset = offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyDataLength) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_data =
license_messages->core_response().key_array[0].key_data;
key_data.length = response_message_length - key_data.offset + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyDataOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_data =
license_messages->core_response().key_array[0].key_data;
key_data.offset = response_message_length - key_data.length + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyControlIvLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t length, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_control_iv.length =
length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyControlIvOffset) {
TestLoadLicenseForHugeBufferLengths(
[](size_t offset, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_control_iv.offset =
offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlIvLengthAPI16) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_control_iv =
license_messages->core_response().key_array[0].key_control_iv;
key_control_iv.length =
response_message_length - key_control_iv.offset + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlIvOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_control_iv =
license_messages->core_response().key_array[0].key_control_iv;
key_control_iv.offset =
response_message_length - key_control_iv.length + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyControlLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t length, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_control.length =
length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyControlOffset) {
TestLoadLicenseForHugeBufferLengths(
[](size_t offset, LicenseRoundTrip* license_messages) {
license_messages->core_response().key_array[0].key_control.offset =
offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlLengthAPI16) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_control =
license_messages->core_response().key_array[0].key_control;
key_control.length = response_message_length - key_control.offset + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_control =
license_messages->core_response().key_array[0].key_control;
key_control.offset = response_message_length - key_control.length + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringEncMacKeyIvLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t length, LicenseRoundTrip* license_messages) {
license_messages->core_response().enc_mac_keys_iv.length = length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringEncMacKeyIvOffset) {
TestLoadLicenseForHugeBufferLengths(
[](size_t offset, LicenseRoundTrip* license_messages) {
license_messages->core_response().enc_mac_keys_iv.offset = offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringEncMacKeyIvLength) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& enc_mac_keys_iv =
license_messages->core_response().enc_mac_keys_iv;
enc_mac_keys_iv.length =
response_message_length - enc_mac_keys_iv.offset + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringEncMacKeyIvOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& enc_mac_keys_iv =
license_messages->core_response().enc_mac_keys_iv;
enc_mac_keys_iv.offset =
response_message_length - enc_mac_keys_iv.length + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringEncMacKeyLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t length, LicenseRoundTrip* license_messages) {
license_messages->core_response().enc_mac_keys.length = length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringEncMacKeyOffset) {
TestLoadLicenseForHugeBufferLengths(
[](size_t offset, LicenseRoundTrip* license_messages) {
license_messages->core_response().enc_mac_keys.offset = offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringEncMacKeyLength) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& enc_mac_keys = license_messages->core_response().enc_mac_keys;
enc_mac_keys.length = response_message_length - enc_mac_keys.offset + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringEncMacKeyOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& enc_mac_keys = license_messages->core_response().enc_mac_keys;
enc_mac_keys.offset = response_message_length - enc_mac_keys.length + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringPstLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t length, LicenseRoundTrip* license_messages) {
license_messages->core_response().pst.length = length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringPstOffset) {
TestLoadLicenseForHugeBufferLengths(
[](size_t offset, LicenseRoundTrip* license_messages) {
license_messages->core_response().pst.offset = offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringPstLength) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& pst = license_messages->core_response().pst;
pst.length = response_message_length - pst.offset + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringPstOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& pst = license_messages->core_response().pst;
pst.offset = response_message_length;
if (pst.length == 0) pst.length = 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringSrmRestrictionDataLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t length, LicenseRoundTrip* license_messages) {
license_messages->core_response().srm_restriction_data.length = length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringSrmRestrictionDataOffset) {
TestLoadLicenseForHugeBufferLengths(
[](size_t offset, LicenseRoundTrip* license_messages) {
license_messages->core_response().srm_restriction_data.offset = offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringSrmRestrictionDataLength) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& srm_restriction_data =
license_messages->core_response().srm_restriction_data;
srm_restriction_data.length =
response_message_length - srm_restriction_data.offset + 1;
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringSrmRestrictionDataOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& srm_restriction_data =
license_messages->core_response().srm_restriction_data;
srm_restriction_data.offset = response_message_length;
if (srm_restriction_data.length == 0) srm_restriction_data.length = 1;
});
}
/** Test that LoadLicense fails gracefully on huge buffer. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeResponseLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t message_size, LicenseRoundTrip* license_messages) {
license_messages->set_message_size(message_size);
},
!kCheckStatus, !kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on huge buffer. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageLength) {
TestLoadLicenseForHugeBufferLengths(
[](size_t message_size, LicenseRoundTrip* license_messages) {
license_messages->set_core_message_size(message_size);
},
!kCheckStatus, !kUpdateCoreMessageSubstringValues);
}
INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoLicenseOverflowTest,
Range<uint32_t>(kCurrentAPI - 1, kCurrentAPI + 1));
/// @}
/// @addtogroup cas
/// @{
/// @}
/// @addtogroup security
/// @{
/** Test that LoadProvisioning fails gracefully on huge buffer. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeResponseLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_message_size(message_size);
},
!kCheckStatus, !kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on huge buffer. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_core_message_size(message_size);
},
!kCheckStatus, !kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on huge buffer. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncPrivateKeyLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t length, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().enc_private_key.length = length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on huge buffer. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncPrivateKeyOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t offset, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().enc_private_key.offset = offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
auto& enc_private_key =
provisioning_messages->core_response().enc_private_key;
enc_private_key.length =
response_message_length - enc_private_key.offset + 1;
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
auto& enc_private_key =
provisioning_messages->core_response().enc_private_key;
enc_private_key.offset =
response_message_length - enc_private_key.length + 1;
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncPrivateKeyIvLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t length, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().enc_private_key_iv.length =
length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncPrivateKeyIvOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t offset, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().enc_private_key_iv.offset =
offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyIvLengthAPI16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
auto& enc_private_key_iv =
provisioning_messages->core_response().enc_private_key_iv;
enc_private_key_iv.length =
response_message_length - enc_private_key_iv.offset + 1;
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyIvOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
auto& enc_private_key_iv =
provisioning_messages->core_response().enc_private_key_iv;
enc_private_key_iv.offset =
response_message_length - enc_private_key_iv.length + 1;
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncMessageKeyLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t length, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().encrypted_message_key.length =
length;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncMessageKeyOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t offset, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().encrypted_message_key.offset =
offset;
},
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyLengthProv30) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
if (global_features.provisioning_method != OEMCrypto_OEMCertificate) {
GTEST_SKIP() << "Test for Prov 3.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
auto& encrypted_message_key =
provisioning_messages->core_response().encrypted_message_key;
encrypted_message_key.length =
response_message_length - encrypted_message_key.offset + 1;
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyOffsetProv30) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
if (global_features.provisioning_method != OEMCrypto_OEMCertificate) {
GTEST_SKIP() << "Test for Prov 3.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
auto& encrypted_message_key =
provisioning_messages->core_response().encrypted_message_key;
encrypted_message_key.offset =
response_message_length - encrypted_message_key.length + 1;
});
}
/// @}
/// @addtogroup security
/// @{
/** Test that OEMCrypto_PrepAndSignProvisioningRequest fails gracefully on a
* huge buffer.
*/
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryPrepareProvisioningRequestForHugeRequestMessageLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestPrepareProvisioningRequestForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_message_size(message_size);
},
kCheckStatus);
}
/** Test that OEMCrypto_PrepAndSignProvisioningRequest fails gracefully on a
* huge buffer.
*/
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryPrepareProvisioningRequestForHugeSignatureLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestPrepareProvisioningRequestForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_request_signature_size(message_size);
},
!kCheckStatus);
}
/** Test that OEMCrypto_PrepAndSignProvisioningRequest fails gracefully on a
* huge buffer.
*/
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryPrepareProvisioningRequestForHugeCoreMessageLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestPrepareProvisioningRequestForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_core_message_size(message_size);
},
kCheckStatus);
}
/// @}
/// @addtogroup cast
/// @{
/// @}
#ifdef CAS_TEST
# include "tuner_hal.h"
class OEMCryptoCasDemoTest : public OEMCryptoEntitlementLicenseTest {};
TEST_P(OEMCryptoCasDemoTest, BasicFlow) {
// License contains entitlement keys, function reused from
// OEMCryptoEntitlementLicenseTest
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message(&license_messages_);
// Randomly generate entitled content keys
entitled_message.FillKeyArray();
if (session_.session_id() == key_session_id) {
GTEST_SKIP()
<< "Skipping test because entitled and entitlement sessions are both "
<< key_session_id << ".";
}
entitled_message.SetEntitledKeySession(key_session_id);
// Encrypt and load 0th key (even key) into OEMCrypto
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadCasKeys(
/*load_even=*/true, /*load_odd=*/false, OEMCrypto_SUCCESS));
//
// Perform DecryptCTR() but for CAS
//
vector<uint8_t> unencrypted_data(256, 0);
vector<uint8_t> encrypted_data(256, 0);
vector<uint8_t> output_buffer(256, 0);
unencrypted_data.resize(encrypted_data.size());
output_buffer.resize(encrypted_data.size());
OEMCrypto_SampleDescription sample_description;
OEMCrypto_SubSampleDescription subsample_description;
GenerateSimpleSampleDescription(encrypted_data, output_buffer,
&sample_description, &subsample_description);
// Use 0th entitled content key and IV to encrypt test data
EncryptCTR(unencrypted_data,
entitled_message.entitled_key_data()->content_key_data,
entitled_message.entitled_key_data()->content_iv, &encrypted_data);
// Assume 0,0 pattern for CTR example
OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0};
// Demo only -- copy IV into sample description so we can use
// WTPI_DecryptSample() in the Tuner decrypt impl. A real implementation would
// use the IV from the entitled content key, but the demo relies on the
// existing decrypt which uses SampleDescription IV.
memcpy(sample_description.iv,
entitled_message.entitled_key_data()->content_iv, 16);
// Get key token to send to Tuner for decrypt
std::vector<uint8_t> key_token;
size_t key_token_length = key_token.size();
OEMCryptoResult res = OEMCrypto_GetOEMKeyToken(
key_session_id, key_token.data(), &key_token_length);
if (res == OEMCrypto_ERROR_SHORT_BUFFER) {
key_token.resize(key_token_length);
res = OEMCrypto_GetOEMKeyToken(key_session_id, key_token.data(),
&key_token_length);
}
ASSERT_EQ(OEMCrypto_SUCCESS, res);
// Decrypt the data
ASSERT_EQ(TUNER_HAL_SUCCESS,
TunerHal_Decrypt(key_token.data(), key_token_length,
TunerHal_KeyParityType_EvenKey,
&sample_description, // an array of samples.
1, // the number of samples.
&pattern));
ASSERT_EQ(unencrypted_data, output_buffer);
}
INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoCasDemoTest,
Range<uint32_t>(kCoreMessagesAPI, kCurrentAPI + 1));
#endif
} // namespace wvoec