From 8ff9df8eebef5ddfa3a48fb8a0fa1b5e8a7d660d Mon Sep 17 00:00:00 2001 From: Aaron Vaage Date: Fri, 4 Dec 2020 14:25:24 -0800 Subject: [PATCH] Remove Init Data From WB_License_Create Rather than having init data for the license white-box be passed in via WB_License_Create, this changes it so that it is assumed that the private key is compiled into the white-box code. Minor changes in this code drop include: - Updating the git attributes to avoid line-ending conflicts between different operating systems - Resolving a linking issue seen on Windows - Removing default parameter for padding in conformance tests --- whitebox/.gitattributes | 9 + whitebox/api/BUILD | 36 +- .../api/{test_data.h => aead_test_data.h} | 16 +- whitebox/api/aead_whitebox.h | 33 +- whitebox/api/aead_whitebox_benchmark.cc | 2 +- whitebox/api/aead_whitebox_create_test.cc | 6 +- .../api/aead_whitebox_cross_instance_test.cc | 7 +- whitebox/api/aead_whitebox_decrypt_test.cc | 7 +- whitebox/api/aead_whitebox_encrypt_test.cc | 6 +- whitebox/api/export.h | 12 - whitebox/api/license_whitebox.h | 138 +++--- whitebox/api/license_whitebox_benchmark.cc | 9 +- .../api/license_whitebox_chromeos_test.cc | 9 +- whitebox/api/license_whitebox_create_test.cc | 35 +- .../api/license_whitebox_decrypt_benchmark.cc | 5 +- whitebox/api/license_whitebox_decrypt_test.cc | 1 - ...license_whitebox_get_secret_string_test.cc | 10 +- .../api/license_whitebox_golden_data_test.cc | 4 +- .../license_whitebox_masked_decrypt_test.cc | 16 +- ...ebox_process_license_response_benchmark.cc | 15 +- ..._whitebox_process_license_response_test.cc | 4 +- .../api/license_whitebox_sign_benchmark.cc | 5 +- ...ense_whitebox_sign_license_request_test.cc | 1 - ...ense_whitebox_sign_renewal_request_test.cc | 1 - whitebox/api/license_whitebox_test_base.cc | 8 +- .../api/license_whitebox_verify_benchmark.cc | 5 +- ...e_whitebox_verify_renewal_response_test.cc | 1 - whitebox/api/test_license_builder.h | 4 +- whitebox/api/test_public_key.h | 17 + whitebox/impl/reference/BUILD | 34 +- whitebox/impl/reference/aead_test_data.cc | 24 + whitebox/impl/reference/aead_whitebox_impl.cc | 430 +++++++++--------- whitebox/impl/reference/license_private_key.h | 16 + whitebox/impl/reference/license_test_data.cc | 23 + .../license_whitebox_golden_data_init_data.cc | 210 ++++----- .../impl/reference/license_whitebox_impl.cc | 24 +- whitebox/impl/reference/test_data.cc | 42 -- 37 files changed, 609 insertions(+), 616 deletions(-) create mode 100644 whitebox/.gitattributes rename whitebox/api/{test_data.h => aead_test_data.h} (55%) delete mode 100644 whitebox/api/export.h create mode 100644 whitebox/api/test_public_key.h create mode 100644 whitebox/impl/reference/aead_test_data.cc create mode 100644 whitebox/impl/reference/license_private_key.h create mode 100644 whitebox/impl/reference/license_test_data.cc delete mode 100644 whitebox/impl/reference/test_data.cc diff --git a/whitebox/.gitattributes b/whitebox/.gitattributes new file mode 100644 index 0000000..24ab300 --- /dev/null +++ b/whitebox/.gitattributes @@ -0,0 +1,9 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.cc text +*.h text +*.txt text diff --git a/whitebox/api/BUILD b/whitebox/api/BUILD index bc0ac92..d1ef59d 100644 --- a/whitebox/api/BUILD +++ b/whitebox/api/BUILD @@ -10,12 +10,6 @@ cc_library( visibility = ["//visibility:public"], ) -cc_library( - name = "export", - hdrs = ["export.h"], - visibility = ["//visibility:private"], -) - cc_library( name = "aead_whitebox", hdrs = [ @@ -23,7 +17,6 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ - ":export", ":result", ], ) @@ -35,16 +28,24 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ - ":export", ":result", ], ) cc_library( - name = "test_data", + name = "test_public_key", testonly = True, hdrs = [ - "test_data.h", + "test_public_key.h", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "aead_test_data", + testonly = True, + hdrs = [ + "aead_test_data.h", ], visibility = ["//visibility:public"], ) @@ -90,10 +91,11 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ + ":aead_test_data", ":aead_whitebox", - ":test_data", "//chromium_deps/testing", ], + alwayslink = True, ) cc_library( @@ -104,13 +106,14 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ + ":aead_test_data", ":aead_whitebox", - ":test_data", "//benchmarking:data_source", "//benchmarking:measurements", "//chromium_deps/base:glog", "//chromium_deps/testing", ], + alwayslink = True, ) cc_library( @@ -134,15 +137,17 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ + ":aead_test_data", ":golden_data", ":license_whitebox", - ":test_data", ":test_license_builder", + ":test_public_key", "//chromium_deps/cdm/keys:api", "//chromium_deps/cdm/protos:license_protocol_proto", "//chromium_deps/testing", "//crypto_utils:rsa_key", ], + alwayslink = True, ) cc_library( @@ -160,15 +165,17 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ + ":aead_test_data", ":license_whitebox", - ":test_data", ":test_license_builder", + ":test_public_key", "//benchmarking:data_source", "//benchmarking:measurements", "//chromium_deps/base:glog", "//chromium_deps/testing", "//crypto_utils:crypto_util", ], + alwayslink = True, ) cc_library( @@ -182,4 +189,5 @@ cc_library( ":license_whitebox", "//chromium_deps/testing", ], + alwayslink = True, ) diff --git a/whitebox/api/test_data.h b/whitebox/api/aead_test_data.h similarity index 55% rename from whitebox/api/test_data.h rename to whitebox/api/aead_test_data.h index 117d2b2..a168edc 100644 --- a/whitebox/api/test_data.h +++ b/whitebox/api/aead_test_data.h @@ -1,27 +1,23 @@ // Copyright 2020 Google LLC. All Rights Reserved. -#ifndef WHITEBOX_API_TEST_DATA_H_ -#define WHITEBOX_API_TEST_DATA_H_ +#ifndef WHITEBOX_API_AEAD_TEST_DATA_H_ +#define WHITEBOX_API_AEAD_TEST_DATA_H_ #include #include +namespace widevine { + // Returns init data that the aead white-box will accept. std::vector GetValidAeadInitData(); // Returns init data that the aead white-box will reject. std::vector GetInvalidAeadInitData(); -// Returns valid init_data needed by the license whitebox tests when calling -// WB_License_Create(). -std::vector GetLicenseInitData(); - // Returns the matching public key for the data returned by // GetLicenseInitData(). The format is a DER encoded PKCS#1 RSAPublicKey. std::vector GetMatchingLicensePublicKey(); -// Returns invalid non-empty init_data that should be rejected by -// WB_License_Create(). -std::vector GetInvalidLicenseInitData(); +} // namespace widevine -#endif // WHITEBOX_API_TEST_DATA_H_ +#endif // WHITEBOX_API_AEAD_TEST_DATA_H_ diff --git a/whitebox/api/aead_whitebox.h b/whitebox/api/aead_whitebox.h index cb9f5dc..28f39ef 100644 --- a/whitebox/api/aead_whitebox.h +++ b/whitebox/api/aead_whitebox.h @@ -6,7 +6,6 @@ #include #include -#include "api/export.h" #include "api/result.h" #ifdef __cplusplus @@ -43,11 +42,11 @@ typedef struct WB_Aead_Whitebox WB_Aead_Whitebox; // |context| was null, if |context_size| was zero, or if |whitebox| was null. // // WB_RESULT_OUT_OF_MEMORY if the necessary memory could not be allocated. -WB_API WB_Result WB_Aead_Create(const uint8_t* whitebox_init_data, - size_t whitebox_init_data_size, - const uint8_t* context, - size_t context_size, - WB_Aead_Whitebox** whitebox); +WB_Result WB_Aead_Create(const uint8_t* whitebox_init_data, + size_t whitebox_init_data_size, + const uint8_t* context, + size_t context_size, + WB_Aead_Whitebox** whitebox); // Releases all resources used by the white-box instance pointed to by // |whitebox|. @@ -55,7 +54,7 @@ WB_API WB_Result WB_Aead_Create(const uint8_t* whitebox_init_data, // Args: // whitebox (in) : A pointer to a white-box instance. Passing in null will // result in a no-op. -WB_API void WB_Aead_Delete(WB_Aead_Whitebox* whitebox); +void WB_Aead_Delete(WB_Aead_Whitebox* whitebox); // Encrypts |input_data| and writes the cipher data, nonce and the data // verification tag to |output_data|. The implementation should generate and use @@ -86,11 +85,11 @@ WB_API void WB_Aead_Delete(WB_Aead_Whitebox* whitebox); // // WB_RESULT_BUFFER_TOO_SMALL if |output_data_size| (as input) was less than // the required size. -WB_API WB_Result WB_Aead_Encrypt(const WB_Aead_Whitebox* whitebox, - const uint8_t* input_data, - size_t input_data_size, - uint8_t* output_data, - size_t* output_data_size); +WB_Result WB_Aead_Encrypt(const WB_Aead_Whitebox* whitebox, + const uint8_t* input_data, + size_t input_data_size, + uint8_t* output_data, + size_t* output_data_size); // Decrypts |input_data| and writes the plaintext to |output_data|. |input_data| // must have been encrypted using WB_Aead_Encrypt() with the same |whitebox|. @@ -120,11 +119,11 @@ WB_API WB_Result WB_Aead_Encrypt(const WB_Aead_Whitebox* whitebox, // // WB_RESULT_DATA_VERIFICATION_ERROR if |input_data| failed data verification. // The state of |output_data| is undefined. -WB_API WB_Result WB_Aead_Decrypt(const WB_Aead_Whitebox* whitebox, - const uint8_t* input_data, - size_t input_data_size, - uint8_t* output_data, - size_t* output_data_size); +WB_Result WB_Aead_Decrypt(const WB_Aead_Whitebox* whitebox, + const uint8_t* input_data, + size_t input_data_size, + uint8_t* output_data, + size_t* output_data_size); #ifdef __cplusplus } diff --git a/whitebox/api/aead_whitebox_benchmark.cc b/whitebox/api/aead_whitebox_benchmark.cc index 2ac2403..052b2ae 100644 --- a/whitebox/api/aead_whitebox_benchmark.cc +++ b/whitebox/api/aead_whitebox_benchmark.cc @@ -5,8 +5,8 @@ #include +#include "api/aead_test_data.h" #include "api/aead_whitebox.h" -#include "api/test_data.h" #include "benchmarking/data_source.h" #include "benchmarking/measurements.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/whitebox/api/aead_whitebox_create_test.cc b/whitebox/api/aead_whitebox_create_test.cc index 1ff0f85..7e3cef6 100644 --- a/whitebox/api/aead_whitebox_create_test.cc +++ b/whitebox/api/aead_whitebox_create_test.cc @@ -2,11 +2,11 @@ #include +#include "api/aead_test_data.h" #include "api/aead_whitebox.h" -#include "api/test_data.h" #include "testing/gtest/include/gtest/gtest.h" -namespace { +namespace widevine { class AeadWhiteboxCreateTest : public ::testing::Test { protected: @@ -72,4 +72,4 @@ TEST_F(AeadWhiteboxCreateTest, InvalidParameterForNullWhitebox) { WB_RESULT_INVALID_PARAMETER); ASSERT_FALSE(whitebox_); } -} // namespace +} // namespace widevine diff --git a/whitebox/api/aead_whitebox_cross_instance_test.cc b/whitebox/api/aead_whitebox_cross_instance_test.cc index f486fc1..75fc2e0 100644 --- a/whitebox/api/aead_whitebox_cross_instance_test.cc +++ b/whitebox/api/aead_whitebox_cross_instance_test.cc @@ -2,11 +2,12 @@ #include +#include "api/aead_test_data.h" #include "api/aead_whitebox.h" -#include "api/test_data.h" #include "testing/gtest/include/gtest/gtest.h" -namespace { +namespace widevine { + // These tests focus on functionality that should and should not exist between // different Aead White-box instances. They assume that all other functionality // of the white-box has already been verified. @@ -122,4 +123,4 @@ TEST_F(AeadWhiteboxCrossInstanceTest, DataVerificationErrorForCommonContext) { ASSERT_EQ(plaintext, common_plaintext_); } -} // namespace +} // namespace widevine diff --git a/whitebox/api/aead_whitebox_decrypt_test.cc b/whitebox/api/aead_whitebox_decrypt_test.cc index a26e63e..4a76c3a 100644 --- a/whitebox/api/aead_whitebox_decrypt_test.cc +++ b/whitebox/api/aead_whitebox_decrypt_test.cc @@ -2,11 +2,12 @@ #include +#include "api/aead_test_data.h" #include "api/aead_whitebox.h" -#include "api/test_data.h" #include "testing/gtest/include/gtest/gtest.h" -namespace { +namespace widevine { + // For our decrypt tests, we assume that WB_Aead_Create() and WB_Aead_Encrypt() // work and each test will have valid encrypted data. class AeadWhiteboxDecryptTest : public ::testing::Test { @@ -153,4 +154,4 @@ TEST_F(AeadWhiteboxDecryptTest, DataVerificationError) { plaintext.data(), &plaintext_size), WB_RESULT_DATA_VERIFICATION_ERROR); } -} // namespace +} // namespace widevine diff --git a/whitebox/api/aead_whitebox_encrypt_test.cc b/whitebox/api/aead_whitebox_encrypt_test.cc index 485d404..14d05ce 100644 --- a/whitebox/api/aead_whitebox_encrypt_test.cc +++ b/whitebox/api/aead_whitebox_encrypt_test.cc @@ -2,15 +2,17 @@ #include +#include "api/aead_test_data.h" #include "api/aead_whitebox.h" -#include "api/test_data.h" #include "testing/gtest/include/gtest/gtest.h" +namespace widevine { namespace { // Regardless of implementation, we need to have enough room in our output // buffer to hold the additional information added by WB_Aead_Encrypt(). So // this number just needs to be reasonably big compared to the input. constexpr size_t kDefaultOutputSize = 256; +} // namespace // For our encrypt tests, we assume that WB_Aead_Create() works and each test // will have a functional instance. In these tests, we will not be checking the @@ -116,4 +118,4 @@ TEST_F(AeadWhiteboxEncryptTest, BufferTooSmallForSmallOutputBuffer) { // only check that |output_size| is larger than |input_.size()|. ASSERT_GT(output_size, input_.size()); } -} // namespace +} // namespace widevine diff --git a/whitebox/api/export.h b/whitebox/api/export.h deleted file mode 100644 index 4d22b97..0000000 --- a/whitebox/api/export.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2020 Google LLC. All Rights Reserved. - -#ifndef WHITEBOX_API_EXPORT_H_ -#define WHITEBOX_API_EXPORT_H_ - -#if defined(_WIN32) -#define WB_API _declspec(dllexport) -#else -#define WB_API __attribute__((visibility("default"))) -#endif - -#endif // WHITEBOX_API_EXPORT_H_ diff --git a/whitebox/api/license_whitebox.h b/whitebox/api/license_whitebox.h index 36f42d9..518fede 100644 --- a/whitebox/api/license_whitebox.h +++ b/whitebox/api/license_whitebox.h @@ -6,7 +6,6 @@ #include #include -#include "api/export.h" #include "api/result.h" #ifdef __cplusplus @@ -21,27 +20,20 @@ typedef enum { WB_CIPHER_MODE_CBC, } WB_CipherMode; -// Creates a new white-box instance using |whitebox_init_data|. A pointer to the -// white-box instance will be returned via |whitebox|. +// Creates a new white-box instance using the implementation's internal private +// key|. A pointer to the white-box instance will be returned via |whitebox|. // // Args: -// whitebox_init_data (in) : The implementation-specific initialization data -// needed to initialize a new white-box instance. -// -// whitebox_init_data_size (in) : The number of bytes in |whitebox_init_data|. -// // whitebox (out) : The output parameter used to return the new white-box // instance. // // Returns: // WB_RESULT_OK if the white-box instance was successfully created. // -// WB_RESULT_INVALID_PARAMETER if |whitebox_init_data| was null or invalid. +// WB_RESULT_INVALID_PARAMETER if |whitebox| was null. // // WB_RESULT_OUT_OF_MEMORY if the necessary memory could not be allocated. -WB_API WB_Result WB_License_Create(const uint8_t* whitebox_init_data, - size_t whitebox_init_data_size, - WB_License_Whitebox** whitebox); +WB_Result WB_License_Create(WB_License_Whitebox** whitebox); // Releases all resources used by the white-box instance pointed to by // |whitebox|. @@ -49,7 +41,7 @@ WB_API WB_Result WB_License_Create(const uint8_t* whitebox_init_data, // Args: // whitebox (in) : A pointer to a white-box instance. Passing in null will // result in a no-op. -WB_API void WB_License_Delete(WB_License_Whitebox* whitebox); +void WB_License_Delete(WB_License_Whitebox* whitebox); // Signs a license request using the CDM's private signing key. // @@ -75,12 +67,11 @@ WB_API void WB_License_Delete(WB_License_Whitebox* whitebox); // // WB_RESULT_BUFFER_TOO_SMALL if |signature_size| (as input) was less than the // required size. -WB_API WB_Result -WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox, - const uint8_t* license_request, - size_t license_request_size, - uint8_t* signature, - size_t* signature_size); +WB_Result WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox, + const uint8_t* license_request, + size_t license_request_size, + uint8_t* signature, + size_t* signature_size); // Verifies a license response using HMAC and the server signing key. // @@ -141,18 +132,17 @@ WB_License_SignLicenseRequest(const WB_License_Whitebox* whitebox, // verification to fail (therefore we return WB_RESULT_INVALID_SIGNATURE). // Doing this was found to allow for better hardening of the license processing // code. -WB_API WB_Result -WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox, - 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); +WB_Result WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox, + 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); // Signs |message| and return the signature via |signature| using HMAC and the // client renewal signing key @@ -181,12 +171,11 @@ WB_License_ProcessLicenseResponse(WB_License_Whitebox* whitebox, // required size. // // WB_RESULT_INVALID_STATE if |whitebox| had no signing keys. -WB_API WB_Result -WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox, - const uint8_t* message, - size_t message_size, - uint8_t* signature, - size_t* signature_size); +WB_Result WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox, + const uint8_t* message, + size_t message_size, + uint8_t* signature, + size_t* signature_size); // Verifies the renewal response using HMAC and the server signing key. // @@ -212,12 +201,11 @@ WB_License_SignRenewalRequest(const WB_License_Whitebox* whitebox, // |signature|. // // WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license. -WB_API WB_Result -WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox, - const uint8_t* message, - size_t message_size, - const uint8_t* signature, - size_t signature_size); +WB_Result WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox, + const uint8_t* message, + size_t message_size, + const uint8_t* signature, + size_t signature_size); // Gets the secret string needed by WB_License_Unmask() in order to unmask the // masked decrypted content returned by WB_License_MaskedDecrypt(). @@ -261,12 +249,12 @@ WB_License_VerifyRenewalResponse(const WB_License_Whitebox* whitebox, // the required size. // // WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license. -WB_API WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox, - WB_CipherMode mode, - const uint8_t* key_id, - size_t key_id_size, - uint8_t* secret_string, - size_t* secret_string_size); +WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox, + WB_CipherMode mode, + const uint8_t* key_id, + size_t key_id_size, + uint8_t* secret_string, + size_t* secret_string_size); // Decrypts |input_data| and writes the plaintext to |output_data|. // @@ -316,16 +304,16 @@ WB_API WB_Result WB_License_GetSecretString(const WB_License_Whitebox* whitebox, // the required size. // // WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license. -WB_API WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox, - WB_CipherMode mode, - const uint8_t* key_id, - size_t key_id_size, - const uint8_t* input_data, - size_t input_data_size, - const uint8_t* iv, - size_t iv_size, - uint8_t* output_data, - size_t* output_data_size); +WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox, + WB_CipherMode mode, + const uint8_t* key_id, + size_t key_id_size, + const uint8_t* input_data, + size_t input_data_size, + const uint8_t* iv, + size_t iv_size, + uint8_t* output_data, + size_t* output_data_size); // Decrypts |input_data| and write the obfuscated plaintext to // |masked_output_data|. The obfuscated plaintext can be deobfuscated using @@ -380,16 +368,16 @@ WB_API WB_Result WB_License_Decrypt(const WB_License_Whitebox* whitebox, // than the required size. // // WB_RESULT_INVALID_STATE if |whitebox| had not loaded a license. -WB_API WB_Result WB_License_MaskedDecrypt(const WB_License_Whitebox* whitebox, - WB_CipherMode mode, - const uint8_t* key_id, - size_t key_id_size, - const uint8_t* input_data, - size_t input_data_size, - const uint8_t* iv, - size_t iv_size, - uint8_t* masked_output_data, - size_t* masked_output_data_size); +WB_Result WB_License_MaskedDecrypt(const WB_License_Whitebox* whitebox, + WB_CipherMode mode, + const uint8_t* key_id, + size_t key_id_size, + const uint8_t* input_data, + size_t input_data_size, + const uint8_t* iv, + size_t iv_size, + uint8_t* masked_output_data, + size_t* masked_output_data_size); // Unmasks a subset of the data in |masked_data| using |secret_string| and // writes it to |unmasked_data|. @@ -417,12 +405,12 @@ WB_API WB_Result WB_License_MaskedDecrypt(const WB_License_Whitebox* whitebox, // secret_string_size (in) : The number of bytes in |secret_string|. // // unmasked_data (out) : The output buffer to write the unmasked data to. -WB_API void WB_License_Unmask(const uint8_t* masked_data, - size_t offset, - size_t size, - const uint8_t* secret_string, - size_t secret_string_size, - uint8_t* unmasked_data); +void WB_License_Unmask(const uint8_t* masked_data, + size_t offset, + size_t size, + const uint8_t* secret_string, + size_t secret_string_size, + uint8_t* unmasked_data); #ifdef __cplusplus } diff --git a/whitebox/api/license_whitebox_benchmark.cc b/whitebox/api/license_whitebox_benchmark.cc index 89fa32b..cf130c5 100644 --- a/whitebox/api/license_whitebox_benchmark.cc +++ b/whitebox/api/license_whitebox_benchmark.cc @@ -9,8 +9,8 @@ #include #include "api/license_whitebox.h" -#include "api/test_data.h" #include "api/test_license_builder.h" +#include "api/test_public_key.h" #include "benchmarking/data_source.h" #include "crypto_utils/crypto_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,7 +25,7 @@ void LicenseWhiteboxBenchmark::SetUp() { key_ = data_source_.Get(kBlockSize); iv_ = data_source_.Get(kBlockSize); - const auto public_key_data = GetMatchingLicensePublicKey(); + const auto public_key_data = GetLicensePublicKey(); public_key_.reset(widevine::RsaPublicKey::Create( std::string(public_key_data.begin(), public_key_data.end()))); ASSERT_TRUE(public_key_); @@ -33,12 +33,13 @@ void LicenseWhiteboxBenchmark::SetUp() { License LicenseWhiteboxBenchmark::CreateLicense() const { widevine::TestLicenseBuilder license_builder; - license_builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey()); + license_builder.AddSigningKey(TestLicenseBuilder::DefaultSigningKey(), + TestLicenseBuilder::NoPadding()); // Use secure crypto as it will work with both Decrypt() and // MaskedDecrypt(). license_builder.AddContentKey( video_widevine::License_KeyContainer_SecurityLevel_SW_SECURE_CRYPTO, - key_id_, key_); + key_id_, key_, TestLicenseBuilder::NoPadding()); widevine::License license; license_builder.Build(*public_key_, &license); diff --git a/whitebox/api/license_whitebox_chromeos_test.cc b/whitebox/api/license_whitebox_chromeos_test.cc index 58694ab..3afe0c5 100644 --- a/whitebox/api/license_whitebox_chromeos_test.cc +++ b/whitebox/api/license_whitebox_chromeos_test.cc @@ -56,15 +56,18 @@ class LicenseWhiteboxChromeOSTest // Only use CBC keys so that we can always use the CBC content. builder.AddContentKey(golden_data_.CBCCryptoKey().level, golden_data_.CBCCryptoKey().id, - golden_data_.CBCCryptoKey().content->key); + golden_data_.CBCCryptoKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddContentKey(golden_data_.CBCDecodeKey().level, golden_data_.CBCDecodeKey().id, - golden_data_.CBCDecodeKey().content->key); + golden_data_.CBCDecodeKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddContentKey(golden_data_.CBCHardwareKey().level, golden_data_.CBCHardwareKey().id, - golden_data_.CBCHardwareKey().content->key); + golden_data_.CBCHardwareKey().content->key, + TestLicenseBuilder::NoPadding()); builder.SetRemoteAttestation(remote_attestation_); builder.SetVerificationStatus(verification_status_); diff --git a/whitebox/api/license_whitebox_create_test.cc b/whitebox/api/license_whitebox_create_test.cc index 221b89e..648f387 100644 --- a/whitebox/api/license_whitebox_create_test.cc +++ b/whitebox/api/license_whitebox_create_test.cc @@ -2,20 +2,12 @@ #include "api/license_whitebox.h" -#include - -#include "api/test_data.h" #include "testing/gtest/include/gtest/gtest.h" namespace { class LicenseWhiteboxCreateTest : public ::testing::Test { protected: - void SetUp() override { - init_data_ = GetLicenseInitData(); - ASSERT_GT(init_data_.size(), 0u); - } - void TearDown() override { WB_License_Delete(whitebox_); } WB_License_Whitebox* whitebox_ = nullptr; @@ -23,35 +15,12 @@ class LicenseWhiteboxCreateTest : public ::testing::Test { }; TEST_F(LicenseWhiteboxCreateTest, Succeeds) { - ASSERT_EQ(WB_License_Create(init_data_.data(), init_data_.size(), &whitebox_), - WB_RESULT_OK); + ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); ASSERT_TRUE(whitebox_); } -TEST_F(LicenseWhiteboxCreateTest, InvalidParameterForNullInitData) { - ASSERT_EQ(WB_License_Create(nullptr, init_data_.size(), &whitebox_), - WB_RESULT_INVALID_PARAMETER); - ASSERT_FALSE(whitebox_); -} - -TEST_F(LicenseWhiteboxCreateTest, InvalidParameterForZeroInitDataSize) { - ASSERT_EQ(WB_License_Create(init_data_.data(), 0, &whitebox_), - WB_RESULT_INVALID_PARAMETER); - ASSERT_FALSE(whitebox_); -} - -TEST_F(LicenseWhiteboxCreateTest, InvalidParameterForInvalidInitData) { - const std::vector invalid_init_data = GetInvalidLicenseInitData(); - - ASSERT_EQ(WB_License_Create(invalid_init_data.data(), - invalid_init_data.size(), &whitebox_), - WB_RESULT_INVALID_PARAMETER); - ASSERT_FALSE(whitebox_); -} - TEST_F(LicenseWhiteboxCreateTest, InvalidParameterForNullWhitebox) { - ASSERT_EQ(WB_License_Create(init_data_.data(), init_data_.size(), nullptr), - WB_RESULT_INVALID_PARAMETER); + ASSERT_EQ(WB_License_Create(nullptr), WB_RESULT_INVALID_PARAMETER); } } // namespace diff --git a/whitebox/api/license_whitebox_decrypt_benchmark.cc b/whitebox/api/license_whitebox_decrypt_benchmark.cc index e93629a..3627846 100644 --- a/whitebox/api/license_whitebox_decrypt_benchmark.cc +++ b/whitebox/api/license_whitebox_decrypt_benchmark.cc @@ -9,7 +9,6 @@ #include "api/license_whitebox.h" #include "api/license_whitebox_benchmark.h" #include "api/result.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "benchmarking/data_source.h" #include "benchmarking/measurements.h" @@ -44,9 +43,7 @@ class LicenseWhiteboxDecryptBenchmark masked_text_.resize(bytes_per_call); plaintext_.resize(bytes_per_call); - const auto init_data = GetLicenseInitData(); - ASSERT_EQ(WB_License_Create(init_data.data(), init_data.size(), &whitebox_), - WB_RESULT_OK); + ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); const auto license = CreateLicense(); ASSERT_EQ( diff --git a/whitebox/api/license_whitebox_decrypt_test.cc b/whitebox/api/license_whitebox_decrypt_test.cc index 1323ee2..382a85e 100644 --- a/whitebox/api/license_whitebox_decrypt_test.cc +++ b/whitebox/api/license_whitebox_decrypt_test.cc @@ -8,7 +8,6 @@ #include "api/golden_data.h" #include "api/license_whitebox_test_base.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "crypto_utils/rsa_key.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/whitebox/api/license_whitebox_get_secret_string_test.cc b/whitebox/api/license_whitebox_get_secret_string_test.cc index 5142ab5..08b81a6 100644 --- a/whitebox/api/license_whitebox_get_secret_string_test.cc +++ b/whitebox/api/license_whitebox_get_secret_string_test.cc @@ -7,7 +7,6 @@ #include "api/golden_data.h" #include "api/license_whitebox_test_base.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "crypto_utils/rsa_key.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,15 +32,18 @@ class LicenseWhiteboxGetSecretStringTest : public LicenseWhiteboxTestBase { builder.AddContentKey(golden_data_.CBCCryptoKey().level, golden_data_.CBCCryptoKey().id, - golden_data_.CBCCryptoKey().content->key); + golden_data_.CBCCryptoKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddContentKey(golden_data_.CBCDecodeKey().level, golden_data_.CBCDecodeKey().id, - golden_data_.CBCDecodeKey().content->key); + golden_data_.CBCDecodeKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddContentKey(golden_data_.CBCHardwareKey().level, golden_data_.CBCHardwareKey().id, - golden_data_.CBCHardwareKey().content->key); + golden_data_.CBCHardwareKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddOperatorSessionKey(non_content_key_id_); diff --git a/whitebox/api/license_whitebox_golden_data_test.cc b/whitebox/api/license_whitebox_golden_data_test.cc index c026de9..54daf09 100644 --- a/whitebox/api/license_whitebox_golden_data_test.cc +++ b/whitebox/api/license_whitebox_golden_data_test.cc @@ -315,9 +315,7 @@ class LicenseWhiteboxDecryptGoldenData : public ::testing::Test { }; TEST_F(LicenseWhiteboxDecryptGoldenData, CryptoKeyWithCbcDataInCbcMode) { - ASSERT_EQ(WB_License_Create(kLicenseWhiteboxInitData, - kLicenseWhiteboxInitDataSize, &whitebox_), - WB_RESULT_OK); + ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); ASSERT_EQ(WB_License_ProcessLicenseResponse( whitebox_, kCoreMessage, kCoreMessageSize, kMessage, diff --git a/whitebox/api/license_whitebox_masked_decrypt_test.cc b/whitebox/api/license_whitebox_masked_decrypt_test.cc index 252b4cc..692422e 100644 --- a/whitebox/api/license_whitebox_masked_decrypt_test.cc +++ b/whitebox/api/license_whitebox_masked_decrypt_test.cc @@ -9,7 +9,6 @@ #include "api/golden_data.h" #include "api/license_whitebox_test_base.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" @@ -42,23 +41,28 @@ class LicenseWhiteboxMaskedDecryptTest : public LicenseWhiteboxTestBase { builder.AddContentKey(golden_data_.CBCCryptoKey().level, golden_data_.CBCCryptoKey().id, - golden_data_.CBCCryptoKey().content->key); + golden_data_.CBCCryptoKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddContentKey(golden_data_.CTRCryptoKey().level, golden_data_.CTRCryptoKey().id, - golden_data_.CTRCryptoKey().content->key); + golden_data_.CTRCryptoKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddContentKey(golden_data_.CBCDecodeKey().level, golden_data_.CBCDecodeKey().id, - golden_data_.CBCDecodeKey().content->key); + golden_data_.CBCDecodeKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddContentKey(golden_data_.CTRDecodeKey().level, golden_data_.CTRDecodeKey().id, - golden_data_.CTRDecodeKey().content->key); + golden_data_.CTRDecodeKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddContentKey(golden_data_.CBCHardwareKey().level, golden_data_.CBCHardwareKey().id, - golden_data_.CBCHardwareKey().content->key); + golden_data_.CBCHardwareKey().content->key, + TestLicenseBuilder::NoPadding()); builder.AddOperatorSessionKey(non_content_key_id_); diff --git a/whitebox/api/license_whitebox_process_license_response_benchmark.cc b/whitebox/api/license_whitebox_process_license_response_benchmark.cc index 5b21b7e..a7fbbaf 100644 --- a/whitebox/api/license_whitebox_process_license_response_benchmark.cc +++ b/whitebox/api/license_whitebox_process_license_response_benchmark.cc @@ -6,7 +6,6 @@ #include "api/license_whitebox.h" #include "api/license_whitebox_benchmark.h" #include "api/result.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "benchmarking/measurements.h" #include "testing/gtest/include/gtest/gtest.h" @@ -37,16 +36,13 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseBenchmark, Sampler sampler; for (size_t i = 0; i < kIterations; i++) { - const auto init_data = GetLicenseInitData(); - // We can only call ProcessLicenseResponse() once per whitebox instance. So // we need to create a new instance each time. Collect samples for create + // process license + delete so that we know the cost of getting a new // license. timer.Reset(); - ASSERT_EQ(WB_License_Create(init_data.data(), init_data.size(), &whitebox_), - WB_RESULT_OK); + ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); ASSERT_EQ(WB_License_ProcessLicenseResponse( whitebox_, license_.core_message.data(), @@ -74,15 +70,12 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseBenchmark, Sampler sampler; for (size_t i = 0; i < kIterations; i++) { - const auto init_data = GetLicenseInitData(); - // We can only call ProcessLicenseResponse() once per whitebox instance. So // we need to create a new instance each time. Collect samples for create + // process license so that we know the true start-up cost. timer.Reset(); - ASSERT_EQ(WB_License_Create(init_data.data(), init_data.size(), &whitebox_), - WB_RESULT_OK); + ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); ASSERT_EQ(WB_License_ProcessLicenseResponse( whitebox_, license_.core_message.data(), @@ -111,9 +104,7 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseBenchmark, ProcessLicenseResponse) { // We can only call ProcessLicenseResponse() once per whitebox instance. So // we need to create a new instance each time. Do this before we reset the // timer so that we are not counting it in the execution time. - const auto init_data = GetLicenseInitData(); - ASSERT_EQ(WB_License_Create(init_data.data(), init_data.size(), &whitebox_), - WB_RESULT_OK); + ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); timer.Reset(); diff --git a/whitebox/api/license_whitebox_process_license_response_test.cc b/whitebox/api/license_whitebox_process_license_response_test.cc index 750d4d9..2c7c64b 100644 --- a/whitebox/api/license_whitebox_process_license_response_test.cc +++ b/whitebox/api/license_whitebox_process_license_response_test.cc @@ -7,7 +7,6 @@ #include "api/golden_data.h" #include "api/license_whitebox_test_base.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" @@ -100,8 +99,7 @@ TEST_F(LicenseWhiteboxProcessLicenseResponseTest, WB_RESULT_INVALID_PARAMETER); } -TEST_F(LicenseWhiteboxProcessLicenseResponseTest, - InvalidParameterWithNoKeys) { +TEST_F(LicenseWhiteboxProcessLicenseResponseTest, InvalidParameterWithNoKeys) { UseLicenseWithNoKeys(); ASSERT_EQ( diff --git a/whitebox/api/license_whitebox_sign_benchmark.cc b/whitebox/api/license_whitebox_sign_benchmark.cc index 5b81190..a8c7e38 100644 --- a/whitebox/api/license_whitebox_sign_benchmark.cc +++ b/whitebox/api/license_whitebox_sign_benchmark.cc @@ -9,7 +9,6 @@ #include "api/license_whitebox.h" #include "api/license_whitebox_benchmark.h" #include "api/result.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "benchmarking/data_source.h" #include "benchmarking/measurements.h" @@ -32,9 +31,7 @@ class LicenseWhiteboxSignBenchmark : public LicenseWhiteboxBenchmark { message_ = Data().Get(kMessageSize); signature_.resize(kSignatureSize); - const auto init_data = GetLicenseInitData(); - ASSERT_EQ(WB_License_Create(init_data.data(), init_data.size(), &whitebox_), - WB_RESULT_OK); + ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); const auto license = CreateLicense(); ASSERT_EQ( diff --git a/whitebox/api/license_whitebox_sign_license_request_test.cc b/whitebox/api/license_whitebox_sign_license_request_test.cc index 4cf901c..eb6c669 100644 --- a/whitebox/api/license_whitebox_sign_license_request_test.cc +++ b/whitebox/api/license_whitebox_sign_license_request_test.cc @@ -7,7 +7,6 @@ #include #include "api/license_whitebox_test_base.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "crypto_utils/rsa_key.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/whitebox/api/license_whitebox_sign_renewal_request_test.cc b/whitebox/api/license_whitebox_sign_renewal_request_test.cc index d075879..c4bef0d 100644 --- a/whitebox/api/license_whitebox_sign_renewal_request_test.cc +++ b/whitebox/api/license_whitebox_sign_renewal_request_test.cc @@ -7,7 +7,6 @@ #include #include "api/license_whitebox_test_base.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" diff --git a/whitebox/api/license_whitebox_test_base.cc b/whitebox/api/license_whitebox_test_base.cc index bce98b6..0e9abac 100644 --- a/whitebox/api/license_whitebox_test_base.cc +++ b/whitebox/api/license_whitebox_test_base.cc @@ -4,16 +4,14 @@ #include -#include "api/test_data.h" +#include "api/test_public_key.h" namespace widevine { void LicenseWhiteboxTestBase::SetUp() { - const std::vector init_data = GetLicenseInitData(); - ASSERT_EQ(WB_License_Create(init_data.data(), init_data.size(), &whitebox_), - WB_RESULT_OK); + ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); - const auto public_key_data = GetMatchingLicensePublicKey(); + const auto public_key_data = GetLicensePublicKey(); public_key_.reset(RsaPublicKey::Create( std::string(public_key_data.begin(), public_key_data.end()))); diff --git a/whitebox/api/license_whitebox_verify_benchmark.cc b/whitebox/api/license_whitebox_verify_benchmark.cc index 6dd7a9f..3ed49e7 100644 --- a/whitebox/api/license_whitebox_verify_benchmark.cc +++ b/whitebox/api/license_whitebox_verify_benchmark.cc @@ -9,7 +9,6 @@ #include "api/license_whitebox.h" #include "api/license_whitebox_benchmark.h" #include "api/result.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "benchmarking/data_source.h" #include "benchmarking/measurements.h" @@ -28,9 +27,7 @@ class LicenseWhiteboxVerifyBenchmark : public LicenseWhiteboxBenchmark { message_ = Data().Get(kMessageSize); signature_ = SignAsServer(message_); - const auto init_data = GetLicenseInitData(); - ASSERT_EQ(WB_License_Create(init_data.data(), init_data.size(), &whitebox_), - WB_RESULT_OK); + ASSERT_EQ(WB_License_Create(&whitebox_), WB_RESULT_OK); const auto license = CreateLicense(); ASSERT_EQ( diff --git a/whitebox/api/license_whitebox_verify_renewal_response_test.cc b/whitebox/api/license_whitebox_verify_renewal_response_test.cc index 59eaab6..076e18f 100644 --- a/whitebox/api/license_whitebox_verify_renewal_response_test.cc +++ b/whitebox/api/license_whitebox_verify_renewal_response_test.cc @@ -7,7 +7,6 @@ #include #include "api/license_whitebox_test_base.h" -#include "api/test_data.h" #include "api/test_license_builder.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" diff --git a/whitebox/api/test_license_builder.h b/whitebox/api/test_license_builder.h index f438faa..30e0107 100644 --- a/whitebox/api/test_license_builder.h +++ b/whitebox/api/test_license_builder.h @@ -50,7 +50,7 @@ class TestLicenseBuilder { TestLicenseBuilder(); void AddSigningKey(const std::vector& key, - const std::vector& padding = NoPadding()); + const std::vector& padding); // Add a content key so that there is some key in the license. This should not // be used with AddContentKey(). @@ -59,7 +59,7 @@ class TestLicenseBuilder { void AddContentKey(video_widevine::License_KeyContainer_SecurityLevel level, const std::vector& key_id, const std::vector& key, - const std::vector& padding = NoPadding()); + const std::vector& padding); // 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 diff --git a/whitebox/api/test_public_key.h b/whitebox/api/test_public_key.h new file mode 100644 index 0000000..072e4be --- /dev/null +++ b/whitebox/api/test_public_key.h @@ -0,0 +1,17 @@ +// Copyright 2020 Google LLC. All Rights Reserved. + +#ifndef WHITEBOX_API_TEST_PUBLIC_KEY_H_ +#define WHITEBOX_API_TEST_PUBLIC_KEY_H_ + +#include +#include + +namespace widevine { + +// Returns the public key that matches the private key used by the license +// white-box. The public key should be a DER encoded PKCS#1 RSAPublicKey. +std::vector GetLicensePublicKey(); + +} // namespace widevine + +#endif // WHITEBOX_API_TEST_PUBLIC_KEY_H_ diff --git a/whitebox/impl/reference/BUILD b/whitebox/impl/reference/BUILD index b7fba73..fbbf041 100644 --- a/whitebox/impl/reference/BUILD +++ b/whitebox/impl/reference/BUILD @@ -19,12 +19,20 @@ cc_library( ], ) +cc_library( + name = "license_private_key", + hdrs = [ + "license_private_key.h", + ], +) + cc_library( name = "license_whitebox", srcs = [ "license_whitebox_impl.cc", ], deps = [ + ":license_private_key", ":memory_util", "//api:license_whitebox", "//api:result", @@ -39,13 +47,25 @@ cc_library( ) cc_library( - name = "test_data", + name = "aead_test_data", testonly = True, srcs = [ - "test_data.cc", + "aead_test_data.cc", ], deps = [ - "//api:test_data", + "//api:aead_test_data", + ], +) + +cc_library( + name = "license_test_data", + testonly = True, + srcs = [ + "license_test_data.cc", + ], + deps = [ + ":license_private_key", + "//api:test_public_key", "//crypto_utils:rsa_test_keys", ], ) @@ -54,8 +74,8 @@ cc_test( name = "aead_whitebox_test", size = "small", deps = [ + ":aead_test_data", ":aead_whitebox", - ":test_data", "//api:aead_whitebox_test", ], ) @@ -64,8 +84,8 @@ cc_test( name = "aead_whitebox_benchmark", size = "small", deps = [ + ":aead_test_data", ":aead_whitebox", - ":test_data", "//api:aead_whitebox_benchmark", ], ) @@ -74,8 +94,8 @@ cc_test( name = "license_whitebox_test", size = "small", deps = [ + ":license_test_data", ":license_whitebox", - ":test_data", "//api:license_whitebox_test", ], ) @@ -84,8 +104,8 @@ cc_test( name = "license_whitebox_benchmark", size = "small", deps = [ + ":license_test_data", ":license_whitebox", - ":test_data", "//api:license_whitebox_benchmark", ], ) diff --git a/whitebox/impl/reference/aead_test_data.cc b/whitebox/impl/reference/aead_test_data.cc new file mode 100644 index 0000000..84f6724 --- /dev/null +++ b/whitebox/impl/reference/aead_test_data.cc @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC. All Rights Reserved. + +#include "api/aead_test_data.h" + +#include + +namespace widevine { + +std::vector GetValidAeadInitData() { + // Valid init data for our AEAD implementation is any AES key, so it just + // needs to be 16 bytes. + return { + 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, + 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, + }; +} + +std::vector GetInvalidAeadInitData() { + // Valid init data would be any 16 bytes. To avoid returning a length of + // zero, just return one byte, that way we are still returning "some data". + return {0x00}; +} + +} // namespace widevine diff --git a/whitebox/impl/reference/aead_whitebox_impl.cc b/whitebox/impl/reference/aead_whitebox_impl.cc index c3d5e95..0bf1fab 100644 --- a/whitebox/impl/reference/aead_whitebox_impl.cc +++ b/whitebox/impl/reference/aead_whitebox_impl.cc @@ -1,215 +1,215 @@ -// Copyright 2020 Google LLC. All Rights Reserved. -#include "api/aead_whitebox.h" - -#include -#include -#include - -#include "base/check_op.h" -#include "base/logging.h" -#include "crypto_utils/crypto_util.h" -#include "impl/reference/memory_util.h" -#include "third_party/boringssl/src/include/openssl/aead.h" -#include "third_party/boringssl/src/include/openssl/rand.h" - -struct WB_Aead_Whitebox { - const EVP_AEAD* algorithm; - size_t nonce_size; - - EVP_AEAD_CTX context; -}; - -namespace { -// EVP_AEAD_CTX_init(), EVP_AEAD_CTX_open(), and EVP_AEAD_CTX_seal() return 1 -// for success and 0 for failure. -const int kAeadSuccess = 1; - -void InitAeadMetadata(WB_Aead_Whitebox* whitebox) { - const EVP_AEAD* algorithm = EVP_aead_aes_128_gcm_siv(); - - whitebox->algorithm = algorithm; - whitebox->nonce_size = EVP_AEAD_nonce_length(algorithm); -} - -std::vector DeriveKey(const WB_Aead_Whitebox* whitebox, - const uint8_t* init_data, - size_t init_data_size, - const uint8_t* context, - size_t context_size) { - // To derive a key, we need a label to introduce some entropy. The label only - // needs to be some fixed, arbitrary non-trivial string. - constexpr char kLabel[] = "Covfefe"; - - const std::string init_data_view(init_data, init_data + init_data_size); - const std::string context_view(context, context + context_size); - - // While we get the key size in bytes, DeriveKey() needs the key size in bits. - const auto derived_key = widevine::crypto_util::DeriveKey( - init_data_view, kLabel, context_view, - EVP_AEAD_key_length(whitebox->algorithm) * 8); - - return std::vector(derived_key.begin(), derived_key.end()); -} -} // namespace - -WB_Result WB_Aead_Create(const uint8_t* whitebox_init_data, - size_t whitebox_init_data_size, - const uint8_t* context, - size_t context_size, - ::WB_Aead_Whitebox** whitebox) { - if (!whitebox_init_data || !context || !whitebox) { - DVLOG(1) << "Invalid parameter: null pointer."; - return WB_RESULT_INVALID_PARAMETER; - } - - if (whitebox_init_data_size == 0 || context_size == 0) { - DVLOG(1) << "Invalid parameter: array size 0."; - return WB_RESULT_INVALID_PARAMETER; - } - - // Use a unique pointer internally so that we can return early and - // automatically release the pointer. Should always be non-null on modern - // compilers (https://isocpp.org/wiki/faq/freestore-mgmt). - std::unique_ptr aead_whitebox(new WB_Aead_Whitebox()); - InitAeadMetadata(aead_whitebox.get()); - - // Rather than using a fixed key, shared across all instances, derive a key - // for each instance using the provided context. This will allow each instance - // to have its own unique key (assuming they provide a unique context) while - // still allowing a specific key to be recreated when needed (e.g. - // device-locked key). - const std::vector key = - DeriveKey(aead_whitebox.get(), whitebox_init_data, - whitebox_init_data_size, context, context_size); - - const int result = EVP_AEAD_CTX_init( - &aead_whitebox->context, aead_whitebox->algorithm, key.data(), key.size(), - EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr); - - if (result != kAeadSuccess) { - DVLOG(1) << "Invalid parameter: invalid init data."; - return WB_RESULT_INVALID_PARAMETER; - } - - // release() will release ownership of the pointer and return the unmanaged - // raw pointer. - *whitebox = aead_whitebox.release(); - return WB_RESULT_OK; -} - -void WB_Aead_Delete(WB_Aead_Whitebox* whitebox) { - if (whitebox != nullptr) { - EVP_AEAD_CTX_cleanup(&whitebox->context); - } - - // Safe to delete nullptr (https://isocpp.org/wiki/faq/freestore-mgmt). - delete whitebox; -} -WB_Result WB_Aead_Encrypt(const WB_Aead_Whitebox* whitebox, - const uint8_t* input_data, - size_t input_data_size, - uint8_t* output_data, - size_t* output_data_size) { - if (!whitebox || !input_data || !output_data || !output_data_size) { - DVLOG(1) << "Invalid parameter: null pointer."; - return WB_RESULT_INVALID_PARAMETER; - } - - if (input_data_size == 0) { - DVLOG(1) << "Invalid parameter: array size 0."; - return WB_RESULT_INVALID_PARAMETER; - } - - std::vector nonce(whitebox->nonce_size); - RAND_bytes(nonce.data(), nonce.size()); - - std::vector output(input_data_size + - EVP_AEAD_max_overhead(whitebox->algorithm)); - size_t sealed_size; - CHECK_EQ(EVP_AEAD_CTX_seal(&whitebox->context, output.data(), &sealed_size, - output.size(), nonce.data(), nonce.size(), - input_data, input_data_size, nullptr, 0), - kAeadSuccess); - output.resize(sealed_size); - - // At this point, |output| will have the encrypted data and authentication - // tag, but in order to decrypt later, we will need the nonce, so append the - // nonce to the output. - output.insert(output.end(), nonce.begin(), nonce.end()); - - if (!widevine::MemCopy(output.data(), output.size(), output_data, - *output_data_size)) { - DVLOG(1) << "Buffer too small: output needs " << output.size() << "."; - *output_data_size = output.size(); - return WB_RESULT_BUFFER_TOO_SMALL; - } - - *output_data_size = output.size(); - return WB_RESULT_OK; -} - -WB_Result WB_Aead_Decrypt(const WB_Aead_Whitebox* whitebox, - const uint8_t* input_data, - size_t input_data_size, - uint8_t* output_data, - size_t* output_data_size) { - if (!whitebox || !input_data || !output_data || !output_data_size) { - DVLOG(1) << "Invalid parameter: null pointer."; - return WB_RESULT_INVALID_PARAMETER; - } - - // If we were to encrypt nothing, we would still get the nonce, so the input - // must at least be large enough to contain the nonce. - if (input_data_size <= whitebox->nonce_size) { - DVLOG(1) << "Invalid parameter: invalid input size."; - return WB_RESULT_INVALID_PARAMETER; - } - - // The input follows the structure: - // |--------input---------| - // |---payload---||-nonce-| - // - // The payload is the combination of authentication tag and ciphertext - // created by our previous call to EVP_AEAD_CTX_seal(). - // - // To use EVP_AEAD_CTX_open(), we need to separate the payload and nonce as - // they must be passed to EVP_AEAD_CTX_open() separately. The result of - // calling EVP_AEAD_CTX_open() will be the plaintext, which will be smaller - // than the payload as the payload included the ciphertext and authentication - // tag. - - const uint8_t* payload_start = input_data; - const size_t payload_size = input_data_size - whitebox->nonce_size; - - const uint8_t* nonce_start = payload_start + payload_size; - const size_t nonce_size = whitebox->nonce_size; - - // Remember, the plaintext will be smaller than the payload, but we are going - // to start with the payload size as it is our best estimate and will scale it - // down when we have the final size. - std::vector plaintext(payload_size); - size_t plaintext_size; - - const int result = EVP_AEAD_CTX_open( - &whitebox->context, plaintext.data(), &plaintext_size, plaintext.size(), - nonce_start, nonce_size, payload_start, payload_size, nullptr, 0); - - if (result != kAeadSuccess) { - DVLOG(1) << "Data verification error: failed to verify input data."; - return WB_RESULT_DATA_VERIFICATION_ERROR; - } - - // Know that EVP_AEAD_CTX_open() has opened the payload, we know the actual - // plaintext size and can now shrink the vector to the correct size. - plaintext.resize(plaintext_size); - - if (!widevine::MemCopy(plaintext.data(), plaintext.size(), output_data, - *output_data_size)) { - DVLOG(1) << "Buffer too small: output needs " << plaintext.size() << "."; - *output_data_size = plaintext.size(); - return WB_RESULT_BUFFER_TOO_SMALL; - } - - *output_data_size = plaintext.size(); - return WB_RESULT_OK; -} +// Copyright 2020 Google LLC. All Rights Reserved. +#include "api/aead_whitebox.h" + +#include +#include +#include + +#include "base/check_op.h" +#include "base/logging.h" +#include "crypto_utils/crypto_util.h" +#include "impl/reference/memory_util.h" +#include "third_party/boringssl/src/include/openssl/aead.h" +#include "third_party/boringssl/src/include/openssl/rand.h" + +struct WB_Aead_Whitebox { + const EVP_AEAD* algorithm; + size_t nonce_size; + + EVP_AEAD_CTX context; +}; + +namespace { +// EVP_AEAD_CTX_init(), EVP_AEAD_CTX_open(), and EVP_AEAD_CTX_seal() return 1 +// for success and 0 for failure. +const int kAeadSuccess = 1; + +void InitAeadMetadata(WB_Aead_Whitebox* whitebox) { + const EVP_AEAD* algorithm = EVP_aead_aes_128_gcm_siv(); + + whitebox->algorithm = algorithm; + whitebox->nonce_size = EVP_AEAD_nonce_length(algorithm); +} + +std::vector DeriveKey(const WB_Aead_Whitebox* whitebox, + const uint8_t* init_data, + size_t init_data_size, + const uint8_t* context, + size_t context_size) { + // To derive a key, we need a label to introduce some entropy. The label only + // needs to be some fixed, arbitrary non-trivial string. + constexpr char kLabel[] = "Covfefe"; + + const std::string init_data_view(init_data, init_data + init_data_size); + const std::string context_view(context, context + context_size); + + // While we get the key size in bytes, DeriveKey() needs the key size in bits. + const auto derived_key = widevine::crypto_util::DeriveKey( + init_data_view, kLabel, context_view, + EVP_AEAD_key_length(whitebox->algorithm) * 8); + + return std::vector(derived_key.begin(), derived_key.end()); +} +} // namespace + +WB_Result WB_Aead_Create(const uint8_t* whitebox_init_data, + size_t whitebox_init_data_size, + const uint8_t* context, + size_t context_size, + ::WB_Aead_Whitebox** whitebox) { + if (!whitebox_init_data || !context || !whitebox) { + DVLOG(1) << "Invalid parameter: null pointer."; + return WB_RESULT_INVALID_PARAMETER; + } + + if (whitebox_init_data_size == 0 || context_size == 0) { + DVLOG(1) << "Invalid parameter: array size 0."; + return WB_RESULT_INVALID_PARAMETER; + } + + // Use a unique pointer internally so that we can return early and + // automatically release the pointer. Should always be non-null on modern + // compilers (https://isocpp.org/wiki/faq/freestore-mgmt). + std::unique_ptr aead_whitebox(new WB_Aead_Whitebox()); + InitAeadMetadata(aead_whitebox.get()); + + // Rather than using a fixed key, shared across all instances, derive a key + // for each instance using the provided context. This will allow each instance + // to have its own unique key (assuming they provide a unique context) while + // still allowing a specific key to be recreated when needed (e.g. + // device-locked key). + const std::vector key = + DeriveKey(aead_whitebox.get(), whitebox_init_data, + whitebox_init_data_size, context, context_size); + + const int result = EVP_AEAD_CTX_init( + &aead_whitebox->context, aead_whitebox->algorithm, key.data(), key.size(), + EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr); + + if (result != kAeadSuccess) { + DVLOG(1) << "Invalid parameter: invalid init data."; + return WB_RESULT_INVALID_PARAMETER; + } + + // release() will release ownership of the pointer and return the unmanaged + // raw pointer. + *whitebox = aead_whitebox.release(); + return WB_RESULT_OK; +} + +void WB_Aead_Delete(WB_Aead_Whitebox* whitebox) { + if (whitebox != nullptr) { + EVP_AEAD_CTX_cleanup(&whitebox->context); + } + + // Safe to delete nullptr (https://isocpp.org/wiki/faq/freestore-mgmt). + delete whitebox; +} +WB_Result WB_Aead_Encrypt(const WB_Aead_Whitebox* whitebox, + const uint8_t* input_data, + size_t input_data_size, + uint8_t* output_data, + size_t* output_data_size) { + if (!whitebox || !input_data || !output_data || !output_data_size) { + DVLOG(1) << "Invalid parameter: null pointer."; + return WB_RESULT_INVALID_PARAMETER; + } + + if (input_data_size == 0) { + DVLOG(1) << "Invalid parameter: array size 0."; + return WB_RESULT_INVALID_PARAMETER; + } + + std::vector nonce(whitebox->nonce_size); + RAND_bytes(nonce.data(), nonce.size()); + + std::vector output(input_data_size + + EVP_AEAD_max_overhead(whitebox->algorithm)); + size_t sealed_size; + CHECK_EQ(EVP_AEAD_CTX_seal(&whitebox->context, output.data(), &sealed_size, + output.size(), nonce.data(), nonce.size(), + input_data, input_data_size, nullptr, 0), + kAeadSuccess); + output.resize(sealed_size); + + // At this point, |output| will have the encrypted data and authentication + // tag, but in order to decrypt later, we will need the nonce, so append the + // nonce to the output. + output.insert(output.end(), nonce.begin(), nonce.end()); + + if (!widevine::MemCopy(output.data(), output.size(), output_data, + *output_data_size)) { + DVLOG(1) << "Buffer too small: output needs " << output.size() << "."; + *output_data_size = output.size(); + return WB_RESULT_BUFFER_TOO_SMALL; + } + + *output_data_size = output.size(); + return WB_RESULT_OK; +} + +WB_Result WB_Aead_Decrypt(const WB_Aead_Whitebox* whitebox, + const uint8_t* input_data, + size_t input_data_size, + uint8_t* output_data, + size_t* output_data_size) { + if (!whitebox || !input_data || !output_data || !output_data_size) { + DVLOG(1) << "Invalid parameter: null pointer."; + return WB_RESULT_INVALID_PARAMETER; + } + + // If we were to encrypt nothing, we would still get the nonce, so the input + // must at least be large enough to contain the nonce. + if (input_data_size <= whitebox->nonce_size) { + DVLOG(1) << "Invalid parameter: invalid input size."; + return WB_RESULT_INVALID_PARAMETER; + } + + // The input follows the structure: + // |--------input---------| + // |---payload---||-nonce-| + // + // The payload is the combination of authentication tag and ciphertext + // created by our previous call to EVP_AEAD_CTX_seal(). + // + // To use EVP_AEAD_CTX_open(), we need to separate the payload and nonce as + // they must be passed to EVP_AEAD_CTX_open() separately. The result of + // calling EVP_AEAD_CTX_open() will be the plaintext, which will be smaller + // than the payload as the payload included the ciphertext and authentication + // tag. + + const uint8_t* payload_start = input_data; + const size_t payload_size = input_data_size - whitebox->nonce_size; + + const uint8_t* nonce_start = payload_start + payload_size; + const size_t nonce_size = whitebox->nonce_size; + + // Remember, the plaintext will be smaller than the payload, but we are going + // to start with the payload size as it is our best estimate and will scale it + // down when we have the final size. + std::vector plaintext(payload_size); + size_t plaintext_size; + + const int result = EVP_AEAD_CTX_open( + &whitebox->context, plaintext.data(), &plaintext_size, plaintext.size(), + nonce_start, nonce_size, payload_start, payload_size, nullptr, 0); + + if (result != kAeadSuccess) { + DVLOG(1) << "Data verification error: failed to verify input data."; + return WB_RESULT_DATA_VERIFICATION_ERROR; + } + + // Know that EVP_AEAD_CTX_open() has opened the payload, we know the actual + // plaintext size and can now shrink the vector to the correct size. + plaintext.resize(plaintext_size); + + if (!widevine::MemCopy(plaintext.data(), plaintext.size(), output_data, + *output_data_size)) { + DVLOG(1) << "Buffer too small: output needs " << plaintext.size() << "."; + *output_data_size = plaintext.size(); + return WB_RESULT_BUFFER_TOO_SMALL; + } + + *output_data_size = plaintext.size(); + return WB_RESULT_OK; +} diff --git a/whitebox/impl/reference/license_private_key.h b/whitebox/impl/reference/license_private_key.h new file mode 100644 index 0000000..9586ce4 --- /dev/null +++ b/whitebox/impl/reference/license_private_key.h @@ -0,0 +1,16 @@ +// Copyright 2020 Google LLC. All Rights Reserved. + +#ifndef WHITEBOX_IMPL_REFERENCE_LICENSE_PRIVATE_KEY_H_ +#define WHITEBOX_IMPL_REFERENCE_LICENSE_PRIVATE_KEY_H_ + +#include +#include + +namespace widevine { + +// Return a RSA 2048-bit private key. +std::vector GetLicensePrivateKey(); + +} // namespace widevine + +#endif // WHITEBOX_IMPL_REFERENCE_LICENSE_PRIVATE_KEY_H_ diff --git a/whitebox/impl/reference/license_test_data.cc b/whitebox/impl/reference/license_test_data.cc new file mode 100644 index 0000000..360b8d4 --- /dev/null +++ b/whitebox/impl/reference/license_test_data.cc @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC. All Rights Reserved. + +#include + +#include "api/test_public_key.h" +#include "crypto_utils/rsa_test_keys.h" +#include "impl/reference/license_private_key.h" + +namespace widevine { + +std::vector GetLicensePrivateKey() { + widevine::RsaTestKeys key_generator; + std::string init_data = key_generator.private_test_key_2_2048_bits(); + return std::vector(init_data.begin(), init_data.end()); +} + +std::vector GetLicensePublicKey() { + widevine::RsaTestKeys key_generator; + std::string init_data = key_generator.public_test_key_2_2048_bits(); + return std::vector(init_data.begin(), init_data.end()); +} + +} // namespace widevine diff --git a/whitebox/impl/reference/license_whitebox_golden_data_init_data.cc b/whitebox/impl/reference/license_whitebox_golden_data_init_data.cc index 263d246..074fc2f 100644 --- a/whitebox/impl/reference/license_whitebox_golden_data_init_data.cc +++ b/whitebox/impl/reference/license_whitebox_golden_data_init_data.cc @@ -3,111 +3,113 @@ #include #include +#include "impl/reference/license_private_key.h" + namespace widevine { -extern const uint8_t kLicenseWhiteboxInitData[] = { - 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, - 0xae, 0xa6, 0xa8, 0xea, 0xdd, 0xac, 0x6f, 0xb4, 0x41, 0x47, 0xcb, 0x18, - 0x81, 0xeb, 0xdf, 0x4f, 0x17, 0xf7, 0x17, 0xc0, 0xab, 0x6f, 0x47, 0x50, - 0xbf, 0xe4, 0x8c, 0xc9, 0x45, 0x24, 0x5e, 0x1c, 0x2e, 0x86, 0x9f, 0xcb, - 0x47, 0x05, 0xf9, 0xfe, 0x91, 0x90, 0xaf, 0xbd, 0x22, 0x14, 0x47, 0xa7, - 0x34, 0x39, 0x79, 0x44, 0xe9, 0x92, 0x83, 0x4a, 0x80, 0xa8, 0x2a, 0xe6, - 0x9f, 0x2b, 0xb7, 0xda, 0x2a, 0xd2, 0xae, 0x57, 0x5b, 0xfa, 0xb6, 0xdf, - 0xca, 0x3e, 0xb1, 0xb8, 0x42, 0x0b, 0xde, 0x46, 0x36, 0xdb, 0x42, 0x33, - 0x8b, 0xda, 0x5c, 0x60, 0x44, 0x7c, 0x99, 0xb4, 0x98, 0xb4, 0x1e, 0xd8, - 0x25, 0x6d, 0x67, 0x84, 0xc9, 0x67, 0xde, 0x05, 0xe6, 0x06, 0xb5, 0xb5, - 0xca, 0xbc, 0xfa, 0xb0, 0xa7, 0x46, 0x29, 0x3f, 0x63, 0x47, 0x9d, 0x70, - 0x8d, 0xa2, 0x8d, 0x22, 0xc6, 0xeb, 0x06, 0xd4, 0x5c, 0x3b, 0x62, 0x98, - 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, - 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, 0x02, 0x82, 0x01, - 0x00, 0x56, 0x73, 0xe7, 0x1f, 0xc3, 0xb5, 0x4c, 0xe2, 0x24, 0x82, 0x5e, - 0x55, 0x76, 0x52, 0x85, 0x0a, 0xc8, 0xe9, 0x26, 0x57, 0xd8, 0x44, 0xd0, - 0x3f, 0x77, 0x8d, 0xb1, 0xe7, 0x1b, 0x93, 0xc2, 0x06, 0x1f, 0x3d, 0xc2, - 0xb1, 0xc4, 0x29, 0x80, 0x33, 0x74, 0x68, 0xf3, 0xa5, 0x22, 0xce, 0x79, - 0x1d, 0x9a, 0x6b, 0x6c, 0xcd, 0x20, 0xf5, 0xc6, 0x89, 0xc5, 0x9f, 0xf9, - 0x04, 0x89, 0xfc, 0x01, 0x19, 0x3c, 0xa3, 0x67, 0x6b, 0x94, 0xfb, 0x49, - 0x35, 0x04, 0x0e, 0xfe, 0xb8, 0x1f, 0xf1, 0x72, 0x08, 0xbd, 0xb4, 0xd1, - 0x53, 0x64, 0xc2, 0x25, 0x81, 0xfd, 0xc4, 0xd3, 0xed, 0x22, 0xbd, 0xde, - 0x9a, 0xce, 0x04, 0x16, 0xff, 0x13, 0x17, 0x98, 0x3e, 0xc1, 0x3b, 0xc7, - 0x0d, 0x03, 0x1b, 0x82, 0xd8, 0x99, 0x24, 0xd0, 0xdc, 0x30, 0xcf, 0xcd, - 0x6e, 0x5e, 0x9d, 0xfd, 0x51, 0x1e, 0xb8, 0x4e, 0x7b, 0x54, 0x83, 0x9b, - 0x4f, 0xf8, 0xa6, 0x03, 0xc1, 0x96, 0xf1, 0x6d, 0xc0, 0xa7, 0x17, 0xbd, - 0xf1, 0x60, 0xcb, 0xe2, 0x05, 0xa5, 0x9b, 0x05, 0x2e, 0xaf, 0xdc, 0xa7, - 0x88, 0xde, 0x53, 0x42, 0xa9, 0xf4, 0x0f, 0xae, 0xf9, 0x96, 0xe9, 0x2c, - 0xa6, 0xe8, 0x9d, 0x2c, 0x6b, 0xbc, 0xd8, 0x0f, 0x09, 0x5f, 0x64, 0xb2, - 0x21, 0x6f, 0xc0, 0x79, 0x3d, 0x6e, 0xad, 0x93, 0x79, 0x35, 0x87, 0x9a, - 0x41, 0xcc, 0x06, 0x24, 0xf0, 0x62, 0x09, 0xfe, 0x46, 0x9a, 0x38, 0xee, - 0xc0, 0xc8, 0x08, 0xce, 0x65, 0xda, 0xe4, 0x89, 0x1a, 0xfb, 0xe9, 0x53, - 0x0c, 0xd1, 0x80, 0x40, 0xfd, 0xc4, 0x97, 0xf8, 0x19, 0x4e, 0x03, 0x90, - 0x4a, 0xda, 0xfd, 0x13, 0x27, 0x89, 0xde, 0x12, 0x8d, 0x52, 0x5a, 0x07, - 0xf1, 0x9a, 0xa4, 0x54, 0x98, 0x86, 0xb2, 0x78, 0x76, 0xbf, 0x3a, 0xa9, - 0x8b, 0xed, 0xc7, 0x8b, 0x31, 0x02, 0x81, 0x81, 0x00, 0xe2, 0xf3, 0xab, - 0x53, 0x7b, 0xee, 0x36, 0xdb, 0xca, 0xa8, 0x74, 0x03, 0xdd, 0xe2, 0xce, - 0x87, 0xe2, 0x8c, 0x55, 0x8e, 0xd4, 0x0f, 0x32, 0xec, 0xd2, 0xf9, 0x8b, - 0x1f, 0x93, 0xdb, 0x84, 0xd2, 0x42, 0xe1, 0xc7, 0x21, 0x24, 0x2e, 0x36, - 0x0c, 0x02, 0x5d, 0x49, 0xea, 0xe0, 0x42, 0xd7, 0x7a, 0x3e, 0xc8, 0x51, - 0x92, 0x39, 0x56, 0x10, 0xd7, 0x90, 0x67, 0xa3, 0x34, 0xd6, 0xc2, 0x4a, - 0x33, 0x74, 0xfd, 0xe2, 0x7e, 0xe1, 0x3e, 0x59, 0xd7, 0x36, 0x6d, 0x7d, - 0xd4, 0xd8, 0x82, 0xfb, 0x2f, 0x1e, 0x5e, 0x32, 0xcd, 0xc3, 0x0a, 0x7f, - 0xbd, 0xb0, 0xb3, 0xf9, 0x77, 0x75, 0xb9, 0x0c, 0x63, 0x54, 0xff, 0x25, - 0xa3, 0xaf, 0x4a, 0x70, 0x61, 0x32, 0x91, 0xde, 0xfb, 0x95, 0x25, 0xb4, - 0x06, 0x98, 0x9d, 0xeb, 0x49, 0xc8, 0xe0, 0xc0, 0x7e, 0x45, 0xfb, 0xe5, - 0xf8, 0x72, 0x5b, 0x6b, 0x19, 0x02, 0x81, 0x81, 0x00, 0xc5, 0x01, 0x4b, - 0xb7, 0x5f, 0x6d, 0xbc, 0xa6, 0x8c, 0xb8, 0xeb, 0xa5, 0xff, 0x0b, 0xd7, - 0x15, 0xd7, 0xef, 0xf6, 0xc9, 0xfe, 0x69, 0xcc, 0xe5, 0xbd, 0x5c, 0xa8, - 0x05, 0xa0, 0x4d, 0x3b, 0x1f, 0xa6, 0xcc, 0x37, 0x7b, 0xb1, 0x46, 0xf2, - 0xc7, 0x67, 0xcd, 0xc1, 0x20, 0xc4, 0x14, 0xbd, 0x0e, 0x01, 0xa7, 0xd6, - 0x3c, 0xe8, 0x18, 0x9d, 0x71, 0x71, 0x37, 0x2a, 0xc0, 0x45, 0x6a, 0x54, - 0xe8, 0x63, 0xf0, 0x6e, 0xd2, 0x9f, 0x95, 0x3b, 0xde, 0xb3, 0xc5, 0x60, - 0x57, 0x3d, 0xed, 0xef, 0x57, 0xcb, 0x3d, 0x35, 0x3a, 0x2e, 0x5d, 0xb8, - 0x0e, 0xf8, 0xff, 0xd2, 0xca, 0xdd, 0xce, 0x0b, 0x10, 0x53, 0xb4, 0xdb, - 0x53, 0xf6, 0x02, 0xa5, 0xf1, 0x23, 0x4d, 0x21, 0x6e, 0xc7, 0x52, 0x5a, - 0x7a, 0x5d, 0x88, 0x32, 0xa8, 0x65, 0x50, 0x21, 0xf5, 0x81, 0x3f, 0x96, - 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, - 0x49, 0x5d, 0x08, 0xf3, 0x60, 0x42, 0xd5, 0x9a, 0x86, 0x17, 0x89, 0x5f, - 0x49, 0x63, 0x79, 0x68, 0xaf, 0x6f, 0x0a, 0xee, 0xc4, 0xab, 0xc8, 0xdc, - 0x0d, 0x6c, 0x17, 0x3c, 0x43, 0x1a, 0xf8, 0x7d, 0x0d, 0x12, 0xdc, 0xfa, - 0x8d, 0xb5, 0x10, 0x25, 0x65, 0x90, 0x36, 0x4a, 0x7c, 0x4b, 0xec, 0x9c, - 0xd8, 0x06, 0x27, 0xfa, 0x41, 0xa8, 0x53, 0x6b, 0x24, 0xf8, 0xcd, 0x23, - 0x97, 0xa3, 0x84, 0x56, 0xe7, 0x29, 0xa9, 0x5f, 0x95, 0x08, 0x9e, 0x2d, - 0x3f, 0xd1, 0xd5, 0x47, 0x51, 0x27, 0x89, 0xc7, 0x6a, 0x29, 0xce, 0x6e, - 0x23, 0xce, 0x0c, 0xbd, 0x5d, 0xfc, 0x4a, 0x9a, 0xb7, 0xe5, 0x59, 0x13, - 0xc2, 0xe6, 0xe3, 0xa1, 0xe9, 0x02, 0x81, 0x81, 0x00, 0xc3, 0x6f, 0x98, - 0xa4, 0xae, 0x97, 0xd7, 0xb9, 0xc6, 0x0a, 0xc1, 0x43, 0xa8, 0xf4, 0x1f, - 0x08, 0xfd, 0x72, 0x81, 0xfa, 0x3b, 0x58, 0xcc, 0x3a, 0xf1, 0x93, 0x54, - 0xe0, 0x57, 0xf9, 0xa5, 0xf8, 0xad, 0x69, 0x14, 0x75, 0xb2, 0x15, 0x77, - 0x4d, 0xd8, 0xad, 0xa6, 0xb5, 0x11, 0xb0, 0x9d, 0x28, 0xa2, 0xfd, 0xd4, - 0xac, 0x11, 0x78, 0x31, 0xe0, 0xd3, 0x76, 0xee, 0x03, 0x56, 0x19, 0xb9, - 0x67, 0xdd, 0x95, 0x2c, 0xeb, 0xe8, 0x02, 0x8d, 0x25, 0x4e, 0x64, 0x35, - 0x41, 0xf7, 0x1e, 0xee, 0xfc, 0xc2, 0x93, 0xd3, 0x15, 0x07, 0xe0, 0x53, - 0x73, 0x0f, 0x14, 0x03, 0x12, 0xdb, 0xdd, 0xc6, 0xde, 0x08, 0x9c, 0x77, - 0xa5, 0x20, 0x7d, 0xda, 0x0f, 0x91, 0x7c, 0xb7, 0xf9, 0x04, 0xe5, 0xae, - 0xfa, 0x8b, 0x85, 0x4c, 0xf3, 0xff, 0xa5, 0xf2, 0x3a, 0x72, 0x61, 0x1a, - 0x09, 0x47, 0x19, 0x7d, 0x7f, 0x02, 0x81, 0x80, 0x65, 0xce, 0x33, 0x53, - 0xca, 0xfb, 0xe0, 0x29, 0x83, 0x12, 0x93, 0x6c, 0xd9, 0xeb, 0x3b, 0xaa, - 0xc5, 0xc4, 0xd1, 0xb0, 0x01, 0x85, 0xba, 0xc7, 0x6d, 0xdb, 0x3f, 0x86, - 0x06, 0x4c, 0x7e, 0xc4, 0x64, 0x65, 0x14, 0x5d, 0x9c, 0xe9, 0x54, 0x62, - 0x5c, 0xf2, 0x6e, 0xe3, 0x14, 0x80, 0x48, 0x0c, 0xbc, 0xb4, 0xa1, 0xb6, - 0x6d, 0x2f, 0xa3, 0x21, 0xc0, 0xfc, 0x45, 0xa9, 0x2e, 0x3d, 0x34, 0x2d, - 0x05, 0x39, 0x4f, 0x4b, 0xf1, 0x8c, 0xd3, 0x61, 0xbb, 0x80, 0x2d, 0xa3, - 0x50, 0x5c, 0xe0, 0xf4, 0xcd, 0xff, 0x95, 0xdc, 0xa8, 0x23, 0x8f, 0x92, - 0x69, 0xcd, 0x36, 0x8a, 0xba, 0xa5, 0xe3, 0xfe, 0xce, 0x8e, 0x67, 0xc5, - 0x54, 0x41, 0x8c, 0x44, 0xc5, 0x50, 0x55, 0x7a, 0x7c, 0x91, 0xc9, 0x2e, - 0x9e, 0x32, 0x63, 0x37, 0x42, 0x68, 0x29, 0x76, 0x41, 0xdb, 0x77, 0xfd, - 0xcb, 0x6a, 0x73, 0x10}; - -extern const size_t kLicenseWhiteboxInitDataSize = - sizeof(kLicenseWhiteboxInitData); +std::vector GetLicensePrivateKey() { + return { + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xae, 0xa6, 0xa8, 0xea, 0xdd, 0xac, 0x6f, 0xb4, 0x41, 0x47, 0xcb, 0x18, + 0x81, 0xeb, 0xdf, 0x4f, 0x17, 0xf7, 0x17, 0xc0, 0xab, 0x6f, 0x47, 0x50, + 0xbf, 0xe4, 0x8c, 0xc9, 0x45, 0x24, 0x5e, 0x1c, 0x2e, 0x86, 0x9f, 0xcb, + 0x47, 0x05, 0xf9, 0xfe, 0x91, 0x90, 0xaf, 0xbd, 0x22, 0x14, 0x47, 0xa7, + 0x34, 0x39, 0x79, 0x44, 0xe9, 0x92, 0x83, 0x4a, 0x80, 0xa8, 0x2a, 0xe6, + 0x9f, 0x2b, 0xb7, 0xda, 0x2a, 0xd2, 0xae, 0x57, 0x5b, 0xfa, 0xb6, 0xdf, + 0xca, 0x3e, 0xb1, 0xb8, 0x42, 0x0b, 0xde, 0x46, 0x36, 0xdb, 0x42, 0x33, + 0x8b, 0xda, 0x5c, 0x60, 0x44, 0x7c, 0x99, 0xb4, 0x98, 0xb4, 0x1e, 0xd8, + 0x25, 0x6d, 0x67, 0x84, 0xc9, 0x67, 0xde, 0x05, 0xe6, 0x06, 0xb5, 0xb5, + 0xca, 0xbc, 0xfa, 0xb0, 0xa7, 0x46, 0x29, 0x3f, 0x63, 0x47, 0x9d, 0x70, + 0x8d, 0xa2, 0x8d, 0x22, 0xc6, 0xeb, 0x06, 0xd4, 0x5c, 0x3b, 0x62, 0x98, + 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, + 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, 0x02, 0x82, 0x01, + 0x00, 0x56, 0x73, 0xe7, 0x1f, 0xc3, 0xb5, 0x4c, 0xe2, 0x24, 0x82, 0x5e, + 0x55, 0x76, 0x52, 0x85, 0x0a, 0xc8, 0xe9, 0x26, 0x57, 0xd8, 0x44, 0xd0, + 0x3f, 0x77, 0x8d, 0xb1, 0xe7, 0x1b, 0x93, 0xc2, 0x06, 0x1f, 0x3d, 0xc2, + 0xb1, 0xc4, 0x29, 0x80, 0x33, 0x74, 0x68, 0xf3, 0xa5, 0x22, 0xce, 0x79, + 0x1d, 0x9a, 0x6b, 0x6c, 0xcd, 0x20, 0xf5, 0xc6, 0x89, 0xc5, 0x9f, 0xf9, + 0x04, 0x89, 0xfc, 0x01, 0x19, 0x3c, 0xa3, 0x67, 0x6b, 0x94, 0xfb, 0x49, + 0x35, 0x04, 0x0e, 0xfe, 0xb8, 0x1f, 0xf1, 0x72, 0x08, 0xbd, 0xb4, 0xd1, + 0x53, 0x64, 0xc2, 0x25, 0x81, 0xfd, 0xc4, 0xd3, 0xed, 0x22, 0xbd, 0xde, + 0x9a, 0xce, 0x04, 0x16, 0xff, 0x13, 0x17, 0x98, 0x3e, 0xc1, 0x3b, 0xc7, + 0x0d, 0x03, 0x1b, 0x82, 0xd8, 0x99, 0x24, 0xd0, 0xdc, 0x30, 0xcf, 0xcd, + 0x6e, 0x5e, 0x9d, 0xfd, 0x51, 0x1e, 0xb8, 0x4e, 0x7b, 0x54, 0x83, 0x9b, + 0x4f, 0xf8, 0xa6, 0x03, 0xc1, 0x96, 0xf1, 0x6d, 0xc0, 0xa7, 0x17, 0xbd, + 0xf1, 0x60, 0xcb, 0xe2, 0x05, 0xa5, 0x9b, 0x05, 0x2e, 0xaf, 0xdc, 0xa7, + 0x88, 0xde, 0x53, 0x42, 0xa9, 0xf4, 0x0f, 0xae, 0xf9, 0x96, 0xe9, 0x2c, + 0xa6, 0xe8, 0x9d, 0x2c, 0x6b, 0xbc, 0xd8, 0x0f, 0x09, 0x5f, 0x64, 0xb2, + 0x21, 0x6f, 0xc0, 0x79, 0x3d, 0x6e, 0xad, 0x93, 0x79, 0x35, 0x87, 0x9a, + 0x41, 0xcc, 0x06, 0x24, 0xf0, 0x62, 0x09, 0xfe, 0x46, 0x9a, 0x38, 0xee, + 0xc0, 0xc8, 0x08, 0xce, 0x65, 0xda, 0xe4, 0x89, 0x1a, 0xfb, 0xe9, 0x53, + 0x0c, 0xd1, 0x80, 0x40, 0xfd, 0xc4, 0x97, 0xf8, 0x19, 0x4e, 0x03, 0x90, + 0x4a, 0xda, 0xfd, 0x13, 0x27, 0x89, 0xde, 0x12, 0x8d, 0x52, 0x5a, 0x07, + 0xf1, 0x9a, 0xa4, 0x54, 0x98, 0x86, 0xb2, 0x78, 0x76, 0xbf, 0x3a, 0xa9, + 0x8b, 0xed, 0xc7, 0x8b, 0x31, 0x02, 0x81, 0x81, 0x00, 0xe2, 0xf3, 0xab, + 0x53, 0x7b, 0xee, 0x36, 0xdb, 0xca, 0xa8, 0x74, 0x03, 0xdd, 0xe2, 0xce, + 0x87, 0xe2, 0x8c, 0x55, 0x8e, 0xd4, 0x0f, 0x32, 0xec, 0xd2, 0xf9, 0x8b, + 0x1f, 0x93, 0xdb, 0x84, 0xd2, 0x42, 0xe1, 0xc7, 0x21, 0x24, 0x2e, 0x36, + 0x0c, 0x02, 0x5d, 0x49, 0xea, 0xe0, 0x42, 0xd7, 0x7a, 0x3e, 0xc8, 0x51, + 0x92, 0x39, 0x56, 0x10, 0xd7, 0x90, 0x67, 0xa3, 0x34, 0xd6, 0xc2, 0x4a, + 0x33, 0x74, 0xfd, 0xe2, 0x7e, 0xe1, 0x3e, 0x59, 0xd7, 0x36, 0x6d, 0x7d, + 0xd4, 0xd8, 0x82, 0xfb, 0x2f, 0x1e, 0x5e, 0x32, 0xcd, 0xc3, 0x0a, 0x7f, + 0xbd, 0xb0, 0xb3, 0xf9, 0x77, 0x75, 0xb9, 0x0c, 0x63, 0x54, 0xff, 0x25, + 0xa3, 0xaf, 0x4a, 0x70, 0x61, 0x32, 0x91, 0xde, 0xfb, 0x95, 0x25, 0xb4, + 0x06, 0x98, 0x9d, 0xeb, 0x49, 0xc8, 0xe0, 0xc0, 0x7e, 0x45, 0xfb, 0xe5, + 0xf8, 0x72, 0x5b, 0x6b, 0x19, 0x02, 0x81, 0x81, 0x00, 0xc5, 0x01, 0x4b, + 0xb7, 0x5f, 0x6d, 0xbc, 0xa6, 0x8c, 0xb8, 0xeb, 0xa5, 0xff, 0x0b, 0xd7, + 0x15, 0xd7, 0xef, 0xf6, 0xc9, 0xfe, 0x69, 0xcc, 0xe5, 0xbd, 0x5c, 0xa8, + 0x05, 0xa0, 0x4d, 0x3b, 0x1f, 0xa6, 0xcc, 0x37, 0x7b, 0xb1, 0x46, 0xf2, + 0xc7, 0x67, 0xcd, 0xc1, 0x20, 0xc4, 0x14, 0xbd, 0x0e, 0x01, 0xa7, 0xd6, + 0x3c, 0xe8, 0x18, 0x9d, 0x71, 0x71, 0x37, 0x2a, 0xc0, 0x45, 0x6a, 0x54, + 0xe8, 0x63, 0xf0, 0x6e, 0xd2, 0x9f, 0x95, 0x3b, 0xde, 0xb3, 0xc5, 0x60, + 0x57, 0x3d, 0xed, 0xef, 0x57, 0xcb, 0x3d, 0x35, 0x3a, 0x2e, 0x5d, 0xb8, + 0x0e, 0xf8, 0xff, 0xd2, 0xca, 0xdd, 0xce, 0x0b, 0x10, 0x53, 0xb4, 0xdb, + 0x53, 0xf6, 0x02, 0xa5, 0xf1, 0x23, 0x4d, 0x21, 0x6e, 0xc7, 0x52, 0x5a, + 0x7a, 0x5d, 0x88, 0x32, 0xa8, 0x65, 0x50, 0x21, 0xf5, 0x81, 0x3f, 0x96, + 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, + 0x49, 0x5d, 0x08, 0xf3, 0x60, 0x42, 0xd5, 0x9a, 0x86, 0x17, 0x89, 0x5f, + 0x49, 0x63, 0x79, 0x68, 0xaf, 0x6f, 0x0a, 0xee, 0xc4, 0xab, 0xc8, 0xdc, + 0x0d, 0x6c, 0x17, 0x3c, 0x43, 0x1a, 0xf8, 0x7d, 0x0d, 0x12, 0xdc, 0xfa, + 0x8d, 0xb5, 0x10, 0x25, 0x65, 0x90, 0x36, 0x4a, 0x7c, 0x4b, 0xec, 0x9c, + 0xd8, 0x06, 0x27, 0xfa, 0x41, 0xa8, 0x53, 0x6b, 0x24, 0xf8, 0xcd, 0x23, + 0x97, 0xa3, 0x84, 0x56, 0xe7, 0x29, 0xa9, 0x5f, 0x95, 0x08, 0x9e, 0x2d, + 0x3f, 0xd1, 0xd5, 0x47, 0x51, 0x27, 0x89, 0xc7, 0x6a, 0x29, 0xce, 0x6e, + 0x23, 0xce, 0x0c, 0xbd, 0x5d, 0xfc, 0x4a, 0x9a, 0xb7, 0xe5, 0x59, 0x13, + 0xc2, 0xe6, 0xe3, 0xa1, 0xe9, 0x02, 0x81, 0x81, 0x00, 0xc3, 0x6f, 0x98, + 0xa4, 0xae, 0x97, 0xd7, 0xb9, 0xc6, 0x0a, 0xc1, 0x43, 0xa8, 0xf4, 0x1f, + 0x08, 0xfd, 0x72, 0x81, 0xfa, 0x3b, 0x58, 0xcc, 0x3a, 0xf1, 0x93, 0x54, + 0xe0, 0x57, 0xf9, 0xa5, 0xf8, 0xad, 0x69, 0x14, 0x75, 0xb2, 0x15, 0x77, + 0x4d, 0xd8, 0xad, 0xa6, 0xb5, 0x11, 0xb0, 0x9d, 0x28, 0xa2, 0xfd, 0xd4, + 0xac, 0x11, 0x78, 0x31, 0xe0, 0xd3, 0x76, 0xee, 0x03, 0x56, 0x19, 0xb9, + 0x67, 0xdd, 0x95, 0x2c, 0xeb, 0xe8, 0x02, 0x8d, 0x25, 0x4e, 0x64, 0x35, + 0x41, 0xf7, 0x1e, 0xee, 0xfc, 0xc2, 0x93, 0xd3, 0x15, 0x07, 0xe0, 0x53, + 0x73, 0x0f, 0x14, 0x03, 0x12, 0xdb, 0xdd, 0xc6, 0xde, 0x08, 0x9c, 0x77, + 0xa5, 0x20, 0x7d, 0xda, 0x0f, 0x91, 0x7c, 0xb7, 0xf9, 0x04, 0xe5, 0xae, + 0xfa, 0x8b, 0x85, 0x4c, 0xf3, 0xff, 0xa5, 0xf2, 0x3a, 0x72, 0x61, 0x1a, + 0x09, 0x47, 0x19, 0x7d, 0x7f, 0x02, 0x81, 0x80, 0x65, 0xce, 0x33, 0x53, + 0xca, 0xfb, 0xe0, 0x29, 0x83, 0x12, 0x93, 0x6c, 0xd9, 0xeb, 0x3b, 0xaa, + 0xc5, 0xc4, 0xd1, 0xb0, 0x01, 0x85, 0xba, 0xc7, 0x6d, 0xdb, 0x3f, 0x86, + 0x06, 0x4c, 0x7e, 0xc4, 0x64, 0x65, 0x14, 0x5d, 0x9c, 0xe9, 0x54, 0x62, + 0x5c, 0xf2, 0x6e, 0xe3, 0x14, 0x80, 0x48, 0x0c, 0xbc, 0xb4, 0xa1, 0xb6, + 0x6d, 0x2f, 0xa3, 0x21, 0xc0, 0xfc, 0x45, 0xa9, 0x2e, 0x3d, 0x34, 0x2d, + 0x05, 0x39, 0x4f, 0x4b, 0xf1, 0x8c, 0xd3, 0x61, 0xbb, 0x80, 0x2d, 0xa3, + 0x50, 0x5c, 0xe0, 0xf4, 0xcd, 0xff, 0x95, 0xdc, 0xa8, 0x23, 0x8f, 0x92, + 0x69, 0xcd, 0x36, 0x8a, 0xba, 0xa5, 0xe3, 0xfe, 0xce, 0x8e, 0x67, 0xc5, + 0x54, 0x41, 0x8c, 0x44, 0xc5, 0x50, 0x55, 0x7a, 0x7c, 0x91, 0xc9, 0x2e, + 0x9e, 0x32, 0x63, 0x37, 0x42, 0x68, 0x29, 0x76, 0x41, 0xdb, 0x77, 0xfd, + 0xcb, 0x6a, 0x73, 0x10, + }; +} } // namespace widevine diff --git a/whitebox/impl/reference/license_whitebox_impl.cc b/whitebox/impl/reference/license_whitebox_impl.cc index 58574a1..a99937a 100644 --- a/whitebox/impl/reference/license_whitebox_impl.cc +++ b/whitebox/impl/reference/license_whitebox_impl.cc @@ -16,6 +16,7 @@ #include "crypto_utils/aes_ctr_encryptor.h" #include "crypto_utils/crypto_util.h" #include "crypto_utils/rsa_key.h" +#include "impl/reference/license_private_key.h" #include "impl/reference/memory_util.h" #include "oemcrypto/odk/include/odk.h" #include "oemcrypto/odk/include/odk_structs.h" @@ -343,27 +344,16 @@ bool IsPlatformHardwareVerified(const video_widevine::License& license) { } // namespace -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 || !whitebox) { +WB_Result WB_License_Create(WB_License_Whitebox** whitebox) { + if (whitebox == nullptr) { DVLOG(1) << "Invalid parameter: null pointer."; return WB_RESULT_INVALID_PARAMETER; } - if (whitebox_init_data_size == 0) { - DVLOG(1) << "Invalid parameter: array size 0."; - return WB_RESULT_INVALID_PARAMETER; - } - - // |whitebox_init_data| is simply the bytes of a PKCS #8 PrivateKeyInfo block - // of a RSA 2048 bit key. - std::unique_ptr key(RsaPrivateKey::Create(std::string( - whitebox_init_data, whitebox_init_data + whitebox_init_data_size))); - if (!key) { - DVLOG(1) << "Invalid parameter: invalid init data."; - return WB_RESULT_INVALID_PARAMETER; - } + const auto init_data = widevine::GetLicensePrivateKey(); + std::unique_ptr key( + RsaPrivateKey::Create(std::string(init_data.begin(), init_data.end()))); + DCHECK(key) << "Failed to load (internal) private key."; // Should always be non-null on modern compilers // (https://isocpp.org/wiki/faq/freestore-mgmt). diff --git a/whitebox/impl/reference/test_data.cc b/whitebox/impl/reference/test_data.cc deleted file mode 100644 index 6f60104..0000000 --- a/whitebox/impl/reference/test_data.cc +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2020 Google LLC. All Rights Reserved. - -#include "api/test_data.h" - -#include - -#include "crypto_utils/rsa_test_keys.h" - -std::vector GetValidAeadInitData() { - // Valid init data for our AEAD implementation is any AES key, so it just - // needs to be 16 bytes. - return { - 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, - 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, - }; -} - -std::vector GetInvalidAeadInitData() { - // Valid init data would be any 16 bytes. To avoid returning a length of - // zero, just return one byte, that way we are still returning "some data". - return {0x00}; -} - -std::vector GetLicenseInitData() { - // For the OpenSSL implementation |init_data| is simply a RSA 2048-bit - // private key. Matching public key is public_test_key_2_2048_bits(). - widevine::RsaTestKeys key_generator; - std::string init_data = key_generator.private_test_key_2_2048_bits(); - return std::vector(init_data.begin(), init_data.end()); -} - -std::vector GetMatchingLicensePublicKey() { - widevine::RsaTestKeys key_generator; - std::string init_data = key_generator.public_test_key_2_2048_bits(); - return std::vector(init_data.begin(), init_data.end()); -} - -std::vector GetInvalidLicenseInitData() { - // For the OpenSSL implementation |init_data| is a private key. So a random - // collection of bytes should not be accepted. - return {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; -}