Update repo with latest changes

This updates the repo to match the internal repo at commit:
521466f84993e273105bd41d930c00cf6d61008f
This commit is contained in:
Jacob Trimble
2021-07-02 11:11:15 -07:00
parent ac8b2f59ea
commit 06a325cfaf
43 changed files with 1752 additions and 1461 deletions

View File

@@ -62,6 +62,9 @@ void WB_Aead_Delete(WB_Aead_Whitebox* whitebox);
// should be at least |input_data_size| + 22 to allow room for the nonce and the // should be at least |input_data_size| + 22 to allow room for the nonce and the
// verification tag. // verification tag.
// //
// This must support |input_data| and |output_data| pointing to the same buffer
// (in-place encrypt).
//
// Args: // Args:
// whitebox (in) : The white-box containing the keys for encryption. // whitebox (in) : The white-box containing the keys for encryption.
// //
@@ -94,6 +97,9 @@ WB_Result WB_Aead_Encrypt(const WB_Aead_Whitebox* whitebox,
// Decrypts |input_data| and writes the plaintext to |output_data|. |input_data| // Decrypts |input_data| and writes the plaintext to |output_data|. |input_data|
// must have been encrypted using WB_Aead_Encrypt() with the same |whitebox|. // must have been encrypted using WB_Aead_Encrypt() with the same |whitebox|.
// //
// This must support |input_data| and |output_data| pointing to the same buffer
// (in-place decrypt).
//
// Args: // Args:
// whitebox (in) : The white-box containing the keys for decryption. // whitebox (in) : The white-box containing the keys for decryption.
// //

View File

@@ -59,6 +59,29 @@ TEST_F(AeadWhiteboxEncryptTest, Success) {
ASSERT_GT(output_size, input_.size()); ASSERT_GT(output_size, input_.size());
} }
// This also validates Decrypt in-place.
TEST_F(AeadWhiteboxEncryptTest, InPlace) {
size_t output_size = kDefaultOutputSize;
std::vector<uint8_t> output(output_size);
// Copy the input to the first part of the output. Then pass the original
// size in input, but the real size as output.
ASSERT_GE(output_size, input_.size());
memcpy(output.data(), input_.data(), input_.size());
ASSERT_EQ(WB_Aead_Encrypt(whitebox_, output.data(), input_.size(),
output.data(), &output_size),
WB_RESULT_OK);
output.resize(output_size);
ASSERT_EQ(WB_Aead_Decrypt(whitebox_, output.data(), output.size(),
output.data(), &output_size),
WB_RESULT_OK);
output.resize(output_size);
ASSERT_EQ(output, input_);
}
TEST_F(AeadWhiteboxEncryptTest, InvalidParameterForNullWhitebox) { TEST_F(AeadWhiteboxEncryptTest, InvalidParameterForNullWhitebox) {
size_t output_size = kDefaultOutputSize; size_t output_size = kDefaultOutputSize;
std::vector<uint8_t> output(output_size); std::vector<uint8_t> output(output_size);

View File

@@ -3,84 +3,87 @@
#include "api/golden_data.h" #include "api/golden_data.h"
namespace widevine { namespace widevine {
namespace {
GoldenData::Content CreateContent(const std::vector<uint8_t>& plaintext,
const std::vector<uint8_t>& ciphertext,
const AesIv& iv,
const AesKey& key,
const KeyId& undefined_key_id,
const KeyId& software_crypto_key_id,
const KeyId& software_decode_key_id,
const KeyId& hardware_key_id) {
GoldenData::Content content;
content.plaintext = plaintext;
content.ciphertext = ciphertext;
content.iv = iv;
content.undefined_key.id = undefined_key_id;
content.undefined_key.level = SecurityLevel::kUndefined;
content.undefined_key.key = key;
content.software_crypto_key.id = software_crypto_key_id;
content.software_crypto_key.level = SecurityLevel::kSoftwareSecureCrypto;
content.software_crypto_key.key = key;
content.software_decode_key.id = software_decode_key_id;
content.software_decode_key.level = SecurityLevel::kSoftwareSecureDecode;
content.software_decode_key.key = key;
content.hardware_key.id = hardware_key_id;
content.hardware_key.level = SecurityLevel::kHardwareSecureCrypto;
content.hardware_key.key = key;
return content;
}
} // namespace
GoldenData::GoldenData() { GoldenData::GoldenData() {
// Content generated with: // Content generated with:
// openssl aes-128-cbc -e -in data.txt // openssl aes-128-cbc -e -in data.txt
// -K EBDD62F16814D27B68EF122AFCE4AE3C // -K EBDD62F16814D27B68EF122AFCE4AE3C
// -iv 30313233343536373839303132333435 | xxd -i // -iv 30313233343536373839303132333435 | xxd -i
// Extra padding was stripped off. // Extra padding was stripped off.
cbc_content_ = { cbc_content_ = CreateContent(
/* plaintext */ {'t', 'h', 'i', 's', ' ', 'i', 's', ' ', 't', 'h', 'e', /* plaintext= */ {'t', 'h', 'i', 's', ' ', 'i', 's', ' ', 't', 'h', 'e',
' ', 'p', 'l', 'a', 'i', 'n', 't', 'e', 'x', 't', ' ', ' ', 'p', 'l', 'a', 'i', 'n', 't', 'e', 'x', 't', ' ',
':', ' ', '3', '2', ' ', 'b', 'y', 't', 'e', 's'}, ':', ' ', '3', '2', ' ', 'b', 'y', 't', 'e', 's'},
/* ciphertext */ /* ciphertext= */ {0x5e, 0x60, 0x0d, 0x3c, 0x29, 0xb9, 0x49, 0x4c,
{0x5e, 0x60, 0x0d, 0x3c, 0x29, 0xb9, 0x49, 0x4c, 0x65, 0x67, 0x7e, 0x65, 0x67, 0x7e, 0x87, 0x82, 0x9d, 0x47, 0x58,
0x87, 0x82, 0x9d, 0x47, 0x58, 0xb9, 0x86, 0xd0, 0x39, 0x6a, 0x67, 0xb9, 0x86, 0xd0, 0x39, 0x6a, 0x67, 0x2c, 0x53,
0x2c, 0x53, 0xe9, 0xbc, 0x99, 0x5b, 0x23, 0x34, 0x9f, 0xf8}, 0xe9, 0xbc, 0x99, 0x5b, 0x23, 0x34, 0x9f, 0xf8},
/* key */ /* iv= */
{0xEB, 0xDD, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B, 0x68, 0xEF, 0x12, 0x2A,
0xFC, 0xE4, 0xAE, 0x3C},
/* iv */
{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35}, 0x32, 0x33, 0x34, 0x35},
}; /* key= */
{0xEB, 0xDD, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B, 0x68, 0xEF, 0x12, 0x2A,
cbc_crypto_key_ = { 0xFC, 0xE4, 0xAE, 0x3C},
SecurityLevel::kSoftwareSecureCrypto, /* undefined_key_id= */ {0xFF, 0, 0, 0},
{0xFF, 0, 0, 0}, /* software_crypto_key_id= */ {0xFF, 1, 0, 0},
&cbc_content_, /* software_decode_key_id= */ {0xFF, 2, 0, 0},
}; /* hardware_key_id= */ {0xFF, 3, 0, 0});
cbc_decode_key_ = {
SecurityLevel::kSoftwareSecureDecode,
{0xFF, 1, 0, 0},
&cbc_content_,
};
cbc_hardware_key_ = {
SecurityLevel::kHardwareSecureCrypto,
{0xFF, 2, 0, 0},
&cbc_content_,
};
// Content generated with: // Content generated with:
// openssl aes-128-ctr -e -in data.txt // openssl aes-128-ctr -e -in data.txt
// -K dd3c6cd4ea73b99d55f2e0357e1f560f // -K dd3c6cd4ea73b99d55f2e0357e1f560f
// -iv d50c08b31fc09e9e748431ca972334e6 | xxd -i // -iv d50c08b31fc09e9e748431ca972334e6 | xxd -i
ctr_content_ = { ctr_content_ = CreateContent(
/* plaintext */ {'T', 'h', 'i', 'r', 't', 'y', '-', 't', 'w', 'o', ' ', /* plaintext */ {'T', 'h', 'i', 'r', 't', 'y', '-', 't', 'w', 'o', ' ',
'b', 'y', 't', 'e', 's', ' ', 'o', 'f', ' ', 'r', 'a', 'b', 'y', 't', 'e', 's', ' ', 'o', 'f', ' ', 'r', 'a',
'n', 'd', 'o', 'm', ' ', 'd', 'a', 't', 'a', '.'}, 'n', 'd', 'o', 'm', ' ', 'd', 'a', 't', 'a', '.'},
/* ciphertext */ /* ciphertext */ {0x5d, 0x83, 0xdd, 0xb9, 0xed, 0x18, 0x2f, 0x10,
{0x5d, 0x83, 0xdd, 0xb9, 0xed, 0x18, 0x2f, 0x10, 0xbf, 0x6f, 0x4d, 0xbf, 0x6f, 0x4d, 0xb0, 0xb3, 0xeb, 0x0d, 0x20,
0xb0, 0xb3, 0xeb, 0x0d, 0x20, 0xd7, 0x7e, 0x9a, 0x3a, 0xc4, 0x41, 0xd7, 0x7e, 0x9a, 0x3a, 0xc4, 0x41, 0xcf, 0x0a,
0xcf, 0x0a, 0xb3, 0xae, 0x02, 0x01, 0x0a, 0xf2, 0x72, 0x72}, 0xb3, 0xae, 0x02, 0x01, 0x0a, 0xf2, 0x72, 0x72},
/* key */
{0xdd, 0x3c, 0x6c, 0xd4, 0xea, 0x73, 0xb9, 0x9d, 0x55, 0xf2, 0xe0, 0x35,
0x7e, 0x1f, 0x56, 0x0f},
/* iv */ /* iv */
{0xd5, 0x0c, 0x08, 0xb3, 0x1f, 0xc0, 0x9e, 0x9e, 0x74, 0x84, 0x31, 0xca, {0xd5, 0x0c, 0x08, 0xb3, 0x1f, 0xc0, 0x9e, 0x9e, 0x74, 0x84, 0x31, 0xca,
0x97, 0x23, 0x34, 0xe6}, 0x97, 0x23, 0x34, 0xe6},
}; /* key */
{0xdd, 0x3c, 0x6c, 0xd4, 0xea, 0x73, 0xb9, 0x9d, 0x55, 0xf2, 0xe0, 0x35,
ctr_crypto_key_ = { 0x7e, 0x1f, 0x56, 0x0f},
SecurityLevel::kSoftwareSecureCrypto, /* undefined_key_id= */ {0xFF, 4, 0, 0},
{0xFF, 3, 0, 0}, /* software_crypto_key_id= */ {0xFF, 5, 0, 0},
&ctr_content_, /* software_decode_key_id= */ {0xFF, 6, 0, 0},
}; /* hardware_key_id= */ {0xFF, 7, 0, 0});
ctr_decode_key_ = {
SecurityLevel::kSoftwareSecureDecode,
{0xFF, 4, 0, 0},
&ctr_content_,
};
ctr_hardware_key_ = {
SecurityLevel::kHardwareSecureCrypto,
{0xFF, 5, 0, 0},
&ctr_content_,
};
} }
KeyId GoldenData::GetFreeId() { KeyId GoldenData::GetFreeId() {

View File

@@ -8,7 +8,7 @@
#include <vector> #include <vector>
#include "api/test_key_types.h" #include "api/test_key_types.h"
#include "cdm/protos/license_protocol.pb.h" #include "license_protocol.pb.h"
namespace widevine { namespace widevine {
@@ -17,40 +17,30 @@ class GoldenData {
struct Content { struct Content {
std::vector<uint8_t> plaintext; std::vector<uint8_t> plaintext;
std::vector<uint8_t> ciphertext; std::vector<uint8_t> ciphertext;
AesKey key;
AesIv iv;
};
struct Key { // IV used to encrypt the plaintext.
SecurityLevel level; AesIv iv;
KeyId id;
const Content* content; // All the keys available to decrypt the ciphertext and get the plaintext.
// Every key here should have the same AES key, but the security level and
// ids will be different.
ContentKeyData undefined_key;
ContentKeyData software_crypto_key;
ContentKeyData software_decode_key;
ContentKeyData hardware_key;
}; };
GoldenData(); GoldenData();
const Content& CBCContent() const { return cbc_content_; } const Content& CBCContent() const { return cbc_content_; }
const Key& CBCCryptoKey() const { return cbc_crypto_key_; }
const Key& CBCDecodeKey() const { return cbc_decode_key_; }
const Key& CBCHardwareKey() const { return cbc_hardware_key_; }
const Content& CTRContent() const { return ctr_content_; } const Content& CTRContent() const { return ctr_content_; }
const Key& CTRCryptoKey() const { return ctr_crypto_key_; }
const Key& CTRDecodeKey() const { return ctr_decode_key_; }
const Key& CTRHardwareKey() const { return ctr_hardware_key_; }
KeyId GetFreeId(); KeyId GetFreeId();
private: private:
Content cbc_content_; Content cbc_content_;
Key cbc_crypto_key_;
Key cbc_decode_key_;
Key cbc_hardware_key_;
Content ctr_content_; Content ctr_content_;
Key ctr_crypto_key_;
Key ctr_decode_key_;
Key ctr_hardware_key_;
uint8_t next_id_ = 0; uint8_t next_id_ = 0;
}; };

View File

@@ -90,7 +90,9 @@ void WB_License_Delete(WB_License_Whitebox* whitebox);
// //
// license_request_size (in) : The number of bytes in the license_request. // license_request_size (in) : The number of bytes in the license_request.
// //
// signature (out) : The generated signature for |license_request|. // signature (out) : The generated signature for |license_request|. This can be
// null if |*signature_size| is 0; this should return
// WB_RESULT_BUFFER_TOO_SMALL and fill |signature_size|.
// //
// signature_size (in/out) : As input, this contains the max number of bytes // signature_size (in/out) : As input, this contains the max number of bytes
// that can be written to |signature|. As output, |signature_size| is set to // that can be written to |signature|. As output, |signature_size| is set to
@@ -245,7 +247,9 @@ WB_Result WB_License_QueryKeyStatus(const WB_License_Whitebox* whitebox,
// //
// message_size (in) : The number of bytes in |message|. // message_size (in) : The number of bytes in |message|.
// //
// signature (out) : The output parameter used to return the signature. // signature (out) : The output parameter used to return the signature. This
// can be null if |*signature_size| is 0; this should return
// WB_RESULT_BUFFER_TOO_SMALL and fill |signature_size|.
// //
// signature_size (in/out) : As input, this contains the max number of bytes // signature_size (in/out) : As input, this contains the max number of bytes
// that can be written to |signature|. As output, |signature_size| is set to // that can be written to |signature|. As output, |signature_size| is set to
@@ -315,7 +319,9 @@ WB_Result WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox,
// key_id_size (in) : The number of bytes in |key_id|. // key_id_size (in) : The number of bytes in |key_id|.
// //
// secret_string (out) : The output parameter used to return the secret string // secret_string (out) : The output parameter used to return the secret string
// that can be passed to WB_License_Unmask(). // that can be passed to WB_License_Unmask(). This can be null if
// |*secret_string_size| is 0; this should return WB_RESULT_BUFFER_TOO_SMALL
// and fill |secret_string_size|.
// //
// secret_string_size (in/out) : As input, this contains the max number of // secret_string_size (in/out) : As input, this contains the max number of
// bytes that can be written to |secret_string|. As output, // bytes that can be written to |secret_string|. As output,
@@ -349,6 +355,9 @@ WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
// Decrypts |input_data| and writes the plaintext to |output_data|. // Decrypts |input_data| and writes the plaintext to |output_data|.
// //
// This must support |input_data| and |output_data| pointing to the same buffer
// (in-place decrypt).
//
// Args: // Args:
// whitebox (in) : The white-box containing the keys needed to decrypt // whitebox (in) : The white-box containing the keys needed to decrypt
// |input_data|. // |input_data|.
@@ -410,6 +419,9 @@ WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox,
// |masked_output_data|. The obfuscated plaintext can be deobfuscated using // |masked_output_data|. The obfuscated plaintext can be deobfuscated using
// WB_License_GetSecretString() and WB_License_Unmask(). // WB_License_GetSecretString() and WB_License_Unmask().
// //
// This must support |input_data| and |output_data| pointing to the same buffer
// (in-place decrypt).
//
// Args: // Args:
// whitebox (in) : The white-box containing the keys needed to decrypt // whitebox (in) : The white-box containing the keys needed to decrypt
// |input_data|. // |input_data|.

View File

@@ -21,8 +21,12 @@ constexpr size_t kBlockSize = 16; // This must align with the AES block size.
} // namespace } // namespace
void LicenseWhiteboxBenchmark::SetUp() { void LicenseWhiteboxBenchmark::SetUp() {
key_id_ = data_source_.Get<4>(); // We use size=4 for all our test key ids. // We use size=4 for all our test key ids.
key_ = data_source_.Get<kBlockSize>(); key_data_.id = data_source_.Get<4>();
key_data_.key = data_source_.Get<kBlockSize>();
// Use secure crypto as it will work with both Decrypt() and MaskedDecrypt().
key_data_.level = SecurityLevel::kSoftwareSecureCrypto;
iv_ = data_source_.Get<kBlockSize>(); iv_ = data_source_.Get<kBlockSize>();
const auto public_key_data = GetEncryptionKey().public_key; const auto public_key_data = GetEncryptionKey().public_key;
@@ -31,14 +35,24 @@ void LicenseWhiteboxBenchmark::SetUp() {
ASSERT_TRUE(encryption_public_key_); ASSERT_TRUE(encryption_public_key_);
} }
License LicenseWhiteboxBenchmark::CreateLicense( License LicenseWhiteboxBenchmark::CreateLicense(WB_LicenseKeyMode key_mode,
WB_LicenseKeyMode key_mode) const { int number_of_content_keys,
SecurityLevel security_level) {
TestLicenseBuilder license_builder; TestLicenseBuilder license_builder;
license_builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey()); license_builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey());
// Use secure crypto as it will work with both Decrypt() and
// MaskedDecrypt(). // Update the first key to match the security level.
license_builder.AddContentKey(SecurityLevel::kSoftwareSecureCrypto, key_id_, key_data_.level = security_level;
key_); license_builder.AddContentKey(key_data_);
CHECK_GE(number_of_content_keys, 1);
for (int i = 1; i < number_of_content_keys; ++i) {
ContentKeyData key;
key.id = data_source_.Get<4>();
key.key = data_source_.Get<kBlockSize>();
key.level = security_level;
license_builder.AddContentKey(key);
}
std::unique_ptr<TestServer> server; std::unique_ptr<TestServer> server;

View File

@@ -20,19 +20,22 @@ class LicenseWhiteboxBenchmark : public ::testing::Test {
protected: protected:
virtual void SetUp() override; virtual void SetUp() override;
// Create a new license. The given key mode will change how the license is // Create a new license with the specified number of content keys using the
// encrypted and signed. The white-box instance is expected to use the correct // security_level provided. The first content key will use
// key mode in order to process the license response. // kSoftwareSecureCrypto, while the remainder will be specified by
License CreateLicense(WB_LicenseKeyMode key_mode) const; // |security_level|. The given key mode will change how the license is
// encrypted and signed. The white-box instance is expected to use the
// correct key mode in order to process the license response.
License CreateLicense(WB_LicenseKeyMode key_mode,
int number_of_content_keys,
SecurityLevel security_level);
// Sign the message using the default HMAC signing key. // Sign the message using the default HMAC signing key.
std::vector<uint8_t> SignAsServer(const std::vector<uint8_t>& message) const; std::vector<uint8_t> SignAsServer(const std::vector<uint8_t>& message) const;
DataSource& Data() { return data_source_; } DataSource& Data() { return data_source_; }
const KeyId& ContentKeyId() const { return key_id_; } const ContentKeyData& ContentKey() const { return key_data_; }
const AesKey& ContentKey() const { return key_; }
const AesIv& ContentIV() const { return iv_; } const AesIv& ContentIV() const { return iv_; }
@@ -40,8 +43,8 @@ class LicenseWhiteboxBenchmark : public ::testing::Test {
DataSource data_source_; DataSource data_source_;
std::unique_ptr<RsaPublicKey> encryption_public_key_; std::unique_ptr<RsaPublicKey> encryption_public_key_;
KeyId key_id_; ContentKeyData key_data_;
AesKey key_;
AesIv iv_; AesIv iv_;
}; };

View File

@@ -45,7 +45,8 @@ class LicenseWhiteboxDecryptBenchmark
ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK);
const auto license = CreateLicense(WB_LICENSE_KEY_MODE_DUAL_KEY); const auto license = CreateLicense(WB_LICENSE_KEY_MODE_DUAL_KEY, 1,
SecurityLevel::kSoftwareSecureCrypto);
ASSERT_EQ(WB_License_ProcessLicenseResponse( ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY,
license.core_message.data(), license.core_message.size(), license.core_message.data(), license.core_message.size(),
@@ -75,7 +76,7 @@ TEST_P(LicenseWhiteboxDecryptBenchmark, DecryptCBCThroughput) {
size_t plaintext_size = plaintext_.size(); size_t plaintext_size = plaintext_.size();
ASSERT_EQ(WB_RESULT_OK, ASSERT_EQ(WB_RESULT_OK,
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC,
ContentKeyId().data(), ContentKeyId().size(), ContentKey().id.data(), ContentKey().id.size(),
ciphertext_.data(), ciphertext_.size(), ciphertext_.data(), ciphertext_.size(),
ContentIV().data(), ContentIV().size(), ContentIV().data(), ContentIV().size(),
plaintext_.data(), &plaintext_size)); plaintext_.data(), &plaintext_size));
@@ -93,7 +94,7 @@ TEST_P(LicenseWhiteboxDecryptBenchmark, DecryptCTRThroughput) {
size_t plaintext_size = plaintext_.size(); size_t plaintext_size = plaintext_.size();
ASSERT_EQ(WB_RESULT_OK, ASSERT_EQ(WB_RESULT_OK,
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CTR, WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CTR,
ContentKeyId().data(), ContentKeyId().size(), ContentKey().id.data(), ContentKey().id.size(),
ciphertext_.data(), ciphertext_.size(), ciphertext_.data(), ciphertext_.size(),
ContentIV().data(), ContentIV().size(), ContentIV().data(), ContentIV().size(),
plaintext_.data(), &plaintext_size)); plaintext_.data(), &plaintext_size));
@@ -108,8 +109,8 @@ TEST_P(LicenseWhiteboxDecryptBenchmark, MaskedDecryptCBCThroughput) {
size_t mask_size = mask.size(); size_t mask_size = mask.size();
ASSERT_EQ(WB_RESULT_OK, ASSERT_EQ(WB_RESULT_OK,
WB_License_GetSecretString( WB_License_GetSecretString(
whitebox_, WB_CIPHER_MODE_CBC, ContentKeyId().data(), whitebox_, WB_CIPHER_MODE_CBC, ContentKey().id.data(),
ContentKeyId().size(), mask.data(), &mask_size)); ContentKey().id.size(), mask.data(), &mask_size));
mask.resize(mask_size); mask.resize(mask_size);
Timer timer; Timer timer;
@@ -121,10 +122,10 @@ TEST_P(LicenseWhiteboxDecryptBenchmark, MaskedDecryptCBCThroughput) {
size_t plaintext_size = plaintext_.size(); size_t plaintext_size = plaintext_.size();
ASSERT_EQ(WB_RESULT_OK, ASSERT_EQ(WB_RESULT_OK,
WB_License_MaskedDecrypt( WB_License_MaskedDecrypt(
whitebox_, WB_CIPHER_MODE_CBC, ContentKeyId().data(), whitebox_, WB_CIPHER_MODE_CBC, ContentKey().id.data(),
ContentKeyId().size(), ciphertext_.data(), ciphertext_.size(), ContentKey().id.size(), ciphertext_.data(),
ContentIV().data(), ContentIV().size(), masked_text_.data(), ciphertext_.size(), ContentIV().data(), ContentIV().size(),
&plaintext_size)); masked_text_.data(), &plaintext_size));
WB_License_Unmask(masked_text_.data(), 0, plaintext_size, mask.data(), WB_License_Unmask(masked_text_.data(), 0, plaintext_size, mask.data(),
mask.size(), plaintext_.data()); mask.size(), plaintext_.data());
@@ -140,8 +141,8 @@ TEST_P(LicenseWhiteboxDecryptBenchmark, MaskedDecryptCTRThroughput) {
size_t mask_size = mask.size(); size_t mask_size = mask.size();
ASSERT_EQ(WB_RESULT_OK, ASSERT_EQ(WB_RESULT_OK,
WB_License_GetSecretString( WB_License_GetSecretString(
whitebox_, WB_CIPHER_MODE_CTR, ContentKeyId().data(), whitebox_, WB_CIPHER_MODE_CTR, ContentKey().id.data(),
ContentKeyId().size(), mask.data(), &mask_size)); ContentKey().id.size(), mask.data(), &mask_size));
mask.resize(mask_size); mask.resize(mask_size);
Timer timer; Timer timer;
@@ -153,10 +154,10 @@ TEST_P(LicenseWhiteboxDecryptBenchmark, MaskedDecryptCTRThroughput) {
size_t plaintext_size = plaintext_.size(); size_t plaintext_size = plaintext_.size();
ASSERT_EQ(WB_RESULT_OK, ASSERT_EQ(WB_RESULT_OK,
WB_License_MaskedDecrypt( WB_License_MaskedDecrypt(
whitebox_, WB_CIPHER_MODE_CTR, ContentKeyId().data(), whitebox_, WB_CIPHER_MODE_CTR, ContentKey().id.data(),
ContentKeyId().size(), ciphertext_.data(), ciphertext_.size(), ContentKey().id.size(), ciphertext_.data(),
ContentIV().data(), ContentIV().size(), masked_text_.data(), ciphertext_.size(), ContentIV().data(), ContentIV().size(),
&plaintext_size)); masked_text_.data(), &plaintext_size));
WB_License_Unmask(masked_text_.data(), 0, plaintext_size, mask.data(), WB_License_Unmask(masked_text_.data(), 0, plaintext_size, mask.data(),
mask.size(), plaintext_.data()); mask.size(), plaintext_.data());

View File

@@ -42,21 +42,11 @@ class LicenseWhiteboxDecryptTest : public LicenseWhiteboxTestBase,
builder.SetSettings(settings); builder.SetSettings(settings);
builder.GetSettings().padding = padding_; builder.GetSettings().padding = padding_;
builder.AddContentKey(golden_data_.CBCCryptoKey().level, builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
golden_data_.CBCCryptoKey().id, builder.AddContentKey(golden_data_.CBCContent().software_decode_key);
golden_data_.CBCCryptoKey().content->key); builder.AddContentKey(golden_data_.CBCContent().hardware_key);
builder.AddContentKey(golden_data_.CTRCryptoKey().level, builder.AddContentKey(golden_data_.CTRContent().software_crypto_key);
golden_data_.CTRCryptoKey().id,
golden_data_.CTRCryptoKey().content->key);
builder.AddContentKey(golden_data_.CBCDecodeKey().level,
golden_data_.CBCDecodeKey().id,
golden_data_.CBCDecodeKey().content->key);
builder.AddContentKey(golden_data_.CBCHardwareKey().level,
golden_data_.CBCHardwareKey().id,
golden_data_.CBCHardwareKey().content->key);
builder.AddOperatorSessionKey(non_content_key_id_); builder.AddOperatorSessionKey(non_content_key_id_);
@@ -91,36 +81,76 @@ TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCbcMode) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_OK); WB_RESULT_OK);
plaintext_.resize(plaintext_size_); plaintext_.resize(plaintext_size_);
ASSERT_EQ(plaintext_, golden_data_.CBCCryptoKey().content->plaintext); ASSERT_EQ(plaintext_, golden_data_.CBCContent().plaintext);
}
TEST_P(LicenseWhiteboxDecryptTest, InPlaceDecryptionCbc) {
TestLicenseBuilder::Settings settings;
LoadLicense(settings);
memcpy(plaintext_.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCContent().ciphertext.size());
ASSERT_EQ(WB_License_Decrypt(
whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCContent().software_crypto_key.id.size(),
plaintext_.data(), plaintext_.size(),
golden_data_.CBCContent().iv.data(),
golden_data_.CBCContent().iv.size(), plaintext_.data(),
&plaintext_size_),
WB_RESULT_OK);
plaintext_.resize(plaintext_size_);
ASSERT_EQ(plaintext_, golden_data_.CBCContent().plaintext);
} }
TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCtrMode) { TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCtrMode) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CTR, whitebox_, WB_CIPHER_MODE_CTR,
golden_data_.CTRCryptoKey().id.data(), golden_data_.CTRContent().software_crypto_key.id.data(),
golden_data_.CTRCryptoKey().id.size(), golden_data_.CTRContent().software_crypto_key.id.size(),
golden_data_.CTRCryptoKey().content->ciphertext.data(), golden_data_.CTRContent().ciphertext.data(),
golden_data_.CTRCryptoKey().content->ciphertext.size(), golden_data_.CTRContent().ciphertext.size(),
golden_data_.CTRCryptoKey().content->iv.data(), golden_data_.CTRContent().iv.data(),
golden_data_.CTRCryptoKey().content->iv.size(), golden_data_.CTRContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_OK); WB_RESULT_OK);
plaintext_.resize(plaintext_size_); plaintext_.resize(plaintext_size_);
ASSERT_EQ(plaintext_, golden_data_.CTRCryptoKey().content->plaintext); ASSERT_EQ(plaintext_, golden_data_.CTRContent().plaintext);
}
TEST_P(LicenseWhiteboxDecryptTest, InPlaceDecryptionCtr) {
TestLicenseBuilder::Settings settings;
LoadLicense(settings);
memcpy(plaintext_.data(), golden_data_.CTRContent().ciphertext.data(),
golden_data_.CTRContent().ciphertext.size());
ASSERT_EQ(WB_License_Decrypt(
whitebox_, WB_CIPHER_MODE_CTR,
golden_data_.CTRContent().software_crypto_key.id.data(),
golden_data_.CTRContent().software_crypto_key.id.size(),
plaintext_.data(), plaintext_.size(),
golden_data_.CTRContent().iv.data(),
golden_data_.CTRContent().iv.size(), plaintext_.data(),
&plaintext_size_),
WB_RESULT_OK);
plaintext_.resize(plaintext_size_);
ASSERT_EQ(plaintext_, golden_data_.CTRContent().plaintext);
} }
// We try to decrypt CBC encrypted data in CTR mode. All operations should be // We try to decrypt CBC encrypted data in CTR mode. All operations should be
@@ -129,18 +159,18 @@ TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCtrMode) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CTR, whitebox_, WB_CIPHER_MODE_CTR,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_OK); WB_RESULT_OK);
plaintext_.resize(plaintext_size_); plaintext_.resize(plaintext_size_);
ASSERT_NE(plaintext_, golden_data_.CBCCryptoKey().content->plaintext); ASSERT_NE(plaintext_, golden_data_.CBCContent().plaintext);
} }
// We try to decrypt CTR encrypted data in CBC mode. All operations should be // We try to decrypt CTR encrypted data in CBC mode. All operations should be
@@ -149,18 +179,18 @@ TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCbcMode) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CTRCryptoKey().id.data(), golden_data_.CTRContent().software_crypto_key.id.data(),
golden_data_.CTRCryptoKey().id.size(), golden_data_.CTRContent().software_crypto_key.id.size(),
golden_data_.CTRCryptoKey().content->ciphertext.data(), golden_data_.CTRContent().ciphertext.data(),
golden_data_.CTRCryptoKey().content->ciphertext.size(), golden_data_.CTRContent().ciphertext.size(),
golden_data_.CTRCryptoKey().content->iv.data(), golden_data_.CTRContent().iv.data(),
golden_data_.CTRCryptoKey().content->iv.size(), golden_data_.CTRContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_OK); WB_RESULT_OK);
plaintext_.resize(plaintext_size_); plaintext_.resize(plaintext_size_);
ASSERT_NE(plaintext_, golden_data_.CTRCryptoKey().content->plaintext); ASSERT_NE(plaintext_, golden_data_.CTRContent().plaintext);
} }
// Try decrypting two different sets of content to make sure that two // Try decrypting two different sets of content to make sure that two
@@ -169,52 +199,52 @@ TEST_P(LicenseWhiteboxDecryptTest, SuccessWithMultipleKeys) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_OK); WB_RESULT_OK);
plaintext_.resize(plaintext_size_); plaintext_.resize(plaintext_size_);
ASSERT_EQ(plaintext_, golden_data_.CBCCryptoKey().content->plaintext); ASSERT_EQ(plaintext_, golden_data_.CBCContent().plaintext);
// Reset our output buffer. // Reset our output buffer.
plaintext_.clear(); plaintext_.clear();
plaintext_size_ = golden_data_.CTRDecodeKey().content->plaintext.size(); plaintext_size_ = golden_data_.CTRContent().plaintext.size();
plaintext_.resize(plaintext_size_); plaintext_.resize(plaintext_size_);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CTR, whitebox_, WB_CIPHER_MODE_CTR,
golden_data_.CTRCryptoKey().id.data(), golden_data_.CTRContent().software_crypto_key.id.data(),
golden_data_.CTRCryptoKey().id.size(), golden_data_.CTRContent().software_crypto_key.id.size(),
golden_data_.CTRCryptoKey().content->ciphertext.data(), golden_data_.CTRContent().ciphertext.data(),
golden_data_.CTRCryptoKey().content->ciphertext.size(), golden_data_.CTRContent().ciphertext.size(),
golden_data_.CTRCryptoKey().content->iv.data(), golden_data_.CTRContent().iv.data(),
golden_data_.CTRCryptoKey().content->iv.size(), golden_data_.CTRContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_OK); WB_RESULT_OK);
plaintext_.resize(plaintext_size_); plaintext_.resize(plaintext_size_);
ASSERT_EQ(plaintext_, golden_data_.CTRCryptoKey().content->plaintext); ASSERT_EQ(plaintext_, golden_data_.CTRContent().plaintext);
} }
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullWhitebox) { TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullWhitebox) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(nullptr, WB_CIPHER_MODE_CBC, nullptr, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -228,13 +258,14 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCipherMode) {
const WB_CipherMode invalid_mode = static_cast<WB_CipherMode>(0xFF); const WB_CipherMode invalid_mode = static_cast<WB_CipherMode>(0xFF);
ASSERT_EQ(WB_License_Decrypt( ASSERT_EQ(WB_License_Decrypt(
whitebox_, invalid_mode, golden_data_.CBCCryptoKey().id.data(), whitebox_, invalid_mode,
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.data(),
plaintext_.data(), &plaintext_size_), golden_data_.CBCContent().iv.size(), plaintext_.data(),
&plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -242,14 +273,14 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullKeyId) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, nullptr, whitebox_, WB_CIPHER_MODE_CBC, nullptr,
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -257,14 +288,14 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForZeroKeyIdSize) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), 0, golden_data_.CBCContent().software_crypto_key.id.data(), 0,
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -272,14 +303,14 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullInputData) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), nullptr, golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), nullptr, golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -289,14 +320,14 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCBCInputDataSize) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(), 14,
14, golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -305,14 +336,14 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForZeroInputDataSize) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(), 0,
0, golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -320,13 +351,13 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullIV) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt( whitebox_, WB_CIPHER_MODE_CBC,
whitebox_, WB_CIPHER_MODE_CBC, golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), nullptr, golden_data_.CBCContent().ciphertext.size(), nullptr,
golden_data_.CBCCryptoKey().content->iv.size(), plaintext_.data(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
&plaintext_size_), &plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -336,14 +367,14 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidIVSize) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), 9, golden_data_.CBCContent().iv.data(), 9, plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -351,15 +382,14 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutput) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), nullptr, &plaintext_size_),
nullptr, &plaintext_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -368,14 +398,14 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutputSize) {
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, WB_License_Decrypt(
golden_data_.CBCCryptoKey().id.data(), whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.data(),
plaintext_.data(), nullptr), golden_data_.CBCContent().iv.size(), plaintext_.data(), nullptr),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -386,13 +416,12 @@ TEST_P(LicenseWhiteboxDecryptTest, KeyUnavailableForMissingKeyId) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC,
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, missing_key_id_.data(), missing_key_id_.data(), missing_key_id_.size(),
missing_key_id_.size(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.size(),
golden_data_.CBCCryptoKey().content->iv.size(),
plaintext_.data(), &plaintext_size_), plaintext_.data(), &plaintext_size_),
WB_RESULT_KEY_UNAVAILABLE); WB_RESULT_KEY_UNAVAILABLE);
} }
@@ -404,11 +433,11 @@ TEST_P(LicenseWhiteboxDecryptTest, KeyUnavailableForNonContentKey) {
ASSERT_EQ( ASSERT_EQ(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC,
non_content_key_id_.data(), non_content_key_id_.size(), non_content_key_id_.data(), non_content_key_id_.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_KEY_UNAVAILABLE); WB_RESULT_KEY_UNAVAILABLE);
} }
@@ -419,14 +448,13 @@ TEST_P(LicenseWhiteboxDecryptTest,
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ(WB_License_Decrypt( ASSERT_EQ(WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC,
whitebox_, WB_CIPHER_MODE_CBC, golden_data_.CBCContent().hardware_key.id.data(),
golden_data_.CBCHardwareKey().id.data(), golden_data_.CBCContent().hardware_key.id.size(),
golden_data_.CBCHardwareKey().id.size(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCHardwareKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCHardwareKey().content->ciphertext.size(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCHardwareKey().content->iv.data(), golden_data_.CBCContent().iv.size(),
golden_data_.CBCHardwareKey().content->iv.size(),
plaintext_.data(), &plaintext_size_), plaintext_.data(), &plaintext_size_),
WB_RESULT_INSUFFICIENT_SECURITY_LEVEL); WB_RESULT_INSUFFICIENT_SECURITY_LEVEL);
} }
@@ -437,15 +465,15 @@ TEST_P(LicenseWhiteboxDecryptTest, InsufficientSecurityLevelForDecodeKey) {
// Use the software decode key as they are limited to // Use the software decode key as they are limited to
// WB_License_Decrypt(). // WB_License_Decrypt().
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCDecodeKey().id.data(), golden_data_.CBCContent().software_decode_key.id.data(),
golden_data_.CBCDecodeKey().id.size(), golden_data_.CBCContent().software_decode_key.id.size(),
golden_data_.CBCDecodeKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCDecodeKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCDecodeKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCDecodeKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_INSUFFICIENT_SECURITY_LEVEL); WB_RESULT_INSUFFICIENT_SECURITY_LEVEL);
} }
@@ -457,21 +485,20 @@ TEST_P(LicenseWhiteboxDecryptTest, BufferTooSmall) {
// using a constant here. // using a constant here.
plaintext_size_ = 8; plaintext_size_ = 8;
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_BUFFER_TOO_SMALL); WB_RESULT_BUFFER_TOO_SMALL);
// We don't use padding so the reported plaintext size should be the same as // We don't use padding so the reported plaintext size should be the same as
// the cipher text size. // the cipher text size.
ASSERT_EQ(plaintext_size_, ASSERT_EQ(plaintext_size_, golden_data_.CBCContent().ciphertext.size());
golden_data_.CBCCryptoKey().content->ciphertext.size());
} }
TEST_P(LicenseWhiteboxDecryptTest, InvalidState) { TEST_P(LicenseWhiteboxDecryptTest, InvalidState) {
@@ -479,15 +506,15 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidState) {
// WB_RESULT_INVALID_STATE is that no key can be found and keys are provided // WB_RESULT_INVALID_STATE is that no key can be found and keys are provided
// via a license. // via a license.
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_INVALID_STATE); WB_RESULT_INVALID_STATE);
} }
@@ -499,15 +526,15 @@ TEST_P(LicenseWhiteboxDecryptTest, KeyUnavailableForInvalidKey) {
settings.include_content_key_iv = false; settings.include_content_key_iv = false;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_Decrypt(
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), golden_data_.CBCContent().ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(), golden_data_.CBCContent().ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(), golden_data_.CBCContent().iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), golden_data_.CBCContent().iv.size(), plaintext_.data(),
plaintext_.data(), &plaintext_size_), &plaintext_size_),
WB_RESULT_KEY_UNAVAILABLE); WB_RESULT_KEY_UNAVAILABLE);
} }

View File

@@ -31,17 +31,12 @@ class LicenseWhiteboxGetSecretStringTest : public LicenseWhiteboxTestBase {
TestLicenseBuilder builder; TestLicenseBuilder builder;
builder.SetSettings(settings); builder.SetSettings(settings);
builder.AddContentKey(golden_data_.CBCCryptoKey().level, builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
golden_data_.CBCCryptoKey().id, builder.AddContentKey(golden_data_.CBCContent().software_decode_key);
golden_data_.CBCCryptoKey().content->key); builder.AddContentKey(golden_data_.CBCContent().hardware_key);
builder.AddContentKey(golden_data_.CBCDecodeKey().level, builder.AddContentKey(golden_data_.CTRContent().software_crypto_key);
golden_data_.CBCDecodeKey().id, builder.AddContentKey(golden_data_.CTRContent().software_decode_key);
golden_data_.CBCDecodeKey().content->key);
builder.AddContentKey(golden_data_.CBCHardwareKey().level,
golden_data_.CBCHardwareKey().id,
golden_data_.CBCHardwareKey().content->key);
builder.AddOperatorSessionKey(non_content_key_id_); builder.AddOperatorSessionKey(non_content_key_id_);
@@ -73,10 +68,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCBCWithCryptoKey) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_OK); WB_RESULT_OK);
ASSERT_GT(secret_string_size_, 0u); ASSERT_GT(secret_string_size_, 0u);
@@ -86,10 +81,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCTRWithCryptoKey) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CTR, whitebox_, WB_CIPHER_MODE_CTR,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CTRContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CTRContent().software_crypto_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_OK); WB_RESULT_OK);
ASSERT_GT(secret_string_size_, 0u); ASSERT_GT(secret_string_size_, 0u);
@@ -99,10 +94,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCBCWithDecodeKey) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCDecodeKey().id.data(), golden_data_.CBCContent().software_decode_key.id.data(),
golden_data_.CBCDecodeKey().id.size(), golden_data_.CBCContent().software_decode_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_OK); WB_RESULT_OK);
ASSERT_GT(secret_string_size_, 0u); ASSERT_GT(secret_string_size_, 0u);
@@ -112,10 +107,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, SuccessForCTRWithDecodeKey) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CTR, whitebox_, WB_CIPHER_MODE_CTR,
golden_data_.CBCDecodeKey().id.data(), golden_data_.CTRContent().software_decode_key.id.data(),
golden_data_.CBCDecodeKey().id.size(), golden_data_.CTRContent().software_decode_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_OK); WB_RESULT_OK);
ASSERT_GT(secret_string_size_, 0u); ASSERT_GT(secret_string_size_, 0u);
@@ -125,10 +120,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, InvalidParameterForNullWhitebox) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(nullptr, WB_CIPHER_MODE_CBC, nullptr, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -144,9 +139,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest,
const WB_CipherMode invalid_mode = static_cast<WB_CipherMode>(0xFF); const WB_CipherMode invalid_mode = static_cast<WB_CipherMode>(0xFF);
ASSERT_EQ(WB_License_GetSecretString( ASSERT_EQ(WB_License_GetSecretString(
whitebox_, invalid_mode, golden_data_.CBCCryptoKey().id.data(), whitebox_, invalid_mode,
golden_data_.CBCCryptoKey().id.size(), secret_string_.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
&secret_string_size_), golden_data_.CBCContent().software_crypto_key.id.size(),
secret_string_.data(), &secret_string_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -154,9 +150,9 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, InvalidParameterForNullKeyId) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, nullptr, whitebox_, WB_CIPHER_MODE_CBC, nullptr,
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -165,21 +161,36 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, InvalidParameterForZeroKeyIdSize) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), 0, golden_data_.CBCContent().software_crypto_key.id.data(), 0,
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
TEST_F(LicenseWhiteboxGetSecretStringTest, CanProbeSizeWithNullString) {
TestLicenseBuilder::Settings settings;
LoadLicense(settings);
secret_string_size_ = 0;
ASSERT_EQ(WB_License_GetSecretString(
whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCContent().software_crypto_key.id.size(),
nullptr, &secret_string_size_),
WB_RESULT_BUFFER_TOO_SMALL);
ASSERT_GT(secret_string_size_, 0);
}
TEST_F(LicenseWhiteboxGetSecretStringTest, TEST_F(LicenseWhiteboxGetSecretStringTest,
InvalidParameterForNullSecretString) { InvalidParameterForNullSecretString) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ(WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, ASSERT_EQ(WB_License_GetSecretString(
golden_data_.CBCCryptoKey().id.data(), whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCContent().software_crypto_key.id.size(),
nullptr, &secret_string_size_), nullptr, &secret_string_size_),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -189,9 +200,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest,
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ(WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, ASSERT_EQ(WB_License_GetSecretString(
golden_data_.CBCCryptoKey().id.data(), whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCContent().software_crypto_key.id.size(),
secret_string_.data(), nullptr), secret_string_.data(), nullptr),
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
@@ -228,10 +240,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest,
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCHardwareKey().id.data(), golden_data_.CBCContent().hardware_key.id.data(),
golden_data_.CBCHardwareKey().id.size(), golden_data_.CBCContent().hardware_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_INSUFFICIENT_SECURITY_LEVEL); WB_RESULT_INSUFFICIENT_SECURITY_LEVEL);
} }
@@ -245,10 +257,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, BufferTooSmall) {
// as it would not introduce enough variation to be effective. We avoid using // as it would not introduce enough variation to be effective. We avoid using
// zero here so that we can verify that we are not just checking for zero. // zero here so that we can verify that we are not just checking for zero.
secret_string_size_ = 1; secret_string_size_ = 1;
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_BUFFER_TOO_SMALL); WB_RESULT_BUFFER_TOO_SMALL);
@@ -262,10 +274,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, InvalidState) {
// Purposely do not load a license so that we won't have any keys, causing // Purposely do not load a license so that we won't have any keys, causing
// use to be in an invalid state. // use to be in an invalid state.
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_INVALID_STATE); WB_RESULT_INVALID_STATE);
} }
@@ -278,10 +290,10 @@ TEST_F(LicenseWhiteboxGetSecretStringTest, KeyUnavailableForInvalidKey) {
settings.include_content_key_iv = false; settings.include_content_key_iv = false;
LoadLicense(settings); LoadLicense(settings);
ASSERT_EQ( ASSERT_EQ(WB_License_GetSecretString(
WB_License_GetSecretString(whitebox_, WB_CIPHER_MODE_CBC, whitebox_, WB_CIPHER_MODE_CBC,
golden_data_.CBCCryptoKey().id.data(), golden_data_.CBCContent().software_crypto_key.id.data(),
golden_data_.CBCCryptoKey().id.size(), golden_data_.CBCContent().software_crypto_key.id.size(),
secret_string_.data(), &secret_string_size_), secret_string_.data(), &secret_string_size_),
WB_RESULT_KEY_UNAVAILABLE); WB_RESULT_KEY_UNAVAILABLE);
} }

View File

@@ -21,11 +21,6 @@ class LicenseWhiteboxKeyControlBlockTest
server_ = TestServer::CreateDualKey(); server_ = TestServer::CreateDualKey();
} }
void AddKeyToLicense(const GoldenData::Key& key,
TestLicenseBuilder* license) {
license->AddContentKey(key.level, key.id, key.content->key);
}
TestLicenseBuilder::KeyControlBlock kcb_; TestLicenseBuilder::KeyControlBlock kcb_;
TestLicenseBuilder::OdkVersion odk_; TestLicenseBuilder::OdkVersion odk_;
@@ -41,9 +36,10 @@ TEST_P(LicenseWhiteboxKeyControlBlockTest, Decrypt) {
builder.GetSettings().key_control_block = kcb_; builder.GetSettings().key_control_block = kcb_;
builder.GetSettings().odk_version = odk_; builder.GetSettings().odk_version = odk_;
const auto& cbc_test_data = golden_data_.CBCCryptoKey(); const auto& content = golden_data_.CBCContent();
const auto& key = content.software_crypto_key;
AddKeyToLicense(cbc_test_data, &builder); builder.AddContentKey(key);
License license; License license;
builder.Build(*server_, &license); builder.Build(*server_, &license);
@@ -57,17 +53,15 @@ TEST_P(LicenseWhiteboxKeyControlBlockTest, Decrypt) {
license.request.data(), license.request.size()), license.request.data(), license.request.size()),
WB_RESULT_OK); WB_RESULT_OK);
std::vector<uint8_t> plaintext(cbc_test_data.content->ciphertext.size()); std::vector<uint8_t> plaintext(content.ciphertext.size());
size_t plaintext_size = plaintext.size(); size_t plaintext_size = plaintext.size();
// Make sure we can actually decrypt some data. // Make sure we can actually decrypt some data.
ASSERT_EQ(WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, ASSERT_EQ(
cbc_test_data.id.data(), cbc_test_data.id.size(), WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, key.id.data(),
cbc_test_data.content->ciphertext.data(), key.id.size(), content.ciphertext.data(),
cbc_test_data.content->ciphertext.size(), content.ciphertext.size(), content.iv.data(),
cbc_test_data.content->iv.data(), content.iv.size(), plaintext.data(), &plaintext_size),
cbc_test_data.content->iv.size(),
plaintext.data(), &plaintext_size),
WB_RESULT_OK); WB_RESULT_OK);
} }
@@ -76,9 +70,10 @@ TEST_P(LicenseWhiteboxKeyControlBlockTest, MaskedDecrypt) {
builder.GetSettings().key_control_block = kcb_; builder.GetSettings().key_control_block = kcb_;
builder.GetSettings().odk_version = odk_; builder.GetSettings().odk_version = odk_;
const auto& cbc_test_data = golden_data_.CBCDecodeKey(); const auto& content = golden_data_.CBCContent();
const auto& key = content.software_decode_key;
AddKeyToLicense(cbc_test_data, &builder); builder.AddContentKey(key);
License license; License license;
builder.Build(*server_, &license); builder.Build(*server_, &license);
@@ -92,17 +87,15 @@ TEST_P(LicenseWhiteboxKeyControlBlockTest, MaskedDecrypt) {
license.request.data(), license.request.size()), license.request.data(), license.request.size()),
WB_RESULT_OK); WB_RESULT_OK);
std::vector<uint8_t> plaintext(cbc_test_data.content->ciphertext.size()); std::vector<uint8_t> plaintext(content.ciphertext.size());
size_t plaintext_size = plaintext.size(); size_t plaintext_size = plaintext.size();
// Make sure we can actually decrypt some data. // Make sure we can actually decrypt some data.
ASSERT_EQ( ASSERT_EQ(WB_License_MaskedDecrypt(
WB_License_MaskedDecrypt( whitebox_, WB_CIPHER_MODE_CBC, key.id.data(), key.id.size(),
whitebox_, WB_CIPHER_MODE_CBC, cbc_test_data.id.data(), content.ciphertext.data(), content.ciphertext.size(),
cbc_test_data.id.size(), cbc_test_data.content->ciphertext.data(), content.iv.data(), content.iv.size(), plaintext.data(),
cbc_test_data.content->ciphertext.size(), &plaintext_size),
cbc_test_data.content->iv.data(), cbc_test_data.content->iv.size(),
plaintext.data(), &plaintext_size),
WB_RESULT_OK); WB_RESULT_OK);
} }

View File

@@ -74,21 +74,19 @@ class LicenseWhiteboxLicenseKeyMode
license.request.size()); license.request.size());
} }
void Decrypt(const GoldenData::Key& golden_data) { void Decrypt(const GoldenData::Content& content, const ContentKeyData& key) {
size_t plaintext_size = golden_data.content->plaintext.size(); size_t plaintext_size = content.plaintext.size();
std::vector<uint8_t> plaintext(plaintext_size); std::vector<uint8_t> plaintext(plaintext_size);
ASSERT_EQ(WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, ASSERT_EQ(WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, key.id.data(),
golden_data.id.data(), golden_data.id.size(), key.id.size(), content.ciphertext.data(),
golden_data.content->ciphertext.data(), content.ciphertext.size(), content.iv.data(),
golden_data.content->ciphertext.size(), content.iv.size(), plaintext.data(),
golden_data.content->iv.data(), &plaintext_size),
golden_data.content->iv.size(),
plaintext.data(), &plaintext_size),
WB_RESULT_OK); WB_RESULT_OK);
plaintext.resize(plaintext_size); plaintext.resize(plaintext_size);
ASSERT_EQ(plaintext, golden_data.content->plaintext); ASSERT_EQ(plaintext, content.plaintext);
} }
std::unique_ptr<TestServer> server_; std::unique_ptr<TestServer> server_;
@@ -117,18 +115,18 @@ TEST_P(LicenseWhiteboxLicenseKeyMode, SignAndProcessLicense) {
SignLicenseRequest(*server); SignLicenseRequest(*server);
const auto& golden_data = golden_data_.CBCCryptoKey(); const auto& content = golden_data_.CBCContent();
const auto& key = content.software_crypto_key;
TestLicenseBuilder builder; TestLicenseBuilder builder;
builder.AddContentKey(golden_data.level, golden_data.id, builder.AddContentKey(key);
golden_data.content->key);
License license; License license;
builder.Build(*server, &license); builder.Build(*server, &license);
if (should_pass_) { if (should_pass_) {
ASSERT_EQ(LoadLicense(license, client_mode_), WB_RESULT_OK); ASSERT_EQ(LoadLicense(license, client_mode_), WB_RESULT_OK);
Decrypt(golden_data); Decrypt(content, key);
} else { } else {
ASSERT_NE(LoadLicense(license, client_mode_), WB_RESULT_OK); ASSERT_NE(LoadLicense(license, client_mode_), WB_RESULT_OK);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <tuple>
#include "api/license_whitebox.h" #include "api/license_whitebox.h"
#include "api/license_whitebox_benchmark.h" #include "api/license_whitebox_benchmark.h"
@@ -14,19 +15,27 @@ namespace widevine {
namespace { namespace {
// The white-box implementation is slow, so the build bots keep timing out. To // The white-box implementation is slow, so the build bots keep timing out. To
// work around this, use a fixed number of iterations. // work around this, use a fixed number of iterations.
constexpr size_t kIterations = 100; constexpr size_t kIterations = 10;
} // namespace } // namespace
// This test takes 3 parameters. The first (key mode) will change how the
// license is encrypted and signed. The second (int) determines the number of
// content keys in the license. The third (security level) determines the
// security level of the content keys other than the first one (which is
// always kSoftwareSecureCrypto so that it works with both Decrypt() and
// MaskedDecrypt()).
class LicenseWhiteboxProcessLicenseResponseBenchmark class LicenseWhiteboxProcessLicenseResponseBenchmark
: public LicenseWhiteboxBenchmark, : public LicenseWhiteboxBenchmark,
public testing::WithParamInterface<WB_LicenseKeyMode> { public ::testing::WithParamInterface<
std::tuple<WB_LicenseKeyMode, int, SecurityLevel>> {
protected: protected:
void SetUp() override { void SetUp() override {
LicenseWhiteboxBenchmark::SetUp(); LicenseWhiteboxBenchmark::SetUp();
key_mode_ = GetParam(); key_mode_ = ::testing::get<0>(GetParam());
license_ = CreateLicense(key_mode_); license_ = CreateLicense(key_mode_, ::testing::get<1>(GetParam()),
::testing::get<2>(GetParam()));
} }
void TearDown() override { WB_License_Delete(whitebox_); } void TearDown() override { WB_License_Delete(whitebox_); }
@@ -39,6 +48,23 @@ class LicenseWhiteboxProcessLicenseResponseBenchmark
License license_; License license_;
}; };
TEST_P(LicenseWhiteboxProcessLicenseResponseBenchmark, ProcessLicenseCreate) {
Timer timer;
Sampler sampler;
for (size_t i = 0; i < kIterations; i++) {
timer.Reset();
ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK);
sampler.Push(timer.Get());
WB_License_Delete(whitebox_);
whitebox_ = nullptr;
}
PrettyPrint("License White-box License Create Duration", sampler,
license_.message.size());
}
TEST_P(LicenseWhiteboxProcessLicenseResponseBenchmark, TEST_P(LicenseWhiteboxProcessLicenseResponseBenchmark,
CreateAndProcessLicenseResponseAndDelete) { CreateAndProcessLicenseResponseAndDelete) {
Timer timer; Timer timer;
@@ -136,12 +162,46 @@ TEST_P(LicenseWhiteboxProcessLicenseResponseBenchmark, ProcessLicenseResponse) {
license_.message.size()); license_.message.size());
} }
INSTANTIATE_TEST_SUITE_P(SingleKey, INSTANTIATE_TEST_SUITE_P(
SingleKeyWithSingleKeyServer,
LicenseWhiteboxProcessLicenseResponseBenchmark, LicenseWhiteboxProcessLicenseResponseBenchmark,
::testing::Values(WB_LICENSE_KEY_MODE_SINGLE_KEY)); ::testing::Values(std::make_tuple(WB_LICENSE_KEY_MODE_SINGLE_KEY,
1,
SecurityLevel::kSoftwareSecureCrypto)));
INSTANTIATE_TEST_SUITE_P(DualKey, INSTANTIATE_TEST_SUITE_P(
FiveCryptoKeysWithSingleKeyServer,
LicenseWhiteboxProcessLicenseResponseBenchmark, LicenseWhiteboxProcessLicenseResponseBenchmark,
::testing::Values(WB_LICENSE_KEY_MODE_DUAL_KEY)); ::testing::Values(std::make_tuple(WB_LICENSE_KEY_MODE_SINGLE_KEY,
5,
SecurityLevel::kSoftwareSecureCrypto)));
INSTANTIATE_TEST_SUITE_P(
FiveDecodeKeysWithSingleKeyServer,
LicenseWhiteboxProcessLicenseResponseBenchmark,
::testing::Values(std::make_tuple(WB_LICENSE_KEY_MODE_SINGLE_KEY,
5,
SecurityLevel::kSoftwareSecureDecode)));
INSTANTIATE_TEST_SUITE_P(
SingleKeyWithDualKeyServer,
LicenseWhiteboxProcessLicenseResponseBenchmark,
::testing::Values(std::make_tuple(WB_LICENSE_KEY_MODE_DUAL_KEY,
1,
SecurityLevel::kSoftwareSecureCrypto)));
INSTANTIATE_TEST_SUITE_P(
FiveCryptoKeysWithDualKeyServer,
LicenseWhiteboxProcessLicenseResponseBenchmark,
::testing::Values(std::make_tuple(WB_LICENSE_KEY_MODE_DUAL_KEY,
5,
SecurityLevel::kSoftwareSecureCrypto)));
INSTANTIATE_TEST_SUITE_P(
FiveDecodeKeysWithDualKeyServer,
LicenseWhiteboxProcessLicenseResponseBenchmark,
::testing::Values(std::make_tuple(WB_LICENSE_KEY_MODE_DUAL_KEY,
5,
SecurityLevel::kSoftwareSecureDecode)));
} // namespace widevine } // namespace widevine

View File

@@ -18,7 +18,7 @@ class LicenseWhiteboxProcessLicenseResponseWithCoreMessageTest
void UseLicenseWithoutSigningKey(OdkVersion odk_version) { void UseLicenseWithoutSigningKey(OdkVersion odk_version) {
TestLicenseBuilder builder; TestLicenseBuilder builder;
builder.GetSettings().odk_version = odk_version; builder.GetSettings().odk_version = odk_version;
builder.AddStubbedContentKey(); builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
const auto server = TestServer::CreateDualKey(); const auto server = TestServer::CreateDualKey();
builder.Build(*server, &license_); builder.Build(*server, &license_);
@@ -31,7 +31,7 @@ class LicenseWhiteboxProcessLicenseResponseWithCoreMessageTest
builder.GetSettings().odk_version = odk_version; builder.GetSettings().odk_version = odk_version;
builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey()); builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey());
builder.AddStubbedContentKey(); builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
auto server = TestServer::CreateDualKey(); auto server = TestServer::CreateDualKey();
builder.Build(*server, &license_); builder.Build(*server, &license_);

View File

@@ -30,7 +30,7 @@ class LicenseWhiteboxProcessLicenseResponseTest
void UseLicenseWithoutSigningKey() { void UseLicenseWithoutSigningKey() {
TestLicenseBuilder builder; TestLicenseBuilder builder;
builder.AddStubbedContentKey(); builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
builder.Build(*server_, &license_); builder.Build(*server_, &license_);
} }
@@ -39,7 +39,7 @@ class LicenseWhiteboxProcessLicenseResponseTest
builder.GetSettings().padding = padding; builder.GetSettings().padding = padding;
builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey()); builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey());
builder.AddStubbedContentKey(); builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
builder.Build(*server_, &license_); builder.Build(*server_, &license_);
} }
@@ -98,7 +98,7 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseTest,
builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey()); builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey());
builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey()); builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey());
builder.AddStubbedContentKey(); builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
builder.Build(*server_, &license_); builder.Build(*server_, &license_);
ASSERT_EQ(WB_License_ProcessLicenseResponse( ASSERT_EQ(WB_License_ProcessLicenseResponse(

View File

@@ -28,8 +28,8 @@ class LicenseWhiteboxQueryContentKeyStatus
protected: protected:
void SetUp() override { void SetUp() override {
LicenseWhiteboxTestBase::SetUp(); LicenseWhiteboxTestBase::SetUp();
decrypt_key_ = &golden_data_.CBCCryptoKey(); decrypt_key_ = &golden_data_.CBCContent().software_crypto_key;
masked_decrypt_key_ = &golden_data_.CBCDecodeKey(); masked_decrypt_key_ = &golden_data_.CBCContent().software_decode_key;
std::tie(license_parsing_, padding_) = GetParam(); std::tie(license_parsing_, padding_) = GetParam();
@@ -40,9 +40,7 @@ class LicenseWhiteboxQueryContentKeyStatus
builder_.SetSettings(settings); builder_.SetSettings(settings);
} }
void AddKey(const GoldenData::Key* key) { void AddKey(const ContentKeyData* key) { builder_.AddContentKey(*key); }
builder_.AddContentKey(key->level, key->id, key->content->key);
}
WB_Result LoadLicense() { WB_Result LoadLicense() {
TestLicenseBuilder::Settings settings = builder_.GetSettings(); TestLicenseBuilder::Settings settings = builder_.GetSettings();
@@ -82,8 +80,8 @@ class LicenseWhiteboxQueryContentKeyStatus
license.request.size()); license.request.size());
} }
const GoldenData::Key* decrypt_key_; const ContentKeyData* decrypt_key_;
const GoldenData::Key* masked_decrypt_key_; const ContentKeyData* masked_decrypt_key_;
private: private:
std::unique_ptr<TestServer> server_; std::unique_ptr<TestServer> server_;
@@ -180,14 +178,18 @@ TEST_P(LicenseWhiteboxQueryContentKeyStatus, InvalidKeyForNoKeyData) {
SetSettings(settings); SetSettings(settings);
AddKey(decrypt_key_); AddKey(decrypt_key_);
ASSERT_EQ(LoadLicense(), WB_RESULT_OK); // Allow either a parsing error, or success and no keys loaded.
WB_Result result = LoadLicense();
if (result != WB_RESULT_INVALID_PARAMETER) {
ASSERT_EQ(result, WB_RESULT_OK);
WB_KeyStatus key_state; WB_KeyStatus key_state;
ASSERT_EQ(WB_License_QueryKeyStatus(whitebox_, WB_KEY_QUERY_TYPE_CONTENT_KEY, ASSERT_EQ(WB_License_QueryKeyStatus(
decrypt_key_->id.data(), whitebox_, WB_KEY_QUERY_TYPE_CONTENT_KEY,
decrypt_key_->id.size(), &key_state), decrypt_key_->id.data(), decrypt_key_->id.size(), &key_state),
WB_RESULT_OK); WB_RESULT_OK);
ASSERT_EQ(key_state, WB_KEY_STATUS_INVALID); ASSERT_EQ(key_state, WB_KEY_STATUS_INVALID);
}
} }
TEST_P(LicenseWhiteboxQueryContentKeyStatus, InvalidKeyForShortKeyData) { TEST_P(LicenseWhiteboxQueryContentKeyStatus, InvalidKeyForShortKeyData) {
@@ -197,14 +199,18 @@ TEST_P(LicenseWhiteboxQueryContentKeyStatus, InvalidKeyForShortKeyData) {
SetSettings(settings); SetSettings(settings);
AddKey(decrypt_key_); AddKey(decrypt_key_);
ASSERT_EQ(LoadLicense(), WB_RESULT_OK); // Allow either a parsing error, or success and no keys loaded.
WB_Result result = LoadLicense();
if (result != WB_RESULT_INVALID_PARAMETER) {
ASSERT_EQ(result, WB_RESULT_OK);
WB_KeyStatus key_state; WB_KeyStatus key_state;
ASSERT_EQ(WB_License_QueryKeyStatus(whitebox_, WB_KEY_QUERY_TYPE_CONTENT_KEY, ASSERT_EQ(WB_License_QueryKeyStatus(
decrypt_key_->id.data(), whitebox_, WB_KEY_QUERY_TYPE_CONTENT_KEY,
decrypt_key_->id.size(), &key_state), decrypt_key_->id.data(), decrypt_key_->id.size(), &key_state),
WB_RESULT_OK); WB_RESULT_OK);
ASSERT_EQ(key_state, WB_KEY_STATUS_INVALID); ASSERT_EQ(key_state, WB_KEY_STATUS_INVALID);
}
} }
TEST_P(LicenseWhiteboxQueryContentKeyStatus, InvalidKeyForLongKeyData) { TEST_P(LicenseWhiteboxQueryContentKeyStatus, InvalidKeyForLongKeyData) {

View File

@@ -61,9 +61,7 @@ class LicenseWhiteboxQuerySigningKeyStatus
// ODK requires there to be at least one content key or else it will fail // ODK requires there to be at least one content key or else it will fail
// to create the core message. // to create the core message.
const auto& content_key = &golden_data_.CBCCryptoKey(); builder_.AddContentKey(golden_data_.CBCContent().software_crypto_key);
builder_.AddContentKey(content_key->level, content_key->id,
content_key->content->key);
auto server = TestServer::CreateDualKey(); auto server = TestServer::CreateDualKey();

View File

@@ -37,8 +37,25 @@ class LicenseWhiteboxSecurityLevelTest
TEST_P(LicenseWhiteboxSecurityLevelTest, CanLoadAndUseKey) { TEST_P(LicenseWhiteboxSecurityLevelTest, CanLoadAndUseKey) {
TestLicenseBuilder builder; TestLicenseBuilder builder;
builder.GetSettings().key_control_block = key_control_block_; builder.GetSettings().key_control_block = key_control_block_;
builder.AddContentKey(security_level_, golden_data_.CBCCryptoKey().id,
golden_data_.CBCCryptoKey().content->key); const auto& content = golden_data_.CBCContent();
const ContentKeyData* key = nullptr;
switch (security_level_) {
case SecurityLevel::kUndefined:
key = &content.undefined_key;
break;
case SecurityLevel::kSoftwareSecureCrypto:
key = &content.software_crypto_key;
break;
default:
ASSERT_FALSE(true);
break;
}
builder.AddContentKey(*key);
auto server = TestServer::CreateDualKey(); auto server = TestServer::CreateDualKey();
@@ -54,7 +71,7 @@ TEST_P(LicenseWhiteboxSecurityLevelTest, CanLoadAndUseKey) {
license.request.data(), license.request.size()), license.request.data(), license.request.size()),
WB_RESULT_OK); WB_RESULT_OK);
plaintext_size_ = golden_data_.CBCCryptoKey().content->ciphertext.size(); plaintext_size_ = golden_data_.CBCContent().ciphertext.size();
plaintext_.resize(plaintext_size_); plaintext_.resize(plaintext_size_);
// Make sure that the key was loaded successfully even if the security level // Make sure that the key was loaded successfully even if the security level
@@ -63,28 +80,20 @@ TEST_P(LicenseWhiteboxSecurityLevelTest, CanLoadAndUseKey) {
// Use EXPECT instead of ASSERT so that we can see the result of both decrypt // Use EXPECT instead of ASSERT so that we can see the result of both decrypt
// calls before failing the test. // calls before failing the test.
EXPECT_EQ( EXPECT_EQ(WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, key->id.data(),
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC, key->id.size(), content.ciphertext.data(),
golden_data_.CBCCryptoKey().id.data(), content.ciphertext.size(), content.iv.data(),
golden_data_.CBCCryptoKey().id.size(), content.iv.size(), plaintext_.data(),
golden_data_.CBCCryptoKey().content->ciphertext.data(), &plaintext_size_),
golden_data_.CBCCryptoKey().content->ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(),
plaintext_.data(), &plaintext_size_),
WB_RESULT_OK); WB_RESULT_OK);
plaintext_size_ = golden_data_.CBCCryptoKey().content->ciphertext.size(); plaintext_size_ = content.ciphertext.size();
plaintext_.resize(plaintext_size_); plaintext_.resize(plaintext_size_);
EXPECT_EQ( EXPECT_EQ(WB_License_MaskedDecrypt(
WB_License_MaskedDecrypt( whitebox_, WB_CIPHER_MODE_CBC, key->id.data(), key->id.size(),
whitebox_, WB_CIPHER_MODE_CBC, golden_data_.CBCCryptoKey().id.data(), content.ciphertext.data(), content.ciphertext.size(),
golden_data_.CBCCryptoKey().id.size(), content.iv.data(), content.iv.size(), plaintext_.data(),
golden_data_.CBCCryptoKey().content->ciphertext.data(),
golden_data_.CBCCryptoKey().content->ciphertext.size(),
golden_data_.CBCCryptoKey().content->iv.data(),
golden_data_.CBCCryptoKey().content->iv.size(), plaintext_.data(),
&plaintext_size_), &plaintext_size_),
WB_RESULT_OK); WB_RESULT_OK);
} }

View File

@@ -19,7 +19,7 @@ namespace {
constexpr size_t kMessageSize = 4 * 1024; constexpr size_t kMessageSize = 4 * 1024;
constexpr size_t kSignatureSize = 256; constexpr size_t kSignatureSize = 256;
constexpr size_t kIterations = 100; constexpr size_t kIterations = 10;
} // namespace } // namespace
@@ -37,7 +37,8 @@ class LicenseWhiteboxSignBenchmark
ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK);
const auto license = CreateLicense(key_mode_); const auto license =
CreateLicense(key_mode_, 1, SecurityLevel::kSoftwareSecureCrypto);
ASSERT_EQ(WB_License_ProcessLicenseResponse( ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, key_mode_, license.core_message.data(), whitebox_, key_mode_, license.core_message.data(),
license.core_message.size(), license.message.data(), license.core_message.size(), license.message.data(),

View File

@@ -98,6 +98,15 @@ TEST_F(LicenseWhiteboxSignLicenseRequestTest,
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
TEST_F(LicenseWhiteboxSignLicenseRequestTest, CanProbeSizeWithNullSignature) {
signature_size_ = 0;
ASSERT_EQ(WB_License_SignLicenseRequest(whitebox_, license_.request.data(),
license_.request.size(), nullptr,
&signature_size_),
WB_RESULT_BUFFER_TOO_SMALL);
ASSERT_GT(signature_size_, 0);
}
TEST_F(LicenseWhiteboxSignLicenseRequestTest, TEST_F(LicenseWhiteboxSignLicenseRequestTest,
InvalidParameterForNullSignatureSize) { InvalidParameterForNullSignatureSize) {
ASSERT_EQ(WB_License_SignLicenseRequest(whitebox_, license_.request.data(), ASSERT_EQ(WB_License_SignLicenseRequest(whitebox_, license_.request.data(),

View File

@@ -32,7 +32,7 @@ class LicenseWhiteboxSignRenewalRequestTest : public LicenseWhiteboxTestBase {
builder.AddSigningKey(signing_key_); builder.AddSigningKey(signing_key_);
// Add a throw away key. We just need a key in the license since a license // Add a throw away key. We just need a key in the license since a license
// should always have a content key. // should always have a content key.
builder.AddStubbedContentKey(); builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
auto server = TestServer::CreateDualKey(); auto server = TestServer::CreateDualKey();
@@ -142,6 +142,19 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest,
WB_RESULT_INVALID_PARAMETER); WB_RESULT_INVALID_PARAMETER);
} }
TEST_F(LicenseWhiteboxSignRenewalRequestTest, CanProbeSizeWithNullSignature) {
TestLicenseBuilder::Settings settings;
settings.padding = TestLicenseBuilder::Padding::kNone;
LoadLicense(settings);
signature_size_ = 0;
ASSERT_EQ(WB_License_SignRenewalRequest(whitebox_, garbage_request_.data(),
garbage_request_.size(), nullptr,
&signature_size_),
WB_RESULT_BUFFER_TOO_SMALL);
ASSERT_GT(signature_size_, 0);
}
TEST_F(LicenseWhiteboxSignRenewalRequestTest, TEST_F(LicenseWhiteboxSignRenewalRequestTest,
InvalidParameterForNullSignature) { InvalidParameterForNullSignature) {
TestLicenseBuilder::Settings settings; TestLicenseBuilder::Settings settings;
@@ -202,7 +215,7 @@ TEST_F(LicenseWhiteboxSignRenewalRequestTest, KeyUnavailableForNoSigningKey) {
// Make a license with no signing key but has a content key. Every license // Make a license with no signing key but has a content key. Every license
// must have a content key. // must have a content key.
TestLicenseBuilder builder; TestLicenseBuilder builder;
builder.AddStubbedContentKey(); builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
auto server = TestServer::CreateDualKey(); auto server = TestServer::CreateDualKey();

View File

@@ -12,244 +12,286 @@ namespace widevine {
namespace { namespace {
const uint8_t kMessage[] = { const uint8_t kMessage[] = {
0x0a, 0x2a, 0x0a, 0x10, 0x53, 0xbc, 0x88, 0x54, 0x04, 0xfc, 0x85, 0xbd, 0x0a, 0x38, 0x0a, 0x10, 0x0b, 0x66, 0x84, 0x0b, 0x99, 0x6a, 0x03, 0xac,
0x75, 0xce, 0x15, 0x2a, 0x06, 0xb5, 0x1f, 0xc5, 0x12, 0x10, 0x53, 0xbc, 0xdc, 0x64, 0x29, 0x5f, 0xb4, 0xbf, 0xbc, 0x3b, 0x12, 0x10, 0x0b, 0x66,
0x88, 0x54, 0x04, 0xfc, 0x85, 0xbd, 0x75, 0xce, 0x15, 0x2a, 0x06, 0xb5, 0x84, 0x0b, 0x99, 0x6a, 0x03, 0xac, 0xdc, 0x64, 0x29, 0x5f, 0xb4, 0xbf,
0x1f, 0xc5, 0x1a, 0x00, 0x20, 0x01, 0x28, 0x00, 0x12, 0x12, 0x08, 0x01, 0xbc, 0x3b, 0x1a, 0x00, 0x20, 0x01, 0x28, 0x00, 0x38, 0x80, 0xa3, 0x05,
0x10, 0x01, 0x18, 0x01, 0x20, 0x80, 0xa3, 0x05, 0x28, 0x80, 0xa3, 0x05, 0x40, 0x80, 0xa3, 0x05, 0x48, 0xe4, 0xa4, 0xd9, 0x86, 0x06, 0x12, 0x17,
0x30, 0x80, 0xa3, 0x05, 0x1a, 0x66, 0x12, 0x10, 0x94, 0x40, 0xfa, 0xa2, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x20, 0x80, 0xa3, 0x05, 0x28, 0x80,
0xd0, 0xe2, 0xa4, 0x80, 0xb4, 0x74, 0x68, 0x91, 0x0a, 0xb9, 0xe4, 0x6a, 0xa3, 0x05, 0x30, 0x80, 0xa3, 0x05, 0x38, 0x80, 0xe7, 0x84, 0x0f, 0x1a,
0x1a, 0x50, 0x30, 0xe2, 0xcb, 0x71, 0xa1, 0x92, 0xb7, 0xc8, 0x3f, 0xd9, 0x66, 0x12, 0x10, 0xc5, 0xe6, 0xb9, 0xb5, 0x64, 0xc2, 0x00, 0x1d, 0x6b,
0x00, 0x2e, 0xf0, 0xf8, 0xb1, 0xe6, 0x9e, 0x62, 0xca, 0x27, 0xb3, 0xa7, 0xfc, 0x41, 0x93, 0xe0, 0xae, 0x3b, 0x4f, 0x1a, 0x50, 0xeb, 0xa5, 0x03,
0x26, 0x19, 0x73, 0x9e, 0xf8, 0xc2, 0x8e, 0x6f, 0xea, 0xb3, 0x5b, 0x01, 0xd5, 0x9a, 0x0b, 0xca, 0xe0, 0xe2, 0x48, 0xbb, 0x8a, 0xcc, 0xb4, 0x29,
0xa6, 0xe8, 0x9b, 0x84, 0x1b, 0x9e, 0xaf, 0xe2, 0xa1, 0xff, 0x4a, 0xca, 0xf6, 0xa3, 0x70, 0x3c, 0xa7, 0x6f, 0x93, 0x13, 0x2b, 0x95, 0x82, 0x2d,
0xcf, 0x84, 0x3f, 0x36, 0xaa, 0x17, 0xa6, 0x0a, 0x0a, 0xe2, 0xcc, 0x12, 0xb0, 0xd0, 0xd8, 0xa3, 0xd7, 0x9b, 0x85, 0xea, 0xfc, 0xdf, 0x0c, 0x54,
0xb1, 0x9f, 0xac, 0x05, 0xdf, 0xe7, 0x00, 0xad, 0xc4, 0xa5, 0xd4, 0x4d, 0x95, 0x9d, 0x5f, 0x68, 0xf7, 0xf8, 0x86, 0x19, 0xaa, 0xe6, 0xaa, 0x2c,
0x46, 0x01, 0xbb, 0xcc, 0x18, 0x7e, 0x4d, 0xb5, 0x05, 0x2a, 0x20, 0x01, 0xe7, 0xe4, 0x98, 0x25, 0x3f, 0x7d, 0x16, 0xfb, 0x6c, 0x9c, 0x7a, 0x44,
0x1a, 0x52, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0xeb, 0x2b, 0xe6, 0x06, 0xb7, 0x00, 0xcb, 0x49, 0xbc, 0x07, 0x1a,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x12, 0x10, 0xf1, 0xed, 0xb7, 0xd0, 0xd3, 0x85, 0xa3, 0x20, 0x01, 0x1a, 0x66, 0x0a, 0x10, 0x30,
0x57, 0xf4, 0xad, 0x5d, 0x0e, 0x2c, 0xf9, 0x78, 0xc9, 0xe4, 0x4d, 0x2e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0xcc, 0x68, 0x1a, 0x20, 0xd7, 0xf5, 0x15, 0x85, 0x3b, 0x33, 0xea, 0x8e, 0x30, 0x30, 0x33, 0x12, 0x10, 0x98, 0x21, 0xd7, 0x57, 0xfe, 0xa0, 0x10,
0x40, 0xef, 0x2a, 0xd0, 0x8f, 0x96, 0x69, 0xb6, 0xf9, 0xdd, 0x63, 0x8f, 0x76, 0x54, 0x4f, 0x72, 0x18, 0x42, 0xab, 0x9a, 0xed, 0x1a, 0x20, 0x86,
0x80, 0x7e, 0x68, 0x02, 0xc7, 0x74, 0x55, 0x5d, 0xd4, 0x17, 0x45, 0x09, 0x42, 0x40, 0x2b, 0x4e, 0x38, 0x1a, 0x0c, 0x7d, 0x29, 0x1a, 0x44, 0x4a,
0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x62, 0x02, 0x48, 0x44, 0x68, 0x24, 0xc8, 0x34, 0x31, 0xf2, 0xd0, 0x2a, 0x07, 0x84, 0xfe, 0x51,
0x1a, 0x52, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xb0, 0x8d, 0x8f, 0x05, 0x05, 0x25, 0x55, 0x20, 0x02, 0x28, 0x01, 0x32,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x12, 0x10, 0xdb, 0x38, 0x00, 0x3a, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x36, 0x00,
0x5d, 0x4a, 0x0d, 0x80, 0x37, 0x42, 0x10, 0x60, 0x0d, 0x24, 0x03, 0xde, 0x01, 0x51, 0x80, 0x01, 0x63, 0xab, 0xd0, 0x80, 0x00, 0x00, 0x08, 0x62,
0xd0, 0x3c, 0x1a, 0x20, 0x22, 0xab, 0x33, 0xb9, 0xe5, 0x16, 0xa2, 0x6d, 0x02, 0x48, 0x44, 0x1a, 0x66, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30,
0x5a, 0x42, 0x45, 0xd4, 0x0e, 0x47, 0x0c, 0xf3, 0x6c, 0x1f, 0x20, 0xd9, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x12,
0x0e, 0x79, 0xd7, 0xb7, 0x34, 0xc1, 0xbe, 0xd2, 0x6b, 0x01, 0xff, 0x73, 0x10, 0x01, 0xc9, 0x40, 0x76, 0x7a, 0x89, 0xb6, 0xce, 0x46, 0x24, 0xc9,
0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x62, 0x02, 0x48, 0x44, 0x2d, 0xec, 0xd8, 0xa3, 0xae, 0x1a, 0x20, 0x6a, 0x76, 0x89, 0x53, 0xf1,
0x1a, 0x55, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xb1, 0xef, 0x2e, 0x97, 0x34, 0x75, 0xfe, 0x17, 0x31, 0xbf, 0x08, 0x9f,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x10, 0xdd, 0xfb, 0x73, 0x5e, 0xab, 0x66, 0x33, 0x81, 0x99, 0xf6, 0xe7, 0x8b, 0x10, 0x46,
0x7a, 0x27, 0x34, 0xd4, 0xec, 0xcf, 0x01, 0x9c, 0xbd, 0x84, 0xe3, 0xf0, 0x47, 0xc4, 0xf8, 0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x42,
0xbd, 0xc6, 0x1a, 0x20, 0x11, 0x0c, 0xa2, 0xc3, 0xb8, 0x95, 0xaf, 0x48, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x36, 0x00, 0x01, 0x51, 0x80, 0x01,
0x80, 0x57, 0xd1, 0x39, 0xec, 0xd7, 0x09, 0x5a, 0x95, 0x31, 0xf8, 0x3f, 0x63, 0xab, 0xd0, 0x80, 0x00, 0x00, 0x08, 0x62, 0x02, 0x48, 0x44, 0x1a,
0xa0, 0x6d, 0x9c, 0xad, 0x10, 0x70, 0xa4, 0x6b, 0x6a, 0x5c, 0xca, 0x73, 0x69, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x62, 0x05, 0x41, 0x55, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x12, 0x10, 0xa1, 0x2c, 0xfe,
0x44, 0x49, 0x4f, 0x1a, 0x52, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0xdf, 0xf5, 0x83, 0x95, 0xa8, 0x15, 0xec, 0xad, 0x23, 0x02, 0x6a, 0xc2,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, 0x12, 0x96, 0x1a, 0x20, 0x76, 0xd6, 0xef, 0x6f, 0x2d, 0x7e, 0xd0, 0x9c, 0x5e,
0x10, 0xcb, 0xac, 0x50, 0x57, 0x81, 0xcd, 0x04, 0xf6, 0x71, 0xb2, 0xc2, 0x1e, 0x58, 0x63, 0x82, 0x1d, 0xe0, 0xe5, 0x6d, 0x62, 0x8a, 0x89, 0xc2,
0x08, 0x86, 0x12, 0x78, 0x58, 0x1a, 0x20, 0x71, 0x0e, 0xd7, 0xa2, 0x8c, 0xe3, 0xce, 0xd7, 0xc3, 0xe8, 0x75, 0x8b, 0x64, 0x81, 0x6f, 0x8a, 0x20,
0x64, 0x75, 0x0b, 0x11, 0x9e, 0x48, 0x47, 0x0c, 0x2d, 0x78, 0x48, 0x1c, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b,
0x98, 0x2f, 0x14, 0x51, 0x15, 0x2a, 0x05, 0xe8, 0x84, 0x6e, 0x61, 0xc2, 0x63, 0x31, 0x36, 0x00, 0x01, 0x51, 0x80, 0x01, 0x63, 0xab, 0xd0, 0x80,
0x26, 0x82, 0xe6, 0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x62, 0x00, 0x00, 0x08, 0x62, 0x05, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x1a, 0x66,
0x02, 0x48, 0x44, 0x1a, 0x52, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x12, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, 0x12, 0x10, 0xf5, 0x88, 0x10, 0xa5,
0x10, 0xa6, 0xd4, 0xb8, 0x0a, 0x37, 0x46, 0xf6, 0xc8, 0x59, 0x5a, 0x30, 0x8b, 0x02, 0xca, 0x94, 0x75, 0xd7, 0xd6, 0x98, 0x2e, 0x65, 0x87, 0x2b,
0x96, 0x39, 0x16, 0x29, 0x1e, 0x1a, 0x20, 0xff, 0xe7, 0xb2, 0x9e, 0x98, 0x1a, 0x20, 0x43, 0x36, 0x3d, 0x05, 0xeb, 0xb4, 0x92, 0x7c, 0x9e, 0xc5,
0x40, 0x33, 0xce, 0x9e, 0xcf, 0x85, 0x60, 0x52, 0x43, 0x38, 0xe6, 0x1b, 0x86, 0xff, 0xe7, 0x6a, 0x5d, 0xb2, 0x35, 0x6d, 0x1e, 0xc8, 0x6e, 0xde,
0x07, 0x10, 0xfa, 0x71, 0xa8, 0x66, 0x0f, 0xd6, 0x9a, 0x09, 0xac, 0xb1, 0x27, 0xfa, 0xac, 0xd3, 0x3d, 0x6e, 0xcc, 0x42, 0x6c, 0xa5, 0x20, 0x02,
0x47, 0xe4, 0x19, 0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x62, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63,
0x02, 0x53, 0x44, 0x1a, 0x52, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x36, 0x00, 0x01, 0x51, 0x80, 0x01, 0x63, 0xab, 0xd0, 0x80, 0x00,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x12, 0x00, 0x08, 0x62, 0x02, 0x48, 0x44, 0x1a, 0x66, 0x0a, 0x10, 0x30, 0x30,
0x10, 0x57, 0x43, 0x24, 0x10, 0x4d, 0xd3, 0xcf, 0x6e, 0xef, 0x37, 0xce, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x5b, 0xba, 0xd1, 0x61, 0x62, 0x1a, 0x20, 0x54, 0xec, 0xbb, 0xc7, 0x4b, 0x30, 0x31, 0x12, 0x10, 0xdf, 0x81, 0x18, 0xb6, 0xf0, 0xf6, 0xef, 0x8a,
0xa6, 0x3f, 0x17, 0xcc, 0x5e, 0xb8, 0x20, 0x41, 0x9e, 0xcf, 0xe2, 0x9f, 0x66, 0xd1, 0x0b, 0x30, 0x6b, 0x15, 0x76, 0x70, 0x1a, 0x20, 0x44, 0xea,
0x03, 0x9d, 0x79, 0xd0, 0x06, 0x0b, 0x0e, 0x6e, 0xf4, 0x9e, 0x93, 0x92, 0x2c, 0xec, 0xe7, 0x93, 0x9e, 0xfb, 0xc2, 0xca, 0xb9, 0x83, 0x74, 0xcb,
0x50, 0x19, 0xbd, 0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x62, 0x0f, 0x89, 0x7b, 0x05, 0xb3, 0xea, 0x12, 0xc2, 0x63, 0xf4, 0x17, 0x8c,
0x02, 0x53, 0x44, 0x1a, 0x52, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x62, 0xd5, 0xce, 0xe7, 0x7f, 0xa3, 0x20, 0x02, 0x28, 0x01, 0x32, 0x00,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x12, 0x3a, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x36, 0x00, 0x01,
0x10, 0xd7, 0x93, 0x22, 0x74, 0xf1, 0x0b, 0x61, 0x26, 0x7e, 0x16, 0xd5, 0x51, 0x80, 0x01, 0x63, 0xab, 0xd0, 0x80, 0x00, 0x00, 0x08, 0x62, 0x02,
0x88, 0x5f, 0x70, 0x2b, 0x3d, 0x1a, 0x20, 0xb2, 0x21, 0xc6, 0xb4, 0x65, 0x53, 0x44, 0x1a, 0x66, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0xf1, 0x00, 0x07, 0x11, 0x0e, 0xe4, 0x67, 0x3c, 0xb4, 0x4c, 0xc9, 0xe9, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x12, 0x10,
0x82, 0x5e, 0xbc, 0x2a, 0x2a, 0xf0, 0x68, 0x45, 0xfe, 0xd2, 0xce, 0xea, 0x49, 0x68, 0x4d, 0x67, 0x0c, 0xdd, 0xbb, 0x57, 0xcc, 0xce, 0x83, 0x3f,
0xae, 0xfb, 0x9a, 0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x62, 0x4b, 0xcf, 0x7f, 0x8a, 0x1a, 0x20, 0x38, 0x91, 0x22, 0xc0, 0x7e, 0x89,
0x02, 0x53, 0x44, 0x1a, 0x52, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0xe4, 0x40, 0xa3, 0x55, 0x7e, 0x65, 0x6e, 0x7d, 0x2a, 0xad, 0x8f, 0x17,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x12, 0x70, 0x5d, 0xe3, 0x4a, 0x92, 0x12, 0x26, 0x10, 0x11, 0x4e, 0x78, 0x9a,
0x10, 0x96, 0x9e, 0xc6, 0xcb, 0xc0, 0xbf, 0xf5, 0x83, 0xef, 0xc9, 0xe7, 0x2d, 0xa1, 0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x12,
0xbb, 0x2a, 0x1a, 0xce, 0x0b, 0x1a, 0x20, 0xe0, 0x23, 0x16, 0x1e, 0x00, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x36, 0x00, 0x01, 0x51, 0x80, 0x01, 0x63,
0x05, 0xc0, 0xfe, 0x97, 0x47, 0x5f, 0x75, 0x69, 0x8c, 0x09, 0x8b, 0x3e, 0xab, 0xd0, 0x80, 0x00, 0x00, 0x08, 0x62, 0x02, 0x53, 0x44, 0x1a, 0x66,
0x93, 0x1b, 0xa4, 0x84, 0x4b, 0xd3, 0xb1, 0x77, 0xd4, 0x42, 0xee, 0x7e, 0x0a, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0xf5, 0xe4, 0x0c, 0x20, 0x02, 0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x62, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x12, 0x10, 0xc8, 0x2d, 0x4d, 0x9c,
0x02, 0x53, 0x44, 0x20, 0xb2, 0x88, 0xc6, 0xfa, 0x05, 0x38, 0x00, 0x1b, 0xbe, 0x00, 0xb3, 0x48, 0x6b, 0x57, 0xe5, 0x1e, 0x13, 0x14, 0xc9,
0x1a, 0x20, 0x5a, 0x01, 0xbd, 0x78, 0xa0, 0x24, 0x10, 0xba, 0xde, 0xf1,
0x1c, 0x29, 0x12, 0x87, 0x9e, 0x5f, 0xf7, 0x60, 0xd6, 0x06, 0x96, 0x0e,
0x2e, 0x77, 0x08, 0x6e, 0xda, 0x15, 0xac, 0x05, 0x43, 0xc5, 0x20, 0x02,
0x28, 0x01, 0x32, 0x00, 0x3a, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63,
0x31, 0x36, 0x00, 0x01, 0x51, 0x80, 0x01, 0x63, 0xab, 0xd0, 0x80, 0x00,
0x00, 0x08, 0x62, 0x02, 0x53, 0x44, 0x1a, 0x66, 0x0a, 0x10, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x36, 0x12, 0x10, 0x83, 0x61, 0x7c, 0xa2, 0x1a, 0x00, 0xe3, 0x7b,
0x02, 0x41, 0x3d, 0xc6, 0x42, 0x06, 0x6f, 0x51, 0x1a, 0x20, 0xef, 0x46,
0xa3, 0x3f, 0x88, 0x0d, 0x1c, 0x89, 0xa4, 0xed, 0xe5, 0x7e, 0xeb, 0x03,
0x5c, 0x75, 0x34, 0x6a, 0x5a, 0x7d, 0xf7, 0xcf, 0x96, 0x3d, 0x18, 0x8e,
0xd2, 0x09, 0xf2, 0x64, 0x37, 0x27, 0x20, 0x02, 0x28, 0x01, 0x32, 0x00,
0x3a, 0x00, 0x42, 0x12, 0x0a, 0x10, 0x6b, 0x63, 0x31, 0x36, 0x00, 0x01,
0x51, 0x80, 0x01, 0x63, 0xab, 0xd0, 0x80, 0x00, 0x00, 0x08, 0x62, 0x02,
0x53, 0x44, 0x20, 0xe4, 0xa4, 0xd9, 0x86, 0x06, 0x38, 0x00,
}; };
const uint8_t kSignature[] = { const uint8_t kSignature[] = {
0x34, 0x7e, 0xc1, 0xa9, 0x3e, 0x1d, 0x66, 0x77, 0x5d, 0xac, 0xe8, 0x78, 0xfb, 0xe1, 0x05, 0xc8, 0x36, 0xe6, 0x12, 0x64, 0xbf, 0x26,
0x8b, 0xc0, 0x37, 0x3e, 0x4c, 0x9b, 0xe5, 0x9c, 0x25, 0x04, 0xed, 0x91, 0x46, 0x11, 0xa1, 0xe5, 0x3b, 0xf0, 0x39, 0x42, 0x34, 0x26,
0x3f, 0x66, 0x6e, 0x6c, 0x51, 0x42, 0x57, 0x7f, 0x6c, 0x53, 0x0a, 0xbd, 0x54, 0xe8, 0x69, 0xeb, 0x78, 0x76, 0x4e, 0xab,
}; };
const uint8_t kSessionKey[] = { const uint8_t kSessionKey[] = {
0x21, 0xd8, 0x3b, 0x58, 0xda, 0xa9, 0x3a, 0x1c, 0xdb, 0xfb, 0x54, 0xff, 0x90, 0xce, 0xab, 0x08, 0x31, 0xfa, 0x7c, 0xc4, 0x9c, 0xf4, 0x03, 0xe8,
0x0d, 0x30, 0xcd, 0x00, 0xff, 0x52, 0xc4, 0xed, 0x5c, 0xf9, 0xc9, 0x1c, 0x6f, 0xa8, 0x81, 0xd0, 0x60, 0xa1, 0xd5, 0x90, 0x86, 0x04, 0x86, 0xbb,
0x7b, 0x41, 0x48, 0xc0, 0x98, 0xa9, 0x74, 0x99, 0x79, 0xa0, 0x75, 0xc3, 0x32, 0xea, 0x44, 0xff, 0xba, 0x88, 0x34, 0x10, 0xef, 0x0f, 0x1a, 0xe2,
0x50, 0xf0, 0xac, 0xfa, 0xec, 0xc4, 0xc0, 0x34, 0x06, 0x5b, 0xb9, 0xaa, 0x80, 0xa9, 0xf6, 0x26, 0x17, 0x56, 0xe5, 0x1c, 0xd2, 0x92, 0xb7, 0x2d,
0x6d, 0xcf, 0x71, 0x69, 0xf0, 0x5e, 0x8f, 0x6b, 0x50, 0x9a, 0x16, 0x54, 0xb5, 0x8c, 0x6b, 0x11, 0x5b, 0x67, 0xe6, 0x1a, 0xa2, 0x58, 0x2b, 0x3d,
0xa7, 0x72, 0x11, 0x50, 0xf9, 0xec, 0x8d, 0xcc, 0x3a, 0x23, 0x16, 0x84, 0xc1, 0x76, 0x4b, 0xf8, 0x4e, 0x71, 0x69, 0xab, 0xdb, 0x3b, 0xdf, 0xca,
0x78, 0xea, 0xaa, 0xbd, 0x6f, 0xd9, 0x88, 0x5f, 0xa8, 0x82, 0x3c, 0x05, 0x62, 0xe0, 0x95, 0x91, 0x2d, 0x4f, 0x52, 0x7e, 0xd6, 0x42, 0xb7, 0xd1,
0x53, 0xe7, 0x76, 0x5f, 0xe3, 0x7a, 0x4a, 0xe5, 0xeb, 0x45, 0x9d, 0x04, 0xd5, 0x5b, 0x1b, 0xc5, 0xde, 0x23, 0x45, 0xa3, 0xd6, 0x3f, 0x2c, 0x69,
0x45, 0xe8, 0x9a, 0x4a, 0x10, 0x02, 0x63, 0x97, 0x35, 0x68, 0x87, 0xc4, 0xcb, 0xb6, 0xfd, 0x38, 0xdd, 0xa4, 0xb8, 0x53, 0xff, 0xa8, 0x06, 0x80,
0xe3, 0xaa, 0xbd, 0x1b, 0xe7, 0xa2, 0xd4, 0x52, 0xb0, 0xea, 0x2d, 0x2f, 0x31, 0x7c, 0x16, 0x26, 0xd1, 0x20, 0x4b, 0x96, 0x57, 0xdd, 0x96, 0xf5,
0x59, 0x62, 0x7e, 0xb4, 0x6b, 0xe0, 0x06, 0x7a, 0xee, 0x98, 0x21, 0x74, 0x04, 0x80, 0x9b, 0x1e, 0x7a, 0xca, 0x8d, 0xb2,
0xec, 0x99, 0x61, 0x55, 0x9b, 0x1d, 0xf9, 0x5d, 0x6f, 0x80, 0x87, 0xdd,
0xf3, 0x7b, 0x5d, 0x98, 0xb6, 0x37, 0x6a, 0x0a, 0x83, 0x5e, 0x36, 0x08,
0x8a, 0xf4, 0xcd, 0x9e, 0x5c, 0x7d, 0xec, 0xf2, 0x4e, 0x5b, 0x4d, 0xac,
0x9a, 0xab, 0xb1, 0x80, 0xc9, 0x58, 0xa0, 0x1d, 0x19, 0x16, 0x0b, 0xd5,
0xea, 0xe7, 0xfc, 0xfd, 0x4e, 0x04, 0x98, 0xa1, 0x8d, 0x79, 0xb0, 0xa7,
0xb5, 0x44, 0xfc, 0x12, 0xd2, 0x04, 0x7d, 0x53, 0x02, 0xfd, 0x70, 0x21,
0xef, 0xfd, 0x64, 0x11, 0x48, 0x03, 0xc4, 0x66, 0x7a, 0x29, 0xc3, 0x83,
0xfc, 0xee, 0xad, 0x9a, 0x4c, 0x97, 0x64, 0x0a, 0x9e, 0x72, 0x42, 0xc1,
0x1f, 0x32, 0x29, 0x80, 0xcf, 0xb9, 0xdc, 0x1d, 0x81, 0x92, 0x13, 0xfe,
0x85, 0x50, 0x53, 0x4a, 0x0a, 0xa2, 0x24, 0x52, 0x26, 0x9a, 0x65, 0x28,
0x13, 0x26, 0xae, 0xf3,
}; };
const uint8_t kLicenseRequest[] = { const uint8_t kLicenseRequest[] = {
0x0a, 0x88, 0x0b, 0x08, 0x01, 0x12, 0xed, 0x09, 0x0a, 0xb0, 0x02, 0x08, 0x0a, 0x9f, 0x0b, 0x08, 0x01, 0x12, 0x83, 0x0a, 0x0a, 0xc3, 0x02, 0x08,
0x02, 0x12, 0x10, 0x0c, 0x36, 0x48, 0x86, 0x75, 0xa1, 0x84, 0x53, 0x4d, 0x02, 0x12, 0x10, 0xa6, 0x06, 0x35, 0x4e, 0x21, 0xbd, 0xa5, 0x68, 0xfe,
0xbc, 0x55, 0x96, 0xc9, 0xf4, 0xaf, 0x0a, 0x18, 0x97, 0xe7, 0xdd, 0xf8, 0x68, 0x8d, 0x2b, 0x43, 0x43, 0x43, 0x0a, 0x18, 0xd8, 0xd2, 0xda, 0x85,
0x05, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x06, 0x22, 0x8c, 0x01, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0x9c,
0x00, 0xae, 0xa6, 0xa8, 0xea, 0xdd, 0xac, 0x6f, 0xb4, 0x41, 0x47, 0xcb, 0x54, 0xb3, 0x2f, 0x66, 0xe3, 0xd2, 0xb8, 0xee, 0x22, 0xa0, 0x3c, 0x76,
0x18, 0x81, 0xeb, 0xdf, 0x4f, 0x17, 0xf7, 0x17, 0xc0, 0xab, 0x6f, 0x47, 0x06, 0x67, 0xd8, 0xc1, 0xbc, 0xe6, 0xbe, 0x6f, 0xb3, 0x93, 0xee, 0xd4,
0x50, 0xbf, 0xe4, 0x8c, 0xc9, 0x45, 0x24, 0x5e, 0x1c, 0x2e, 0x86, 0x9f, 0xe6, 0xcb, 0x11, 0x00, 0xb5, 0x16, 0x49, 0xe1, 0x8e, 0xcc, 0xea, 0xbe,
0xcb, 0x47, 0x05, 0xf9, 0xfe, 0x91, 0x90, 0xaf, 0xbd, 0x22, 0x14, 0x47, 0xc6, 0x45, 0x34, 0xfc, 0x13, 0xed, 0x0a, 0x90, 0x22, 0xe0, 0x6d, 0x6f,
0xa7, 0x34, 0x39, 0x79, 0x44, 0xe9, 0x92, 0x83, 0x4a, 0x80, 0xa8, 0x2a, 0xaf, 0x64, 0xa8, 0xc2, 0x05, 0xf9, 0x2c, 0x51, 0x52, 0xd4, 0x42, 0x47,
0xe6, 0x9f, 0x2b, 0xb7, 0xda, 0x2a, 0xd2, 0xae, 0x57, 0x5b, 0xfa, 0xb6, 0xfe, 0x03, 0x99, 0xf1, 0x03, 0x7e, 0x09, 0x08, 0x65, 0x50, 0xb9, 0x36,
0xdf, 0xca, 0x3e, 0xb1, 0xb8, 0x42, 0x0b, 0xde, 0x46, 0x36, 0xdb, 0x42, 0x8f, 0x62, 0xc5, 0x1a, 0x18, 0x27, 0xb8, 0xf3, 0x89, 0x53, 0x5a, 0x9d,
0x33, 0x8b, 0xda, 0x5c, 0x60, 0x44, 0x7c, 0x99, 0xb4, 0x98, 0xb4, 0x1e, 0xfb, 0xe4, 0x9b, 0xb4, 0xea, 0x48, 0x7c, 0x0f, 0x30, 0x02, 0x82, 0x6c,
0xd8, 0x25, 0x6d, 0x67, 0x84, 0xc9, 0x67, 0xde, 0x05, 0xe6, 0x06, 0xb5, 0xf7, 0xb6, 0xf7, 0x82, 0x1f, 0xbb, 0x0b, 0x87, 0x95, 0xd0, 0xda, 0x7e,
0xb5, 0xca, 0xbc, 0xfa, 0xb0, 0xa7, 0x46, 0x29, 0x3f, 0x63, 0x47, 0x9d, 0xb9, 0x0e, 0x58, 0xa3, 0x6d, 0xde, 0x50, 0x4d, 0xa0, 0x21, 0x1b, 0x72,
0x70, 0x8d, 0xa2, 0x8d, 0x22, 0xc6, 0xeb, 0x06, 0xd4, 0x5c, 0x3b, 0x62, 0xf3, 0x97, 0xbf, 0x98, 0xab, 0xb1, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01,
0x98, 0xc7, 0xda, 0x16, 0x8f, 0x17, 0x59, 0xd5, 0xcb, 0xd1, 0x5d, 0xe3, 0x28, 0x93, 0xab, 0x01, 0x48, 0x01, 0x5a, 0x91, 0x01, 0x0a, 0x8c, 0x01,
0xe1, 0x07, 0xe6, 0x97, 0x87, 0xf4, 0x22, 0x53, 0xfa, 0xf9, 0xa9, 0xf5, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xb5, 0xdf, 0x28, 0x81, 0xfc,
0xeb, 0xd7, 0x55, 0xdf, 0x32, 0x2d, 0x4e, 0x07, 0x86, 0x25, 0x44, 0x93, 0x29, 0x80, 0xe4, 0xe6, 0x49, 0x6e, 0x62, 0xe5, 0xf3, 0x23, 0x99, 0x59,
0xd6, 0xf7, 0xc6, 0xf9, 0x78, 0x91, 0x24, 0x1e, 0xd4, 0x6b, 0xe3, 0x4a, 0x54, 0x84, 0x1b, 0xf1, 0xde, 0x27, 0x8b, 0xe6, 0x22, 0xec, 0x02, 0x68,
0xff, 0x4a, 0x3a, 0xb9, 0x89, 0x90, 0x61, 0x87, 0xb9, 0x41, 0x45, 0x02, 0x58, 0x6e, 0x5b, 0x11, 0x90, 0x7a, 0xb3, 0xb3, 0x35, 0xab, 0x02, 0xb7,
0xfd, 0xd0, 0xc5, 0x5a, 0x98, 0x41, 0x88, 0xa4, 0xe3, 0xe2, 0xa2, 0x9d, 0xf6, 0xd8, 0x74, 0xef, 0x90, 0xd8, 0xab, 0xb1, 0x44, 0x04, 0x7e, 0x15,
0x9a, 0x90, 0x3f, 0x44, 0x8e, 0x3a, 0xe1, 0xd1, 0xe9, 0x79, 0x9a, 0xc6, 0x02, 0xac, 0x9d, 0x1e, 0x4e, 0xef, 0x9c, 0xdf, 0x31, 0xdb, 0x7a, 0x03,
0xe2, 0x7c, 0x8e, 0x9c, 0x3d, 0xb2, 0xe0, 0x26, 0x5a, 0x46, 0x13, 0xc8, 0xd6, 0xa9, 0xfe, 0x6e, 0xd6, 0x4e, 0x5d, 0xaf, 0xdd, 0x63, 0x62, 0x5e,
0x43, 0x9f, 0xf7, 0x51, 0x7e, 0xbb, 0x55, 0x6d, 0xcc, 0x97, 0x38, 0xdb, 0xa9, 0x56, 0x82, 0x2c, 0x09, 0x26, 0xc5, 0x61, 0x58, 0xf2, 0x04, 0xd5,
0xa4, 0x4b, 0x96, 0x40, 0xe5, 0x2d, 0x8f, 0x43, 0xe3, 0x21, 0x15, 0xda, 0x0a, 0x40, 0x22, 0xb7, 0x9a, 0x46, 0x4d, 0x88, 0x2c, 0x75, 0x8f, 0xc1,
0x34, 0x97, 0x7a, 0x9e, 0xbb, 0x02, 0x03, 0x01, 0x00, 0x01, 0x28, 0xe8, 0x18, 0x6a, 0xf8, 0xf6, 0x5d, 0xb1, 0x77, 0x24, 0xcb, 0x0e, 0x0f, 0x99,
0x3d, 0x48, 0x01, 0x12, 0x80, 0x02, 0xa2, 0x05, 0x30, 0x91, 0xed, 0xc2, 0x38, 0x7c, 0x0a, 0x4a, 0xd1, 0xda, 0xef, 0x35, 0x80, 0x60, 0x56, 0xbc,
0x17, 0xfd, 0x92, 0x5c, 0x69, 0x1f, 0xb4, 0x82, 0x35, 0x75, 0xcb, 0x48, 0xe9, 0x16, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0x10, 0x01, 0x12, 0x80,
0x22, 0x07, 0x54, 0x72, 0x05, 0x86, 0x2e, 0xa1, 0x98, 0xc9, 0x46, 0x07, 0x02, 0x9b, 0x38, 0xd0, 0x18, 0xc4, 0xff, 0x1c, 0xd8, 0x70, 0x6e, 0x12,
0xc9, 0x26, 0x6b, 0x05, 0x56, 0xa2, 0xa6, 0x5b, 0xe3, 0xba, 0x80, 0xd0, 0xb2, 0x84, 0xfd, 0x61, 0x0a, 0x95, 0x2f, 0xe5, 0x77, 0x36, 0x38, 0xeb,
0x01, 0xb3, 0xbd, 0x9f, 0x7b, 0x15, 0xe3, 0xe6, 0xad, 0x85, 0xe6, 0x92, 0x9c, 0x3d, 0xa3, 0x97, 0xe0, 0x71, 0x2e, 0x04, 0xa0, 0x1b, 0xff, 0x31,
0x35, 0xec, 0x9b, 0x18, 0x7e, 0x1d, 0x39, 0x93, 0xfb, 0x0b, 0x2c, 0xe8, 0x97, 0x43, 0x31, 0xe5, 0xac, 0x9f, 0xfa, 0xc8, 0xa7, 0xe2, 0x11, 0x2a,
0xa0, 0xee, 0x6e, 0x27, 0x8f, 0x08, 0x99, 0xc7, 0xd6, 0x08, 0x1f, 0xe5, 0x68, 0x06, 0x9e, 0x05, 0x68, 0xa7, 0x12, 0x13, 0x72, 0x3c, 0xb0, 0x93,
0xd4, 0x9b, 0x30, 0x83, 0x31, 0xf8, 0x49, 0x05, 0x9b, 0xa0, 0x30, 0xaa, 0x46, 0x4a, 0x85, 0xbe, 0x45, 0x39, 0xd1, 0x8f, 0xaf, 0xb1, 0x97, 0x47,
0xc1, 0x61, 0xd4, 0xec, 0x81, 0x28, 0xe1, 0x80, 0x17, 0x09, 0xdc, 0x35, 0x22, 0x55, 0x44, 0x1d, 0xac, 0x64, 0x3b, 0xe1, 0x38, 0x29, 0x11, 0x9c,
0xb8, 0xdc, 0xd3, 0x46, 0x7b, 0xa6, 0xad, 0x44, 0x90, 0x17, 0x99, 0x8e, 0xda, 0x56, 0x2f, 0x28, 0x25, 0x91, 0x4e, 0x5e, 0x59, 0xe4, 0xc9, 0x1c,
0x43, 0xd4, 0x35, 0x00, 0x98, 0x6c, 0xe5, 0xc3, 0x2e, 0xad, 0x80, 0xa6, 0xf0, 0x8b, 0xda, 0x52, 0x8d, 0x40, 0xe6, 0xe0, 0x89, 0xf8, 0xa1, 0x16,
0x35, 0x3e, 0xed, 0xb2, 0x22, 0xe0, 0xad, 0x8a, 0xd0, 0x1a, 0x5e, 0x27, 0x29, 0x1b, 0xfa, 0xaf, 0x18, 0xf6, 0x87, 0x94, 0x1b, 0x17, 0x8f, 0x49,
0x29, 0xe2, 0xd9, 0x01, 0x2d, 0xf3, 0xe8, 0xb8, 0xa5, 0x6d, 0x8b, 0xfb, 0xc6, 0x76, 0x24, 0x13, 0xd8, 0x5e, 0x95, 0x08, 0x47, 0x7b, 0xda, 0x11,
0x1c, 0x8e, 0x77, 0xa1, 0xe0, 0x8e, 0x64, 0x1b, 0xfb, 0x3a, 0x05, 0x2f, 0x41, 0xf9, 0x5b, 0x4a, 0x39, 0x09, 0x76, 0x06, 0xd2, 0xd9, 0xdc, 0x57,
0x96, 0x6f, 0xe7, 0x86, 0xff, 0x75, 0x8f, 0xdf, 0x3d, 0xf4, 0x2d, 0x7a, 0x05, 0xbc, 0x97, 0x36, 0xfb, 0xaa, 0xfa, 0x92, 0x65, 0x2f, 0x88, 0x68,
0xfc, 0x76, 0x0d, 0xf1, 0xde, 0x60, 0xe7, 0x4b, 0xc1, 0x87, 0xb0, 0x3f, 0x11, 0xea, 0x07, 0x3e, 0x0a, 0x0e, 0xce, 0x66, 0xba, 0xac, 0x99, 0x01,
0xa3, 0xe6, 0x37, 0xf1, 0xf0, 0x0a, 0x9e, 0x99, 0xe2, 0x7f, 0x6a, 0x99, 0xf9, 0xe8, 0x75, 0x92, 0xdc, 0x48, 0xef, 0x55, 0xf5, 0x5c, 0x2b, 0x3c,
0xe1, 0xde, 0x2c, 0x23, 0x8d, 0xc6, 0x2d, 0xe8, 0x4d, 0x4a, 0x2b, 0x02, 0x58, 0xf0, 0x1a, 0xf3, 0xb8, 0xa7, 0x7a, 0xba, 0x69, 0x54, 0xd1, 0xee,
0xf2, 0xc1, 0xea, 0xae, 0x9d, 0x2f, 0xb3, 0xee, 0x84, 0xe9, 0xb8, 0xe4, 0x7f, 0x88, 0xc6, 0x7e, 0xf6, 0xed, 0x5e, 0x52, 0x9d, 0x94, 0x98, 0x9f,
0x7b, 0x62, 0x47, 0x9c, 0xf0, 0xed, 0x80, 0x37, 0xcf, 0x92, 0xc5, 0xae, 0x75, 0xd9, 0x1f, 0xa2, 0x65, 0xb2, 0x0c, 0xd7, 0x66, 0x4f, 0xb0, 0xfe,
0xbb, 0x32, 0x31, 0xb4, 0xd7, 0xc4, 0xce, 0xa3, 0x4e, 0xb6, 0xd6, 0xe9, 0xc6, 0xbb, 0x2f, 0x0d, 0x7b, 0x64, 0x38, 0x47, 0x56, 0x53, 0x3b, 0x24,
0x72, 0x5f, 0xd1, 0xe5, 0xa0, 0xf1, 0xfb, 0x79, 0xb1, 0xa8, 0x1a, 0xb4, 0xc0, 0x80, 0xf9, 0x78, 0x98, 0xe0, 0x38, 0xb2, 0x66, 0x40, 0xfe, 0x72,
0x05, 0x0a, 0xae, 0x02, 0x08, 0x01, 0x12, 0x10, 0x65, 0x80, 0x2c, 0x9b, 0x0f, 0xc5, 0x5a, 0x48, 0x43, 0xb1, 0x22, 0xd7, 0xcb, 0x19, 0x2f, 0xf8,
0x62, 0x5e, 0x5a, 0x31, 0x9c, 0x33, 0xdc, 0x1c, 0xb7, 0xc3, 0xc6, 0xd4, 0x81, 0x17, 0x6b, 0x7c, 0x09, 0x1a, 0xb7, 0x05, 0x0a, 0xb1, 0x02, 0x08,
0x18, 0xe3, 0xa5, 0xbd, 0xd0, 0x05, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x01, 0x12, 0x10, 0x6a, 0x77, 0x52, 0x7d, 0x1e, 0x88, 0x1c, 0x88, 0xef,
0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb8, 0x05, 0x02, 0x04, 0x3c, 0x2a, 0xcf, 0x40, 0x9e, 0xba, 0x65, 0xad, 0xa0, 0x18, 0xe8, 0xde, 0x84, 0x82,
0x8a, 0x0f, 0xd8, 0xd2, 0x5c, 0x61, 0x3e, 0x1e, 0x3e, 0x3b, 0x5e, 0x34, 0x06, 0x22, 0x8e, 0x02, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
0x9f, 0x33, 0x2f, 0x04, 0x51, 0x6a, 0x75, 0x10, 0xd3, 0x80, 0x21, 0xa5, 0x00, 0xb6, 0xc1, 0x1a, 0x4a, 0x1c, 0x69, 0x0d, 0xa5, 0x59, 0xc4, 0x94,
0x62, 0x9b, 0x9a, 0xa0, 0x27, 0xae, 0xad, 0x3c, 0x75, 0x9b, 0x7a, 0xfe, 0xcd, 0x19, 0x64, 0x85, 0xaa, 0x1e, 0x48, 0x3f, 0x9d, 0xfa, 0x3a, 0x70,
0x70, 0xbe, 0xd6, 0x5f, 0x3d, 0xf6, 0x86, 0x0f, 0xf5, 0xeb, 0x60, 0xb9, 0x73, 0xc1, 0xb8, 0xda, 0x0c, 0xba, 0xd6, 0x51, 0xbe, 0x90, 0x73, 0xd2,
0x83, 0xa3, 0xff, 0xa3, 0x3f, 0xde, 0x06, 0xf3, 0xb7, 0x30, 0x14, 0xdf, 0x7f, 0xd6, 0x5f, 0xbf, 0xf5, 0xb5, 0x34, 0xc1, 0x2c, 0x48, 0xa0, 0x21,
0xc8, 0x45, 0xab, 0x37, 0x1c, 0x66, 0x00, 0x56, 0x2e, 0x9d, 0x90, 0x4f, 0x55, 0x0f, 0x6b, 0xdb, 0x0a, 0xfa, 0xe5, 0xa1, 0x3e, 0xb1, 0x1b, 0x19,
0x84, 0x2b, 0x8b, 0xa4, 0xa5, 0xd9, 0x20, 0x0f, 0xfa, 0x3e, 0xd4, 0x5d, 0x3d, 0xd6, 0x35, 0x87, 0x26, 0x2f, 0x48, 0x04, 0x06, 0x11, 0xc1, 0xb8,
0x70, 0x55, 0x20, 0xa5, 0xc3, 0x72, 0xa8, 0x89, 0xf9, 0xe3, 0x14, 0x38, 0x6d, 0x0d, 0x30, 0x4e, 0xff, 0xe2, 0x2d, 0xb7, 0xc1, 0x50, 0xaf, 0xc2,
0x62, 0x34, 0xc6, 0x89, 0x7a, 0xe6, 0x55, 0x85, 0x1f, 0xcd, 0x9a, 0xdb, 0x90, 0x20, 0xfc, 0x6f, 0x25, 0xac, 0xd7, 0xcd, 0x2b, 0x34, 0x54, 0xbc,
0x4e, 0xf9, 0x12, 0x6c, 0x78, 0x38, 0x6e, 0xa9, 0x3b, 0xcb, 0x25, 0xba, 0xcc, 0xed, 0xdb, 0x77, 0xab, 0xf2, 0x99, 0xbe, 0xc8, 0x71, 0x62, 0x6a,
0x3e, 0xc4, 0x75, 0xc5, 0x5c, 0x60, 0x8e, 0x77, 0x1c, 0x76, 0x3a, 0xb0, 0xed, 0x09, 0xce, 0x9d, 0xd3, 0xec, 0xef, 0x00, 0x73, 0xbc, 0x06, 0x9b,
0x25, 0x06, 0xf9, 0xb0, 0x72, 0x52, 0xd6, 0xab, 0xf7, 0xea, 0x64, 0xb1, 0xd2, 0x7a, 0xf5, 0x71, 0xfa, 0xa7, 0xd1, 0xd4, 0x33, 0xb6, 0x05, 0x4b,
0xeb, 0xde, 0x7b, 0x95, 0xc6, 0x40, 0x76, 0x90, 0x53, 0x3b, 0xd6, 0x89, 0x3d, 0x70, 0xdb, 0xa3, 0xd0, 0x99, 0x88, 0x27, 0x86, 0x41, 0x83, 0xd0,
0x0b, 0x92, 0x74, 0xc1, 0x60, 0x66, 0xf7, 0x4f, 0xc4, 0x01, 0xea, 0x35, 0x13, 0xa6, 0xf0, 0x64, 0xd9, 0xd4, 0x87, 0x6a, 0x6b, 0x44, 0x33, 0x5b,
0x5f, 0x0a, 0x02, 0x10, 0x68, 0x14, 0xd4, 0x9b, 0xf0, 0xc8, 0x9e, 0x6e, 0xa4, 0x1f, 0x23, 0x2e, 0xba, 0x6e, 0x74, 0xc3, 0x52, 0x92, 0xe8, 0xdc,
0x1f, 0x8d, 0xb2, 0xa4, 0x78, 0x41, 0xcd, 0x0d, 0xad, 0x79, 0x32, 0x96, 0x76, 0xdb, 0x18, 0x75, 0x51, 0x15, 0x86, 0x26, 0x34, 0x39, 0xf6, 0xbe,
0xa1, 0x07, 0xc3, 0x62, 0x23, 0x40, 0x4f, 0x2b, 0xf1, 0xfc, 0xa1, 0x6f, 0x61, 0xf0, 0xe6, 0x24, 0x43, 0x1e, 0x11, 0x0f, 0x8c, 0x02, 0xba, 0xd8,
0xd0, 0xa4, 0xb9, 0x82, 0x63, 0x4d, 0xb6, 0x24, 0x07, 0xf8, 0xf1, 0x4a, 0x81, 0x47, 0xf7, 0xe4, 0xc0, 0x86, 0x73, 0xa5, 0xaa, 0x1d, 0xf5, 0x29,
0xca, 0xe3, 0xb0, 0x5a, 0x03, 0x8b, 0xd3, 0xe4, 0xbb, 0xba, 0xe4, 0x39, 0x27, 0x09, 0x66, 0xab, 0x1e, 0xe4, 0x37, 0x25, 0x67, 0x2d, 0x8c, 0x06,
0x1b, 0xbf, 0xa7, 0xa4, 0x7f, 0xb9, 0xd0, 0x1d, 0xe8, 0x57, 0xea, 0x88, 0x0a, 0xb3, 0xb2, 0xf2, 0x9c, 0xaa, 0x4c, 0x60, 0x38, 0xe6, 0xe4, 0x28,
0xe5, 0xe3, 0x6e, 0xe3, 0x6e, 0x24, 0x58, 0x59, 0xfc, 0x0f, 0x02, 0x03, 0x65, 0x49, 0x5d, 0xf6, 0xb4, 0x1e, 0x52, 0xc3, 0x7d, 0x39, 0x35, 0x8d,
0x01, 0x00, 0x01, 0x28, 0xe8, 0x3d, 0x12, 0x80, 0x03, 0x7e, 0x06, 0x58, 0x77, 0x30, 0x58, 0x75, 0x83, 0x92, 0x47, 0x8c, 0xa1, 0xdb, 0x91, 0x84,
0x1a, 0x01, 0x91, 0x84, 0xab, 0x57, 0x2a, 0xfd, 0xca, 0xdd, 0xd0, 0x3f, 0xf1, 0x49, 0x1a, 0x16, 0xd9, 0x02, 0x03, 0x01, 0x00, 0x01, 0x28, 0x93,
0x16, 0x1c, 0xe6, 0x82, 0x00, 0xf8, 0xe6, 0xf8, 0xad, 0x16, 0x19, 0x47, 0xab, 0x01, 0x48, 0x01, 0x12, 0x80, 0x03, 0x5d, 0x5b, 0xb2, 0xa3, 0x4b,
0x36, 0x0b, 0xc8, 0xd4, 0x9c, 0x0d, 0x68, 0x00, 0x9b, 0x1c, 0x46, 0x44, 0x3e, 0x36, 0x8d, 0x63, 0x44, 0xfb, 0x22, 0x2e, 0xee, 0xb3, 0x1a, 0x67,
0xf9, 0xb3, 0xf3, 0xfb, 0x6d, 0xdf, 0xd9, 0x2e, 0xf9, 0x2d, 0xe6, 0x2d, 0xf3, 0xf8, 0xab, 0xa4, 0x7f, 0x87, 0x26, 0xd9, 0xbc, 0xf7, 0xdf, 0x79,
0x41, 0xd4, 0x59, 0xd2, 0x9d, 0x81, 0xbf, 0xae, 0xf3, 0x97, 0x0a, 0x3a, 0xff, 0xf0, 0x10, 0xe1, 0x21, 0x34, 0xb7, 0x44, 0xf8, 0xcb, 0x38, 0xa3,
0x39, 0xd2, 0x5b, 0x26, 0x62, 0xec, 0xb0, 0x3b, 0x2d, 0xa7, 0xb6, 0x83, 0xbb, 0x60, 0xa8, 0x4c, 0x2a, 0xda, 0xb3, 0xeb, 0x7f, 0x25, 0x7a, 0xb3,
0x02, 0xfa, 0xa6, 0xdd, 0x98, 0xd9, 0x5a, 0x14, 0x3c, 0xc8, 0xc1, 0xcb, 0xe4, 0x4f, 0x43, 0xca, 0x6d, 0x9c, 0xe9, 0x5f, 0xa1, 0x4b, 0xde, 0x90,
0x6a, 0xdd, 0xa7, 0x6d, 0x2e, 0xe9, 0xc3, 0x72, 0x3f, 0xaf, 0x95, 0xa2, 0x93, 0x9d, 0x32, 0x0a, 0x30, 0x43, 0xff, 0x27, 0x2d, 0xa1, 0xea, 0x1e,
0x9c, 0xdc, 0x3e, 0x96, 0x8b, 0x68, 0x21, 0xa9, 0x1c, 0x05, 0x1c, 0xa2, 0x35, 0x11, 0xbd, 0xf6, 0x16, 0x55, 0xec, 0x8f, 0xf1, 0x28, 0x3f, 0x86,
0x80, 0xa8, 0x66, 0x69, 0x71, 0x0a, 0x1a, 0xd7, 0xa4, 0x4b, 0xf9, 0x21, 0x86, 0x31, 0x4c, 0x4f, 0x34, 0x70, 0xf4, 0x37, 0xfc, 0x0c, 0x5b, 0xd3,
0x80, 0x27, 0x46, 0x0d, 0xf6, 0x94, 0xe2, 0xe9, 0x27, 0x03, 0x96, 0xdf, 0xe9, 0x12, 0x6c, 0x42, 0xb8, 0xf2, 0x54, 0x42, 0x48, 0xe7, 0x08, 0x26,
0x22, 0x19, 0x63, 0xf2, 0x1e, 0xe6, 0xaa, 0x22, 0x0a, 0x5e, 0xe4, 0xa4, 0xfd, 0x5b, 0xe0, 0xe8, 0xe3, 0x95, 0x11, 0x88, 0xba, 0xfe, 0xaa, 0xaa,
0xd0, 0xfe, 0xb3, 0xd5, 0x3e, 0xb5, 0x73, 0x2f, 0x8f, 0x91, 0xe9, 0xa9, 0x92, 0x30, 0xc5, 0x35, 0x18, 0xd7, 0xf2, 0x4a, 0x26, 0xf6, 0xfb, 0x15,
0x6b, 0x3b, 0x8b, 0xe2, 0x84, 0xc5, 0x13, 0x39, 0xea, 0x28, 0x4d, 0x4d, 0x44, 0xe6, 0xa2, 0x47, 0x4b, 0x18, 0xd1, 0x97, 0x1c, 0x42, 0x31, 0x67,
0x0e, 0xdd, 0x55, 0xb6, 0xad, 0x56, 0xf7, 0x41, 0x64, 0x20, 0xe0, 0x5e, 0x82, 0x59, 0x2d, 0x58, 0x19, 0x29, 0x78, 0x27, 0xed, 0xf8, 0x37, 0x2b,
0x05, 0x9f, 0x97, 0x34, 0xa9, 0x6b, 0xe2, 0x5a, 0xa4, 0x45, 0x60, 0xdb, 0x07, 0xbb, 0x75, 0xea, 0xb4, 0xbd, 0x2f, 0xa2, 0xdd, 0x33, 0xc7, 0x5c,
0xa8, 0xc3, 0x87, 0x55, 0xa4, 0x2a, 0x82, 0xbd, 0x7f, 0x88, 0xed, 0xd1, 0x1a, 0xa8, 0x54, 0x6d, 0x2a, 0x3c, 0xb8, 0xd9, 0xf6, 0xbc, 0xa8, 0xd4,
0x9d, 0xf3, 0x46, 0xa6, 0x67, 0xb3, 0x3b, 0x81, 0x14, 0xc7, 0x6a, 0x88, 0x4d, 0x34, 0xbb, 0xa6, 0x43, 0xad, 0x91, 0xac, 0xac, 0x7d, 0x10, 0x29,
0x38, 0xc4, 0x23, 0xd8, 0x24, 0xa5, 0x0b, 0x23, 0x25, 0x1a, 0x08, 0x81, 0xe6, 0xf9, 0x41, 0xc9, 0xa2, 0xe5, 0xb9, 0x34, 0x39, 0x5a, 0x1f, 0xb7,
0x36, 0xd6, 0xe8, 0xf4, 0x75, 0x29, 0x9d, 0x2a, 0xfd, 0x46, 0xce, 0xa5, 0x8b, 0x2a, 0x19, 0x97, 0xa7, 0x31, 0x95, 0x03, 0x99, 0x16, 0xa2, 0x83,
0x1b, 0x5c, 0xbd, 0xf7, 0x89, 0xa5, 0x72, 0x12, 0x5c, 0xd2, 0x4f, 0xbb, 0xf9, 0xd8, 0xbb, 0x87, 0xab, 0x54, 0xc7, 0x3a, 0x88, 0x26, 0x68, 0xbd,
0x81, 0x3b, 0x38, 0x7a, 0x10, 0xcd, 0x2a, 0x30, 0xe3, 0x44, 0x76, 0x34, 0xb5, 0x00, 0xc8, 0x31, 0x63, 0x30, 0x4c, 0x09, 0x46, 0xb8, 0x92, 0xd7,
0xab, 0x34, 0x08, 0xf9, 0x6b, 0x9c, 0xf3, 0xd9, 0x88, 0x96, 0xd4, 0x05, 0xe8, 0xf7, 0xe1, 0x41, 0xb2, 0x1a, 0x00, 0x7a, 0xce, 0x15, 0x1e, 0x87,
0xf3, 0xf5, 0x40, 0xd9, 0xc5, 0x79, 0x62, 0x76, 0x0f, 0xcd, 0x17, 0x7c, 0x41, 0x00, 0x7e, 0x62, 0x3a, 0xc8, 0xd5, 0xd4, 0x97, 0xf4, 0x98, 0x10,
0xdd, 0x10, 0x1e, 0xb8, 0xa4, 0x14, 0x8b, 0x9c, 0x29, 0xce, 0xd5, 0xea, 0xf3, 0x86, 0x8d, 0xa7, 0x99, 0xb8, 0x06, 0xc9, 0x21, 0xcf, 0x03, 0x71,
0xd6, 0x45, 0xa9, 0x5b, 0x69, 0x8f, 0x1c, 0xdc, 0x6e, 0x1d, 0xb6, 0x67, 0x90, 0xe4, 0x71, 0x0d, 0x48, 0xed, 0xa8, 0x23, 0x6c, 0x7b, 0x31, 0xa5,
0x8b, 0x85, 0x07, 0x41, 0x86, 0x08, 0x0d, 0x68, 0xd1, 0x3c, 0xd3, 0x7e, 0xfe, 0x05, 0x5e, 0x3c, 0x02, 0xe4, 0x32, 0xce, 0xc6, 0x5a, 0x07, 0xd4,
0x07, 0xb1, 0x6d, 0xe3, 0x70, 0xcd, 0x9a, 0xfb, 0x9b, 0x25, 0x56, 0x4a, 0xbe, 0x73, 0x7e, 0xe2, 0x8e, 0x94, 0x52, 0xae, 0x25, 0x59, 0x09, 0xc0,
0x73, 0xa3, 0x0e, 0x2a, 0xf8, 0x08, 0x5e, 0xa3, 0x7d, 0x31, 0x0c, 0x47, 0x72, 0x2a, 0xd4, 0xb6, 0x52, 0xed, 0x44, 0x5b, 0x8a, 0xa5, 0xaf, 0xc8,
0x4f, 0x0e, 0x67, 0xac, 0x00, 0xca, 0x99, 0x2a, 0x52, 0x96, 0xfa, 0xed, 0xfd, 0x94, 0x51, 0xdb, 0x00, 0x23, 0x61, 0xe6, 0xf4, 0x0f, 0xe2, 0xd1,
0xad, 0x7a, 0xa0, 0x6e, 0xcd, 0x79, 0x0f, 0x1e, 0x3d, 0x42, 0x65, 0x58, 0x0f, 0xa4, 0xc0, 0xd3, 0x22, 0x99, 0x0e, 0xa8, 0xf3, 0xe6, 0xa4, 0x2a,
0xfa, 0x98, 0x38, 0x3e, 0x3c, 0xd2, 0xed, 0x48, 0x30, 0x1a, 0x1b, 0x0a, 0xfd, 0xf2, 0x6b, 0x46, 0x41, 0x99, 0xf3, 0xb3, 0x29, 0xa4, 0x9f, 0xb8,
0x11, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x52, 0xfd, 0xad, 0x27, 0x39, 0x3a, 0x4c, 0xe2, 0xcb, 0xd6, 0x11, 0xa5,
0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x06, 0x78, 0x38, 0x36, 0x2d, 0x7a, 0xc7, 0x79, 0x46, 0x96, 0xb7, 0x4a, 0x1a, 0x1b, 0x0a, 0x11, 0x61,
0x36, 0x34, 0x1a, 0x16, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x5f,
0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x06, 0x78, 0x38, 0x36, 0x2d, 0x36, 0x34,
0x6c, 0x65, 0x1a, 0x17, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x1a, 0x16, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x5f,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x09, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x43, 0x44, 0x4d, 0x1a, 0x16, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x1a, 0x17, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x61,
0x6f, 0x72, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x05, 0x4c, 0x69, 0x6d, 0x65, 0x12, 0x09, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x43, 0x44,
0x6e, 0x75, 0x78, 0x1a, 0x24, 0x0a, 0x14, 0x77, 0x69, 0x64, 0x65, 0x76, 0x4d, 0x1a, 0x16, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
0x69, 0x6e, 0x65, 0x5f, 0x63, 0x64, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x05, 0x4c, 0x69, 0x6e, 0x75,
0x69, 0x6f, 0x6e, 0x12, 0x0c, 0x34, 0x2e, 0x31, 0x30, 0x2e, 0x31, 0x36, 0x78, 0x1a, 0x23, 0x0a, 0x14, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e,
0x38, 0x36, 0x2e, 0x39, 0x36, 0x32, 0x08, 0x08, 0x00, 0x10, 0x00, 0x18, 0x65, 0x5f, 0x63, 0x64, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x01, 0x20, 0x00, 0x12, 0x3f, 0x0a, 0x3d, 0x0a, 0x27, 0x08, 0x01, 0x12, 0x6e, 0x12, 0x0b, 0x34, 0x2e, 0x31, 0x30, 0x2e, 0x30, 0x2e, 0x32, 0x30,
0x01, 0x30, 0x1a, 0x0d, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x32, 0x30, 0x32, 0x0a, 0x08, 0x01, 0x10, 0x00, 0x18, 0x01, 0x20, 0x00,
0x5f, 0x74, 0x65, 0x73, 0x74, 0x22, 0x0a, 0x32, 0x30, 0x31, 0x35, 0x5f, 0x28, 0x10, 0x12, 0x3c, 0x0a, 0x3a, 0x0a, 0x24, 0x08, 0x01, 0x12, 0x01,
0x74, 0x65, 0x61, 0x72, 0x73, 0x2a, 0x05, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x35, 0x1a, 0x0d, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x5f,
0x10, 0x01, 0x1a, 0x10, 0x53, 0xbc, 0x88, 0x54, 0x04, 0xfc, 0x85, 0xbd, 0x74, 0x65, 0x73, 0x74, 0x22, 0x0a, 0x32, 0x30, 0x31, 0x35, 0x5f, 0x74,
0x75, 0xce, 0x15, 0x2a, 0x06, 0xb5, 0x1f, 0xc5, 0x18, 0x01, 0x20, 0xb2, 0x65, 0x61, 0x72, 0x73, 0x2a, 0x02, 0x53, 0x44, 0x10, 0x01, 0x1a, 0x10,
0x88, 0xc6, 0xfa, 0x05, 0x30, 0x15, 0x0b, 0x66, 0x84, 0x0b, 0x99, 0x6a, 0x03, 0xac, 0xdc, 0x64, 0x29, 0x5f,
0xb4, 0xbf, 0xbc, 0x3b, 0x18, 0x01, 0x20, 0xe4, 0xa4, 0xd9, 0x86, 0x06,
0x30, 0x15, 0x38, 0xd0, 0xd7, 0x8e, 0x0b,
};
const uint8_t kCoreMessage[] = {
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0xc8, 0x00, 0x05, 0x00, 0x10,
0x01, 0x63, 0xab, 0xd0, 0x82, 0x87, 0xf6, 0xac, 0x00, 0x00, 0x00, 0x57,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x51, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x51, 0x80, 0x00, 0x00, 0x00, 0x00,
0x01, 0xe1, 0x33, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xbf,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x01, 0x27, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x39,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x4b, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x8f, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x01, 0xa1, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xb3,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xfa,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x02, 0x1e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x02, 0x62, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x74,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x86, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xca, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x02, 0xdc, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0xee,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x32,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x44, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x03, 0x56, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x03, 0x9a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0xac,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0xbe, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f,
0x00, 0x00, 0x00, 0x10, 0x1a, 0xe1, 0x53, 0x83, 0x05, 0x9f, 0x0d, 0xe1,
0x9c, 0x7c, 0x45, 0xd3, 0xf0, 0x2c, 0x2b, 0xe2, 0xca, 0xdf, 0x22, 0x34,
0x38, 0xea, 0x2d, 0xf4, 0x35, 0x6a, 0x96, 0xac, 0x90, 0x57, 0x05, 0xb7,
}; };
const size_t kMessageSize = sizeof(kMessage); const size_t kMessageSize = sizeof(kMessage);
const size_t kLicenseRequestSize = sizeof(kLicenseRequest); const size_t kLicenseRequestSize = sizeof(kLicenseRequest);
const size_t kSignatureSize = sizeof(kSignature); const size_t kSignatureSize = sizeof(kSignature);
const size_t kSessionKeySize = sizeof(kSessionKey); const size_t kSessionKeySize = sizeof(kSessionKey);
const size_t kCoreMessageSize = sizeof(kCoreMessage);
// The pointer for core message must be non-null, but the length needs to be
// zero.
const uint8_t kCoreMessage[] = {0};
const size_t kCoreMessageSize = 0;
const uint8_t kPlaintext[] = { const uint8_t kPlaintext[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

View File

@@ -29,7 +29,8 @@ class LicenseWhiteboxVerifyBenchmark : public LicenseWhiteboxBenchmark {
ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK);
const auto license = CreateLicense(WB_LICENSE_KEY_MODE_DUAL_KEY); const auto license = CreateLicense(WB_LICENSE_KEY_MODE_DUAL_KEY, 1,
SecurityLevel::kSoftwareSecureCrypto);
ASSERT_EQ(WB_License_ProcessLicenseResponse( ASSERT_EQ(WB_License_ProcessLicenseResponse(
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY,
license.core_message.data(), license.core_message.size(), license.core_message.data(), license.core_message.size(),
@@ -49,7 +50,7 @@ class LicenseWhiteboxVerifyBenchmark : public LicenseWhiteboxBenchmark {
}; };
TEST_F(LicenseWhiteboxVerifyBenchmark, VerifyRenewalResponse) { TEST_F(LicenseWhiteboxVerifyBenchmark, VerifyRenewalResponse) {
constexpr size_t kIterations = 100; constexpr size_t kIterations = 10;
Timer timer; Timer timer;
Sampler sampler; Sampler sampler;

View File

@@ -32,7 +32,7 @@ class LicenseWhiteboxVerifyRenewalResponseTest
builder.SetSettings(settings); builder.SetSettings(settings);
builder.AddSigningKey(signing_key); builder.AddSigningKey(signing_key);
builder.AddStubbedContentKey(); builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
auto server = TestServer::CreateDualKey(); auto server = TestServer::CreateDualKey();
@@ -229,7 +229,7 @@ TEST_F(LicenseWhiteboxVerifyRenewalResponseTest,
// Create a license with no signing key and one content key (every license // Create a license with no signing key and one content key (every license
// must have a content key). // must have a content key).
widevine::TestLicenseBuilder builder; widevine::TestLicenseBuilder builder;
builder.AddStubbedContentKey(); builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
auto server = TestServer::CreateDualKey(); auto server = TestServer::CreateDualKey();

View File

@@ -116,25 +116,27 @@ class RemoteAttestationAndVerificationTest
mode_ = DisableOverride(key, mode_); mode_ = DisableOverride(key, mode_);
} }
content_ = golden_data_.CBCContent();
switch (key) { switch (key) {
case Key::kCrypto: case Key::kCrypto:
key_ = golden_data_.CBCCryptoKey(); key_ = content_.software_crypto_key;
break; break;
case Key::kDecode: case Key::kDecode:
key_ = golden_data_.CBCDecodeKey(); key_ = content_.software_decode_key;
break; break;
case Key::kHardware: case Key::kHardware:
key_ = golden_data_.CBCHardwareKey(); key_ = content_.hardware_key;
break; break;
} }
} }
WB_Result LoadLicense(const GoldenData::Key& key, WB_Result LoadLicense(const ContentKeyData& key,
RemoteAttestation remote_attestation, RemoteAttestation remote_attestation,
VerificationStatus verification_status, VerificationStatus verification_status,
Padding padding) { Padding padding) {
TestLicenseBuilder builder; TestLicenseBuilder builder;
builder.AddContentKey(key.level, key.id, key.content->key); builder.AddContentKey(key);
builder.GetSettings().remote_attestation = remote_attestation; builder.GetSettings().remote_attestation = remote_attestation;
builder.GetSettings().verification_status = verification_status; builder.GetSettings().verification_status = verification_status;
builder.GetSettings().padding = padding; builder.GetSettings().padding = padding;
@@ -153,30 +155,30 @@ class RemoteAttestationAndVerificationTest
license.request.size()); license.request.size());
} }
WB_Result Decrypt(const GoldenData::Key& key) { WB_Result Decrypt(const GoldenData::Content& content,
size_t plaintext_size = key.content->ciphertext.size(); const ContentKeyData& key) {
size_t plaintext_size = content.ciphertext.size();
plaintext_.resize(plaintext_size); plaintext_.resize(plaintext_size);
auto result = WB_License_Decrypt( auto result = WB_License_Decrypt(
whitebox_, WB_CIPHER_MODE_CBC, key.id.data(), key.id.size(), whitebox_, WB_CIPHER_MODE_CBC, key.id.data(), key.id.size(),
key.content->ciphertext.data(), key.content->ciphertext.size(), content.ciphertext.data(), content.ciphertext.size(), content.iv.data(),
key.content->iv.data(), key.content->iv.size(), plaintext_.data(), content.iv.size(), plaintext_.data(), &plaintext_size);
&plaintext_size);
plaintext_.resize(plaintext_size); plaintext_.resize(plaintext_size);
return result; return result;
} }
WB_Result MaskedDecrypt(const GoldenData::Key& key) { WB_Result MaskedDecrypt(const GoldenData::Content& content,
size_t masked_text_size = key.content->ciphertext.size(); const ContentKeyData& key) {
size_t masked_text_size = content.ciphertext.size();
std::vector<uint8_t> masked_text(masked_text_size); std::vector<uint8_t> masked_text(masked_text_size);
auto result = WB_License_MaskedDecrypt( auto result = WB_License_MaskedDecrypt(
whitebox_, WB_CIPHER_MODE_CBC, key.id.data(), key.id.size(), whitebox_, WB_CIPHER_MODE_CBC, key.id.data(), key.id.size(),
key.content->ciphertext.data(), key.content->ciphertext.size(), content.ciphertext.data(), content.ciphertext.size(), content.iv.data(),
key.content->iv.data(), key.content->iv.size(), masked_text.data(), content.iv.size(), masked_text.data(), &masked_text_size);
&masked_text_size);
masked_text.resize(masked_text_size); masked_text.resize(masked_text_size);
@@ -210,11 +212,13 @@ class RemoteAttestationAndVerificationTest
} }
Padding padding_; Padding padding_;
GoldenData::Key key_;
RemoteAttestation ra_; RemoteAttestation ra_;
VerificationStatus vmp_; VerificationStatus vmp_;
Mode mode_; Mode mode_;
GoldenData::Content content_;
ContentKeyData key_;
// This is the buffer used to store the output of each decrypt and unmask // This is the buffer used to store the output of each decrypt and unmask
// call. // call.
std::vector<uint8_t> plaintext_; std::vector<uint8_t> plaintext_;
@@ -225,21 +229,21 @@ TEST_P(RemoteAttestationAndVerificationTest, Decrypt) {
switch (mode_) { switch (mode_) {
case Mode::kDecryptPass: case Mode::kDecryptPass:
ASSERT_EQ(Decrypt(key_), WB_RESULT_OK); ASSERT_EQ(Decrypt(content_, key_), WB_RESULT_OK);
ASSERT_EQ(plaintext_, key_.content->plaintext); ASSERT_EQ(plaintext_, content_.plaintext);
break; break;
case Mode::kDecryptFail: case Mode::kDecryptFail:
ASSERT_NE(Decrypt(key_), WB_RESULT_OK); ASSERT_NE(Decrypt(content_, key_), WB_RESULT_OK);
break; break;
case Mode::kMaskedDecryptPass: case Mode::kMaskedDecryptPass:
ASSERT_EQ(MaskedDecrypt(key_), WB_RESULT_OK); ASSERT_EQ(MaskedDecrypt(content_, key_), WB_RESULT_OK);
ASSERT_EQ(plaintext_, key_.content->plaintext); ASSERT_EQ(plaintext_, content_.plaintext);
break; break;
case Mode::kMaskedDecryptFail: case Mode::kMaskedDecryptFail:
ASSERT_NE(MaskedDecrypt(key_), WB_RESULT_OK); ASSERT_NE(MaskedDecrypt(content_, key_), WB_RESULT_OK);
break; break;
} }
} }

View File

@@ -30,6 +30,14 @@ enum class SecurityLevel {
kUndefined, kUndefined,
}; };
struct ContentKeyData {
// The unique key id for this key. Any instance with this id should contain
// the same level and key as this.
KeyId id;
SecurityLevel level;
AesKey key;
};
} // namespace widevine } // namespace widevine
#endif // WHITEBOX_API_TEST_KEY_TYPES_H_ #endif // WHITEBOX_API_TEST_KEY_TYPES_H_

View File

@@ -236,7 +236,7 @@ std::vector<uint8_t> GetPadding(TestLicenseBuilder::Padding padding) {
return {}; return {};
} }
void AddContentKeyToContainer(const TestLicenseBuilder::ContentKey& key_data, void AddContentKeyToContainer(const ContentKeyData& key_data,
const TestLicenseBuilder::Settings& settings, const TestLicenseBuilder::Settings& settings,
const std::string& container_key, const std::string& container_key,
video_widevine::License_KeyContainer* container) { video_widevine::License_KeyContainer* container) {
@@ -414,22 +414,8 @@ void TestLicenseBuilder::AddSigningKey(const SigningKey& key) {
signing_keys_.push_back(key); signing_keys_.push_back(key);
} }
void TestLicenseBuilder::AddStubbedContentKey() { void TestLicenseBuilder::AddContentKey(const ContentKeyData& key) {
content_keys_.emplace_back(); content_keys_.push_back(key);
auto& key_data = content_keys_.back();
key_data.level = SecurityLevel::kSoftwareSecureCrypto;
key_data.id = {0, 0, 0, 0};
key_data.key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
}
void TestLicenseBuilder::AddContentKey(SecurityLevel level,
const KeyId& id,
const AesKey& key) {
content_keys_.emplace_back();
auto& key_data = content_keys_.back();
key_data.level = level;
key_data.id = id;
key_data.key = key;
} }
void TestLicenseBuilder::AddOperatorSessionKey(const KeyId& id) { void TestLicenseBuilder::AddOperatorSessionKey(const KeyId& id) {

View File

@@ -9,7 +9,7 @@
#include "api/test_key_types.h" #include "api/test_key_types.h"
#include "api/test_server.h" #include "api/test_server.h"
#include "cdm/protos/license_protocol.pb.h" #include "license_protocol.pb.h"
namespace widevine { namespace widevine {
@@ -28,21 +28,6 @@ struct License {
class TestLicenseBuilder { class TestLicenseBuilder {
public: public:
struct ContentKey {
KeyId id;
AesKey key;
// Default to the security level being undefined in the key container. When
// undefined, the key should be treated as if it is "software secure
// crypto".
//
// However, when we use the key control block, the security level in the key
// container does not matter as the key control block will always have the
// security level.
SecurityLevel level = SecurityLevel::kUndefined;
};
// Signing keys must be 512 bits (64 bytes). // Signing keys must be 512 bits (64 bytes).
using SigningKey = std::array<uint8_t, 64>; using SigningKey = std::array<uint8_t, 64>;
@@ -125,11 +110,7 @@ class TestLicenseBuilder {
void AddSigningKey(const SigningKey& key); void AddSigningKey(const SigningKey& key);
// Add a content key so that there is some key in the license. This should not void AddContentKey(const ContentKeyData& key);
// be used with AddContentKey().
void AddStubbedContentKey();
void AddContentKey(SecurityLevel level, const KeyId& id, const AesKey& key);
// The key id will matter as we will need to reference it, but the key won't // The key id will matter as we will need to reference it, but the key won't
// matter since we are only using it as a means to verify that a non-content // matter since we are only using it as a means to verify that a non-content
@@ -156,7 +137,7 @@ class TestLicenseBuilder {
Settings settings_; Settings settings_;
std::vector<ContentKey> content_keys_; std::vector<ContentKeyData> content_keys_;
std::vector<SigningKey> signing_keys_; std::vector<SigningKey> signing_keys_;
std::vector<KeyId> operator_session_keys_; std::vector<KeyId> operator_session_keys_;
}; };

View File

@@ -2,164 +2,166 @@
#include "api/test_license_whitebox_keys.h" #include "api/test_license_whitebox_keys.h"
// When the license response was collected for the UAT tests, the license server
// only supported a single key. In order for the UAT tests to work, the
// encryption and signing keys must be the same key.
namespace widevine { namespace widevine {
namespace { namespace {
constexpr uint8_t kDevicePublicKey[] = { constexpr uint8_t kSigningPublicKey[] = {
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xae, 0xa6, 0xa8, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0x9c, 0x54, 0xb3, 0x2f, 0x66,
0xea, 0xdd, 0xac, 0x6f, 0xb4, 0x41, 0x47, 0xcb, 0x18, 0x81, 0xeb, 0xdf, 0xe3, 0xd2, 0xb8, 0xee, 0x22, 0xa0, 0x3c, 0x76, 0x06, 0x67, 0xd8, 0xc1,
0x4f, 0x17, 0xf7, 0x17, 0xc0, 0xab, 0x6f, 0x47, 0x50, 0xbf, 0xe4, 0x8c, 0xbc, 0xe6, 0xbe, 0x6f, 0xb3, 0x93, 0xee, 0xd4, 0xe6, 0xcb, 0x11, 0x00,
0xc9, 0x45, 0x24, 0x5e, 0x1c, 0x2e, 0x86, 0x9f, 0xcb, 0x47, 0x05, 0xf9, 0xb5, 0x16, 0x49, 0xe1, 0x8e, 0xcc, 0xea, 0xbe, 0xc6, 0x45, 0x34, 0xfc,
0xfe, 0x91, 0x90, 0xaf, 0xbd, 0x22, 0x14, 0x47, 0xa7, 0x34, 0x39, 0x79, 0x13, 0xed, 0x0a, 0x90, 0x22, 0xe0, 0x6d, 0x6f, 0xaf, 0x64, 0xa8, 0xc2,
0x44, 0xe9, 0x92, 0x83, 0x4a, 0x80, 0xa8, 0x2a, 0xe6, 0x9f, 0x2b, 0xb7, 0x05, 0xf9, 0x2c, 0x51, 0x52, 0xd4, 0x42, 0x47, 0xfe, 0x03, 0x99, 0xf1,
0xda, 0x2a, 0xd2, 0xae, 0x57, 0x5b, 0xfa, 0xb6, 0xdf, 0xca, 0x3e, 0xb1, 0x03, 0x7e, 0x09, 0x08, 0x65, 0x50, 0xb9, 0x36, 0x8f, 0x62, 0xc5, 0x1a,
0xb8, 0x42, 0x0b, 0xde, 0x46, 0x36, 0xdb, 0x42, 0x33, 0x8b, 0xda, 0x5c, 0x18, 0x27, 0xb8, 0xf3, 0x89, 0x53, 0x5a, 0x9d, 0xfb, 0xe4, 0x9b, 0xb4,
0x60, 0x44, 0x7c, 0x99, 0xb4, 0x98, 0xb4, 0x1e, 0xd8, 0x25, 0x6d, 0x67, 0xea, 0x48, 0x7c, 0x0f, 0x30, 0x02, 0x82, 0x6c, 0xf7, 0xb6, 0xf7, 0x82,
0x84, 0xc9, 0x67, 0xde, 0x05, 0xe6, 0x06, 0xb5, 0xb5, 0xca, 0xbc, 0xfa, 0x1f, 0xbb, 0x0b, 0x87, 0x95, 0xd0, 0xda, 0x7e, 0xb9, 0x0e, 0x58, 0xa3,
0xb0, 0xa7, 0x46, 0x29, 0x3f, 0x63, 0x47, 0x9d, 0x70, 0x8d, 0xa2, 0x8d, 0x6d, 0xde, 0x50, 0x4d, 0xa0, 0x21, 0x1b, 0x72, 0xf3, 0x97, 0xbf, 0x98,
0x22, 0xc6, 0xeb, 0x06, 0xd4, 0x5c, 0x3b, 0x62, 0x98, 0xc7, 0xda, 0x16, 0xab, 0xb1, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01,
0x8f, 0x17, 0x59, 0xd5, 0xcb, 0xd1, 0x5d, 0xe3, 0xe1, 0x07, 0xe6, 0x97,
0x87, 0xf4, 0x22, 0x53, 0xfa, 0xf9, 0xa9, 0xf5, 0xeb, 0xd7, 0x55, 0xdf,
0x32, 0x2d, 0x4e, 0x07, 0x86, 0x25, 0x44, 0x93, 0xd6, 0xf7, 0xc6, 0xf9,
0x78, 0x91, 0x24, 0x1e, 0xd4, 0x6b, 0xe3, 0x4a, 0xff, 0x4a, 0x3a, 0xb9,
0x89, 0x90, 0x61, 0x87, 0xb9, 0x41, 0x45, 0x02, 0xfd, 0xd0, 0xc5, 0x5a,
0x98, 0x41, 0x88, 0xa4, 0xe3, 0xe2, 0xa2, 0x9d, 0x9a, 0x90, 0x3f, 0x44,
0x8e, 0x3a, 0xe1, 0xd1, 0xe9, 0x79, 0x9a, 0xc6, 0xe2, 0x7c, 0x8e, 0x9c,
0x3d, 0xb2, 0xe0, 0x26, 0x5a, 0x46, 0x13, 0xc8, 0x43, 0x9f, 0xf7, 0x51,
0x7e, 0xbb, 0x55, 0x6d, 0xcc, 0x97, 0x38, 0xdb, 0xa4, 0x4b, 0x96, 0x40,
0xe5, 0x2d, 0x8f, 0x43, 0xe3, 0x21, 0x15, 0xda, 0x34, 0x97, 0x7a, 0x9e,
0xbb, 0x02, 0x03, 0x01, 0x00, 0x01,
}; };
constexpr uint8_t kDevicePrivateKey[] = { constexpr uint8_t kEncryptionPublicKey[] = {
0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xb5, 0xdf, 0x28, 0x81, 0xfc,
0xae, 0xa6, 0xa8, 0xea, 0xdd, 0xac, 0x6f, 0xb4, 0x41, 0x47, 0xcb, 0x18, 0x29, 0x80, 0xe4, 0xe6, 0x49, 0x6e, 0x62, 0xe5, 0xf3, 0x23, 0x99, 0x59,
0x81, 0xeb, 0xdf, 0x4f, 0x17, 0xf7, 0x17, 0xc0, 0xab, 0x6f, 0x47, 0x50, 0x54, 0x84, 0x1b, 0xf1, 0xde, 0x27, 0x8b, 0xe6, 0x22, 0xec, 0x02, 0x68,
0xbf, 0xe4, 0x8c, 0xc9, 0x45, 0x24, 0x5e, 0x1c, 0x2e, 0x86, 0x9f, 0xcb, 0x58, 0x6e, 0x5b, 0x11, 0x90, 0x7a, 0xb3, 0xb3, 0x35, 0xab, 0x02, 0xb7,
0x47, 0x05, 0xf9, 0xfe, 0x91, 0x90, 0xaf, 0xbd, 0x22, 0x14, 0x47, 0xa7, 0xf6, 0xd8, 0x74, 0xef, 0x90, 0xd8, 0xab, 0xb1, 0x44, 0x04, 0x7e, 0x15,
0x34, 0x39, 0x79, 0x44, 0xe9, 0x92, 0x83, 0x4a, 0x80, 0xa8, 0x2a, 0xe6, 0x02, 0xac, 0x9d, 0x1e, 0x4e, 0xef, 0x9c, 0xdf, 0x31, 0xdb, 0x7a, 0x03,
0x9f, 0x2b, 0xb7, 0xda, 0x2a, 0xd2, 0xae, 0x57, 0x5b, 0xfa, 0xb6, 0xdf, 0xd6, 0xa9, 0xfe, 0x6e, 0xd6, 0x4e, 0x5d, 0xaf, 0xdd, 0x63, 0x62, 0x5e,
0xca, 0x3e, 0xb1, 0xb8, 0x42, 0x0b, 0xde, 0x46, 0x36, 0xdb, 0x42, 0x33, 0xa9, 0x56, 0x82, 0x2c, 0x09, 0x26, 0xc5, 0x61, 0x58, 0xf2, 0x04, 0xd5,
0x8b, 0xda, 0x5c, 0x60, 0x44, 0x7c, 0x99, 0xb4, 0x98, 0xb4, 0x1e, 0xd8, 0x0a, 0x40, 0x22, 0xb7, 0x9a, 0x46, 0x4d, 0x88, 0x2c, 0x75, 0x8f, 0xc1,
0x25, 0x6d, 0x67, 0x84, 0xc9, 0x67, 0xde, 0x05, 0xe6, 0x06, 0xb5, 0xb5, 0x18, 0x6a, 0xf8, 0xf6, 0x5d, 0xb1, 0x77, 0x24, 0xcb, 0x0e, 0x0f, 0x99,
0xca, 0xbc, 0xfa, 0xb0, 0xa7, 0x46, 0x29, 0x3f, 0x63, 0x47, 0x9d, 0x70, 0x38, 0x7c, 0x0a, 0x4a, 0xd1, 0xda, 0xef, 0x35, 0x80, 0x60, 0x56, 0xbc,
0x8d, 0xa2, 0x8d, 0x22, 0xc6, 0xeb, 0x06, 0xd4, 0x5c, 0x3b, 0x62, 0x98, 0xe9, 0x16, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01,
0xc7, 0xda, 0x16, 0x8f, 0x17, 0x59, 0xd5, 0xcb, 0xd1, 0x5d, 0xe3, 0xe1, };
0x07, 0xe6, 0x97, 0x87, 0xf4, 0x22, 0x53, 0xfa, 0xf9, 0xa9, 0xf5, 0xeb,
0xd7, 0x55, 0xdf, 0x32, 0x2d, 0x4e, 0x07, 0x86, 0x25, 0x44, 0x93, 0xd6, constexpr uint8_t kSigningPrivateKey[] = {
0xf7, 0xc6, 0xf9, 0x78, 0x91, 0x24, 0x1e, 0xd4, 0x6b, 0xe3, 0x4a, 0xff, 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0x9c,
0x4a, 0x3a, 0xb9, 0x89, 0x90, 0x61, 0x87, 0xb9, 0x41, 0x45, 0x02, 0xfd, 0x54, 0xb3, 0x2f, 0x66, 0xe3, 0xd2, 0xb8, 0xee, 0x22, 0xa0, 0x3c, 0x76,
0xd0, 0xc5, 0x5a, 0x98, 0x41, 0x88, 0xa4, 0xe3, 0xe2, 0xa2, 0x9d, 0x9a, 0x06, 0x67, 0xd8, 0xc1, 0xbc, 0xe6, 0xbe, 0x6f, 0xb3, 0x93, 0xee, 0xd4,
0x90, 0x3f, 0x44, 0x8e, 0x3a, 0xe1, 0xd1, 0xe9, 0x79, 0x9a, 0xc6, 0xe2, 0xe6, 0xcb, 0x11, 0x00, 0xb5, 0x16, 0x49, 0xe1, 0x8e, 0xcc, 0xea, 0xbe,
0x7c, 0x8e, 0x9c, 0x3d, 0xb2, 0xe0, 0x26, 0x5a, 0x46, 0x13, 0xc8, 0x43, 0xc6, 0x45, 0x34, 0xfc, 0x13, 0xed, 0x0a, 0x90, 0x22, 0xe0, 0x6d, 0x6f,
0x9f, 0xf7, 0x51, 0x7e, 0xbb, 0x55, 0x6d, 0xcc, 0x97, 0x38, 0xdb, 0xa4, 0xaf, 0x64, 0xa8, 0xc2, 0x05, 0xf9, 0x2c, 0x51, 0x52, 0xd4, 0x42, 0x47,
0x4b, 0x96, 0x40, 0xe5, 0x2d, 0x8f, 0x43, 0xe3, 0x21, 0x15, 0xda, 0x34, 0xfe, 0x03, 0x99, 0xf1, 0x03, 0x7e, 0x09, 0x08, 0x65, 0x50, 0xb9, 0x36,
0x97, 0x7a, 0x9e, 0xbb, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x8f, 0x62, 0xc5, 0x1a, 0x18, 0x27, 0xb8, 0xf3, 0x89, 0x53, 0x5a, 0x9d,
0x00, 0x56, 0x73, 0xe7, 0x1f, 0xc3, 0xb5, 0x4c, 0xe2, 0x24, 0x82, 0x5e, 0xfb, 0xe4, 0x9b, 0xb4, 0xea, 0x48, 0x7c, 0x0f, 0x30, 0x02, 0x82, 0x6c,
0x55, 0x76, 0x52, 0x85, 0x0a, 0xc8, 0xe9, 0x26, 0x57, 0xd8, 0x44, 0xd0, 0xf7, 0xb6, 0xf7, 0x82, 0x1f, 0xbb, 0x0b, 0x87, 0x95, 0xd0, 0xda, 0x7e,
0x3f, 0x77, 0x8d, 0xb1, 0xe7, 0x1b, 0x93, 0xc2, 0x06, 0x1f, 0x3d, 0xc2, 0xb9, 0x0e, 0x58, 0xa3, 0x6d, 0xde, 0x50, 0x4d, 0xa0, 0x21, 0x1b, 0x72,
0xb1, 0xc4, 0x29, 0x80, 0x33, 0x74, 0x68, 0xf3, 0xa5, 0x22, 0xce, 0x79, 0xf3, 0x97, 0xbf, 0x98, 0xab, 0xb1, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01,
0x1d, 0x9a, 0x6b, 0x6c, 0xcd, 0x20, 0xf5, 0xc6, 0x89, 0xc5, 0x9f, 0xf9, 0x02, 0x81, 0x80, 0x40, 0x61, 0xf7, 0xab, 0xd1, 0x7d, 0x89, 0x46, 0xc5,
0x04, 0x89, 0xfc, 0x01, 0x19, 0x3c, 0xa3, 0x67, 0x6b, 0x94, 0xfb, 0x49, 0x38, 0x38, 0x72, 0xbe, 0x0e, 0xd4, 0x4c, 0xe6, 0x39, 0x34, 0x74, 0x80,
0x35, 0x04, 0x0e, 0xfe, 0xb8, 0x1f, 0xf1, 0x72, 0x08, 0xbd, 0xb4, 0xd1, 0x8f, 0x5e, 0x20, 0xf1, 0xc8, 0x9d, 0x20, 0x03, 0x01, 0x11, 0x4d, 0x5b,
0x53, 0x64, 0xc2, 0x25, 0x81, 0xfd, 0xc4, 0xd3, 0xed, 0x22, 0xbd, 0xde, 0x1a, 0x13, 0x15, 0xa8, 0x7d, 0x02, 0x7a, 0x98, 0x48, 0x62, 0x8a, 0xc3,
0x9a, 0xce, 0x04, 0x16, 0xff, 0x13, 0x17, 0x98, 0x3e, 0xc1, 0x3b, 0xc7, 0xa2, 0xc1, 0x78, 0x00, 0x93, 0xa4, 0xea, 0x85, 0x81, 0xad, 0x45, 0x8d,
0x0d, 0x03, 0x1b, 0x82, 0xd8, 0x99, 0x24, 0xd0, 0xdc, 0x30, 0xcf, 0xcd, 0xb6, 0x85, 0x99, 0x48, 0x89, 0xfa, 0x14, 0x12, 0x6d, 0x9f, 0x2f, 0x85,
0x6e, 0x5e, 0x9d, 0xfd, 0x51, 0x1e, 0xb8, 0x4e, 0x7b, 0x54, 0x83, 0x9b, 0xda, 0xeb, 0x69, 0x51, 0x21, 0x3c, 0x70, 0x45, 0xc7, 0x32, 0xd2, 0x83,
0x4f, 0xf8, 0xa6, 0x03, 0xc1, 0x96, 0xf1, 0x6d, 0xc0, 0xa7, 0x17, 0xbd, 0xa1, 0x3f, 0xbc, 0x5a, 0x53, 0x84, 0x2b, 0xde, 0xc3, 0x80, 0x33, 0x9e,
0xf1, 0x60, 0xcb, 0xe2, 0x05, 0xa5, 0x9b, 0x05, 0x2e, 0xaf, 0xdc, 0xa7, 0x67, 0x60, 0xad, 0x38, 0xaa, 0x3b, 0xde, 0xd7, 0x30, 0xe0, 0xa9, 0xd0,
0x88, 0xde, 0x53, 0x42, 0xa9, 0xf4, 0x0f, 0xae, 0xf9, 0x96, 0xe9, 0x2c, 0x78, 0x46, 0xc8, 0x23, 0x9f, 0xcf, 0xc4, 0x7c, 0x2d, 0x56, 0x1e, 0xc3,
0xa6, 0xe8, 0x9d, 0x2c, 0x6b, 0xbc, 0xd8, 0x0f, 0x09, 0x5f, 0x64, 0xb2, 0x21, 0x02, 0x35, 0xe7, 0xbf, 0xf4, 0x8f, 0x12, 0x76, 0x6d, 0x89, 0x02,
0x21, 0x6f, 0xc0, 0x79, 0x3d, 0x6e, 0xad, 0x93, 0x79, 0x35, 0x87, 0x9a, 0x41, 0x00, 0xd8, 0x7f, 0x34, 0xd2, 0x3b, 0x51, 0x7f, 0xe9, 0x42, 0x02,
0x41, 0xcc, 0x06, 0x24, 0xf0, 0x62, 0x09, 0xfe, 0x46, 0x9a, 0x38, 0xee, 0x9d, 0xea, 0x31, 0x55, 0x80, 0xab, 0xea, 0x09, 0x85, 0x3f, 0x06, 0x16,
0xc0, 0xc8, 0x08, 0xce, 0x65, 0xda, 0xe4, 0x89, 0x1a, 0xfb, 0xe9, 0x53, 0x79, 0x6e, 0x2c, 0x47, 0x65, 0xe7, 0x0f, 0xf5, 0x2e, 0x52, 0x5c, 0x49,
0x0c, 0xd1, 0x80, 0x40, 0xfd, 0xc4, 0x97, 0xf8, 0x19, 0x4e, 0x03, 0x90, 0xcc, 0xd5, 0xf4, 0xcb, 0x67, 0xfa, 0x1b, 0x42, 0x2f, 0x5a, 0x73, 0x67,
0x4a, 0xda, 0xfd, 0x13, 0x27, 0x89, 0xde, 0x12, 0x8d, 0x52, 0x5a, 0x07, 0x2e, 0x53, 0xcd, 0x4b, 0x5b, 0xfa, 0xe7, 0x9e, 0x8f, 0xbe, 0x4b, 0x32,
0xf1, 0x9a, 0xa4, 0x54, 0x98, 0x86, 0xb2, 0x78, 0x76, 0xbf, 0x3a, 0xa9, 0x72, 0x21, 0xfb, 0x99, 0x3b, 0xa9, 0x02, 0x41, 0x00, 0xb8, 0xdb, 0x13,
0x8b, 0xed, 0xc7, 0x8b, 0x31, 0x02, 0x81, 0x81, 0x00, 0xe2, 0xf3, 0xab, 0x64, 0x1e, 0x81, 0x4f, 0x85, 0xc3, 0xbe, 0xc8, 0x21, 0xcd, 0x2b, 0x57,
0x53, 0x7b, 0xee, 0x36, 0xdb, 0xca, 0xa8, 0x74, 0x03, 0xdd, 0xe2, 0xce, 0x1c, 0x61, 0x16, 0xcb, 0x93, 0x0a, 0x31, 0xb8, 0x24, 0xbc, 0xb7, 0xf8,
0x87, 0xe2, 0x8c, 0x55, 0x8e, 0xd4, 0x0f, 0x32, 0xec, 0xd2, 0xf9, 0x8b, 0x5c, 0xde, 0x9c, 0x8e, 0x0f, 0x91, 0x21, 0xf7, 0x3a, 0x98, 0x9d, 0x3f,
0x1f, 0x93, 0xdb, 0x84, 0xd2, 0x42, 0xe1, 0xc7, 0x21, 0x24, 0x2e, 0x36, 0xf9, 0x2a, 0x1a, 0x52, 0x3a, 0x13, 0x5a, 0x9b, 0x5c, 0x37, 0x44, 0x0a,
0x0c, 0x02, 0x5d, 0x49, 0xea, 0xe0, 0x42, 0xd7, 0x7a, 0x3e, 0xc8, 0x51, 0x35, 0x19, 0xac, 0xaa, 0x7e, 0xa6, 0xbb, 0xdb, 0x31, 0x5a, 0x88, 0x07,
0x92, 0x39, 0x56, 0x10, 0xd7, 0x90, 0x67, 0xa3, 0x34, 0xd6, 0xc2, 0x4a, 0x63, 0x02, 0x40, 0x25, 0xaf, 0x7e, 0xf2, 0x59, 0x81, 0x06, 0x53, 0x04,
0x33, 0x74, 0xfd, 0xe2, 0x7e, 0xe1, 0x3e, 0x59, 0xd7, 0x36, 0x6d, 0x7d, 0x3a, 0x90, 0x62, 0x83, 0xd3, 0xee, 0x61, 0xfe, 0x8b, 0x49, 0xb6, 0x7e,
0xd4, 0xd8, 0x82, 0xfb, 0x2f, 0x1e, 0x5e, 0x32, 0xcd, 0xc3, 0x0a, 0x7f, 0xc8, 0xca, 0xba, 0x72, 0xda, 0xba, 0xd2, 0x4d, 0xe4, 0xcf, 0xfb, 0x66,
0xbd, 0xb0, 0xb3, 0xf9, 0x77, 0x75, 0xb9, 0x0c, 0x63, 0x54, 0xff, 0x25, 0x35, 0x32, 0x82, 0xcb, 0xe9, 0xdc, 0x5f, 0x9c, 0xff, 0x18, 0x5f, 0x16,
0xa3, 0xaf, 0x4a, 0x70, 0x61, 0x32, 0x91, 0xde, 0xfb, 0x95, 0x25, 0xb4, 0x57, 0x8f, 0xa8, 0xe6, 0xc3, 0x87, 0x6f, 0x55, 0x82, 0x34, 0x63, 0x5b,
0x06, 0x98, 0x9d, 0xeb, 0x49, 0xc8, 0xe0, 0xc0, 0x7e, 0x45, 0xfb, 0xe5, 0x93, 0x9c, 0x6a, 0x6d, 0xf1, 0x6e, 0x81, 0x02, 0x40, 0x67, 0x6a, 0x68,
0xf8, 0x72, 0x5b, 0x6b, 0x19, 0x02, 0x81, 0x81, 0x00, 0xc5, 0x01, 0x4b, 0x56, 0xc2, 0x9a, 0x25, 0x1a, 0xf8, 0x7f, 0x6b, 0x07, 0x3d, 0xf8, 0xd9,
0xb7, 0x5f, 0x6d, 0xbc, 0xa6, 0x8c, 0xb8, 0xeb, 0xa5, 0xff, 0x0b, 0xd7, 0x2b, 0x0f, 0x45, 0xe9, 0x6d, 0xc1, 0x6e, 0x3f, 0x4e, 0x8e, 0x25, 0x7d,
0x15, 0xd7, 0xef, 0xf6, 0xc9, 0xfe, 0x69, 0xcc, 0xe5, 0xbd, 0x5c, 0xa8, 0xd4, 0xb6, 0xd5, 0x6e, 0xc4, 0x56, 0xb5, 0x61, 0xd2, 0x6e, 0x3e, 0xca,
0x05, 0xa0, 0x4d, 0x3b, 0x1f, 0xa6, 0xcc, 0x37, 0x7b, 0xb1, 0x46, 0xf2, 0xe3, 0x62, 0x22, 0x87, 0x8d, 0xe5, 0xf5, 0xf2, 0xa4, 0x8c, 0x66, 0x8c,
0xc7, 0x67, 0xcd, 0xc1, 0x20, 0xc4, 0x14, 0xbd, 0x0e, 0x01, 0xa7, 0xd6, 0x2f, 0x58, 0xc5, 0xb8, 0x3c, 0x52, 0x9b, 0x15, 0xed, 0x6e, 0x70, 0x5b,
0x3c, 0xe8, 0x18, 0x9d, 0x71, 0x71, 0x37, 0x2a, 0xc0, 0x45, 0x6a, 0x54, 0x71, 0x02, 0x41, 0x00, 0x93, 0xbd, 0x21, 0x13, 0x72, 0x56, 0xaa, 0xd7,
0xe8, 0x63, 0xf0, 0x6e, 0xd2, 0x9f, 0x95, 0x3b, 0xde, 0xb3, 0xc5, 0x60, 0xef, 0x3a, 0xa7, 0xc4, 0x00, 0x42, 0x56, 0xa9, 0x17, 0xd1, 0x08, 0x44,
0x57, 0x3d, 0xed, 0xef, 0x57, 0xcb, 0x3d, 0x35, 0x3a, 0x2e, 0x5d, 0xb8, 0x29, 0x10, 0x6d, 0x0d, 0x50, 0x2c, 0x49, 0x1d, 0x6b, 0x3f, 0x84, 0x5c,
0x0e, 0xf8, 0xff, 0xd2, 0xca, 0xdd, 0xce, 0x0b, 0x10, 0x53, 0xb4, 0xdb, 0xe8, 0x69, 0x1f, 0x83, 0xa8, 0xc2, 0x59, 0x88, 0x6a, 0x18, 0x02, 0x42,
0x53, 0xf6, 0x02, 0xa5, 0xf1, 0x23, 0x4d, 0x21, 0x6e, 0xc7, 0x52, 0x5a, 0xfb, 0xf2, 0x85, 0x64, 0x2b, 0x42, 0xc5, 0xc4, 0x8d, 0xc4, 0x28, 0x13,
0x7a, 0x5d, 0x88, 0x32, 0xa8, 0x65, 0x50, 0x21, 0xf5, 0x81, 0x3f, 0x96, 0x95, 0x3c, 0x96, 0x61, 0x21, 0x61, 0x01, 0x9b,
0xd4, 0x57, 0x48, 0x66, 0xf3, 0x02, 0x81, 0x81, 0x00, 0xdd, 0x83, 0xd6, };
0x62, 0x9a, 0xe1, 0x0c, 0xfc, 0x84, 0x96, 0xdc, 0xfd, 0xf5, 0x31, 0xee,
0x42, 0x25, 0x76, 0xb1, 0xff, 0xc1, 0xad, 0xc0, 0x17, 0xf5, 0x68, 0x8a, constexpr uint8_t kEncryptionPrivateKey[] = {
0x49, 0x5d, 0x08, 0xf3, 0x60, 0x42, 0xd5, 0x9a, 0x86, 0x17, 0x89, 0x5f, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xb5,
0x49, 0x63, 0x79, 0x68, 0xaf, 0x6f, 0x0a, 0xee, 0xc4, 0xab, 0xc8, 0xdc, 0xdf, 0x28, 0x81, 0xfc, 0x29, 0x80, 0xe4, 0xe6, 0x49, 0x6e, 0x62, 0xe5,
0x0d, 0x6c, 0x17, 0x3c, 0x43, 0x1a, 0xf8, 0x7d, 0x0d, 0x12, 0xdc, 0xfa, 0xf3, 0x23, 0x99, 0x59, 0x54, 0x84, 0x1b, 0xf1, 0xde, 0x27, 0x8b, 0xe6,
0x8d, 0xb5, 0x10, 0x25, 0x65, 0x90, 0x36, 0x4a, 0x7c, 0x4b, 0xec, 0x9c, 0x22, 0xec, 0x02, 0x68, 0x58, 0x6e, 0x5b, 0x11, 0x90, 0x7a, 0xb3, 0xb3,
0xd8, 0x06, 0x27, 0xfa, 0x41, 0xa8, 0x53, 0x6b, 0x24, 0xf8, 0xcd, 0x23, 0x35, 0xab, 0x02, 0xb7, 0xf6, 0xd8, 0x74, 0xef, 0x90, 0xd8, 0xab, 0xb1,
0x97, 0xa3, 0x84, 0x56, 0xe7, 0x29, 0xa9, 0x5f, 0x95, 0x08, 0x9e, 0x2d, 0x44, 0x04, 0x7e, 0x15, 0x02, 0xac, 0x9d, 0x1e, 0x4e, 0xef, 0x9c, 0xdf,
0x3f, 0xd1, 0xd5, 0x47, 0x51, 0x27, 0x89, 0xc7, 0x6a, 0x29, 0xce, 0x6e, 0x31, 0xdb, 0x7a, 0x03, 0xd6, 0xa9, 0xfe, 0x6e, 0xd6, 0x4e, 0x5d, 0xaf,
0x23, 0xce, 0x0c, 0xbd, 0x5d, 0xfc, 0x4a, 0x9a, 0xb7, 0xe5, 0x59, 0x13, 0xdd, 0x63, 0x62, 0x5e, 0xa9, 0x56, 0x82, 0x2c, 0x09, 0x26, 0xc5, 0x61,
0xc2, 0xe6, 0xe3, 0xa1, 0xe9, 0x02, 0x81, 0x81, 0x00, 0xc3, 0x6f, 0x98, 0x58, 0xf2, 0x04, 0xd5, 0x0a, 0x40, 0x22, 0xb7, 0x9a, 0x46, 0x4d, 0x88,
0xa4, 0xae, 0x97, 0xd7, 0xb9, 0xc6, 0x0a, 0xc1, 0x43, 0xa8, 0xf4, 0x1f, 0x2c, 0x75, 0x8f, 0xc1, 0x18, 0x6a, 0xf8, 0xf6, 0x5d, 0xb1, 0x77, 0x24,
0x08, 0xfd, 0x72, 0x81, 0xfa, 0x3b, 0x58, 0xcc, 0x3a, 0xf1, 0x93, 0x54, 0xcb, 0x0e, 0x0f, 0x99, 0x38, 0x7c, 0x0a, 0x4a, 0xd1, 0xda, 0xef, 0x35,
0xe0, 0x57, 0xf9, 0xa5, 0xf8, 0xad, 0x69, 0x14, 0x75, 0xb2, 0x15, 0x77, 0x80, 0x60, 0x56, 0xbc, 0xe9, 0x16, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01,
0x4d, 0xd8, 0xad, 0xa6, 0xb5, 0x11, 0xb0, 0x9d, 0x28, 0xa2, 0xfd, 0xd4, 0x02, 0x81, 0x80, 0x58, 0x31, 0x52, 0xcf, 0x55, 0x9c, 0x3a, 0xa8, 0xc5,
0xac, 0x11, 0x78, 0x31, 0xe0, 0xd3, 0x76, 0xee, 0x03, 0x56, 0x19, 0xb9, 0x13, 0x2e, 0xb8, 0x3e, 0x91, 0xdc, 0xdd, 0x6b, 0xf8, 0x13, 0xe8, 0x09,
0x67, 0xdd, 0x95, 0x2c, 0xeb, 0xe8, 0x02, 0x8d, 0x25, 0x4e, 0x64, 0x35, 0x2d, 0x95, 0x37, 0xbd, 0xed, 0x89, 0x4c, 0xd1, 0x94, 0xb0, 0x4e, 0xf1,
0x41, 0xf7, 0x1e, 0xee, 0xfc, 0xc2, 0x93, 0xd3, 0x15, 0x07, 0xe0, 0x53, 0x01, 0x82, 0xbe, 0xc9, 0x54, 0x69, 0x0c, 0xf4, 0x70, 0x7b, 0x1e, 0x99,
0x73, 0x0f, 0x14, 0x03, 0x12, 0xdb, 0xdd, 0xc6, 0xde, 0x08, 0x9c, 0x77, 0x5d, 0x3f, 0xf4, 0x62, 0x0d, 0x7d, 0xb0, 0x36, 0x38, 0x09, 0xc4, 0x57,
0xa5, 0x20, 0x7d, 0xda, 0x0f, 0x91, 0x7c, 0xb7, 0xf9, 0x04, 0xe5, 0xae, 0x02, 0x28, 0x27, 0x86, 0x04, 0x03, 0x4d, 0x21, 0x96, 0x5c, 0xdc, 0xcf,
0xfa, 0x8b, 0x85, 0x4c, 0xf3, 0xff, 0xa5, 0xf2, 0x3a, 0x72, 0x61, 0x1a, 0xd8, 0x72, 0xa7, 0x98, 0x78, 0x14, 0x38, 0x41, 0x2c, 0x2f, 0xa4, 0x77,
0x09, 0x47, 0x19, 0x7d, 0x7f, 0x02, 0x81, 0x80, 0x65, 0xce, 0x33, 0x53, 0xec, 0x3e, 0x76, 0x80, 0x04, 0xba, 0xa2, 0xb6, 0x63, 0xbe, 0xa6, 0x7d,
0xca, 0xfb, 0xe0, 0x29, 0x83, 0x12, 0x93, 0x6c, 0xd9, 0xeb, 0x3b, 0xaa, 0xf2, 0x7e, 0x95, 0xaf, 0x15, 0xb3, 0x17, 0x26, 0xd9, 0x1f, 0x01, 0x27,
0xc5, 0xc4, 0xd1, 0xb0, 0x01, 0x85, 0xba, 0xc7, 0x6d, 0xdb, 0x3f, 0x86, 0xda, 0x20, 0xe2, 0x62, 0xb4, 0xf2, 0xb9, 0x05, 0xf3, 0x86, 0x95, 0x92,
0x06, 0x4c, 0x7e, 0xc4, 0x64, 0x65, 0x14, 0x5d, 0x9c, 0xe9, 0x54, 0x62, 0x45, 0x73, 0xd7, 0xd3, 0xa0, 0x1c, 0xcc, 0x89, 0xf3, 0x27, 0x81, 0x02,
0x5c, 0xf2, 0x6e, 0xe3, 0x14, 0x80, 0x48, 0x0c, 0xbc, 0xb4, 0xa1, 0xb6, 0x41, 0x00, 0xec, 0x3c, 0x1d, 0xdd, 0xd4, 0xae, 0x09, 0xd8, 0x81, 0xa9,
0x6d, 0x2f, 0xa3, 0x21, 0xc0, 0xfc, 0x45, 0xa9, 0x2e, 0x3d, 0x34, 0x2d, 0xfc, 0xc3, 0x46, 0xa3, 0xf1, 0x37, 0x9f, 0x7d, 0xc0, 0x70, 0x52, 0xab,
0x05, 0x39, 0x4f, 0x4b, 0xf1, 0x8c, 0xd3, 0x61, 0xbb, 0x80, 0x2d, 0xa3, 0x34, 0x25, 0xc3, 0xf6, 0x43, 0xe0, 0x08, 0xc5, 0x8b, 0x91, 0x23, 0x83,
0x50, 0x5c, 0xe0, 0xf4, 0xcd, 0xff, 0x95, 0xdc, 0xa8, 0x23, 0x8f, 0x92, 0x79, 0xac, 0x46, 0xf7, 0x63, 0xb8, 0x5c, 0x3d, 0xd6, 0x78, 0x67, 0xd4,
0x69, 0xcd, 0x36, 0x8a, 0xba, 0xa5, 0xe3, 0xfe, 0xce, 0x8e, 0x67, 0xc5, 0x19, 0xcf, 0x6c, 0x27, 0x5e, 0xea, 0x28, 0x81, 0x7b, 0xf8, 0xfd, 0x25,
0x54, 0x41, 0x8c, 0x44, 0xc5, 0x50, 0x55, 0x7a, 0x7c, 0x91, 0xc9, 0x2e, 0xa5, 0x35, 0x15, 0x63, 0x94, 0x47, 0x02, 0x41, 0x00, 0xc5, 0x16, 0xa5,
0x9e, 0x32, 0x63, 0x37, 0x42, 0x68, 0x29, 0x76, 0x41, 0xdb, 0x77, 0xfd, 0x1b, 0x0d, 0xeb, 0x48, 0xce, 0x2b, 0x55, 0xef, 0xd1, 0x69, 0xa2, 0x78,
0xcb, 0x6a, 0x73, 0x10, 0x12, 0x32, 0x72, 0x89, 0xa8, 0x3b, 0xbb, 0x07, 0x1d, 0x89, 0x36, 0x5b,
0x7d, 0x41, 0xc0, 0xcf, 0xef, 0xad, 0x29, 0xda, 0x3e, 0x11, 0x80, 0xe7,
0x97, 0xac, 0x7f, 0x18, 0xa9, 0xb5, 0x76, 0x60, 0xf3, 0x42, 0x01, 0xa4,
0xa3, 0xf2, 0x05, 0x91, 0x58, 0x90, 0x83, 0x53, 0xa1, 0x74, 0x7c, 0x2f,
0xd1, 0x02, 0x41, 0x00, 0xb2, 0xf4, 0x3f, 0x73, 0xc2, 0x1f, 0x2d, 0x1a,
0x33, 0xef, 0x7f, 0xa8, 0xb6, 0x24, 0x8f, 0x20, 0xa1, 0xd3, 0x73, 0x2a,
0x23, 0x95, 0xc9, 0xe5, 0x29, 0xf3, 0xae, 0x2b, 0x52, 0xb9, 0xc3, 0x26,
0x69, 0x8e, 0xb9, 0x67, 0x46, 0x43, 0x35, 0xe9, 0x7d, 0x06, 0xe3, 0x27,
0x47, 0x10, 0x27, 0x95, 0x37, 0xcb, 0x03, 0x5d, 0xc2, 0xdd, 0x83, 0xfa,
0x74, 0x5a, 0x46, 0x32, 0x56, 0x47, 0x9f, 0x15, 0x02, 0x41, 0x00, 0x97,
0x0b, 0x3d, 0xc9, 0xb8, 0x27, 0x23, 0x8a, 0xed, 0xe7, 0x54, 0x7d, 0xd7,
0x49, 0x2e, 0x60, 0x33, 0xcd, 0x57, 0xf6, 0x58, 0xa0, 0x83, 0x59, 0x7d,
0x78, 0xed, 0x30, 0xd7, 0x9d, 0x9f, 0x3e, 0x7e, 0x25, 0x5f, 0x1e, 0xc6,
0x67, 0x56, 0x16, 0x05, 0x9a, 0xfa, 0x19, 0xc5, 0xfa, 0x4d, 0x5e, 0xe0,
0xad, 0x45, 0xb2, 0x67, 0x9f, 0x20, 0xbf, 0x11, 0x31, 0xb4, 0x7c, 0x3e,
0x3b, 0x96, 0xa1, 0x02, 0x41, 0x00, 0x94, 0x82, 0x10, 0x66, 0xfe, 0xed,
0x68, 0x3b, 0x7f, 0xfb, 0x50, 0x3d, 0x35, 0xa0, 0x34, 0x0b, 0xc7, 0xbf,
0x5c, 0x7e, 0x01, 0x59, 0x77, 0xbb, 0xb2, 0xdf, 0x21, 0xbf, 0x1f, 0x67,
0x82, 0xd5, 0xca, 0x81, 0x8c, 0x99, 0xbf, 0x0c, 0x0f, 0xe6, 0x86, 0xd7,
0x32, 0x25, 0xa0, 0x63, 0x31, 0xa3, 0x2f, 0xd0, 0x89, 0x12, 0x2f, 0x2b,
0x95, 0x82, 0x28, 0xe3, 0x70, 0x3e, 0x7f, 0x04, 0xaa, 0x99,
}; };
std::vector<uint8_t> AsVector(const uint8_t* data, size_t length) { std::vector<uint8_t> AsVector(const uint8_t* data, size_t length) {
return std::vector<uint8_t>(data, data + length); return std::vector<uint8_t>(data, data + length);
} }
// Since we are going to return the same key for encryption and signing, create
// a common function for them to both call.
WhiteboxKey GetKey() {
WhiteboxKey key;
key.private_key = AsVector(kDevicePrivateKey, sizeof(kDevicePrivateKey));
key.public_key = AsVector(kDevicePublicKey, sizeof(kDevicePublicKey));
return key;
}
} // namespace } // namespace
WhiteboxKey GetEncryptionKey() { WhiteboxKey GetEncryptionKey() {
return GetKey(); WhiteboxKey key;
key.private_key =
AsVector(kEncryptionPrivateKey, sizeof(kEncryptionPrivateKey));
key.public_key = AsVector(kEncryptionPublicKey, sizeof(kEncryptionPublicKey));
return key;
} }
WhiteboxKey GetSigningKey() { WhiteboxKey GetSigningKey() {
return GetKey(); WhiteboxKey key;
key.private_key = AsVector(kSigningPrivateKey, sizeof(kSigningPrivateKey));
key.public_key = AsVector(kSigningPublicKey, sizeof(kSigningPublicKey));
return key;
} }
} // namespace widevine } // namespace widevine

View File

@@ -68,7 +68,7 @@ void PrettyPrint(const std::string& title,
LOG(INFO) << title; LOG(INFO) << title;
LOG(INFO) << " Sample Size: " << samples.SampleSize() << " (" LOG(INFO) << " Sample Size: " << samples.SampleSize() << " ("
<< per_sample_size << " bytes)"; << per_sample_size << " bytes)";
LOG(INFO) << " Min (0%): " << percentiles.Get(0).count() << " us"; LOG(INFO) << " Min (1%): " << percentiles.Get(1).count() << " us";
LOG(INFO) << " 25%: " << percentiles.Get(25).count() << " us"; LOG(INFO) << " 25%: " << percentiles.Get(25).count() << " us";
LOG(INFO) << " Median (50%): " << percentiles.Get(50).count() << " us"; LOG(INFO) << " Median (50%): " << percentiles.Get(50).count() << " us";
LOG(INFO) << " 75%: " << percentiles.Get(75).count() << " us"; LOG(INFO) << " 75%: " << percentiles.Get(75).count() << " us";

View File

@@ -5,7 +5,7 @@
cc_library( cc_library(
name = "license_protocol_proto", name = "license_protocol_proto",
hdrs = ["license_protocol.pb.h"], hdrs = ["license_protocol.pb.h"],
strip_include_prefix = "//chromium_deps", strip_include_prefix = "//chromium_deps/cdm/protos",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//chromium_deps/cdm/protos/defs:license_protocol_proto", "//chromium_deps/cdm/protos/defs:license_protocol_proto",

View File

@@ -14,6 +14,8 @@ namespace {
constexpr size_t kAesBlockSize = 16; constexpr size_t kAesBlockSize = 16;
} // namespace } // namespace
AesCbcDecryptor::~AesCbcDecryptor() {}
bool AesCbcDecryptor::SetKey(const uint8_t* key, size_t key_size) { bool AesCbcDecryptor::SetKey(const uint8_t* key, size_t key_size) {
DCHECK(key); DCHECK(key);

View File

@@ -12,6 +12,8 @@ namespace widevine {
class AesCbcDecryptor { class AesCbcDecryptor {
public: public:
virtual ~AesCbcDecryptor();
// Prepares the encryptor with the key. // Prepares the encryptor with the key.
virtual bool SetKey(const uint8_t* key, size_t key_size); virtual bool SetKey(const uint8_t* key, size_t key_size);

View File

@@ -14,6 +14,8 @@ namespace {
constexpr size_t kAesBlockSize = 16; constexpr size_t kAesBlockSize = 16;
} // namespace } // namespace
AesCbcEncryptor::~AesCbcEncryptor() {}
bool AesCbcEncryptor::SetKey(const uint8_t* key, size_t key_size) { bool AesCbcEncryptor::SetKey(const uint8_t* key, size_t key_size) {
DCHECK(key); DCHECK(key);

View File

@@ -12,6 +12,8 @@ namespace widevine {
class AesCbcEncryptor { class AesCbcEncryptor {
public: public:
virtual ~AesCbcEncryptor();
// Prepares the encryptor with the key. // Prepares the encryptor with the key.
virtual bool SetKey(const uint8_t* key, size_t key_size); virtual bool SetKey(const uint8_t* key, size_t key_size);

View File

@@ -26,6 +26,8 @@ bool Increment64(uint8_t* counter) {
} // namespace } // namespace
AesCtrEncryptor::~AesCtrEncryptor() {}
bool AesCtrEncryptor::SetKey(const uint8_t* key, size_t key_size) { bool AesCtrEncryptor::SetKey(const uint8_t* key, size_t key_size) {
DCHECK(key); DCHECK(key);

View File

@@ -12,6 +12,8 @@ namespace widevine {
class AesCtrEncryptor { class AesCtrEncryptor {
public: public:
virtual ~AesCtrEncryptor();
// Prepares the encryptor with the key. // Prepares the encryptor with the key.
virtual bool SetKey(const uint8_t* key, size_t key_size); virtual bool SetKey(const uint8_t* key, size_t key_size);

View File

@@ -8,7 +8,7 @@
#include <string> #include <string>
#include "api/license_whitebox.h" #include "api/license_whitebox.h"
#include "cdm/protos/license_protocol.pb.h" #include "license_protocol.pb.h"
namespace widevine { namespace widevine {

View File

@@ -5,7 +5,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include "cdm/protos/license_protocol.pb.h" #include "license_protocol.pb.h"
#include "reference/impl/content_key.h" #include "reference/impl/content_key.h"
#include "reference/impl/odk.h" #include "reference/impl/odk.h"
#include "reference/impl/renewal_key.h" #include "reference/impl/renewal_key.h"

View File

@@ -12,11 +12,11 @@
#include "base/check.h" #include "base/check.h"
#include "base/check_op.h" #include "base/check_op.h"
#include "base/logging.h" #include "base/logging.h"
#include "cdm/protos/license_protocol.pb.h"
#include "crypto_utils/aes_cbc_decryptor.h" #include "crypto_utils/aes_cbc_decryptor.h"
#include "crypto_utils/aes_ctr_encryptor.h" #include "crypto_utils/aes_ctr_encryptor.h"
#include "crypto_utils/crypto_util.h" #include "crypto_utils/crypto_util.h"
#include "crypto_utils/rsa_key.h" #include "crypto_utils/rsa_key.h"
#include "license_protocol.pb.h"
#include "oemcrypto/odk/include/odk.h" #include "oemcrypto/odk/include/odk.h"
#include "oemcrypto/odk/include/odk_message.h" #include "oemcrypto/odk/include/odk_message.h"
#include "oemcrypto/odk/include/odk_structs.h" #include "oemcrypto/odk/include/odk_structs.h"
@@ -81,6 +81,16 @@ uint8_t InverseMaskingFunction1(uint8_t input) {
return mapping[input]; return mapping[input];
} }
bool CheckAndUpdateSize(size_t min_size, size_t* out_size) {
const bool good = *out_size >= min_size;
if (!good) {
DVLOG(1) << "Buffer too small: needs " << min_size << ", but was "
<< *out_size << ".";
}
*out_size = min_size;
return good;
}
} // namespace } // namespace
// The white-box type can't be in the namespace as it is declared in the header. // The white-box type can't be in the namespace as it is declared in the header.
@@ -148,7 +158,7 @@ WB_Result DecryptBuffer(WB_CipherMode mode,
size_t iv_size, size_t iv_size,
uint8_t* output_data, uint8_t* output_data,
size_t* output_data_size) { size_t* output_data_size) {
if (!input_data || !iv || !output_data || !output_data_size) { if (!input_data || !iv || !output_data_size) {
DVLOG(1) << "Invalid parameter: null pointer."; DVLOG(1) << "Invalid parameter: null pointer.";
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
} }
@@ -158,6 +168,16 @@ WB_Result DecryptBuffer(WB_CipherMode mode,
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
} }
// There is no padding, so the output will be the same length as the input.
if (!CheckAndUpdateSize(input_data_size, output_data_size)) {
return WB_RESULT_BUFFER_TOO_SMALL;
}
if (!output_data) {
DVLOG(1) << "Invalid parameter: null pointer.";
return WB_RESULT_INVALID_PARAMETER;
}
// Data must be "block aligned" for CBC. CTR does not have this requirement. // Data must be "block aligned" for CBC. CTR does not have this requirement.
if (mode == WB_CIPHER_MODE_CBC && input_data_size % AES_BLOCK_SIZE != 0) { if (mode == WB_CIPHER_MODE_CBC && input_data_size % AES_BLOCK_SIZE != 0) {
DVLOG(1) << "Invalid parameter: bad block size."; DVLOG(1) << "Invalid parameter: bad block size.";
@@ -171,14 +191,6 @@ WB_Result DecryptBuffer(WB_CipherMode mode,
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
} }
// There is no padding, so the output will be the same length as the input.
if (*output_data_size < input_data_size) {
DVLOG(1) << "Buffer too small: needs " << input_data_size << " but got "
<< *output_data_size << ".";
*output_data_size = input_data_size;
return WB_RESULT_BUFFER_TOO_SMALL;
}
// If we passed a key to this function, it should be the correct size. If it // If we passed a key to this function, it should be the correct size. If it
// wasn't, we should not have saved the content key. // wasn't, we should not have saved the content key.
CHECK(key) << "Missing key data"; CHECK(key) << "Missing key data";
@@ -191,15 +203,13 @@ WB_Result DecryptBuffer(WB_CipherMode mode,
AesCbcDecryptor decryptor; AesCbcDecryptor decryptor;
CHECK(decryptor.SetKey(key, key_size)); CHECK(decryptor.SetKey(key, key_size));
*output_data_size = input_data_size;
CHECK(decryptor.Decrypt(iv, iv_size, input_data, input_data_size, CHECK(decryptor.Decrypt(iv, iv_size, input_data, input_data_size,
output_data)); output_data));
} else if (mode == WB_CIPHER_MODE_CTR) { } else if (mode == WB_CIPHER_MODE_CTR) {
AesCtrDecryptor decryptor; AesCtrDecryptor decryptor;
CHECK(decryptor.SetKey(key, key_size)); CHECK(decryptor.SetKey(key, key_size));
// Encrypt and Decrypt for CBC use the same interface. // Encrypt and Decrypt for CTR use the same interface.
*output_data_size = input_data_size;
CHECK(decryptor.Encrypt(iv, iv_size, input_data, input_data_size, CHECK(decryptor.Encrypt(iv, iv_size, input_data, input_data_size,
output_data)); output_data));
} else { } else {
@@ -249,15 +259,26 @@ WB_Result WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox,
size_t license_request_size, size_t license_request_size,
uint8_t* signature, uint8_t* signature,
size_t* signature_size) { size_t* signature_size) {
if (!whitebox || !license_request || !signature || !signature_size) { if (!whitebox || !signature_size) {
DVLOG(1) << "Invalid parameter: null pointer."; DVLOG(1) << "Invalid parameter: null pointer.";
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
} }
const size_t real_sign_size = whitebox->signing_key->KeySize();
if (!CheckAndUpdateSize(real_sign_size, signature_size)) {
return WB_RESULT_BUFFER_TOO_SMALL;
}
// Only check after checking for short buffer so callers can query the size
// without a buffer.
if (license_request_size == 0) { if (license_request_size == 0) {
DVLOG(1) << "Invalid parameter: array size 0."; DVLOG(1) << "Invalid parameter: array size 0.";
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
} }
if (!license_request || !signature) {
DVLOG(1) << "Invalid parameter: null pointer.";
return WB_RESULT_INVALID_PARAMETER;
}
std::string result; std::string result;
@@ -267,14 +288,8 @@ WB_Result WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox,
std::string(license_request, license_request + license_request_size), std::string(license_request, license_request + license_request_size),
&result)); &result));
if (!widevine::MemCopy(result.data(), result.size(), signature, CHECK(widevine::MemCopy(result.data(), result.size(), signature,
*signature_size)) { *signature_size));
DVLOG(1) << "Buffer too small: signature needs " << result.size() << ".";
*signature_size = result.size();
return WB_RESULT_BUFFER_TOO_SMALL;
}
*signature_size = result.size();
return WB_RESULT_OK; return WB_RESULT_OK;
} }
@@ -501,7 +516,16 @@ WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox,
size_t message_size, size_t message_size,
uint8_t* signature, uint8_t* signature,
size_t* signature_size) { size_t* signature_size) {
if (!whitebox || !message || !signature || !signature_size) { if (!whitebox || !message || !signature_size) {
DVLOG(1) << "Invalid parameter: null pointer.";
return WB_RESULT_INVALID_PARAMETER;
}
if (!CheckAndUpdateSize(SHA256_DIGEST_LENGTH, signature_size)) {
return WB_RESULT_BUFFER_TOO_SMALL;
}
if (!signature) {
DVLOG(1) << "Invalid parameter: null pointer."; DVLOG(1) << "Invalid parameter: null pointer.";
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
} }
@@ -532,15 +556,8 @@ WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox,
whitebox->renewal_key->client.end()), whitebox->renewal_key->client.end()),
std::string(message, message + message_size)); std::string(message, message + message_size));
if (!widevine::MemCopy(computed_signature.data(), computed_signature.size(), CHECK(widevine::MemCopy(computed_signature.data(), computed_signature.size(),
signature, *signature_size)) { signature, *signature_size));
DVLOG(1) << "Buffer too small: signature needs "
<< computed_signature.size() << ".";
*signature_size = computed_signature.size();
return WB_RESULT_BUFFER_TOO_SMALL;
}
*signature_size = computed_signature.size();
return WB_RESULT_OK; return WB_RESULT_OK;
} }
@@ -600,7 +617,7 @@ WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
size_t key_id_size, size_t key_id_size,
uint8_t* secret_string, uint8_t* secret_string,
size_t* secret_string_size) { size_t* secret_string_size) {
if (!whitebox || !key_id || !secret_string || !secret_string_size) { if (!whitebox || !key_id || !secret_string_size) {
DVLOG(1) << "Invalid parameter: null pointer."; DVLOG(1) << "Invalid parameter: null pointer.";
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
} }
@@ -615,6 +632,16 @@ WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
} }
const auto secret_pattern = GetSecretStringFor(mode);
if (!CheckAndUpdateSize(secret_pattern.size(), secret_string_size)) {
return WB_RESULT_BUFFER_TOO_SMALL;
}
if (!secret_string) {
DVLOG(1) << "Invalid parameter: null pointer.";
return WB_RESULT_INVALID_PARAMETER;
}
if (key_id_size == 0) { if (key_id_size == 0) {
DVLOG(1) << "Invalid parameter: array size 0."; DVLOG(1) << "Invalid parameter: array size 0.";
return WB_RESULT_INVALID_PARAMETER; return WB_RESULT_INVALID_PARAMETER;
@@ -640,15 +667,8 @@ WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox,
return WB_RESULT_INSUFFICIENT_SECURITY_LEVEL; return WB_RESULT_INSUFFICIENT_SECURITY_LEVEL;
} }
const auto secret_pattern = GetSecretStringFor(mode); CHECK(widevine::MemCopy(secret_pattern.data(), secret_pattern.size(),
if (!widevine::MemCopy(secret_pattern.data(), secret_pattern.size(), secret_string, *secret_string_size));
secret_string, *secret_string_size)) {
DVLOG(1) << "Buffer too small: needs " << secret_pattern.size() << ".";
*secret_string_size = secret_pattern.size();
return WB_RESULT_BUFFER_TOO_SMALL;
}
*secret_string_size = secret_pattern.size();
return WB_RESULT_OK; return WB_RESULT_OK;
} }

View File

@@ -28,22 +28,22 @@ WB_Result GetODKContext(const std::string& combined_message,
ODK_Message_Create(mutable_message.data(), mutable_message.size()); ODK_Message_Create(mutable_message.data(), mutable_message.size());
ODK_Message_SetSize(&msg, core_message_size); ODK_Message_SetSize(&msg, core_message_size);
const ODK_MessageStatus message_status = ODK_Message_GetStatus(&msg);
if (message_status != MESSAGE_STATUS_OK) {
DVLOG(1) << "Invalid core message status: " << message_status;
return WB_RESULT_INVALID_SIGNATURE;
}
ODK_LicenseResponse license_response{{{0, 0, {}}}, NULL, {0}}; ODK_LicenseResponse license_response{{{0, 0, {}}}, NULL, {0}};
license_response.parsed_license = &(context->license); license_response.parsed_license = &(context->license);
Unpack_ODK_LicenseResponse(&msg, &license_response); Unpack_ODK_LicenseResponse(&msg, &license_response);
const ODK_MessageStatus message_status = ODK_Message_GetStatus(&msg);
if (message_status != MESSAGE_STATUS_OK) {
DVLOG(1) << "Invalid core message status: 0x" << std::hex << message_status;
return WB_RESULT_INVALID_PARAMETER;
}
const auto& core_message = license_response.request.core_message; const auto& core_message = license_response.request.core_message;
if (core_message.message_type != ODK_License_Response_Type) { if (core_message.message_type != ODK_License_Response_Type) {
DVLOG(1) << "Failed core message type: " << core_message.message_type; DVLOG(1) << "Failed core message type: " << core_message.message_type;
return WB_RESULT_INVALID_SIGNATURE; return WB_RESULT_INVALID_PARAMETER;
} }
context->major_version = core_message.nonce_values.api_major_version; context->major_version = core_message.nonce_values.api_major_version;

View File

@@ -3,7 +3,7 @@
#ifndef WHITEBOX_REFERENCE_IMPL_PROTOBUF_LICENSE_PARSER_H_ #ifndef WHITEBOX_REFERENCE_IMPL_PROTOBUF_LICENSE_PARSER_H_
#define WHITEBOX_REFERENCE_IMPL_PROTOBUF_LICENSE_PARSER_H_ #define WHITEBOX_REFERENCE_IMPL_PROTOBUF_LICENSE_PARSER_H_
#include "cdm/protos/license_protocol.pb.h" #include "license_protocol.pb.h"
#include "reference/impl/content_key.h" #include "reference/impl/content_key.h"
#include "reference/impl/license_parser.h" #include "reference/impl/license_parser.h"