Update partner repo
This updates the partner repo to match the internal version, including the following changes: - Adds a WB_RESULT_NOT_IMPLEMENTED error code - Add a flag to control new features (e.g. entitlement support). - Updates tests to match new expectations
This commit is contained in:
@@ -7,11 +7,7 @@
|
||||
#
|
||||
# test_aead_whitebox : The target for testing the AEAD white-box.
|
||||
#
|
||||
# general_license_whitebox_with_vmpra : The target for testing the license
|
||||
# white-box against generated licenses with VMP/RA functionality.
|
||||
#
|
||||
# general_license_whitebox_without_vmpra : The target for testing the license
|
||||
# white-box against generated licenses without VMP/RA functionality.
|
||||
# general_license_whitebox: The target for testing the license white-box.
|
||||
#
|
||||
# uat_license_whitebox : The target for testing the license white-box against
|
||||
# licenses from Widevine's UAT server.
|
||||
@@ -26,12 +22,7 @@ cc_library(
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "general_license_whitebox_with_vmpra",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "general_license_whitebox_without_vmpra",
|
||||
name = "general_license_whitebox",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
|
||||
@@ -13,11 +13,7 @@ package(default_visibility = [
|
||||
#
|
||||
# test_aead_whitebox : The target for testing the AEAD white-box.
|
||||
#
|
||||
# general_license_whitebox_with_vmpra : The target for testing the license
|
||||
# white-box against generated licenses with VMP/RA functionality.
|
||||
#
|
||||
# general_license_whitebox_without_vmpra : The target for testing the license
|
||||
# white-box against generated licenses without VMP/RA functionality.
|
||||
# general_license_whitebox: The target for testing the license white-box.
|
||||
#
|
||||
# uat_license_whitebox : The target for testing the license white-box against
|
||||
# licenses from Widevine's UAT server.
|
||||
@@ -53,25 +49,16 @@ cc_test(
|
||||
size = "small",
|
||||
deps = [
|
||||
"@whitebox_api//api:license_whitebox_test",
|
||||
"//impl:general_license_whitebox_without_vmpra",
|
||||
"//impl:general_license_whitebox",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "remote_attestation_and_verification_with_vmpra_test",
|
||||
name = "remote_attestation_and_verification_test",
|
||||
size = "small",
|
||||
deps = [
|
||||
"@whitebox_api//api:remote_attestation_and_verification_with_vmpra_test",
|
||||
"//impl:general_license_whitebox_with_vmpra",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "remote_attestation_and_verification_without_vmpra_test",
|
||||
size = "small",
|
||||
deps = [
|
||||
"@whitebox_api//api:remote_attestation_and_verification_without_vmpra_test",
|
||||
"//impl:general_license_whitebox_without_vmpra",
|
||||
"@whitebox_api//api:remote_attestation_and_verification_test",
|
||||
"//impl:general_license_whitebox",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -80,7 +67,7 @@ cc_test(
|
||||
size = "small",
|
||||
deps = [
|
||||
"@whitebox_api//api:license_whitebox_benchmark",
|
||||
"//impl:general_license_whitebox_without_vmpra",
|
||||
"//impl:general_license_whitebox",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
40
whitebox/BUILD
Normal file
40
whitebox/BUILD
Normal file
@@ -0,0 +1,40 @@
|
||||
# Copyright 2022 Google LLC. All Rights Reserved.
|
||||
|
||||
load("//:defs.bzl", "build_type")
|
||||
|
||||
build_type(name="build_type", build_setting_default="chrome")
|
||||
|
||||
config_setting(
|
||||
name="is_chrome",
|
||||
flag_values={
|
||||
"//:build_type": "chrome",
|
||||
}
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name="is_chromeos",
|
||||
flag_values={
|
||||
"//:build_type": "chromeos",
|
||||
}
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name="is_ce",
|
||||
flag_values={
|
||||
"//:build_type": "ce",
|
||||
}
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name="is_old_api",
|
||||
flag_values={
|
||||
"//:build_type": "old",
|
||||
}
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name="is_old_vmpra",
|
||||
flag_values={
|
||||
"//:build_type": "old_vmpra",
|
||||
}
|
||||
)
|
||||
@@ -30,6 +30,27 @@ To build the full repo and run all tests, from within or below the repo root
|
||||
bazel build "//..."
|
||||
bazel test "//..."
|
||||
```
|
||||
## Security Level
|
||||
|
||||
There are two possible interpretations of the `SW_SECURE_DECODE` security level:
|
||||
first is used by Chrome, where it can only be used with the "masked" decrypt
|
||||
path; the second is used by the CE CDM where it is treated the same as
|
||||
`SW_SECURE_CRYPTO`.
|
||||
|
||||
Both the tests and the reference implementation support both interpretations.
|
||||
Selecting which one is done using a pre-processor define
|
||||
`ALWAYS_DECRYPT_TO_CLEAR`. This is set automatically by Bazel based on the
|
||||
build type, which can be set with either `--//:build_type=chrome` or
|
||||
`--//:build_type=ce` (defaulting to Chrome). This also controls the tests and
|
||||
their expectations. e.g.
|
||||
|
||||
```bash
|
||||
bazel test ... --//:build_type=ce
|
||||
```
|
||||
|
||||
The external implementations don't need to use this pre-processor define to
|
||||
control which interpretation is used, but it must conform to one of them and
|
||||
pass the associated tests.
|
||||
|
||||
## API
|
||||
|
||||
|
||||
@@ -2,12 +2,34 @@
|
||||
|
||||
package(default_visibility = ["//visibility:private"])
|
||||
|
||||
cc_library(
|
||||
name = "shared_settings",
|
||||
defines = select({
|
||||
"//:is_ce": [
|
||||
"ALWAYS_DECRYPT_TO_CLEAR",
|
||||
"HAS_ENTITLEMENT",
|
||||
"HAS_SIGN_PST_REPORT",
|
||||
],
|
||||
"//:is_old_api": [],
|
||||
"//:is_old_vmpra": [],
|
||||
"//conditions:default": [
|
||||
"HAS_PROVIDER_KEYS",
|
||||
],
|
||||
}) + select({
|
||||
"//:is_chromeos": ["WV_ENABLE_HW_VERIFICATION=1"],
|
||||
"//:is_old_vmpra": ["WV_ENABLE_HW_VERIFICATION=1"],
|
||||
"//conditions:default": ["WV_ENABLE_HW_VERIFICATION=0"],
|
||||
}),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "result",
|
||||
hdrs = [
|
||||
"result.h",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":shared_settings"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -18,6 +40,7 @@ cc_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":result",
|
||||
":shared_settings",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -29,6 +52,21 @@ cc_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":result",
|
||||
":shared_settings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "license_whitebox_proxy",
|
||||
srcs = select({
|
||||
"//:is_old_api": ["license_whitebox_proxy_impl.cc"],
|
||||
"//:is_old_vmpra": ["license_whitebox_proxy_impl.cc"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":license_whitebox",
|
||||
":license_whitebox_provider_keys_test_data",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -37,6 +75,7 @@ cc_library(
|
||||
hdrs = [
|
||||
"test_key_types.h",
|
||||
],
|
||||
deps = [":shared_settings"],
|
||||
)
|
||||
|
||||
# This target provided the header needed to access the test keys. The
|
||||
@@ -49,6 +88,7 @@ cc_library(
|
||||
"test_license_whitebox_keys.h",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":shared_settings"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -57,7 +97,11 @@ cc_library(
|
||||
"test_license_whitebox_keys_general.cc",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":test_license_whitebox_keys"],
|
||||
deps = [
|
||||
":license_whitebox_proxy",
|
||||
":shared_settings",
|
||||
":test_license_whitebox_keys",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -66,7 +110,11 @@ cc_library(
|
||||
"test_license_whitebox_keys_uat.cc",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":test_license_whitebox_keys"],
|
||||
deps = [
|
||||
":license_whitebox_proxy",
|
||||
":shared_settings",
|
||||
":test_license_whitebox_keys",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -75,6 +123,7 @@ cc_library(
|
||||
"aead_test_data.h",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":shared_settings"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -86,6 +135,7 @@ cc_library(
|
||||
"test_license_provider_keys.h",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":shared_settings"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -94,6 +144,7 @@ cc_library(
|
||||
"license_whitebox_provider_keys_test_data.h",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":shared_settings"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -105,6 +156,7 @@ cc_library(
|
||||
"golden_data.h",
|
||||
],
|
||||
deps = [
|
||||
":shared_settings",
|
||||
":test_key_types",
|
||||
"//chromium_deps/cdm/protos:license_protocol_proto",
|
||||
],
|
||||
@@ -115,6 +167,7 @@ cc_library(
|
||||
srcs = ["test_server.cc"],
|
||||
hdrs = ["test_server.h"],
|
||||
deps = [
|
||||
":shared_settings",
|
||||
":test_license_whitebox_keys",
|
||||
"//chromium_deps/base:glog",
|
||||
"//crypto_utils:rsa_key",
|
||||
@@ -127,6 +180,7 @@ cc_library(
|
||||
hdrs = ["test_license_builder.h"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":shared_settings",
|
||||
":test_key_types",
|
||||
":test_license_provider_keys",
|
||||
":test_server",
|
||||
@@ -150,6 +204,7 @@ cc_library(
|
||||
deps = [
|
||||
":aead_test_data",
|
||||
":aead_whitebox",
|
||||
":shared_settings",
|
||||
"//chromium_deps/testing",
|
||||
],
|
||||
alwayslink = True,
|
||||
@@ -164,6 +219,7 @@ cc_library(
|
||||
deps = [
|
||||
":aead_test_data",
|
||||
":aead_whitebox",
|
||||
":shared_settings",
|
||||
"//benchmarking:data_source",
|
||||
"//benchmarking:measurements",
|
||||
"//chromium_deps/base:glog",
|
||||
@@ -184,6 +240,8 @@ cc_library(
|
||||
":golden_data",
|
||||
":license_whitebox",
|
||||
":license_whitebox_provider_keys_test_data",
|
||||
":license_whitebox_proxy",
|
||||
":shared_settings",
|
||||
":test_license_whitebox_keys",
|
||||
"//chromium_deps/testing",
|
||||
"//crypto_utils:rsa_key",
|
||||
@@ -215,6 +273,7 @@ cc_library(
|
||||
":license_whitebox",
|
||||
":license_whitebox_provider_keys_test_data",
|
||||
":license_whitebox_test_base",
|
||||
":shared_settings",
|
||||
":test_license_builder",
|
||||
"//chromium_deps/testing",
|
||||
],
|
||||
@@ -222,31 +281,15 @@ cc_library(
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "remote_attestation_and_verification_with_vmpra_test",
|
||||
name = "remote_attestation_and_verification_test",
|
||||
srcs = [
|
||||
"remote_attestation_and_verification_test.cc",
|
||||
],
|
||||
defines = ["WV_ENABLE_HW_VERIFICATION=1"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":license_whitebox",
|
||||
":license_whitebox_test_base",
|
||||
":test_license_builder",
|
||||
"//chromium_deps/testing",
|
||||
],
|
||||
alwayslink = True,
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "remote_attestation_and_verification_without_vmpra_test",
|
||||
srcs = [
|
||||
"remote_attestation_and_verification_test.cc",
|
||||
],
|
||||
defines = ["WV_ENABLE_HW_VERIFICATION=0"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":license_whitebox",
|
||||
":license_whitebox_test_base",
|
||||
":shared_settings",
|
||||
":test_license_builder",
|
||||
"//chromium_deps/testing",
|
||||
],
|
||||
@@ -269,6 +312,7 @@ cc_library(
|
||||
deps = [
|
||||
":license_whitebox",
|
||||
":license_whitebox_provider_keys_test_data",
|
||||
":shared_settings",
|
||||
":test_key_types",
|
||||
":test_license_builder",
|
||||
":test_license_whitebox_keys",
|
||||
@@ -290,6 +334,7 @@ cc_library(
|
||||
deps = [
|
||||
":license_whitebox",
|
||||
":license_whitebox_provider_keys_test_data",
|
||||
":shared_settings",
|
||||
"//chromium_deps/testing",
|
||||
],
|
||||
alwayslink = True,
|
||||
|
||||
@@ -47,7 +47,7 @@ class LicenseWhiteboxDecryptTest
|
||||
// Creates and loads a license. The license is created using |settings|
|
||||
// updated to include the test parameters. The license is loaded using
|
||||
// |provider_key_id|.
|
||||
void LoadLicense(const TestLicenseBuilder::Settings& settings,
|
||||
bool LoadLicense(const TestLicenseBuilder::Settings& settings,
|
||||
size_t provider_key_id) {
|
||||
TestLicenseBuilder builder;
|
||||
builder.SetSettings(settings);
|
||||
@@ -69,15 +69,19 @@ class LicenseWhiteboxDecryptTest
|
||||
License license;
|
||||
builder.Build(*server, &license);
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY,
|
||||
license.core_message.data(), license.core_message.size(),
|
||||
license.message.data(), license.message.size(),
|
||||
license.signature.data(), license.signature.size(),
|
||||
license.session_key.data(), license.session_key.size(),
|
||||
provider_key_id, license.request.data(), license.request.size()),
|
||||
WB_RESULT_OK);
|
||||
const auto result = WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license.core_message.data(),
|
||||
license.core_message.size(), license.message.data(),
|
||||
license.message.size(), license.signature.data(),
|
||||
license.signature.size(), license.session_key.data(),
|
||||
license.session_key.size(), provider_key_id, license.request.data(),
|
||||
license.request.size());
|
||||
#ifndef HAS_PROVIDER_KEYS
|
||||
if (provider_key_id != 0 && result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
return false;
|
||||
#endif
|
||||
EXPECT_EQ(result, WB_RESULT_OK);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need two special keys for this test, one that will be used for a
|
||||
@@ -95,7 +99,8 @@ class LicenseWhiteboxDecryptTest
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCbcMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -113,7 +118,8 @@ TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCbcMode) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InPlaceDecryptionCbc) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
memcpy(plaintext_.data(), golden_data_.CBCContent().ciphertext.data(),
|
||||
golden_data_.CBCContent().ciphertext.size());
|
||||
@@ -133,7 +139,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InPlaceDecryptionCbc) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCtrMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CTR,
|
||||
@@ -151,7 +158,8 @@ TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCtrMode) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InPlaceDecryptionCtr) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
memcpy(plaintext_.data(), golden_data_.CTRContent().ciphertext.data(),
|
||||
golden_data_.CTRContent().ciphertext.size());
|
||||
@@ -173,7 +181,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InPlaceDecryptionCtr) {
|
||||
// successful, but the resulting plaintext should not match.
|
||||
TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCtrMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CTR,
|
||||
@@ -193,7 +202,8 @@ TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCbcDataInCtrMode) {
|
||||
// successful, but the resulting plaintext should not match.
|
||||
TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCbcMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -213,7 +223,8 @@ TEST_P(LicenseWhiteboxDecryptTest, CryptoKeyWithCtrDataInCbcMode) {
|
||||
// different keys can be used at the same time.
|
||||
TEST_P(LicenseWhiteboxDecryptTest, SuccessWithMultipleKeys) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -250,7 +261,8 @@ TEST_P(LicenseWhiteboxDecryptTest, SuccessWithMultipleKeys) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullWhitebox) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
nullptr, WB_CIPHER_MODE_CBC,
|
||||
@@ -266,7 +278,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullWhitebox) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCipherMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
// In order to trick the compiler into letting us pass an invalid enum value
|
||||
// to WB__License_Decrypt(), we need to cast it. If we don't do this, the
|
||||
@@ -287,7 +300,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCipherMode) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullKeyId) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC, nullptr,
|
||||
@@ -302,7 +316,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullKeyId) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForZeroKeyIdSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -317,7 +332,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForZeroKeyIdSize) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullInputData) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -334,7 +350,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullInputData) {
|
||||
// not care.
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCBCInputDataSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -350,7 +367,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidCBCInputDataSize) {
|
||||
// The white-box (using any cipher mode) should reject input with size zero.
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForZeroInputDataSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -365,7 +383,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForZeroInputDataSize) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullIV) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -381,7 +400,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullIV) {
|
||||
// IV size should be 16. Any number other than 16 should fail.
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidIVSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -396,7 +416,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForInvalidIVSize) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutput) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -411,7 +432,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutput) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutputSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_Decrypt(
|
||||
@@ -430,7 +452,8 @@ TEST_P(LicenseWhiteboxDecryptTest, InvalidParameterForNullOutputSize) {
|
||||
// and "dropped content key", as those keys were in the license but ignored.
|
||||
TEST_P(LicenseWhiteboxDecryptTest, KeyUnavailableForMissingKeyId) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC,
|
||||
missing_key_id_.data(), missing_key_id_.size(),
|
||||
@@ -444,7 +467,8 @@ TEST_P(LicenseWhiteboxDecryptTest, KeyUnavailableForMissingKeyId) {
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, KeyUnavailableForNonContentKey) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -462,7 +486,8 @@ TEST_P(LicenseWhiteboxDecryptTest, KeyUnavailableForNonContentKey) {
|
||||
TEST_P(LicenseWhiteboxDecryptTest,
|
||||
InsufficientSecurityLevelForHardwareContentKey) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(whitebox_, WB_CIPHER_MODE_CBC,
|
||||
golden_data_.CBCContent().hardware_key.id.data(),
|
||||
@@ -477,10 +502,16 @@ TEST_P(LicenseWhiteboxDecryptTest,
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, InsufficientSecurityLevelForDecodeKey) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
// Use the software decode key as they are limited to
|
||||
// WB_License_Decrypt().
|
||||
#ifdef ALWAYS_DECRYPT_TO_CLEAR
|
||||
const auto expected = WB_RESULT_OK;
|
||||
#else
|
||||
const auto expected = WB_RESULT_INSUFFICIENT_SECURITY_LEVEL;
|
||||
#endif
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
golden_data_.CBCContent().software_decode_key.id.data(),
|
||||
@@ -490,12 +521,13 @@ TEST_P(LicenseWhiteboxDecryptTest, InsufficientSecurityLevelForDecodeKey) {
|
||||
golden_data_.CBCContent().iv.data(),
|
||||
golden_data_.CBCContent().iv.size(), plaintext_.data(),
|
||||
&plaintext_size_),
|
||||
WB_RESULT_INSUFFICIENT_SECURITY_LEVEL);
|
||||
expected);
|
||||
}
|
||||
|
||||
TEST_P(LicenseWhiteboxDecryptTest, BufferTooSmall) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
// Our ciphertext will be large enough that we should not need to worry about
|
||||
// using a constant here.
|
||||
@@ -540,7 +572,8 @@ TEST_P(LicenseWhiteboxDecryptTest, KeyUnavailableForInvalidKey) {
|
||||
// we just need an invalid key, so we use one way of invalidating the key.
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.include_content_key_iv = false;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -577,7 +610,8 @@ TEST_P(LicenseWhiteboxDecryptTest, MismatchProviderKeyId) {
|
||||
}
|
||||
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, other_provider_key_id);
|
||||
if (!LoadLicense(settings, other_provider_key_id))
|
||||
GTEST_SKIP();
|
||||
|
||||
// Decryption should succeed, but the plaintext should be incorrect.
|
||||
ASSERT_EQ(WB_License_Decrypt(
|
||||
|
||||
@@ -32,29 +32,31 @@ class LicenseWhiteboxEntitlementContentKeyTest
|
||||
};
|
||||
|
||||
TEST_F(LicenseWhiteboxEntitlementContentKeyTest, Decrypt) {
|
||||
ASSERT_EQ(WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY,
|
||||
license_.core_message.data(), license_.core_message.size(),
|
||||
license_.message.data(), license_.message.size(),
|
||||
license_.signature.data(), license_.signature.size(),
|
||||
license_.session_key.data(), license_.session_key.size(),
|
||||
kNoProviderKeyId, license_.request.data(),
|
||||
license_.request.size()),
|
||||
WB_RESULT_OK);
|
||||
auto result = WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
||||
license_.core_message.size(), license_.message.data(),
|
||||
license_.message.size(), license_.signature.data(),
|
||||
license_.signature.size(), license_.session_key.data(),
|
||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
||||
license_.request.size());
|
||||
#ifndef HAS_ENTITLEMENT
|
||||
if (result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
|
||||
const KeyId key_id = golden_data_.GetFreeId();
|
||||
auto& content = golden_data_.EntitlementContent();
|
||||
ASSERT_EQ(WB_License_LoadEntitledContentKey(
|
||||
whitebox_,
|
||||
content.entitlement_key.id.data(),
|
||||
content.entitlement_key.id.size(),
|
||||
key_id.data(),
|
||||
key_id.size(),
|
||||
content.key_data_iv.data(),
|
||||
content.key_data_iv.size(),
|
||||
content.key_data.data(),
|
||||
content.key_data.size()),
|
||||
WB_RESULT_OK);
|
||||
result = WB_License_LoadEntitledContentKey(
|
||||
whitebox_, content.entitlement_key.id.data(),
|
||||
content.entitlement_key.id.size(), key_id.data(), key_id.size(),
|
||||
content.key_data_iv.data(), content.key_data_iv.size(),
|
||||
content.key_data.data(), content.key_data.size());
|
||||
#ifndef HAS_ENTITLEMENT
|
||||
if (result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
|
||||
std::vector<uint8_t> decrypted(content.plaintext.size());
|
||||
size_t decrypted_size = decrypted.size();
|
||||
|
||||
@@ -54,7 +54,7 @@ class LicenseWhiteboxMaskedDecryptTest
|
||||
// Creates and loads a license. The license is created using |settings|
|
||||
// updated to include the test parameters. The license is loaded using
|
||||
// |provider_key_id|.
|
||||
void LoadLicense(const TestLicenseBuilder::Settings& settings,
|
||||
bool LoadLicense(const TestLicenseBuilder::Settings& settings,
|
||||
size_t provider_key_id) {
|
||||
TestLicenseBuilder builder;
|
||||
builder.SetSettings(settings);
|
||||
@@ -75,15 +75,19 @@ class LicenseWhiteboxMaskedDecryptTest
|
||||
License license;
|
||||
builder.Build(*server, &license);
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY,
|
||||
license.core_message.data(), license.core_message.size(),
|
||||
license.message.data(), license.message.size(),
|
||||
license.signature.data(), license.signature.size(),
|
||||
license.session_key.data(), license.session_key.size(),
|
||||
provider_key_id, license.request.data(), license.request.size()),
|
||||
WB_RESULT_OK);
|
||||
const auto result = WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license.core_message.data(),
|
||||
license.core_message.size(), license.message.data(),
|
||||
license.message.size(), license.signature.data(),
|
||||
license.signature.size(), license.session_key.data(),
|
||||
license.session_key.size(), provider_key_id, license.request.data(),
|
||||
license.request.size());
|
||||
#ifndef HAS_PROVIDER_KEYS
|
||||
if (provider_key_id != 0 && result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
return false;
|
||||
#endif
|
||||
EXPECT_EQ(result, WB_RESULT_OK);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need two special keys for this test, one that will be used for a
|
||||
@@ -106,7 +110,8 @@ class LicenseWhiteboxMaskedDecryptTest
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCbcDataInCbcMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -145,7 +150,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCbcDataInCbcMode) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyInPlaceCbc) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
memcpy(masked_text_.data(), golden_data_.CBCContent().ciphertext.data(),
|
||||
golden_data_.CBCContent().ciphertext.size());
|
||||
@@ -186,7 +192,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyInPlaceCbc) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCtrDataInCtrMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CTR,
|
||||
@@ -225,7 +232,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCtrDataInCtrMode) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyInPlaceCtr) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
memcpy(masked_text_.data(), golden_data_.CTRContent().ciphertext.data(),
|
||||
golden_data_.CTRContent().ciphertext.size());
|
||||
@@ -268,7 +276,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyInPlaceCtr) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCbcDataInCtrMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CTR,
|
||||
@@ -308,7 +317,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCbcDataInCtrMode) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCtrDataInCbcMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -346,7 +356,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, DecodeKeyWithCtrDataInCbcMode) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataInCbcMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -385,7 +396,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataInCbcMode) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataInCtrMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CTR,
|
||||
@@ -426,7 +438,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataInCtrMode) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataInCtrMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CTR,
|
||||
@@ -466,7 +479,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataInCtrMode) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataInCbcMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -504,7 +518,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataInCbcMode) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataAndPKCS8Padding) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kPKSC8;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -543,7 +558,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCbcDataAndPKCS8Padding) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataAndPKCS8Padding) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kPKSC8;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CTR,
|
||||
@@ -587,7 +603,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, CryptoKeyWithCtrDataAndPKCS8Padding) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, SuccessWithMultipleKeys) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -667,7 +684,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, SuccessWithMultipleKeys) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullWhitebox) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
nullptr, WB_CIPHER_MODE_CBC,
|
||||
@@ -684,7 +702,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullWhitebox) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForInvalidCipherMode) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
// In order to trick the compiler into letting us pass an invalid enum value
|
||||
// to WB__License_MaskedDecrypt(), we need to cast it. If we don't do this,
|
||||
@@ -706,7 +725,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForInvalidCipherMode) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullKeyId) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC, nullptr,
|
||||
@@ -722,7 +742,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullKeyId) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullZeroKeyIdSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -738,7 +759,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullZeroKeyIdSize) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullInputData) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -757,7 +779,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest,
|
||||
InvalidParameterForInvalidCBCInputDataSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -774,7 +797,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest,
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForZeroInputDataSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -790,7 +814,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForZeroInputDataSize) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullIV) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -807,7 +832,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullIV) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForInvalidIVSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -823,7 +849,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForInvalidIVSize) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullOutput) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_MaskedDecrypt(
|
||||
@@ -840,7 +867,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullOutput) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullOutputSize) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_MaskedDecrypt(
|
||||
@@ -860,7 +888,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidParameterForNullOutputSize) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, KeyUnavailableForMissingKeyId) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_MaskedDecrypt(whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -876,7 +905,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, KeyUnavailableForMissingKeyId) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, KeyUnavailableForNonContentKey) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC, non_content_key_id_.data(),
|
||||
@@ -895,7 +925,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest,
|
||||
InsufficientSecurityLevelForHardwareContentKey) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_MaskedDecrypt(whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -928,7 +959,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, InvalidState) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, BufferTooSmall) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
// Our ciphertext will be large enough that we should not need to worry about
|
||||
// using a constant here.
|
||||
@@ -955,7 +987,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, BufferTooSmall) {
|
||||
TEST_P(LicenseWhiteboxMaskedDecryptTest, SuccessForSubRangeUnmask) {
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -997,7 +1030,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, KeyUnavailableForInvalidKey) {
|
||||
// we just need an invalid key, so we use one way of invalidating the key.
|
||||
TestLicenseBuilder::Settings settings;
|
||||
settings.include_content_key_iv = false;
|
||||
LoadLicense(settings, provider_key_id_);
|
||||
if (!LoadLicense(settings, provider_key_id_))
|
||||
GTEST_SKIP();
|
||||
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
whitebox_, WB_CIPHER_MODE_CBC,
|
||||
@@ -1034,7 +1068,8 @@ TEST_P(LicenseWhiteboxMaskedDecryptTest, MismatchProviderKeyId) {
|
||||
}
|
||||
|
||||
TestLicenseBuilder::Settings settings;
|
||||
LoadLicense(settings, alternate_provider_key_id);
|
||||
if (!LoadLicense(settings, alternate_provider_key_id))
|
||||
GTEST_SKIP();
|
||||
|
||||
// Decryption should succeed, but the plaintext should be incorrect.
|
||||
ASSERT_EQ(WB_License_MaskedDecrypt(
|
||||
|
||||
@@ -95,14 +95,18 @@ TEST_P(LicenseWhiteboxProcessLicenseResponseBenchmark,
|
||||
WB_License_Create(init_data_.data(), init_data_.size(), &whitebox_),
|
||||
WB_RESULT_OK);
|
||||
|
||||
ASSERT_EQ(WB_License_ProcessLicenseResponse(
|
||||
const auto result = WB_License_ProcessLicenseResponse(
|
||||
whitebox_, key_mode_, license_.core_message.data(),
|
||||
license_.core_message.size(), license_.message.data(),
|
||||
license_.message.size(), license_.signature.data(),
|
||||
license_.signature.size(), license_.session_key.data(),
|
||||
license_.session_key.size(), provider_key_id_,
|
||||
license_.request.data(), license_.request.size()),
|
||||
WB_RESULT_OK);
|
||||
license_.session_key.size(), provider_key_id_, license_.request.data(),
|
||||
license_.request.size());
|
||||
#ifndef HAS_PROVIDER_KEYS
|
||||
if (provider_key_id_ != 0 && result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
|
||||
WB_License_Delete(whitebox_);
|
||||
|
||||
@@ -130,14 +134,18 @@ TEST_P(LicenseWhiteboxProcessLicenseResponseBenchmark,
|
||||
WB_License_Create(init_data_.data(), init_data_.size(), &whitebox_),
|
||||
WB_RESULT_OK);
|
||||
|
||||
ASSERT_EQ(WB_License_ProcessLicenseResponse(
|
||||
const auto result = WB_License_ProcessLicenseResponse(
|
||||
whitebox_, key_mode_, license_.core_message.data(),
|
||||
license_.core_message.size(), license_.message.data(),
|
||||
license_.message.size(), license_.signature.data(),
|
||||
license_.signature.size(), license_.session_key.data(),
|
||||
license_.session_key.size(), provider_key_id_,
|
||||
license_.request.data(), license_.request.size()),
|
||||
WB_RESULT_OK);
|
||||
license_.session_key.size(), provider_key_id_, license_.request.data(),
|
||||
license_.request.size());
|
||||
#ifndef HAS_PROVIDER_KEYS
|
||||
if (provider_key_id_ != 0 && result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
|
||||
sampler.Push(timer.Get());
|
||||
|
||||
@@ -163,14 +171,18 @@ TEST_P(LicenseWhiteboxProcessLicenseResponseBenchmark, ProcessLicenseResponse) {
|
||||
|
||||
timer.Reset();
|
||||
|
||||
ASSERT_EQ(WB_License_ProcessLicenseResponse(
|
||||
const auto result = WB_License_ProcessLicenseResponse(
|
||||
whitebox_, key_mode_, license_.core_message.data(),
|
||||
license_.core_message.size(), license_.message.data(),
|
||||
license_.message.size(), license_.signature.data(),
|
||||
license_.signature.size(), license_.session_key.data(),
|
||||
license_.session_key.size(), provider_key_id_,
|
||||
license_.request.data(), license_.request.size()),
|
||||
WB_RESULT_OK);
|
||||
license_.session_key.size(), provider_key_id_, license_.request.data(),
|
||||
license_.request.size());
|
||||
#ifndef HAS_PROVIDER_KEYS
|
||||
if (provider_key_id_ != 0 && result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
|
||||
sampler.Push(timer.Get());
|
||||
|
||||
|
||||
@@ -103,15 +103,18 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseTest,
|
||||
SuccessWithEntitlementKey) {
|
||||
UseLicenseWithEntitlementKey();
|
||||
|
||||
ASSERT_EQ(WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY,
|
||||
license_.core_message.data(), license_.core_message.size(),
|
||||
license_.message.data(), license_.message.size(),
|
||||
license_.signature.data(), license_.signature.size(),
|
||||
license_.session_key.data(), license_.session_key.size(),
|
||||
kNoProviderKeyId, license_.request.data(),
|
||||
license_.request.size()),
|
||||
WB_RESULT_OK);
|
||||
const auto result = WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
||||
license_.core_message.size(), license_.message.data(),
|
||||
license_.message.size(), license_.signature.data(),
|
||||
license_.signature.size(), license_.session_key.data(),
|
||||
license_.session_key.size(), kNoProviderKeyId, license_.request.data(),
|
||||
license_.request.size());
|
||||
#ifndef HAS_ENTITLEMENT
|
||||
if (result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
}
|
||||
|
||||
// If there were multiple signing keys (this can only happen if a license server
|
||||
@@ -163,15 +166,18 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseTest, SuccessWithProviderKey) {
|
||||
builder.AddContentKey(golden_data_.CBCContent().software_crypto_key);
|
||||
builder.Build(*server_, &license_);
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_ProcessLicenseResponse(
|
||||
const auto result = WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
||||
license_.core_message.size(), license_.message.data(),
|
||||
license_.message.size(), license_.signature.data(),
|
||||
license_.signature.size(), license_.session_key.data(),
|
||||
license_.session_key.size(), kProviderKeyId, license_.request.data(),
|
||||
license_.request.size()),
|
||||
WB_RESULT_OK);
|
||||
license_.request.size());
|
||||
#ifndef HAS_PROVIDER_KEYS
|
||||
if (result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
}
|
||||
|
||||
TEST_F(LicenseWhiteboxProcessLicenseResponseTest, InvalidProviderKey) {
|
||||
@@ -181,15 +187,18 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseTest, InvalidProviderKey) {
|
||||
const size_t kInvalidProviderKey = 0xfff;
|
||||
UseLicenseWithSigningKey(TestLicenseBuilder::Padding::kNone);
|
||||
|
||||
ASSERT_EQ(
|
||||
WB_License_ProcessLicenseResponse(
|
||||
const auto result = WB_License_ProcessLicenseResponse(
|
||||
whitebox_, WB_LICENSE_KEY_MODE_DUAL_KEY, license_.core_message.data(),
|
||||
license_.core_message.size(), license_.message.data(),
|
||||
license_.message.size(), license_.signature.data(),
|
||||
license_.signature.size(), license_.session_key.data(),
|
||||
license_.session_key.size(), kInvalidProviderKey,
|
||||
license_.request.data(), license_.request.size()),
|
||||
WB_RESULT_OK);
|
||||
license_.session_key.size(), kInvalidProviderKey, license_.request.data(),
|
||||
license_.request.size());
|
||||
#ifndef HAS_PROVIDER_KEYS
|
||||
if (result == WB_RESULT_NOT_IMPLEMENTED)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
}
|
||||
|
||||
class LicenseWhiteboxProcessLicenseResponseErrorTest
|
||||
|
||||
95
whitebox/api/license_whitebox_proxy_impl.cc
Normal file
95
whitebox/api/license_whitebox_proxy_impl.cc
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright 2022 Google LLC. All Rights Reserved.
|
||||
|
||||
#include "api/license_whitebox.h"
|
||||
#include "api/license_whitebox_provider_keys_test_data.h"
|
||||
|
||||
// This file contains definitions of the new whitebox API functions that proxy
|
||||
// to older versions of the API to allow running tests against old
|
||||
// implementations. These functions are marked with WEAK to make sure they are
|
||||
// only used in the final binary if another definition doesn't appear.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// MSVC handles weak symbols the way we want, so we don't need to define
|
||||
// anything.
|
||||
# define WEAK
|
||||
#elif defined(__GNUC__)
|
||||
# define WEAK __attribute__((weak))
|
||||
#else
|
||||
# error "Unknown compiler"
|
||||
#endif
|
||||
|
||||
WEAK WB_Result WB_License_Create(WB_License_Whitebox** whitebox);
|
||||
WEAK WB_Result
|
||||
WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox,
|
||||
WB_LicenseKeyMode license_key_mode,
|
||||
const uint8_t* core_message,
|
||||
size_t core_message_size,
|
||||
const uint8_t* message,
|
||||
size_t message_size,
|
||||
const uint8_t* signature,
|
||||
size_t signature_size,
|
||||
const uint8_t* session_key,
|
||||
size_t session_key_size,
|
||||
const uint8_t* license_request,
|
||||
size_t license_request_size);
|
||||
|
||||
WEAK WB_Result WB_License_Create(const uint8_t* whitebox_init_data,
|
||||
size_t whitebox_init_data_size,
|
||||
WB_License_Whitebox** whitebox) {
|
||||
if (whitebox_init_data_size && !whitebox_init_data) {
|
||||
return WB_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return WB_License_Create(whitebox);
|
||||
}
|
||||
|
||||
WEAK WB_Result WB_License_ProcessLicenseResponse(
|
||||
WB_License_Whitebox* whitebox, WB_LicenseKeyMode license_key_mode,
|
||||
const uint8_t* core_message, size_t core_message_size,
|
||||
const uint8_t* message, size_t message_size, const uint8_t* signature,
|
||||
size_t signature_size, const uint8_t* session_key, size_t session_key_size,
|
||||
size_t provider_key_id, const uint8_t* license_request,
|
||||
size_t license_request_size) {
|
||||
if (provider_key_id != 0) {
|
||||
return WB_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return WB_License_ProcessLicenseResponse(
|
||||
whitebox, license_key_mode, core_message, core_message_size, message,
|
||||
message_size, signature, signature_size, session_key, session_key_size,
|
||||
license_request, license_request_size);
|
||||
}
|
||||
|
||||
WEAK WB_Result
|
||||
WB_License_LoadEntitledContentKey(WB_License_Whitebox* whitebox,
|
||||
const uint8_t* entitlement_key_id,
|
||||
size_t entitlement_key_id_size,
|
||||
const uint8_t* content_key_id,
|
||||
size_t content_key_id_size,
|
||||
const uint8_t* iv,
|
||||
size_t iv_size,
|
||||
const uint8_t* key_data,
|
||||
size_t key_data_size) {
|
||||
return WB_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
WEAK WB_Result WB_License_SignPstReport(const WB_License_Whitebox* whitebox,
|
||||
const uint8_t* message,
|
||||
size_t message_size,
|
||||
uint8_t* signature,
|
||||
size_t* signature_size) {
|
||||
return WB_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
namespace widevine {
|
||||
|
||||
WEAK std::vector<uint8_t> GetLicenseWhiteboxProviderKeysInitData() {
|
||||
// Note that for some reason, this replaces the reference implementation,
|
||||
// even though the others don't. So this function means we can't use this
|
||||
// file with the reference implementation.
|
||||
|
||||
// Return a non-empty buffer so we can check whether the data is passed for
|
||||
// a test.
|
||||
return {1};
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
@@ -122,7 +122,11 @@ TEST_P(LicenseWhiteboxQueryContentKeyStatus, ValidMaskedDecryptKey) {
|
||||
masked_decrypt_key_->id.size(), &key_state),
|
||||
WB_RESULT_OK);
|
||||
|
||||
#ifdef ALWAYS_DECRYPT_TO_CLEAR
|
||||
ASSERT_EQ(key_state, WB_KEY_STATUS_CONTENT_KEY_DECRYPT);
|
||||
#else
|
||||
ASSERT_EQ(key_state, WB_KEY_STATUS_CONTENT_KEY_MASKED_DECRYPT);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_P(LicenseWhiteboxQueryContentKeyStatus, NoKeyForNoId) {
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
namespace widevine {
|
||||
|
||||
constexpr const bool kRenewal = true;
|
||||
|
||||
class LicenseWhiteboxSignRenewalPstTest
|
||||
: public LicenseWhiteboxTestBase,
|
||||
public testing::WithParamInterface<bool> {
|
||||
@@ -26,8 +28,8 @@ class LicenseWhiteboxSignRenewalPstTest
|
||||
signature_size_ = 256;
|
||||
signature_.resize(signature_size_);
|
||||
|
||||
sign_func_ =
|
||||
GetParam() ? &WB_License_SignRenewalRequest : &WB_License_SignPstReport;
|
||||
sign_func_ = GetParam() == kRenewal ? &WB_License_SignRenewalRequest
|
||||
: &WB_License_SignPstReport;
|
||||
}
|
||||
|
||||
void LoadLicense(const TestLicenseBuilder::Settings& settings) {
|
||||
@@ -63,7 +65,8 @@ class LicenseWhiteboxSignRenewalPstTest
|
||||
std::string key_str(signing_key_.begin(), signing_key_.end());
|
||||
key_str.erase(0, crypto_util::kSigningKeySizeBytes);
|
||||
|
||||
auto func = GetParam() ? &widevine::crypto_util::CreateSignatureHmacSha256
|
||||
auto func = GetParam() == kRenewal
|
||||
? &widevine::crypto_util::CreateSignatureHmacSha256
|
||||
: &widevine::crypto_util::CreateSignatureHmacSha1;
|
||||
const std::string signature =
|
||||
func(key_str, std::string(message.begin(), message.end()));
|
||||
@@ -97,10 +100,15 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, SuccessWithInvalidRequest) {
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings);
|
||||
|
||||
ASSERT_EQ(
|
||||
const auto result =
|
||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||
signature_.data(), &signature_size_),
|
||||
WB_RESULT_OK);
|
||||
signature_.data(), &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
|
||||
signature_.resize(signature_size_);
|
||||
ASSERT_EQ(signature_, GetSignature(garbage_request_));
|
||||
@@ -111,10 +119,15 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, SuccessWithSigningKeyPKSC8Padding) {
|
||||
settings.padding = TestLicenseBuilder::Padding::kPKSC8;
|
||||
LoadLicense(settings);
|
||||
|
||||
ASSERT_EQ(
|
||||
const auto result =
|
||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||
signature_.data(), &signature_size_),
|
||||
WB_RESULT_OK);
|
||||
signature_.data(), &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_OK);
|
||||
|
||||
signature_.resize(signature_size_);
|
||||
ASSERT_EQ(signature_, GetSignature(garbage_request_));
|
||||
@@ -125,10 +138,15 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullWhitebox) {
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings);
|
||||
|
||||
ASSERT_EQ(
|
||||
const auto result =
|
||||
sign_func_(nullptr, garbage_request_.data(), garbage_request_.size(),
|
||||
signature_.data(), &signature_size_),
|
||||
WB_RESULT_INVALID_PARAMETER);
|
||||
signature_.data(), &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullMessage) {
|
||||
@@ -136,9 +154,14 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullMessage) {
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings);
|
||||
|
||||
ASSERT_EQ(sign_func_(whitebox_, nullptr, garbage_request_.size(),
|
||||
signature_.data(), &signature_size_),
|
||||
WB_RESULT_INVALID_PARAMETER);
|
||||
const auto result = sign_func_(whitebox_, nullptr, garbage_request_.size(),
|
||||
signature_.data(), &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForZeroMessageSize) {
|
||||
@@ -146,9 +169,14 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForZeroMessageSize) {
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings);
|
||||
|
||||
ASSERT_EQ(sign_func_(whitebox_, garbage_request_.data(), 0, signature_.data(),
|
||||
&signature_size_),
|
||||
WB_RESULT_INVALID_PARAMETER);
|
||||
const auto result = sign_func_(whitebox_, garbage_request_.data(), 0,
|
||||
signature_.data(), &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, CanProbeSizeWithNullSignature) {
|
||||
@@ -157,9 +185,15 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, CanProbeSizeWithNullSignature) {
|
||||
LoadLicense(settings);
|
||||
signature_size_ = 0;
|
||||
|
||||
ASSERT_EQ(sign_func_(whitebox_, garbage_request_.data(),
|
||||
garbage_request_.size(), nullptr, &signature_size_),
|
||||
WB_RESULT_BUFFER_TOO_SMALL);
|
||||
const auto result =
|
||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||
nullptr, &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_BUFFER_TOO_SMALL);
|
||||
ASSERT_GT(signature_size_, 0);
|
||||
}
|
||||
|
||||
@@ -168,9 +202,15 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidParameterForNullSignature) {
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings);
|
||||
|
||||
ASSERT_EQ(sign_func_(whitebox_, garbage_request_.data(),
|
||||
garbage_request_.size(), nullptr, &signature_size_),
|
||||
WB_RESULT_INVALID_PARAMETER);
|
||||
const auto result =
|
||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||
nullptr, &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
TEST_P(LicenseWhiteboxSignRenewalPstTest,
|
||||
@@ -179,9 +219,15 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest,
|
||||
settings.padding = TestLicenseBuilder::Padding::kNone;
|
||||
LoadLicense(settings);
|
||||
|
||||
ASSERT_EQ(sign_func_(whitebox_, garbage_request_.data(),
|
||||
garbage_request_.size(), signature_.data(), nullptr),
|
||||
WB_RESULT_INVALID_PARAMETER);
|
||||
const auto result =
|
||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||
signature_.data(), nullptr);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, BufferTooSmall) {
|
||||
@@ -194,10 +240,15 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, BufferTooSmall) {
|
||||
// "too small".
|
||||
signature_size_ = 1;
|
||||
|
||||
ASSERT_EQ(
|
||||
const auto result =
|
||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||
signature_.data(), &signature_size_),
|
||||
WB_RESULT_BUFFER_TOO_SMALL);
|
||||
signature_.data(), &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_BUFFER_TOO_SMALL);
|
||||
|
||||
// Since the API does not limit the signature size, we can't specify the
|
||||
// actual expected size, however, it should at least be greater than our "too
|
||||
@@ -210,10 +261,15 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, InvalidStateForNoLicense) {
|
||||
// have no license loaded in order to have no renewal key, which is the
|
||||
// criteria WB_RESULT_INVALID_STATE.
|
||||
|
||||
ASSERT_EQ(
|
||||
const auto result =
|
||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||
signature_.data(), &signature_size_),
|
||||
WB_RESULT_INVALID_STATE);
|
||||
signature_.data(), &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_INVALID_STATE);
|
||||
}
|
||||
|
||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, KeyUnavailableForNoSigningKey) {
|
||||
@@ -237,10 +293,15 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, KeyUnavailableForNoSigningKey) {
|
||||
license.request.size()),
|
||||
WB_RESULT_OK);
|
||||
|
||||
ASSERT_EQ(
|
||||
const auto result =
|
||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||
signature_.data(), &signature_size_),
|
||||
WB_RESULT_KEY_UNAVAILABLE);
|
||||
signature_.data(), &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_KEY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
TEST_P(LicenseWhiteboxSignRenewalPstTest, KeyUnavailableForInvalidKey) {
|
||||
@@ -251,17 +312,22 @@ TEST_P(LicenseWhiteboxSignRenewalPstTest, KeyUnavailableForInvalidKey) {
|
||||
settings.include_signing_key_iv = false;
|
||||
LoadLicense(settings);
|
||||
|
||||
ASSERT_EQ(
|
||||
const auto result =
|
||||
sign_func_(whitebox_, garbage_request_.data(), garbage_request_.size(),
|
||||
signature_.data(), &signature_size_),
|
||||
WB_RESULT_KEY_UNAVAILABLE);
|
||||
signature_.data(), &signature_size_);
|
||||
#ifndef HAS_SIGN_PST_REPORT
|
||||
if (GetParam() != kRenewal && result == WB_RESULT_NOT_IMPLEMENTED) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
#endif
|
||||
ASSERT_EQ(result, WB_RESULT_KEY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(TestAll,
|
||||
LicenseWhiteboxSignRenewalPstTest,
|
||||
testing::Bool(),
|
||||
[](const testing::TestParamInfo<bool>& info) {
|
||||
return info.param ? "Renewal" : "PST";
|
||||
return info.param == kRenewal ? "Renewal" : "PST";
|
||||
});
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
@@ -35,6 +35,32 @@ enum class Mode {
|
||||
kMaskedDecryptFail,
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, Key key) {
|
||||
switch (key) {
|
||||
case Key::kCrypto:
|
||||
return os << "SW_SECURE_CRYPTO";
|
||||
case Key::kDecode:
|
||||
return os << "SW_SECURE_DECODE";
|
||||
case Key::kHardware:
|
||||
return os << "HW_SECURE_DECODE";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, Mode mode) {
|
||||
switch (mode) {
|
||||
case Mode::kDecryptPass:
|
||||
return os << "DecryptPass";
|
||||
case Mode::kDecryptFail:
|
||||
return os << "DecryptFail";
|
||||
case Mode::kMaskedDecryptPass:
|
||||
return os << "MaskedDecryptPass";
|
||||
case Mode::kMaskedDecryptFail:
|
||||
return os << "MaskedDecryptFail";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
// WV_ENABLE_HW_VERIFICATION = 0: prevent VMP/RA from overriding the key
|
||||
// security level.
|
||||
//
|
||||
@@ -58,9 +84,11 @@ Mode DisableOverrideForCrypto(Mode mode) {
|
||||
// it says that we could use it with decrypt. Remember, anything that works
|
||||
// with decrypt can work with masked decrypt, but not the other way around.
|
||||
Mode DisableOverrideForDecode(Mode mode) {
|
||||
#ifndef ALWAYS_DECRYPT_TO_CLEAR
|
||||
if (mode == Mode::kDecryptPass) {
|
||||
return Mode::kDecryptFail;
|
||||
}
|
||||
#endif
|
||||
|
||||
return mode;
|
||||
}
|
||||
@@ -107,6 +135,12 @@ class RemoteAttestationAndVerificationTest
|
||||
padding_ = std::get<0>(params);
|
||||
std::tie(key, ra_, vmp_, mode_) = std::get<1>(params);
|
||||
|
||||
#ifdef ALWAYS_DECRYPT_TO_CLEAR
|
||||
if (key == Key::kDecode) {
|
||||
if (mode_ == Mode::kDecryptFail) mode_ = Mode::kDecryptPass;
|
||||
}
|
||||
#endif
|
||||
|
||||
// These tests are written as "we are testing that VMP/RA can override the
|
||||
// key's security level". However, when the white-box does not have that
|
||||
// functionality, it should not be able to do that. As a simple way to test
|
||||
|
||||
@@ -39,6 +39,9 @@ typedef enum {
|
||||
// The input data failed to be verified. This may happen if the data was
|
||||
// corrupted or tampered.
|
||||
WB_RESULT_DATA_VERIFICATION_ERROR = 8,
|
||||
|
||||
// The method or settings aren't supported in this version of the whitebox.
|
||||
WB_RESULT_NOT_IMPLEMENTED = 9,
|
||||
} WB_Result;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#define WHITEBOX_API_LICENSE_BUILDER_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -152,6 +153,45 @@ class TestLicenseBuilder {
|
||||
std::vector<KeyId> operator_session_keys_;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
TestLicenseBuilder::Padding value) {
|
||||
switch (value) {
|
||||
case TestLicenseBuilder::Padding::kNone:
|
||||
return os << "NoPadding";
|
||||
case TestLicenseBuilder::Padding::kPKSC8:
|
||||
return os << "PKSC8";
|
||||
default:
|
||||
return os << "<Unknown Padding>";
|
||||
}
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
TestLicenseBuilder::RemoteAttestation value) {
|
||||
switch (value) {
|
||||
case TestLicenseBuilder::RemoteAttestation::kUnavailable:
|
||||
return os << "RA Unavailable";
|
||||
case TestLicenseBuilder::RemoteAttestation::kVerified:
|
||||
return os << "RA Verified";
|
||||
case TestLicenseBuilder::RemoteAttestation::kUnverified:
|
||||
return os << "RA Unverified";
|
||||
default:
|
||||
return os << "<Unknown RA>";
|
||||
}
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
TestLicenseBuilder::VerificationStatus value) {
|
||||
switch (value) {
|
||||
case TestLicenseBuilder::VerificationStatus::kUnavailable:
|
||||
return os << "Unverified";
|
||||
case TestLicenseBuilder::VerificationStatus::kHardwareVerified:
|
||||
return os << "HardwareVerified";
|
||||
default:
|
||||
return os << "VerifiedOther";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
#endif // WHITEBOX_API_LICENSE_BUILDER_H_
|
||||
|
||||
14
whitebox/defs.bzl
Normal file
14
whitebox/defs.bzl
Normal file
@@ -0,0 +1,14 @@
|
||||
# Copyright 2022 Google LLC. All Rights Reserved.
|
||||
|
||||
BuildType = provider(fields = ["type"])
|
||||
|
||||
# old/old_vmpra are used to test against the old API; this involves adding
|
||||
# compatibility proxies for old functions and not expecting any "extra" features
|
||||
possible_types = ["chrome", "chromeos", "ce", "old", "old_vmpra"]
|
||||
|
||||
def _impl(ctx):
|
||||
if ctx.build_setting_value not in possible_types:
|
||||
fail("Invalid build type: " + ctx.build_setting_value)
|
||||
return BuildType(type=ctx.build_setting_value)
|
||||
|
||||
build_type = rule(implementation=_impl, build_setting=config.string(flag=True))
|
||||
@@ -13,11 +13,7 @@ package(default_visibility = [
|
||||
#
|
||||
# test_aead_whitebox : The target for testing the AEAD white-box.
|
||||
#
|
||||
# general_license_whitebox_with_vmpra : The target for testing the license
|
||||
# white-box against generated licenses with VMP/RA functionality.
|
||||
#
|
||||
# general_license_whitebox_without_vmpra : The target for testing the license
|
||||
# white-box against generated licenses without VMP/RA functionality.
|
||||
# general_license_whitebox: The target for testing the license white-box.
|
||||
#
|
||||
# uat_license_whitebox : The target for testing the license white-box against
|
||||
# licenses from Widevine's UAT server.
|
||||
@@ -32,6 +28,7 @@ cc_library(
|
||||
hdrs = ["odk.h"],
|
||||
deps = [
|
||||
"//api:result",
|
||||
"//api:shared_settings",
|
||||
"//chromium_deps/base:glog",
|
||||
"//external:odk",
|
||||
],
|
||||
@@ -41,6 +38,7 @@ cc_library(
|
||||
name = "memory_util",
|
||||
srcs = ["memory_util.cc"],
|
||||
hdrs = ["memory_util.h"],
|
||||
deps = ["//api:shared_settings"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -48,6 +46,7 @@ cc_library(
|
||||
hdrs = ["content_key.h"],
|
||||
deps = [
|
||||
"//api:license_whitebox",
|
||||
"//api:shared_settings",
|
||||
"//chromium_deps/cdm/protos:license_protocol_proto",
|
||||
],
|
||||
)
|
||||
@@ -69,6 +68,7 @@ cc_library(
|
||||
":odk",
|
||||
":renewal_key",
|
||||
"//api:result",
|
||||
"//api:shared_settings",
|
||||
"//chromium_deps/cdm/protos:license_protocol_proto",
|
||||
"//crypto_utils:aes_cbc_decryptor",
|
||||
"//crypto_utils:crypto_util",
|
||||
@@ -81,49 +81,19 @@ cc_library(
|
||||
hdrs = ["odk_license_parser.h"],
|
||||
deps = [
|
||||
":license_parser",
|
||||
"//api:shared_settings",
|
||||
"//chromium_deps/base:glog",
|
||||
"//crypto_utils:crypto_util",
|
||||
],
|
||||
)
|
||||
|
||||
# For the protobuf license parser, we need to have three targets:
|
||||
# 1. The header target
|
||||
# 2. The VMP/RA enabled target
|
||||
# 3. The VMP/RA disabled target
|
||||
#
|
||||
# The header target is needed so that we can defer which parser we are going to
|
||||
# support until the top-level target.
|
||||
#
|
||||
# The two implementation targets are created (as near copies) to avoid issues
|
||||
# around when the define is resolved.
|
||||
cc_library(
|
||||
name = "protobuf_license_parser",
|
||||
hdrs = ["protobuf_license_parser.h"],
|
||||
deps = [
|
||||
":license_parser",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "protobuf_license_parser_with_vmpra",
|
||||
srcs = ["protobuf_license_parser.cc"],
|
||||
defines = ["WV_ENABLE_HW_VERIFICATION=1"],
|
||||
deps = [
|
||||
":license_parser",
|
||||
":protobuf_license_parser",
|
||||
"//chromium_deps/base:glog",
|
||||
"//chromium_deps/cdm/protos:license_protocol_proto",
|
||||
"//crypto_utils:crypto_util",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "protobuf_license_parser_without_vmpra",
|
||||
srcs = ["protobuf_license_parser.cc"],
|
||||
defines = ["WV_ENABLE_HW_VERIFICATION=0"],
|
||||
deps = [
|
||||
":license_parser",
|
||||
":protobuf_license_parser",
|
||||
"//api:shared_settings",
|
||||
"//chromium_deps/base:glog",
|
||||
"//chromium_deps/cdm/protos:license_protocol_proto",
|
||||
"//crypto_utils:crypto_util",
|
||||
@@ -140,6 +110,7 @@ cc_library(
|
||||
srcs = ["private_keys.cc"],
|
||||
hdrs = ["private_keys.h"],
|
||||
deps = [
|
||||
"//api:shared_settings",
|
||||
"//api:test_license_whitebox_keys",
|
||||
],
|
||||
)
|
||||
@@ -153,6 +124,7 @@ cc_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api:license_whitebox_provider_keys_test_data",
|
||||
"//api:shared_settings",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -172,6 +144,7 @@ cc_library(
|
||||
"//api:aead_test_data",
|
||||
"//api:aead_whitebox",
|
||||
"//api:result",
|
||||
"//api:shared_settings",
|
||||
"//chromium_deps/third_party/boringssl",
|
||||
"//crypto_utils:crypto_util",
|
||||
],
|
||||
@@ -197,6 +170,7 @@ cc_library(
|
||||
":protobuf_license_parser",
|
||||
"//api:license_whitebox",
|
||||
"//api:result",
|
||||
"//api:shared_settings",
|
||||
"//chromium_deps/cdm/keys:dev_certs",
|
||||
"//chromium_deps/cdm/protos:license_protocol_proto",
|
||||
"//crypto_utils:aes_cbc_decryptor",
|
||||
@@ -208,21 +182,12 @@ cc_library(
|
||||
|
||||
# These targets provid the license whitebox for all general tests.
|
||||
cc_library(
|
||||
name = "general_license_whitebox_with_vmpra",
|
||||
name = "general_license_whitebox",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":license_whitebox_core",
|
||||
":protobuf_license_parser_with_vmpra",
|
||||
"//api:test_license_whitebox_keys_general",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "general_license_whitebox_without_vmpra",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":license_whitebox_core",
|
||||
":protobuf_license_parser_without_vmpra",
|
||||
":protobuf_license_parser",
|
||||
"//api:shared_settings",
|
||||
"//api:test_license_whitebox_keys_general",
|
||||
],
|
||||
)
|
||||
@@ -234,7 +199,8 @@ cc_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":license_whitebox_core",
|
||||
":protobuf_license_parser_with_vmpra",
|
||||
":protobuf_license_parser",
|
||||
"//api:shared_settings",
|
||||
"//api:test_license_whitebox_keys_uat",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -88,7 +88,11 @@ WB_KeyStatus LicenseParser::GetKeyStatus(
|
||||
case video_widevine::License_KeyContainer_SecurityLevel_SW_SECURE_CRYPTO:
|
||||
return WB_KEY_STATUS_CONTENT_KEY_DECRYPT;
|
||||
case video_widevine::License_KeyContainer_SecurityLevel_SW_SECURE_DECODE:
|
||||
#ifdef ALWAYS_DECRYPT_TO_CLEAR
|
||||
return WB_KEY_STATUS_CONTENT_KEY_DECRYPT;
|
||||
#else
|
||||
return WB_KEY_STATUS_CONTENT_KEY_MASKED_DECRYPT;
|
||||
#endif
|
||||
default:
|
||||
// For example, this could be a hardware key - a valid key but can't be
|
||||
// used by the CDM. However, this may get override later if the device is
|
||||
|
||||
@@ -9,45 +9,48 @@
|
||||
#include "base/logging.h"
|
||||
#include "oemcrypto/odk/include/OEMCryptoCENCCommon.h"
|
||||
#include "oemcrypto/odk/include/odk.h"
|
||||
#include "oemcrypto/odk/include/odk_message.h"
|
||||
#include "oemcrypto/odk/src/odk_serialize.h"
|
||||
#include "oemcrypto/odk/src/serialization_base.h"
|
||||
#include "oemcrypto/odk/include/odk_structs.h"
|
||||
|
||||
// Most of the logic to parse the core message comes from `ODK_ParseResponse()`.
|
||||
// We copy the logic since the function as a whole is not compatible with what
|
||||
// we need to do here.
|
||||
WB_Result GetODKContext(const std::string& combined_message,
|
||||
size_t core_message_size,
|
||||
ODKContext* context) {
|
||||
// ODK_Message requires a mutable buffer and the buffer must exist as long as
|
||||
// the message exists.
|
||||
std::vector<uint8_t> mutable_message(combined_message.begin(),
|
||||
combined_message.end());
|
||||
ODK_TimerLimits timer;
|
||||
ODK_ClockValues clock;
|
||||
ODK_NonceValues nonce;
|
||||
|
||||
ODK_Message msg =
|
||||
ODK_Message_Create(mutable_message.data(), mutable_message.size());
|
||||
ODK_Message_SetSize(&msg, core_message_size);
|
||||
|
||||
ODK_LicenseResponse license_response{{{0, 0, {}}}, nullptr, {0}};
|
||||
license_response.parsed_license = &(context->license);
|
||||
|
||||
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;
|
||||
OEMCryptoResult result = ODK_InitializeSessionValues(
|
||||
&timer, &clock, &nonce, ODK_MAJOR_VERSION, /* session_id= */ 0);
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
DVLOG(1) << "Error initializing ODK structs: " << result;
|
||||
return WB_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
const auto& core_message = license_response.request.core_message;
|
||||
|
||||
if (core_message.message_type != ODK_License_Response_Type) {
|
||||
DVLOG(1) << "Failed core message type: " << core_message.message_type;
|
||||
// By using initial_license_load==false, ODK won't validate the nonce.
|
||||
#if ODK_MAJOR_VERSION == 16
|
||||
uint8_t request_hash[16];
|
||||
#endif
|
||||
for (bool usage_entry_present : {false, true}) {
|
||||
// Parse using both values for |usage_entry_present|, it needs to match the
|
||||
// license request, but we don't know it here. This avoids an extra
|
||||
// argument and allows us to use ODK_ParseLicense. The value will be
|
||||
// verified by the caller.
|
||||
result = ODK_ParseLicense(
|
||||
reinterpret_cast<const uint8_t*>(combined_message.c_str()),
|
||||
combined_message.size(), core_message_size,
|
||||
/* initial_license_load= */ false, usage_entry_present,
|
||||
#if ODK_MAJOR_VERSION == 16
|
||||
request_hash,
|
||||
#endif
|
||||
&timer, &clock, &nonce, &context->license);
|
||||
if (result != ODK_ERROR_CORE_MESSAGE) break;
|
||||
}
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
DVLOG(1) << "Error parsing license response: " << result;
|
||||
return WB_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
context->major_version = core_message.nonce_values.api_major_version;
|
||||
context->minor_version = core_message.nonce_values.api_minor_version;
|
||||
context->major_version = nonce.api_major_version;
|
||||
context->minor_version = nonce.api_minor_version;
|
||||
|
||||
// Now that it is initialized, mark it as valid.
|
||||
context->is_valid = true;
|
||||
|
||||
@@ -201,6 +201,10 @@ InternalKey OdkLicenseParser::ParseInternalKey(
|
||||
}
|
||||
|
||||
const std::string key_control_block = ExtractItem(key.key_control, message);
|
||||
if (key_control_block.empty()) {
|
||||
VLOG(3) << "Empty key control block.";
|
||||
return InternalKey();
|
||||
}
|
||||
|
||||
video_widevine::License_KeyContainer_SecurityLevel security_level;
|
||||
CHECK(ExtractLevel(key_control_block, &security_level));
|
||||
|
||||
@@ -13,11 +13,7 @@ package(default_visibility = [
|
||||
#
|
||||
# test_aead_whitebox : The target for testing the AEAD white-box.
|
||||
#
|
||||
# general_license_whitebox_with_vmpra : The target for testing the license
|
||||
# white-box against generated licenses with VMP/RA functionality.
|
||||
#
|
||||
# general_license_whitebox_without_vmpra : The target for testing the license
|
||||
# white-box against generated licenses without VMP/RA functionality.
|
||||
# general_license_whitebox: The target for testing the license white-box.
|
||||
#
|
||||
# uat_license_whitebox : The target for testing the license white-box against
|
||||
# licenses from Widevine's UAT server.
|
||||
@@ -53,27 +49,17 @@ cc_test(
|
||||
size = "small",
|
||||
deps = [
|
||||
"//api:license_whitebox_test",
|
||||
"//reference/impl:general_license_whitebox_without_vmpra",
|
||||
"//reference/impl:general_license_whitebox",
|
||||
"//reference/impl:license_whitebox_provider_keys_test_data"
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "remote_attestation_and_verification_with_vmpra_test",
|
||||
name = "remote_attestation_and_verification_test",
|
||||
size = "small",
|
||||
deps = [
|
||||
"//api:remote_attestation_and_verification_with_vmpra_test",
|
||||
"//reference/impl:general_license_whitebox_with_vmpra",
|
||||
"//reference/impl:license_whitebox_provider_keys_test_data"
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "remote_attestation_and_verification_without_vmpra_test",
|
||||
size = "small",
|
||||
deps = [
|
||||
"//api:remote_attestation_and_verification_without_vmpra_test",
|
||||
"//reference/impl:general_license_whitebox_without_vmpra",
|
||||
"//api:remote_attestation_and_verification_test",
|
||||
"//reference/impl:general_license_whitebox",
|
||||
"//reference/impl:license_whitebox_provider_keys_test_data"
|
||||
],
|
||||
)
|
||||
@@ -83,7 +69,7 @@ cc_test(
|
||||
size = "small",
|
||||
deps = [
|
||||
"//api:license_whitebox_benchmark",
|
||||
"//reference/impl:general_license_whitebox_without_vmpra",
|
||||
"//reference/impl:general_license_whitebox",
|
||||
"//reference/impl:license_whitebox_provider_keys_test_data"
|
||||
],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user