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
This commit is contained in:
9
whitebox/.gitattributes
vendored
Normal file
9
whitebox/.gitattributes
vendored
Normal file
@@ -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
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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 <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
namespace widevine {
|
||||
|
||||
// Returns init data that the aead white-box will accept.
|
||||
std::vector<uint8_t> GetValidAeadInitData();
|
||||
|
||||
// Returns init data that the aead white-box will reject.
|
||||
std::vector<uint8_t> GetInvalidAeadInitData();
|
||||
|
||||
// Returns valid init_data needed by the license whitebox tests when calling
|
||||
// WB_License_Create().
|
||||
std::vector<uint8_t> GetLicenseInitData();
|
||||
|
||||
// Returns the matching public key for the data returned by
|
||||
// GetLicenseInitData(). The format is a DER encoded PKCS#1 RSAPublicKey.
|
||||
std::vector<uint8_t> GetMatchingLicensePublicKey();
|
||||
|
||||
// Returns invalid non-empty init_data that should be rejected by
|
||||
// WB_License_Create().
|
||||
std::vector<uint8_t> GetInvalidLicenseInitData();
|
||||
} // namespace widevine
|
||||
|
||||
#endif // WHITEBOX_API_TEST_DATA_H_
|
||||
#endif // WHITEBOX_API_AEAD_TEST_DATA_H_
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
|
||||
@@ -2,15 +2,17 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
|
||||
@@ -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_
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <vector>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -2,20 +2,12 @@
|
||||
|
||||
#include "api/license_whitebox.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t> 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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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_);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
|
||||
@@ -4,16 +4,14 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "api/test_data.h"
|
||||
#include "api/test_public_key.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
void LicenseWhiteboxTestBase::SetUp() {
|
||||
const std::vector<uint8_t> 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())));
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
|
||||
@@ -50,7 +50,7 @@ class TestLicenseBuilder {
|
||||
TestLicenseBuilder();
|
||||
|
||||
void AddSigningKey(const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& padding = NoPadding());
|
||||
const std::vector<uint8_t>& 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<uint8_t>& key_id,
|
||||
const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& padding = NoPadding());
|
||||
const std::vector<uint8_t>& 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
|
||||
|
||||
17
whitebox/api/test_public_key.h
Normal file
17
whitebox/api/test_public_key.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
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<uint8_t> GetLicensePublicKey();
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
#endif // WHITEBOX_API_TEST_PUBLIC_KEY_H_
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
24
whitebox/impl/reference/aead_test_data.cc
Normal file
24
whitebox/impl/reference/aead_test_data.cc
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
|
||||
#include "api/aead_test_data.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace widevine {
|
||||
|
||||
std::vector<uint8_t> 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<uint8_t> 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
|
||||
@@ -1,215 +1,215 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
#include "api/aead_whitebox.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t> 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<uint8_t>(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<WB_Aead_Whitebox> 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<uint8_t> 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<uint8_t> nonce(whitebox->nonce_size);
|
||||
RAND_bytes(nonce.data(), nonce.size());
|
||||
|
||||
std::vector<uint8_t> 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<uint8_t> 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 <string.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#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<uint8_t> 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<uint8_t>(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<WB_Aead_Whitebox> 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<uint8_t> 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<uint8_t> nonce(whitebox->nonce_size);
|
||||
RAND_bytes(nonce.data(), nonce.size());
|
||||
|
||||
std::vector<uint8_t> 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<uint8_t> 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;
|
||||
}
|
||||
|
||||
16
whitebox/impl/reference/license_private_key.h
Normal file
16
whitebox/impl/reference/license_private_key.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
namespace widevine {
|
||||
|
||||
// Return a RSA 2048-bit private key.
|
||||
std::vector<uint8_t> GetLicensePrivateKey();
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
#endif // WHITEBOX_IMPL_REFERENCE_LICENSE_PRIVATE_KEY_H_
|
||||
23
whitebox/impl/reference/license_test_data.cc
Normal file
23
whitebox/impl/reference/license_test_data.cc
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "api/test_public_key.h"
|
||||
#include "crypto_utils/rsa_test_keys.h"
|
||||
#include "impl/reference/license_private_key.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
std::vector<uint8_t> GetLicensePrivateKey() {
|
||||
widevine::RsaTestKeys key_generator;
|
||||
std::string init_data = key_generator.private_test_key_2_2048_bits();
|
||||
return std::vector<uint8_t>(init_data.begin(), init_data.end());
|
||||
}
|
||||
|
||||
std::vector<uint8_t> GetLicensePublicKey() {
|
||||
widevine::RsaTestKeys key_generator;
|
||||
std::string init_data = key_generator.public_test_key_2_2048_bits();
|
||||
return std::vector<uint8_t>(init_data.begin(), init_data.end());
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
@@ -3,111 +3,113 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#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<uint8_t> 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
|
||||
|
||||
@@ -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<RsaPrivateKey> 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<RsaPrivateKey> 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).
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
|
||||
#include "api/test_data.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "crypto_utils/rsa_test_keys.h"
|
||||
|
||||
std::vector<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t>(init_data.begin(), init_data.end());
|
||||
}
|
||||
|
||||
std::vector<uint8_t> GetMatchingLicensePublicKey() {
|
||||
widevine::RsaTestKeys key_generator;
|
||||
std::string init_data = key_generator.public_test_key_2_2048_bits();
|
||||
return std::vector<uint8_t>(init_data.begin(), init_data.end());
|
||||
}
|
||||
|
||||
std::vector<uint8_t> 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};
|
||||
}
|
||||
Reference in New Issue
Block a user