Merge changes Ic7459870,I655babf1,I463642fb,Iccdbcc0b,I2ebbd8f7, ... into sc-dev
* changes: Fix another typo Update license comment Update Version Compatibility Document Modify OEMCrypto unit tests to allow 16.3 or 16.4 Update OEMCrypto test comments and logs Update OEMCryptoCENC.h header to obfuscate missing functions Clean up duration tests Use either spelling of AllocateSecureBuffer in dynamic adapter Update ODK library for OPK compatibility
This commit is contained in:
committed by
Android (Google) Code Review
commit
c1d423487f
@@ -885,6 +885,16 @@ class Adapter {
|
||||
LOOKUP_ALL(16, MinorAPIVersion, OEMCrypto_MinorAPIVersion);
|
||||
// clang-format on
|
||||
|
||||
// There was a mistake in version 16.3 of the header that did not rename
|
||||
// OEMCrypto_AllocateSecureBuffer or OEMCrypto_FreeSecureBuffer
|
||||
if (level1_.AllocateSecureBuffer == NULL ||
|
||||
level1_.FreeSecureBuffer == NULL) {
|
||||
level1_.AllocateSecureBuffer = (L1_AllocateSecureBuffer_t)dlsym(
|
||||
level1_library_, "OEMCrypto_AllocateSecureBuffer");
|
||||
level1_.FreeSecureBuffer = (L1_FreeSecureBuffer_t)dlsym(
|
||||
level1_library_, "OEMCrypto_FreeSecureBuffer");
|
||||
}
|
||||
|
||||
// TODO(119830252): make the code below available to a static adapter.
|
||||
// Check if the keybox or oem certificate is valid, if so, we are finished
|
||||
// with initialization.
|
||||
|
||||
@@ -468,7 +468,7 @@ class CdmDurationTest : public WvCdmTestBaseWithEngine,
|
||||
//
|
||||
// In the document, we use realistic rental times in hours or days. In these
|
||||
// tests, we will use round numbers so that it is easier to read. For example,
|
||||
// instead of a seven day rental duration, we will use a 200 rental duration.
|
||||
// instead of a seven day rental duration, we will use a 100 rental duration.
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -477,8 +477,6 @@ class CdmDurationTest : public WvCdmTestBaseWithEngine,
|
||||
class CdmUseCase_Streaming : public CdmDurationTest {
|
||||
public:
|
||||
CdmUseCase_Streaming() : CdmDurationTest("CDM_Streaming") {
|
||||
// Rental duration = 3 hours hard. (use 300 for readability)
|
||||
// Playback duration = 0 (unlimited)
|
||||
timer_limits_.soft_enforce_rental_duration = false;
|
||||
timer_limits_.rental_duration_seconds = 40;
|
||||
timer_limits_.total_playback_duration_seconds = 0;
|
||||
@@ -1055,11 +1053,11 @@ class RenewalTest : public CdmDurationTest {
|
||||
void LoadRenewal(uint64_t time_of_load, const RenewalPolicy& renewal_policy) {
|
||||
ASSERT_NE(renewal_in_flight_, nullptr);
|
||||
std::string http_response;
|
||||
// TODO(fredgc): Tune this. Most of the network latency will probably show
|
||||
// up in the next few commands. I think the tests have enough slop to
|
||||
// account for reasonable latency with the current value of
|
||||
// kRoundTripTime. But We'll know I made a mistake if we see errors about
|
||||
// "Test Clock skew..." in the SleepUntil call below.
|
||||
// Most of the network latency will probably show up in the next few
|
||||
// commands. I think the tests have enough slop to account for reasonable
|
||||
// latency with the current value of kRoundTripTime. But We'll know I made a
|
||||
// mistake if we see errors about "Test Clock skew..." in the SleepUntil
|
||||
// call below.
|
||||
ASSERT_TRUE(renewal_in_flight_->GetResponse(&http_response));
|
||||
int status_code = renewal_in_flight_->GetStatusCode(http_response);
|
||||
ASSERT_EQ(kHttpOk, status_code);
|
||||
@@ -1683,9 +1681,9 @@ INSTANTIATE_TEST_CASE_P(Both, CdmUseCase_UnlimitedStreaming,
|
||||
class CdmUseCase_LicenseDuration : public CdmDurationTest {
|
||||
public:
|
||||
CdmUseCase_LicenseDuration() : CdmDurationTest("CDM_LicenseDuration") {
|
||||
// Rental duration = 3 hours hard. (use 300 for readability)
|
||||
// Playback duration = 0 (unlimited)
|
||||
timer_limits_.soft_enforce_rental_duration = true;
|
||||
// The policy does not specify a rental duration, but the server adjusts it
|
||||
// so that it looks like this to a v16 device.
|
||||
timer_limits_.rental_duration_seconds = 40u;
|
||||
timer_limits_.soft_enforce_playback_duration = false;
|
||||
timer_limits_.total_playback_duration_seconds = 40u;
|
||||
@@ -1695,13 +1693,18 @@ class CdmUseCase_LicenseDuration : public CdmDurationTest {
|
||||
// Playback within rental duration.
|
||||
TEST_P(CdmUseCase_LicenseDuration, Case1) {
|
||||
// Allow playback within the playback window.
|
||||
LoadAndAllowPlayback(start_of_playback_, EndOfPlaybackWindow());
|
||||
LoadAndAllowPlayback(start_of_playback_, EndOfRentalWindow());
|
||||
}
|
||||
|
||||
// Playback exceeds rental duration.
|
||||
TEST_P(CdmUseCase_LicenseDuration, Case2) {
|
||||
// Allow playback within the playback window, but not beyond.
|
||||
LoadAndTerminatePlayback(start_of_playback_, EndOfPlaybackWindow());
|
||||
LoadAndAllowPlayback(start_of_playback_, EndOfRentalWindow());
|
||||
// Do not allow playback after playback window. For a v16 CDM with a v15
|
||||
// OEMCrypto, playback is cutoff at the rental window, and for a v16 CDM with
|
||||
// a v16 OEMCrypto, playback is allowed a little longer. In both cases,
|
||||
// playback is not allowed after the end of the playback window.
|
||||
SleepUntil(EndOfPlaybackWindow() + kFudge);
|
||||
FailDecrypt();
|
||||
}
|
||||
|
||||
// Playback with stops/restarts within rental duration, last one exceeds
|
||||
@@ -1713,8 +1716,12 @@ TEST_P(CdmUseCase_LicenseDuration, Case3) {
|
||||
start_of_playback_ + 3 * kPlayDuration);
|
||||
UnloadLicense();
|
||||
AllowLenience();
|
||||
LoadAndTerminatePlayback(start_of_playback_ + 4 * kPlayDuration,
|
||||
EndOfPlaybackWindow());
|
||||
LoadAndAllowPlayback(start_of_playback_ + 4 * kPlayDuration,
|
||||
EndOfRentalWindow());
|
||||
// As above, do not allow playback after playback window.
|
||||
AllowLenience();
|
||||
SleepUntil(EndOfPlaybackWindow() + kFudge);
|
||||
FailDecrypt();
|
||||
}
|
||||
|
||||
// Playback within rental duration, restart exceeds playback duration.
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/**
|
||||
@@ -480,8 +480,8 @@ typedef enum OEMCrypto_ProvisioningMethod {
|
||||
OEMCrypto_ProvisioningError = 0, // Device cannot be provisioned.
|
||||
OEMCrypto_DrmCertificate = 1, // Device has baked in DRM certificate
|
||||
// (level 3 only)
|
||||
OEMCrypto_Keybox = 2, // Device has factory installed unique keybox.
|
||||
OEMCrypto_OEMCertificate = 3 // Device has factory installed OEM certificate.
|
||||
OEMCrypto_Keybox = 2, // Device has factory installed unique keybox.
|
||||
OEMCrypto_OEMCertificate = 3 // Device has factory installed OEM certificate.
|
||||
} OEMCrypto_ProvisioningMethod;
|
||||
|
||||
/**
|
||||
@@ -489,7 +489,7 @@ typedef enum OEMCrypto_ProvisioningMethod {
|
||||
*/
|
||||
#define OEMCrypto_Supports_RSA_2048bit 0x1
|
||||
#define OEMCrypto_Supports_RSA_3072bit 0x2
|
||||
#define OEMCrypto_Supports_RSA_CAST 0x10
|
||||
#define OEMCrypto_Supports_RSA_CAST 0x10
|
||||
#define OEMCrypto_Supports_ECC_secp256r1 0x100
|
||||
#define OEMCrypto_Supports_ECC_secp384r1 0x200
|
||||
#define OEMCrypto_Supports_ECC_secp521r1 0x400
|
||||
@@ -504,12 +504,12 @@ typedef enum OEMCrypto_ProvisioningMethod {
|
||||
/**
|
||||
* Return values from OEMCrypto_GetAnalogOutputFlags.
|
||||
*/
|
||||
#define OEMCrypto_No_Analog_Output 0x0
|
||||
#define OEMCrypto_Supports_Analog_Output 0x1
|
||||
#define OEMCrypto_Can_Disable_Analog_Ouptput 0x2
|
||||
#define OEMCrypto_Supports_CGMS_A 0x4
|
||||
#define OEMCrypto_No_Analog_Output 0x0
|
||||
#define OEMCrypto_Supports_Analog_Output 0x1
|
||||
#define OEMCrypto_Can_Disable_Analog_Ouptput 0x2
|
||||
#define OEMCrypto_Supports_CGMS_A 0x4
|
||||
// Unknown_Analog_Output is used only for backwards compatibility.
|
||||
#define OEMCrypto_Unknown_Analog_Output (1<<31)
|
||||
#define OEMCrypto_Unknown_Analog_Output (1 << 31)
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -622,6 +622,8 @@ typedef enum OEMCrypto_ProvisioningMethod {
|
||||
#define OEMCrypto_DecryptCENC _oecc105
|
||||
#define OEMCrypto_LoadDRMPrivateKey _oecc107
|
||||
#define OEMCrypto_MinorAPIVersion _oecc108
|
||||
#define OEMCrypto_AllocateSecureBuffer _oecc109
|
||||
#define OEMCrypto_FreeSecureBuffer _oecc110
|
||||
// clang-format on
|
||||
|
||||
/// @addtogroup initcontrol
|
||||
@@ -956,7 +958,7 @@ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
|
||||
/**
|
||||
* OEMCrypto will use ODK_PrepareCoreLicenseRequest to prepare the core
|
||||
* message. If it returns OEMCrypto_SUCCESS, then OEMCrypto shall sign the
|
||||
* the message body using the DRM certificate's private key. If it returns an
|
||||
* message body using the DRM certificate's private key. If it returns an
|
||||
* error, the error should be returned by OEMCrypto to the CDM layer.
|
||||
* ODK_PrepareCoreLicenseRequest is described in the document "Widevine Core
|
||||
* Message Serialization".
|
||||
@@ -1667,6 +1669,7 @@ OEMCryptoResult OEMCrypto_LoadKeys(
|
||||
* @param[in] signature: pointer to memory containing the signature.
|
||||
* @param[in] signature_length: length of the signature, in bytes.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS success OEMCrypto_ERROR_NO_DEVICE_KEY
|
||||
* @retval OEMCrypto_SUCCESS success
|
||||
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
|
||||
* @retval OEMCrypto_ERROR_INVALID_SESSION
|
||||
@@ -3011,10 +3014,10 @@ OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* device_id,
|
||||
/**
|
||||
* Return the Key Data field from the Keybox.
|
||||
*
|
||||
* @param[out] keyData: pointer to the buffer to hold the Key Data field from
|
||||
* @param[out] key_data: pointer to the buffer to hold the Key Data field from
|
||||
* the Keybox
|
||||
* @param[in,out] keyDataLength: on input, the allocated buffer size. On output,
|
||||
* the number of bytes in Key Data
|
||||
* @param[in,out] key_data_length: on input, the allocated buffer size. On
|
||||
* output, the number of bytes in Key Data
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS success
|
||||
* @retval OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return
|
||||
@@ -4722,12 +4725,25 @@ OEMCryptoResult OEMCrypto_FreeSecureBuffer(
|
||||
* current version of OEMCrypto. They are being declared here to help with
|
||||
* backwards compatibility.
|
||||
*/
|
||||
|
||||
/*
|
||||
* OEMCrypto_GenerateSignature
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_GenerateSignature(OEMCrypto_SESSION session,
|
||||
const uint8_t* message,
|
||||
size_t message_length,
|
||||
uint8_t* signature,
|
||||
size_t* signature_length);
|
||||
|
||||
/*
|
||||
* OEMCrypto_RewrapDeviceRSAKey30
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
||||
OEMCrypto_SESSION session, const uint32_t* unaligned_nonce,
|
||||
const uint8_t* encrypted_message_key, size_t encrypted_message_key_length,
|
||||
@@ -4735,6 +4751,12 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
||||
const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key,
|
||||
size_t* wrapped_rsa_key_length);
|
||||
|
||||
/*
|
||||
* OEMCrypto_RewrapDeviceRSAKey
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
|
||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||
const uint8_t* signature, size_t signature_length,
|
||||
@@ -4742,26 +4764,70 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
|
||||
size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv,
|
||||
uint8_t* wrapped_rsa_key, size_t* wrapped_rsa_key_length);
|
||||
|
||||
/*
|
||||
* OEMCrypto_UpdateUsageTable
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_UpdateUsageTable(void);
|
||||
|
||||
OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION, const uint8_t*,
|
||||
size_t, const uint8_t*, size_t,
|
||||
const uint8_t*, size_t);
|
||||
/*
|
||||
* OEMCrypto_DeleteUsageEntry
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_DeleteUsageEntry(
|
||||
OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length,
|
||||
const uint8_t* message, size_t message_length, const uint8_t* signature,
|
||||
size_t signature_length);
|
||||
|
||||
OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t*, size_t);
|
||||
/*
|
||||
* OEMCrypto_ForceDeleteUsageEntry
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst,
|
||||
size_t pst_length);
|
||||
|
||||
/*
|
||||
* OEMCrypto_CopyOldUsageEntry
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_CopyOldUsageEntry(OEMCrypto_SESSION session,
|
||||
const uint8_t* pst,
|
||||
size_t pst_length);
|
||||
|
||||
/*
|
||||
* OEMCrypto_DeleteOldUsageTable
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_DeleteOldUsageTable(void);
|
||||
|
||||
/*
|
||||
* OEMCrypto_CreateOldUsageEntry
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_CreateOldUsageEntry(
|
||||
uint64_t time_since_license_received, uint64_t time_since_first_decrypt,
|
||||
uint64_t time_since_last_decrypt, OEMCrypto_Usage_Entry_Status status,
|
||||
uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst,
|
||||
size_t pst_length);
|
||||
|
||||
/*
|
||||
* OEMCrypto_GenerateDerivedKeys_V15
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_GenerateDerivedKeys_V15(
|
||||
OEMCrypto_SESSION session, const uint8_t* mac_key_context,
|
||||
uint32_t mac_key_context_length, const uint8_t* enc_key_context,
|
||||
@@ -4773,18 +4839,36 @@ typedef struct {
|
||||
size_t offset; // offset into the pattern in blocks for this call.
|
||||
} OEMCrypto_CENCEncryptPatternDesc_V15;
|
||||
|
||||
/*
|
||||
* OEMCrypto_DecryptCENC_V15
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_DecryptCENC_V15(
|
||||
OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length,
|
||||
bool is_encrypted, const uint8_t* iv,
|
||||
OEMCrypto_SESSION session, const uint8_t* data_addr,
|
||||
size_t data_addr_length, bool is_encrypted, const uint8_t* iv,
|
||||
size_t block_offset, // used for CTR "cenc" mode only.
|
||||
OEMCrypto_DestBufferDesc* out_buffer_descriptor,
|
||||
OEMCrypto_DestBufferDesc* out_buffer,
|
||||
const OEMCrypto_CENCEncryptPatternDesc_V15* pattern,
|
||||
uint8_t subsample_flags);
|
||||
|
||||
/*
|
||||
* OEMCrypto_GetOEMPublicCertificate_V15
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_GetOEMPublicCertificate_V15(
|
||||
OEMCrypto_SESSION session, uint8_t* public_cert,
|
||||
size_t* public_cert_length);
|
||||
|
||||
/*
|
||||
* OEMCrypto_LoadDeviceRSAKey
|
||||
* @deprecated
|
||||
* Not required for the current version of OEMCrypto. Declared here to
|
||||
* help with backward compatibility.
|
||||
*/
|
||||
OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
|
||||
const uint8_t* wrapped_rsa_key,
|
||||
size_t wrapped_rsa_key_length);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
@@ -96,7 +96,6 @@ namespace wvoec3 {
|
||||
#define Level3_AllocateSecureBuffer _lcc111
|
||||
#define Level3_FreeSecureBuffer _lcc112
|
||||
#else
|
||||
#define Level3_IsInApp _oecc00
|
||||
#define Level3_Initialize _oecc01
|
||||
#define Level3_Terminate _oecc02
|
||||
#define Level3_InstallKeyboxOrOEMCert _oecc03
|
||||
@@ -173,11 +172,11 @@ namespace wvoec3 {
|
||||
// of the two functions below. This is to be fixed when
|
||||
// OEMCrypto_AllocateSecureBuffer and OEMCrypto_FreeSecureBuffer are added to
|
||||
// OEMCryptoCENC.h
|
||||
#define Level3_AllocateSecureBuffer OEMCrypto_AllocateSecureBuffer
|
||||
#define Level3_FreeSecureBuffer OEMCrypto_FreeSecureBuffer
|
||||
#define Level3_AllocateSecureBuffer OEMCrypto_AllocateSecureBuffer
|
||||
#define Level3_FreeSecureBuffer OEMCrypto_FreeSecureBuffer
|
||||
#endif
|
||||
|
||||
#define Level3_GetInitializationState _oecl3o01
|
||||
#define Level3_GetInitializationState _oecl3o01
|
||||
// clang-format on
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WV_OEMCRYPTO_TYPES_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@@ -27,6 +27,7 @@ cc_library_static {
|
||||
|
||||
srcs: [
|
||||
"src/odk.c",
|
||||
"src/odk_message.c",
|
||||
"src/odk_overflow.c",
|
||||
"src/odk_serialize.c",
|
||||
"src/odk_timer.c",
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
This ODK Library is used to generate and parse core OEMCrypto messages for
|
||||
OEMCrypto v16 and above.
|
||||
|
||||
This library is used by both OEMCrypto on a device, and by Widevine license and
|
||||
provisioning servers.
|
||||
OEMCrypto v16 and above. This library is used by both OEMCrypto on a device
|
||||
and by Widevine license and provisioning servers.
|
||||
|
||||
The source of truth for these files is in the server code base on piper. Do not
|
||||
edit these files in the Android directory tree or in the Widevine Git
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
@@ -87,6 +87,7 @@ typedef enum OEMCryptoResult {
|
||||
OEMCrypto_ERROR_LICENSE_RELOAD = 57,
|
||||
OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES = 58,
|
||||
OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION = 59,
|
||||
OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION = 60,
|
||||
/* ODK return values */
|
||||
ODK_ERROR_BASE = 1000,
|
||||
ODK_ERROR_CORE_MESSAGE = ODK_ERROR_BASE,
|
||||
@@ -116,7 +117,7 @@ typedef enum OEMCrypto_Usage_Entry_Status {
|
||||
typedef enum OEMCrypto_LicenseType {
|
||||
OEMCrypto_ContentLicense = 0,
|
||||
OEMCrypto_EntitlementLicense = 1,
|
||||
OEMCrypto_LicenstType_MaxValue = OEMCrypto_EntitlementLicense,
|
||||
OEMCrypto_LicenseType_MaxValue = OEMCrypto_EntitlementLicense,
|
||||
} OEMCrypto_LicenseType;
|
||||
|
||||
/* Private key type used in the provisioning response. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
// clang-format off
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_ODK_ATTRIBUTES_H_
|
||||
|
||||
143
libwvdrmengine/oemcrypto/odk/include/odk_message.h
Normal file
143
libwvdrmengine/oemcrypto/odk/include/odk_message.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_ODK_MESSAGE_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_ODK_MESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* ODK_Message is the structure that defines the serialized messages passed
|
||||
* between the REE and TEE. ODK_Message is an abstract data type that represents
|
||||
* the concept of a message without disclosing the implementation details. By
|
||||
* hiding the internal structure, modification of the message fields by code
|
||||
* that is not privy to the message definition can be prevented. If the message
|
||||
* definition was exposed, there could be serious yet subtle errors in message
|
||||
* manipulation anywhere in the code base. By restricting message modification
|
||||
* it is possible to enforce validity and integrity with a small set of
|
||||
* primitives that can be carefully reviewed. Checks can be added to verify that
|
||||
* a message's fields are internally consistent before every operation. As an
|
||||
* example, it can be guaranteed that the message status will be checked prior
|
||||
* to accessing any field so parsing will be stopped when the message status is
|
||||
* set after any parse error is detected. This also makes development easier
|
||||
* since any access to the message structure can be tracked through a single
|
||||
* point so, for example, it becomes possible to add trace statements globally
|
||||
* to all message operations by only changing the field accessors. Finally it
|
||||
* simplifies maintenance by localizing changes to the message structure to a
|
||||
* few files.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
# define ALIGNED __attribute__((aligned))
|
||||
#else
|
||||
# define ALIGNED
|
||||
# error ODK_Message must be aligned to the maximum useful alignment of the \
|
||||
machine you are compiling for. Define the ALIGNED macro accordingly.
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#define SIZE_OF_ODK_MESSAGE_IMPL 64
|
||||
uint8_t opaque_data[SIZE_OF_ODK_MESSAGE_IMPL];
|
||||
} ALIGNED ODK_Message;
|
||||
|
||||
typedef enum {
|
||||
MESSAGE_STATUS_OK = 0xe937fcf7,
|
||||
MESSAGE_STATUS_UNKNOWN_ERROR = 0xe06c1190,
|
||||
MESSAGE_STATUS_OVERFLOW_ERROR = 0xc43ae4bc,
|
||||
MESSAGE_STATUS_UNDERFLOW_ERROR = 0x7123cd0b,
|
||||
MESSAGE_STATUS_PARSE_ERROR = 0x0b9f6189,
|
||||
MESSAGE_STATUS_NULL_POINTER_ERROR = 0x2d66837a,
|
||||
MESSAGE_STATUS_API_VALUE_ERROR = 0x6ba34f47,
|
||||
MESSAGE_STATUS_END_OF_MESSAGE_ERROR = 0x998db72a,
|
||||
MESSAGE_STATUS_INVALID_ENUM_VALUE = 0xedb88197,
|
||||
MESSAGE_STATUS_INVALID_TAG_ERROR = 0x14dce06a,
|
||||
MESSAGE_STATUS_NOT_INITIALIZED = 0x2990b6c6,
|
||||
MESSAGE_STATUS_OUT_OF_MEMORY = 0xfc5c64cc,
|
||||
MESSAGE_STATUS_MAP_SHARED_MEMORY_FAILED = 0xfafecacf,
|
||||
MESSAGE_STATUS_SECURE_BUFFER_ERROR = 0x78f0e873
|
||||
} ODK_MessageStatus;
|
||||
|
||||
/*
|
||||
* Create a message structure that references a separate data buffer. An
|
||||
* initialized message is returned. The caller is responsible for ensuring that
|
||||
* the buffer remains allocated for the lifetime of the message. If |buffer|
|
||||
* is NULL or |capacity| is zero, the message is invalid and the status
|
||||
* will be set to MESSAGE_STATUS_NOT_INITIALIZED.
|
||||
*/
|
||||
ODK_Message ODK_Message_Create(uint8_t* buffer, size_t capacity);
|
||||
|
||||
/*
|
||||
* Erase the contents of the message, set it to an empty state by setting the
|
||||
* message size and read offset to 0, effectively erasing the contents of the
|
||||
* message. The message data buffer pointer remains unchanged, i.e. the message
|
||||
* retains ownership of the buffer. The message status is reset to
|
||||
* MESSAGE_STATUS_OK.
|
||||
*/
|
||||
void ODK_Message_Clear(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Reset read pointer to the beginning of the message and clear status
|
||||
* so that parsing of the message will restart at the beginning of the
|
||||
* message. The message status is reset to MESSAGE_STATUS_OK.
|
||||
*/
|
||||
void ODK_Message_Reset(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Return a pointer to the message data buffer, i.e. the message payload.
|
||||
* This is the buffer address that was passed into ODK_Message_Create.
|
||||
*/
|
||||
uint8_t* ODK_Message_GetBase(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Get the maximum number of bytes the message can hold.
|
||||
*/
|
||||
size_t ODK_Message_GetCapacity(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Get the number of bytes currently in the message
|
||||
*/
|
||||
size_t ODK_Message_GetSize(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Get the offset of where the next bytes will be read from the message data
|
||||
* buffer.
|
||||
*/
|
||||
size_t ODK_Message_GetOffset(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Return the status of the message
|
||||
*/
|
||||
ODK_MessageStatus ODK_Message_GetStatus(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Set the message status to a specific value
|
||||
*/
|
||||
void ODK_Message_SetStatus(ODK_Message* message, ODK_MessageStatus status);
|
||||
|
||||
/*
|
||||
* Set the size of the message to a value. This may be needed after writing data
|
||||
* into the message data buffer.
|
||||
*/
|
||||
void ODK_Message_SetSize(ODK_Message* message, size_t size);
|
||||
|
||||
/*
|
||||
* Test if the integrity of a message. This means that the status must be
|
||||
* MESSAGE_STATUS_OK and that the internal fields of the message are
|
||||
* within the range of valid values.
|
||||
*/
|
||||
bool ODK_Message_IsValid(ODK_Message* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_ODK_MESSAGE_H_
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
|
||||
@@ -12,10 +12,14 @@
|
||||
|
||||
/* The version of this library. */
|
||||
#define ODK_MAJOR_VERSION 16
|
||||
#define ODK_MINOR_VERSION 3
|
||||
// TODO(b/163416999): Do not change minor version to 16.5 on master branch. The
|
||||
// version 16.5 is reserved for Alcatraz, iOS, and other L3 platforms using
|
||||
// third-party obfuscation tools. The version should not be used for CE CDM or
|
||||
// Android CDM. We should jump straight to 17.0.
|
||||
#define ODK_MINOR_VERSION 4
|
||||
|
||||
/* ODK Version string. Date changed automatically on each release. */
|
||||
#define ODK_RELEASE_DATE "ODK v16.3 2020-08-18"
|
||||
#define ODK_RELEASE_DATE "ODK v16.4 2020-10-23"
|
||||
|
||||
/* The lowest version number for an ODK message. */
|
||||
#define ODK_FIRST_VERSION 16
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file is distributed
|
||||
// under the Widevine Master License Agreement.
|
||||
// under the Widevine License Agreement.
|
||||
|
||||
// Partners are expected to edit this file to support target specific code
|
||||
// and limits.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "core_message_deserialize.h"
|
||||
@@ -39,13 +39,11 @@ bool ParseRequest(uint32_t message_type,
|
||||
reinterpret_cast<const uint8_t*>(oemcrypto_core_message.c_str());
|
||||
const size_t buf_length = oemcrypto_core_message.size();
|
||||
|
||||
uint8_t blk[SIZE_OF_MESSAGE_STRUCT];
|
||||
Message* msg = reinterpret_cast<Message*>(blk);
|
||||
InitMessage(msg, const_cast<uint8_t*>(buf), buf_length);
|
||||
SetSize(msg, buf_length);
|
||||
ODK_Message msg = ODK_Message_Create(const_cast<uint8_t*>(buf), buf_length);
|
||||
ODK_Message_SetSize(&msg, buf_length);
|
||||
|
||||
unpacker(msg, prepared);
|
||||
if (!ValidMessage(msg)) {
|
||||
unpacker(&msg, prepared);
|
||||
if (!ODK_Message_IsValid(&msg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -80,7 +78,7 @@ bool ParseRequest(uint32_t message_type,
|
||||
// than the total message size. We allow the total message size to be larger
|
||||
// for forward compatibility because future messages might have extra fields
|
||||
// that we can ignore.
|
||||
if (core_message.message_length < GetOffset(msg)) return false;
|
||||
if (core_message.message_length < ODK_Message_GetOffset(&msg)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "core_message_serialize.h"
|
||||
@@ -50,18 +50,16 @@ bool CreateResponse(uint32_t message_type, const S& core_request,
|
||||
|
||||
static constexpr size_t BUF_CAPACITY = 2048;
|
||||
std::vector<uint8_t> buf(BUF_CAPACITY, 0);
|
||||
uint8_t blk[SIZE_OF_MESSAGE_STRUCT];
|
||||
Message* msg = reinterpret_cast<Message*>(blk);
|
||||
InitMessage(msg, buf.data(), buf.capacity());
|
||||
packer(msg, &response);
|
||||
if (!ValidMessage(msg)) {
|
||||
ODK_Message msg = ODK_Message_Create(buf.data(), buf.capacity());
|
||||
packer(&msg, &response);
|
||||
if (!ODK_Message_IsValid(&msg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t message_length = GetSize(msg);
|
||||
InitMessage(msg, buf.data() + sizeof(header->message_type),
|
||||
sizeof(header->message_length));
|
||||
Pack_uint32_t(msg, &message_length);
|
||||
uint32_t message_length = ODK_Message_GetSize(&msg);
|
||||
msg = ODK_Message_Create(buf.data() + sizeof(header->message_type),
|
||||
sizeof(header->message_length));
|
||||
Pack_uint32_t(&msg, &message_length);
|
||||
oemcrypto_core_message->assign(reinterpret_cast<const char*>(buf.data()),
|
||||
message_length);
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "core_message_serialize_proto.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "odk.h"
|
||||
@@ -27,9 +27,7 @@ static OEMCryptoResult ODK_PrepareRequest(
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
|
||||
uint8_t blk[SIZE_OF_MESSAGE_STRUCT];
|
||||
Message* msg = (Message*)blk;
|
||||
InitMessage(msg, message, *core_message_length);
|
||||
ODK_Message msg = ODK_Message_Create(message, *core_message_length);
|
||||
|
||||
/* The core message should be at the beginning of the buffer, and with a
|
||||
* shorter length. */
|
||||
@@ -52,7 +50,7 @@ static OEMCryptoResult ODK_PrepareRequest(
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
Pack_ODK_PreparedLicenseRequest(
|
||||
msg, (ODK_PreparedLicenseRequest*)prepared_request_buffer);
|
||||
&msg, (ODK_PreparedLicenseRequest*)prepared_request_buffer);
|
||||
break;
|
||||
}
|
||||
case ODK_Renewal_Request_Type: {
|
||||
@@ -61,7 +59,7 @@ static OEMCryptoResult ODK_PrepareRequest(
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
Pack_ODK_PreparedRenewalRequest(
|
||||
msg, (ODK_PreparedRenewalRequest*)prepared_request_buffer);
|
||||
&msg, (ODK_PreparedRenewalRequest*)prepared_request_buffer);
|
||||
break;
|
||||
}
|
||||
case ODK_Provisioning_Request_Type: {
|
||||
@@ -71,7 +69,7 @@ static OEMCryptoResult ODK_PrepareRequest(
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
Pack_ODK_PreparedProvisioningRequest(
|
||||
msg, (ODK_PreparedProvisioningRequest*)prepared_request_buffer);
|
||||
&msg, (ODK_PreparedProvisioningRequest*)prepared_request_buffer);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -80,13 +78,13 @@ static OEMCryptoResult ODK_PrepareRequest(
|
||||
}
|
||||
|
||||
*core_message_length = core_message->message_length;
|
||||
if (GetStatus(msg) != MESSAGE_STATUS_OK) {
|
||||
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK) {
|
||||
/* This is to indicate the caller that the core_message_length has been
|
||||
* appropriately set, but the message buffer is either empty or too small,
|
||||
* which needs to be initialized and filled in the subsequent call. */
|
||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||
}
|
||||
if (GetSize(msg) != *core_message_length) {
|
||||
if (ODK_Message_GetSize(&msg) != *core_message_length) {
|
||||
/* This should not happen. Something is wrong. */
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
@@ -102,20 +100,11 @@ static OEMCryptoResult ODK_ParseResponse(
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
|
||||
uint8_t blk[SIZE_OF_MESSAGE_STRUCT];
|
||||
Message* msg = (Message*)blk;
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
/* We initialize the message buffer with a size of the entire message
|
||||
* length. */
|
||||
/* TODO(b/164486737): Fix the cast-qual warning */
|
||||
InitMessage(msg, (uint8_t*)message, message_length);
|
||||
#pragma GCC diagnostic pop
|
||||
ODK_Message msg = ODK_Message_Create((uint8_t*)message, message_length);
|
||||
|
||||
/* The core message should be at the beginning of the buffer, and with a
|
||||
* shorter length. The core message is the part we are parsing. */
|
||||
SetSize(msg, core_message_length);
|
||||
ODK_Message_SetSize(&msg, core_message_length);
|
||||
|
||||
/* Parse message and unpack it into response buffer. */
|
||||
switch (message_type) {
|
||||
@@ -123,14 +112,14 @@ static OEMCryptoResult ODK_ParseResponse(
|
||||
if (sizeof(ODK_LicenseResponse) > response_buffer_length) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
Unpack_ODK_LicenseResponse(msg, (ODK_LicenseResponse*)response_buffer);
|
||||
Unpack_ODK_LicenseResponse(&msg, (ODK_LicenseResponse*)response_buffer);
|
||||
break;
|
||||
}
|
||||
case ODK_Renewal_Response_Type: {
|
||||
if (sizeof(ODK_RenewalResponse) > response_buffer_length) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
Unpack_ODK_RenewalResponse(msg, (ODK_RenewalResponse*)response_buffer);
|
||||
Unpack_ODK_RenewalResponse(&msg, (ODK_RenewalResponse*)response_buffer);
|
||||
break;
|
||||
}
|
||||
case ODK_Provisioning_Response_Type: {
|
||||
@@ -138,7 +127,7 @@ static OEMCryptoResult ODK_ParseResponse(
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
Unpack_ODK_ProvisioningResponse(
|
||||
msg, (ODK_ProvisioningResponse*)response_buffer);
|
||||
&msg, (ODK_ProvisioningResponse*)response_buffer);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -147,9 +136,9 @@ static OEMCryptoResult ODK_ParseResponse(
|
||||
}
|
||||
|
||||
ODK_CoreMessage* core_message = (ODK_CoreMessage*)response_buffer;
|
||||
if (GetStatus(msg) != MESSAGE_STATUS_OK ||
|
||||
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
|
||||
message_type != core_message->message_type ||
|
||||
GetOffset(msg) != core_message->message_length) {
|
||||
ODK_Message_GetOffset(&msg) != core_message->message_length) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
|
||||
@@ -307,20 +296,24 @@ OEMCryptoResult ODK_ParseLicense(
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
|
||||
if (parsed_license->nonce_required) {
|
||||
if (initial_license_load) {
|
||||
if (nonce_values->nonce !=
|
||||
license_response.request.core_message.nonce_values.nonce ||
|
||||
nonce_values->session_id !=
|
||||
license_response.request.core_message.nonce_values.session_id) {
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
}
|
||||
} else { /* !initial_license_load */
|
||||
nonce_values->nonce =
|
||||
license_response.request.core_message.nonce_values.nonce;
|
||||
nonce_values->session_id =
|
||||
license_response.request.core_message.nonce_values.session_id;
|
||||
/* If this is the first time we load this license, then we verify that the
|
||||
* nonce values are the correct, otherwise we copy the nonce values. If the
|
||||
* nonce values are not required to be correct, then we don't know if this is
|
||||
* an initial load or not. In that case, we also copy the values so that we
|
||||
* can use the nonce values later for a renewal.
|
||||
*/
|
||||
if (parsed_license->nonce_required && initial_license_load) {
|
||||
if (nonce_values->nonce !=
|
||||
license_response.request.core_message.nonce_values.nonce ||
|
||||
nonce_values->session_id !=
|
||||
license_response.request.core_message.nonce_values.session_id) {
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
}
|
||||
} else { /* !initial_license_load, or can't tell if initial. */
|
||||
nonce_values->nonce =
|
||||
license_response.request.core_message.nonce_values.nonce;
|
||||
nonce_values->session_id =
|
||||
license_response.request.core_message.nonce_values.session_id;
|
||||
}
|
||||
/* For v16, in order to be backwards compatible with a v15 license server,
|
||||
* OEMCrypto stores a hash of the core license request and only signs the
|
||||
@@ -367,9 +360,12 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
|
||||
*/
|
||||
/* If a renewal request is lost in transit, we should throw it out and create
|
||||
* a new one. We use the timestamp to make sure we have the latest request.
|
||||
* We only do this if playback has already started. This allows us to reload
|
||||
* an offline license and also reload a renewal before starting playback.
|
||||
*/
|
||||
if (clock_values->time_of_renewal_request <
|
||||
renewal_response.request.playback_time) {
|
||||
if (clock_values->timer_status != ODK_CLOCK_TIMER_STATUS_LICENSE_LOADED &&
|
||||
clock_values->time_of_renewal_request <
|
||||
renewal_response.request.playback_time) {
|
||||
return ODK_STALE_RENEWAL;
|
||||
}
|
||||
return ODK_ComputeRenewalDuration(timer_limits, clock_values, system_time,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_SRC_ODK_ASSERT_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_SRC_ODK_ENDIAN_H_
|
||||
@@ -11,11 +11,23 @@ extern "C" {
|
||||
|
||||
#if defined(__linux__) || defined(__ANDROID__)
|
||||
#include <endian.h>
|
||||
#define oemcrypto_htobe16 htobe16
|
||||
#define oemcrypto_be16toh be16toh
|
||||
#define oemcrypto_htobe32 htobe32
|
||||
#define oemcrypto_be32toh be32toh
|
||||
#define oemcrypto_htobe64 htobe64
|
||||
#define oemcrypto_be64toh be64toh
|
||||
#else /* defined(__linux__) || defined(__ANDROID__) */
|
||||
#elif defined(__APPLE__)
|
||||
#include <libkern/OSByteOrder.h>
|
||||
#define oemcrypto_htobe16 OSSwapHostToBigInt16
|
||||
#define oemcrypto_be16toh OSSwapBigToHostInt16
|
||||
#define oemcrypto_htobe32 OSSwapHostToBigInt32
|
||||
#define oemcrypto_be32toh OSSwapBigToHostInt32
|
||||
#define oemcrypto_htobe64 OSSwapHostToBigInt64
|
||||
#define oemcrypto_be64toh OSSwapBigToHostInt64
|
||||
#else /* defined(__linux__) || defined(__ANDROID__) */
|
||||
uint32_t oemcrypto_htobe16(uint16_t u16);
|
||||
uint32_t oemcrypto_be16toh(uint16_t u16);
|
||||
uint32_t oemcrypto_htobe32(uint32_t u32);
|
||||
uint32_t oemcrypto_be32toh(uint32_t u32);
|
||||
uint64_t oemcrypto_htobe64(uint64_t u64);
|
||||
|
||||
171
libwvdrmengine/oemcrypto/odk/src/odk_message.c
Normal file
171
libwvdrmengine/oemcrypto/odk/src/odk_message.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#include "odk_message.h"
|
||||
#include "odk_message_priv.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* C11 defines static_assert in assert.h. If it is available, force a compile
|
||||
* time error if the abstract ODK_Message struct size does not match its
|
||||
* implementation. If static_assert is not available, the runtime assert in
|
||||
* InitMessage will catch the mismatch at the time a message is initialized.
|
||||
*/
|
||||
#ifdef static_assert
|
||||
static_assert(
|
||||
sizeof(ODK_Message) >= sizeof(ODK_Message_Impl),
|
||||
"sizeof(ODK_Message) is too small. You can increase "
|
||||
"SIZE_OF_ODK_MESSAGE_IMPL in odk_message.h to make it large enough.");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create a message structure that references a separate data buffer. An
|
||||
* initialized message is returned. The caller is responsible for ensuring that
|
||||
* the buffer remains allocated for the lifetime of the message. |buffer| may be
|
||||
* NULL. Serialization into a message with a NULL buffer will cause the message
|
||||
* size to be incremented, but no data will be written into the message
|
||||
* buffer. This is useful for calculating the amount of space a message will
|
||||
* need, prior to doing the actual serialization. The buffer contents are
|
||||
* unchanged by this function.
|
||||
*/
|
||||
ODK_Message ODK_Message_Create(uint8_t* buffer, size_t capacity) {
|
||||
assert(sizeof(ODK_Message) >= sizeof(ODK_Message_Impl));
|
||||
ODK_Message message;
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)&message;
|
||||
message_impl->base = buffer;
|
||||
message_impl->capacity = capacity;
|
||||
message_impl->size = 0;
|
||||
message_impl->read_offset = 0;
|
||||
message_impl->status = MESSAGE_STATUS_OK;
|
||||
return message;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase the contents of the message, set it to an empty state by setting the
|
||||
* message size and read offset to 0, effectively erasing the contents of the
|
||||
* message. The message data buffer pointer remains unchanged, i.e. the message
|
||||
* retains ownership of the buffer. The message buffer is zero-filled. The
|
||||
* message status is reset to MESSAGE_STATUS_OK.
|
||||
*/
|
||||
void ODK_Message_Clear(ODK_Message* message) {
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
assert(message_impl != NULL);
|
||||
message_impl->read_offset = 0;
|
||||
message_impl->size = 0;
|
||||
message_impl->status = MESSAGE_STATUS_OK;
|
||||
if (message_impl->base) {
|
||||
memset(message_impl->base, 0, message_impl->capacity);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset read pointer to the beginning of the message and clear status
|
||||
* so that parsing of the message will restart at the beginning of the
|
||||
* message. The message status is reset to MESSAGE_STATUS_OK.
|
||||
*/
|
||||
void ODK_Message_Reset(ODK_Message* message) {
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
assert(message_impl != NULL);
|
||||
message_impl->read_offset = 0;
|
||||
message_impl->status = MESSAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pointer to the message data buffer, i.e. the message payload.
|
||||
* This is the buffer address that was passed into ODK_Message_Create.
|
||||
*/
|
||||
uint8_t* ODK_Message_GetBase(ODK_Message* message) {
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
assert(message_impl != NULL);
|
||||
return message_impl->base;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the maximum number of bytes the message can hold.
|
||||
*/
|
||||
size_t ODK_Message_GetCapacity(ODK_Message* message) {
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
assert(message_impl != NULL);
|
||||
return message_impl->capacity;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the number of bytes currently in the message
|
||||
*/
|
||||
size_t ODK_Message_GetSize(ODK_Message* message) {
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
assert(message_impl != NULL);
|
||||
return message_impl->size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the offset of where the next bytes will be read from the message data
|
||||
* buffer.
|
||||
*/
|
||||
size_t ODK_Message_GetOffset(ODK_Message* message) {
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
assert(message_impl != NULL);
|
||||
return message_impl->read_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the status of the message
|
||||
*/
|
||||
ODK_MessageStatus ODK_Message_GetStatus(ODK_Message* message) {
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
assert(message_impl != NULL);
|
||||
return message_impl->status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the message status to a specific value
|
||||
*/
|
||||
void ODK_Message_SetStatus(ODK_Message* message, ODK_MessageStatus status) {
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
assert(message_impl != NULL);
|
||||
/* preserve the first error */
|
||||
if (message_impl->status == MESSAGE_STATUS_OK) {
|
||||
message_impl->status = status;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the size of the message to a value. This may be needed after writing data
|
||||
* into the message data buffer.
|
||||
*/
|
||||
void ODK_Message_SetSize(ODK_Message* message, size_t size) {
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
assert(message_impl != NULL);
|
||||
assert(size <= message_impl->capacity);
|
||||
message_impl->size = size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test if the integrity of a message. This means that the status must be
|
||||
* MESSAGE_STATUS_OK and that the base, read_offset, size and capacity of the
|
||||
* message are within the range of valid values. The message's base pointer
|
||||
* may be NULL if the buffer has not been assigned yet, that is not invalid.
|
||||
*/
|
||||
bool ODK_Message_IsValid(ODK_Message* message) {
|
||||
assert(message);
|
||||
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
|
||||
if (message_impl == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (message_impl->status != MESSAGE_STATUS_OK) {
|
||||
return false;
|
||||
}
|
||||
if (message_impl->read_offset > message_impl->capacity ||
|
||||
message_impl->size > message_impl->capacity ||
|
||||
message_impl->read_offset > message_impl->size) {
|
||||
message_impl->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
41
libwvdrmengine/oemcrypto/odk/src/odk_message_priv.h
Normal file
41
libwvdrmengine/oemcrypto/odk/src/odk_message_priv.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_ODK_MESSAGE_PRIV_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_ODK_MESSAGE_PRIV_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file must only be included by odk_message.c and serialization_base.c.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* This is the implementation of a message. This structure is private, i.e. it
|
||||
* should only be included by files that are allowed to modify the internals of
|
||||
* a message, that being odk_message.c and serialization_base.c. To ensure
|
||||
* proper alignment and message size, an ODK_Message_Impl should never be
|
||||
* allocated directly, instead allocate ODK_Message and cast to ODK_Message_Impl
|
||||
* because ODK_Message_Impl may be smaller than ODK_Message.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t* base;
|
||||
size_t capacity;
|
||||
size_t size;
|
||||
size_t read_offset;
|
||||
ODK_MessageStatus status;
|
||||
} ODK_Message_Impl;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_ODK_MESSAGE_PRIV_H_
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -34,3 +34,13 @@ int odk_add_overflow_ux(size_t a, size_t b, size_t* c) {
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int odk_mul_overflow_ux(size_t a, size_t b, size_t* c) {
|
||||
if (b > 0 && a > SIZE_MAX / b) {
|
||||
return 1;
|
||||
}
|
||||
if (c) {
|
||||
*c = a * b;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_SRC_ODK_OVERFLOW_H_
|
||||
@@ -15,6 +15,7 @@ extern "C" {
|
||||
int odk_sub_overflow_u64(uint64_t a, uint64_t b, uint64_t* c);
|
||||
int odk_add_overflow_u64(uint64_t a, uint64_t b, uint64_t* c);
|
||||
int odk_add_overflow_ux(size_t a, size_t b, size_t* c);
|
||||
int odk_mul_overflow_ux(size_t a, size_t b, size_t* c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*
|
||||
@@ -13,20 +13,20 @@
|
||||
|
||||
/* @@ private serialize */
|
||||
|
||||
static void Pack_ODK_NonceValues(Message* msg, ODK_NonceValues const* obj) {
|
||||
static void Pack_ODK_NonceValues(ODK_Message* msg, ODK_NonceValues const* obj) {
|
||||
Pack_uint16_t(msg, &obj->api_minor_version);
|
||||
Pack_uint16_t(msg, &obj->api_major_version);
|
||||
Pack_uint32_t(msg, &obj->nonce);
|
||||
Pack_uint32_t(msg, &obj->session_id);
|
||||
}
|
||||
|
||||
static void Pack_ODK_CoreMessage(Message* msg, ODK_CoreMessage const* obj) {
|
||||
static void Pack_ODK_CoreMessage(ODK_Message* msg, ODK_CoreMessage const* obj) {
|
||||
Pack_uint32_t(msg, &obj->message_type);
|
||||
Pack_uint32_t(msg, &obj->message_length);
|
||||
Pack_ODK_NonceValues(msg, &obj->nonce_values);
|
||||
}
|
||||
|
||||
static void Pack_OEMCrypto_KeyObject(Message* msg,
|
||||
static void Pack_OEMCrypto_KeyObject(ODK_Message* msg,
|
||||
OEMCrypto_KeyObject const* obj) {
|
||||
Pack_OEMCrypto_Substring(msg, &obj->key_id);
|
||||
Pack_OEMCrypto_Substring(msg, &obj->key_data_iv);
|
||||
@@ -35,7 +35,7 @@ static void Pack_OEMCrypto_KeyObject(Message* msg,
|
||||
Pack_OEMCrypto_Substring(msg, &obj->key_control);
|
||||
}
|
||||
|
||||
static void Pack_ODK_TimerLimits(Message* msg, ODK_TimerLimits const* obj) {
|
||||
static void Pack_ODK_TimerLimits(ODK_Message* msg, ODK_TimerLimits const* obj) {
|
||||
Pack_bool(msg, &obj->soft_enforce_rental_duration);
|
||||
Pack_bool(msg, &obj->soft_enforce_playback_duration);
|
||||
Pack_uint64_t(msg, &obj->earliest_playback_start_seconds);
|
||||
@@ -44,10 +44,11 @@ static void Pack_ODK_TimerLimits(Message* msg, ODK_TimerLimits const* obj) {
|
||||
Pack_uint64_t(msg, &obj->initial_renewal_duration_seconds);
|
||||
}
|
||||
|
||||
static void Pack_ODK_ParsedLicense(Message* msg, ODK_ParsedLicense const* obj) {
|
||||
static void Pack_ODK_ParsedLicense(ODK_Message* msg,
|
||||
ODK_ParsedLicense const* obj) {
|
||||
/* hand-coded */
|
||||
if (obj->key_array_length > ODK_MAX_NUM_KEYS) {
|
||||
SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
|
||||
ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
|
||||
return;
|
||||
}
|
||||
Pack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv);
|
||||
@@ -64,7 +65,7 @@ static void Pack_ODK_ParsedLicense(Message* msg, ODK_ParsedLicense const* obj) {
|
||||
}
|
||||
}
|
||||
|
||||
static void Pack_ODK_ParsedProvisioning(Message* msg,
|
||||
static void Pack_ODK_ParsedProvisioning(ODK_Message* msg,
|
||||
ODK_ParsedProvisioning const* obj) {
|
||||
Pack_enum(msg, obj->key_type);
|
||||
Pack_OEMCrypto_Substring(msg, &obj->enc_private_key);
|
||||
@@ -74,19 +75,19 @@ static void Pack_ODK_ParsedProvisioning(Message* msg,
|
||||
|
||||
/* @@ odk serialize */
|
||||
|
||||
void Pack_ODK_PreparedLicenseRequest(Message* msg,
|
||||
void Pack_ODK_PreparedLicenseRequest(ODK_Message* msg,
|
||||
ODK_PreparedLicenseRequest const* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
}
|
||||
|
||||
void Pack_ODK_PreparedRenewalRequest(Message* msg,
|
||||
void Pack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
ODK_PreparedRenewalRequest const* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Pack_uint64_t(msg, &obj->playback_time);
|
||||
}
|
||||
|
||||
void Pack_ODK_PreparedProvisioningRequest(
|
||||
Message* msg, ODK_PreparedProvisioningRequest const* obj) {
|
||||
ODK_Message* msg, ODK_PreparedProvisioningRequest const* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Pack_uint32_t(msg, &obj->device_id_length);
|
||||
PackArray(msg, &obj->device_id[0], sizeof(obj->device_id));
|
||||
@@ -94,18 +95,20 @@ void Pack_ODK_PreparedProvisioningRequest(
|
||||
|
||||
/* @@ kdo serialize */
|
||||
|
||||
void Pack_ODK_LicenseResponse(Message* msg, ODK_LicenseResponse const* obj) {
|
||||
void Pack_ODK_LicenseResponse(ODK_Message* msg,
|
||||
ODK_LicenseResponse const* obj) {
|
||||
Pack_ODK_PreparedLicenseRequest(msg, &obj->request);
|
||||
Pack_ODK_ParsedLicense(msg, (const ODK_ParsedLicense*)obj->parsed_license);
|
||||
PackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash));
|
||||
}
|
||||
|
||||
void Pack_ODK_RenewalResponse(Message* msg, ODK_RenewalResponse const* obj) {
|
||||
void Pack_ODK_RenewalResponse(ODK_Message* msg,
|
||||
ODK_RenewalResponse const* obj) {
|
||||
Pack_ODK_PreparedRenewalRequest(msg, &obj->request);
|
||||
Pack_uint64_t(msg, &obj->renewal_duration_seconds);
|
||||
}
|
||||
|
||||
void Pack_ODK_ProvisioningResponse(Message* msg,
|
||||
void Pack_ODK_ProvisioningResponse(ODK_Message* msg,
|
||||
ODK_ProvisioningResponse const* obj) {
|
||||
Pack_ODK_PreparedProvisioningRequest(msg, &obj->request);
|
||||
Pack_ODK_ParsedProvisioning(
|
||||
@@ -116,20 +119,21 @@ void Pack_ODK_ProvisioningResponse(Message* msg,
|
||||
|
||||
/* @@ private deserialize */
|
||||
|
||||
static void Unpack_ODK_NonceValues(Message* msg, ODK_NonceValues* obj) {
|
||||
static void Unpack_ODK_NonceValues(ODK_Message* msg, ODK_NonceValues* obj) {
|
||||
Unpack_uint16_t(msg, &obj->api_minor_version);
|
||||
Unpack_uint16_t(msg, &obj->api_major_version);
|
||||
Unpack_uint32_t(msg, &obj->nonce);
|
||||
Unpack_uint32_t(msg, &obj->session_id);
|
||||
}
|
||||
|
||||
static void Unpack_ODK_CoreMessage(Message* msg, ODK_CoreMessage* obj) {
|
||||
static void Unpack_ODK_CoreMessage(ODK_Message* msg, ODK_CoreMessage* obj) {
|
||||
Unpack_uint32_t(msg, &obj->message_type);
|
||||
Unpack_uint32_t(msg, &obj->message_length);
|
||||
Unpack_ODK_NonceValues(msg, &obj->nonce_values);
|
||||
}
|
||||
|
||||
static void Unpack_OEMCrypto_KeyObject(Message* msg, OEMCrypto_KeyObject* obj) {
|
||||
static void Unpack_OEMCrypto_KeyObject(ODK_Message* msg,
|
||||
OEMCrypto_KeyObject* obj) {
|
||||
Unpack_OEMCrypto_Substring(msg, &obj->key_id);
|
||||
Unpack_OEMCrypto_Substring(msg, &obj->key_data_iv);
|
||||
Unpack_OEMCrypto_Substring(msg, &obj->key_data);
|
||||
@@ -137,7 +141,7 @@ static void Unpack_OEMCrypto_KeyObject(Message* msg, OEMCrypto_KeyObject* obj) {
|
||||
Unpack_OEMCrypto_Substring(msg, &obj->key_control);
|
||||
}
|
||||
|
||||
static void Unpack_ODK_TimerLimits(Message* msg, ODK_TimerLimits* obj) {
|
||||
static void Unpack_ODK_TimerLimits(ODK_Message* msg, ODK_TimerLimits* obj) {
|
||||
Unpack_bool(msg, &obj->soft_enforce_rental_duration);
|
||||
Unpack_bool(msg, &obj->soft_enforce_playback_duration);
|
||||
Unpack_uint64_t(msg, &obj->earliest_playback_start_seconds);
|
||||
@@ -146,7 +150,7 @@ static void Unpack_ODK_TimerLimits(Message* msg, ODK_TimerLimits* obj) {
|
||||
Unpack_uint64_t(msg, &obj->initial_renewal_duration_seconds);
|
||||
}
|
||||
|
||||
static void Unpack_ODK_ParsedLicense(Message* msg, ODK_ParsedLicense* obj) {
|
||||
static void Unpack_ODK_ParsedLicense(ODK_Message* msg, ODK_ParsedLicense* obj) {
|
||||
Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv);
|
||||
Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys);
|
||||
Unpack_OEMCrypto_Substring(msg, &obj->pst);
|
||||
@@ -156,7 +160,7 @@ static void Unpack_ODK_ParsedLicense(Message* msg, ODK_ParsedLicense* obj) {
|
||||
Unpack_ODK_TimerLimits(msg, &obj->timer_limits);
|
||||
Unpack_uint32_t(msg, &obj->key_array_length);
|
||||
if (obj->key_array_length > ODK_MAX_NUM_KEYS) {
|
||||
SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
|
||||
ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
|
||||
return;
|
||||
}
|
||||
uint32_t i;
|
||||
@@ -165,7 +169,7 @@ static void Unpack_ODK_ParsedLicense(Message* msg, ODK_ParsedLicense* obj) {
|
||||
}
|
||||
}
|
||||
|
||||
static void Unpack_ODK_ParsedProvisioning(Message* msg,
|
||||
static void Unpack_ODK_ParsedProvisioning(ODK_Message* msg,
|
||||
ODK_ParsedProvisioning* obj) {
|
||||
obj->key_type = (OEMCrypto_PrivateKeyType)Unpack_enum(msg);
|
||||
Unpack_OEMCrypto_Substring(msg, &obj->enc_private_key);
|
||||
@@ -175,42 +179,42 @@ static void Unpack_ODK_ParsedProvisioning(Message* msg,
|
||||
|
||||
/* @ kdo deserialize */
|
||||
|
||||
void Unpack_ODK_PreparedLicenseRequest(Message* msg,
|
||||
void Unpack_ODK_PreparedLicenseRequest(ODK_Message* msg,
|
||||
ODK_PreparedLicenseRequest* obj) {
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
}
|
||||
|
||||
void Unpack_ODK_PreparedRenewalRequest(Message* msg,
|
||||
void Unpack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
ODK_PreparedRenewalRequest* obj) {
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Unpack_uint64_t(msg, &obj->playback_time);
|
||||
}
|
||||
|
||||
void Unpack_ODK_PreparedProvisioningRequest(
|
||||
Message* msg, ODK_PreparedProvisioningRequest* obj) {
|
||||
ODK_Message* msg, ODK_PreparedProvisioningRequest* obj) {
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Unpack_uint32_t(msg, &obj->device_id_length);
|
||||
UnpackArray(msg, &obj->device_id[0], sizeof(obj->device_id));
|
||||
}
|
||||
|
||||
void Unpack_ODK_PreparedCommonRequest(Message* msg,
|
||||
void Unpack_ODK_PreparedCommonRequest(ODK_Message* msg,
|
||||
ODK_PreparedCommonRequest* obj) {
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
}
|
||||
/* @@ odk deserialize */
|
||||
|
||||
void Unpack_ODK_LicenseResponse(Message* msg, ODK_LicenseResponse* obj) {
|
||||
void Unpack_ODK_LicenseResponse(ODK_Message* msg, ODK_LicenseResponse* obj) {
|
||||
Unpack_ODK_PreparedLicenseRequest(msg, &obj->request);
|
||||
Unpack_ODK_ParsedLicense(msg, obj->parsed_license);
|
||||
UnpackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash));
|
||||
}
|
||||
|
||||
void Unpack_ODK_RenewalResponse(Message* msg, ODK_RenewalResponse* obj) {
|
||||
void Unpack_ODK_RenewalResponse(ODK_Message* msg, ODK_RenewalResponse* obj) {
|
||||
Unpack_ODK_PreparedRenewalRequest(msg, &obj->request);
|
||||
Unpack_uint64_t(msg, &obj->renewal_duration_seconds);
|
||||
}
|
||||
|
||||
void Unpack_ODK_ProvisioningResponse(Message* msg,
|
||||
void Unpack_ODK_ProvisioningResponse(ODK_Message* msg,
|
||||
ODK_ProvisioningResponse* obj) {
|
||||
Unpack_ODK_PreparedProvisioningRequest(msg, &obj->request);
|
||||
Unpack_ODK_ParsedProvisioning(msg, obj->parsed_provisioning);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*
|
||||
@@ -16,34 +16,34 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* odk pack */
|
||||
void Pack_ODK_PreparedLicenseRequest(Message* msg,
|
||||
void Pack_ODK_PreparedLicenseRequest(ODK_Message* msg,
|
||||
const ODK_PreparedLicenseRequest* obj);
|
||||
void Pack_ODK_PreparedRenewalRequest(Message* msg,
|
||||
void Pack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
const ODK_PreparedRenewalRequest* obj);
|
||||
void Pack_ODK_PreparedProvisioningRequest(
|
||||
Message* msg, const ODK_PreparedProvisioningRequest* obj);
|
||||
ODK_Message* msg, const ODK_PreparedProvisioningRequest* obj);
|
||||
|
||||
/* odk unpack */
|
||||
void Unpack_ODK_LicenseResponse(Message* msg, ODK_LicenseResponse* obj);
|
||||
void Unpack_ODK_RenewalResponse(Message* msg, ODK_RenewalResponse* obj);
|
||||
void Unpack_ODK_ProvisioningResponse(Message* msg,
|
||||
void Unpack_ODK_LicenseResponse(ODK_Message* msg, ODK_LicenseResponse* obj);
|
||||
void Unpack_ODK_RenewalResponse(ODK_Message* msg, ODK_RenewalResponse* obj);
|
||||
void Unpack_ODK_ProvisioningResponse(ODK_Message* msg,
|
||||
ODK_ProvisioningResponse* obj);
|
||||
|
||||
/* kdo pack */
|
||||
void Pack_ODK_LicenseResponse(Message* msg, const ODK_LicenseResponse* obj);
|
||||
void Pack_ODK_RenewalResponse(Message* msg, const ODK_RenewalResponse* obj);
|
||||
void Pack_ODK_ProvisioningResponse(Message* msg,
|
||||
void Pack_ODK_LicenseResponse(ODK_Message* msg, const ODK_LicenseResponse* obj);
|
||||
void Pack_ODK_RenewalResponse(ODK_Message* msg, const ODK_RenewalResponse* obj);
|
||||
void Pack_ODK_ProvisioningResponse(ODK_Message* msg,
|
||||
const ODK_ProvisioningResponse* obj);
|
||||
|
||||
/* kdo unpack */
|
||||
void Unpack_ODK_PreparedLicenseRequest(Message* msg,
|
||||
void Unpack_ODK_PreparedLicenseRequest(ODK_Message* msg,
|
||||
ODK_PreparedLicenseRequest* obj);
|
||||
void Unpack_ODK_PreparedRenewalRequest(Message* msg,
|
||||
void Unpack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
ODK_PreparedRenewalRequest* obj);
|
||||
void Unpack_ODK_PreparedProvisioningRequest(
|
||||
Message* msg, ODK_PreparedProvisioningRequest* obj);
|
||||
ODK_Message* msg, ODK_PreparedProvisioningRequest* obj);
|
||||
|
||||
void Unpack_ODK_PreparedCommonRequest(Message* msg,
|
||||
void Unpack_ODK_PreparedCommonRequest(ODK_Message* msg,
|
||||
ODK_PreparedCommonRequest* obj);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_SRC_ODK_STRUCTS_PRIV_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "odk_util.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_SRC_ODK_UTIL_H_
|
||||
|
||||
@@ -1,74 +1,64 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "serialization_base.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "odk_message.h"
|
||||
#include "odk_message_priv.h"
|
||||
#include "odk_overflow.h"
|
||||
|
||||
struct _Message {
|
||||
uint8_t* base;
|
||||
size_t capacity;
|
||||
size_t size; /* bytes written */
|
||||
size_t read_offset; /* bytes read */
|
||||
MessageStatus status;
|
||||
};
|
||||
|
||||
bool ValidMessage(Message* message) {
|
||||
if (message == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (message->status != MESSAGE_STATUS_OK) {
|
||||
return false;
|
||||
}
|
||||
if (message->base == NULL) {
|
||||
message->status = MESSAGE_STATUS_NULL_POINTER_ERROR;
|
||||
return false;
|
||||
}
|
||||
if (message->size > message->capacity ||
|
||||
message->read_offset > message->size) {
|
||||
message->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
/*
|
||||
* An ODK_Message_Impl pointer must only be obtained by calling GetMessageImpl.
|
||||
* This forces any message to pass the validity check before being operated on,
|
||||
* which means that no function can modify or access the internals of a message
|
||||
* without having it be validated first.
|
||||
*/
|
||||
static ODK_Message_Impl* GetMessageImpl(ODK_Message* message) {
|
||||
if (!ODK_Message_IsValid(message)) return NULL;
|
||||
return (ODK_Message_Impl*)message;
|
||||
}
|
||||
|
||||
static void PackBytes(Message* message, const uint8_t* ptr, size_t count) {
|
||||
if (count <= message->capacity - message->size) {
|
||||
memcpy((void*)(message->base + message->size), (void*)ptr, count);
|
||||
message->size += count;
|
||||
static void PackBytes(ODK_Message* message, const uint8_t* ptr, size_t count) {
|
||||
ODK_Message_Impl* message_impl = GetMessageImpl(message);
|
||||
if (!message_impl) return;
|
||||
if (count <= message_impl->capacity - message_impl->size) {
|
||||
memcpy((void*)(message_impl->base + message_impl->size), (const void*)ptr,
|
||||
count);
|
||||
message_impl->size += count;
|
||||
} else {
|
||||
message->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
message_impl->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void Pack_enum(Message* message, int value) {
|
||||
void Pack_enum(ODK_Message* message, int value) {
|
||||
uint32_t v32 = value;
|
||||
Pack_uint32_t(message, &v32);
|
||||
}
|
||||
|
||||
void Pack_bool(Message* message, const bool* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void Pack_bool(ODK_Message* message, const bool* value) {
|
||||
assert(value);
|
||||
uint8_t data[4] = {0};
|
||||
data[3] = *value ? 1 : 0;
|
||||
PackBytes(message, data, sizeof(data));
|
||||
}
|
||||
|
||||
void Pack_uint16_t(Message* message, const uint16_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void Pack_uint16_t(ODK_Message* message, const uint16_t* value) {
|
||||
assert(value);
|
||||
uint8_t data[2] = {0};
|
||||
data[0] = *value >> 8;
|
||||
data[1] = *value >> 0;
|
||||
PackBytes(message, data, sizeof(data));
|
||||
}
|
||||
|
||||
void Pack_uint32_t(Message* message, const uint32_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void Pack_uint32_t(ODK_Message* message, const uint32_t* value) {
|
||||
assert(value);
|
||||
uint8_t data[4] = {0};
|
||||
data[0] = *value >> 24;
|
||||
data[1] = *value >> 16;
|
||||
@@ -77,160 +67,112 @@ void Pack_uint32_t(Message* message, const uint32_t* value) {
|
||||
PackBytes(message, data, sizeof(data));
|
||||
}
|
||||
|
||||
void Pack_uint64_t(Message* message, const uint64_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void Pack_uint64_t(ODK_Message* message, const uint64_t* value) {
|
||||
assert(value);
|
||||
uint32_t hi = *value >> 32;
|
||||
uint32_t lo = *value;
|
||||
Pack_uint32_t(message, &hi);
|
||||
Pack_uint32_t(message, &lo);
|
||||
}
|
||||
|
||||
void PackArray(Message* message, const uint8_t* base, size_t size) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void PackArray(ODK_Message* message, const uint8_t* base, size_t size) {
|
||||
PackBytes(message, base, size);
|
||||
}
|
||||
|
||||
void Pack_OEMCrypto_Substring(Message* msg, const OEMCrypto_Substring* obj) {
|
||||
void Pack_OEMCrypto_Substring(ODK_Message* message,
|
||||
const OEMCrypto_Substring* obj) {
|
||||
assert(obj);
|
||||
uint32_t offset = (uint32_t)obj->offset;
|
||||
uint32_t length = (uint32_t)obj->length;
|
||||
Pack_uint32_t(msg, &offset);
|
||||
Pack_uint32_t(msg, &length);
|
||||
Pack_uint32_t(message, &offset);
|
||||
Pack_uint32_t(message, &length);
|
||||
}
|
||||
|
||||
static void UnpackBytes(Message* message, uint8_t* ptr, size_t count) {
|
||||
if (count <= message->size - message->read_offset) {
|
||||
memcpy((void*)ptr, (void*)(message->base + message->read_offset), count);
|
||||
message->read_offset += count;
|
||||
static void UnpackBytes(ODK_Message* message, uint8_t* ptr, size_t count) {
|
||||
assert(ptr);
|
||||
ODK_Message_Impl* message_impl = GetMessageImpl(message);
|
||||
if (!message_impl) return;
|
||||
if (count <= message_impl->size - message_impl->read_offset) {
|
||||
memcpy((void*)ptr, (void*)(message_impl->base + message_impl->read_offset),
|
||||
count);
|
||||
message_impl->read_offset += count;
|
||||
} else {
|
||||
message->status = MESSAGE_STATUS_UNDERFLOW_ERROR;
|
||||
message_impl->status = MESSAGE_STATUS_UNDERFLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int Unpack_enum(Message* message) {
|
||||
int Unpack_enum(ODK_Message* message) {
|
||||
uint32_t v32;
|
||||
Unpack_uint32_t(message, &v32);
|
||||
return v32;
|
||||
}
|
||||
|
||||
void Unpack_bool(Message* message, bool* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void Unpack_bool(ODK_Message* message, bool* value) {
|
||||
uint8_t data[4] = {0};
|
||||
UnpackBytes(message, data, sizeof(data));
|
||||
assert(value);
|
||||
*value = (0 != data[3]);
|
||||
}
|
||||
|
||||
void Unpack_uint16_t(Message* message, uint16_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void Unpack_uint16_t(ODK_Message* message, uint16_t* value) {
|
||||
assert(value);
|
||||
uint8_t data[2] = {0};
|
||||
UnpackBytes(message, data, sizeof(data));
|
||||
*value = data[0];
|
||||
*value = *value << 8 | data[1];
|
||||
}
|
||||
|
||||
void Unpack_uint32_t(Message* message, uint32_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void Unpack_uint32_t(ODK_Message* message, uint32_t* value) {
|
||||
ODK_Message_Impl* message_impl = GetMessageImpl(message);
|
||||
if (!message_impl) return;
|
||||
uint8_t data[4] = {0};
|
||||
UnpackBytes(message, data, sizeof(data));
|
||||
assert(value);
|
||||
*value = data[0];
|
||||
*value = *value << 8 | data[1];
|
||||
*value = *value << 8 | data[2];
|
||||
*value = *value << 8 | data[3];
|
||||
}
|
||||
|
||||
void Unpack_uint64_t(Message* message, uint64_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void Unpack_uint64_t(ODK_Message* message, uint64_t* value) {
|
||||
uint32_t hi = 0;
|
||||
uint32_t lo = 0;
|
||||
Unpack_uint32_t(message, &hi);
|
||||
Unpack_uint32_t(message, &lo);
|
||||
assert(value);
|
||||
*value = hi;
|
||||
*value = *value << 32 | lo;
|
||||
}
|
||||
|
||||
void Unpack_OEMCrypto_Substring(Message* msg, OEMCrypto_Substring* obj) {
|
||||
void Unpack_OEMCrypto_Substring(ODK_Message* message,
|
||||
OEMCrypto_Substring* obj) {
|
||||
uint32_t offset = 0, length = 0;
|
||||
Unpack_uint32_t(msg, &offset);
|
||||
Unpack_uint32_t(msg, &length);
|
||||
if (!ValidMessage(msg)) return;
|
||||
Unpack_uint32_t(message, &offset);
|
||||
Unpack_uint32_t(message, &length);
|
||||
ODK_Message_Impl* message_impl = GetMessageImpl(message);
|
||||
if (!message_impl) return;
|
||||
|
||||
/* Each substring should be contained within the message body, which is in the
|
||||
* total message, just after the core message. The offset of a substring is
|
||||
* relative to the message body. So we need to verify:
|
||||
* 0 < offset and offset + length < message->capacity - message->size
|
||||
* or offset + length + message->size < message->capacity
|
||||
* 0 < offset and offset + length < message_impl->capacity -
|
||||
* message_impl->size or offset + length + message_impl->size <
|
||||
* message_impl->capacity
|
||||
*/
|
||||
size_t substring_end = 0; /* = offset + length; */
|
||||
size_t end = 0; /* = substring_end + message->size; */
|
||||
size_t end = 0; /* = substring_end + message_impl->size; */
|
||||
if (odk_add_overflow_ux(offset, length, &substring_end) ||
|
||||
odk_add_overflow_ux(substring_end, msg->size, &end) ||
|
||||
end > msg->capacity) {
|
||||
msg->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
odk_add_overflow_ux(substring_end, message_impl->size, &end) ||
|
||||
end > message_impl->capacity) {
|
||||
message_impl->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
return;
|
||||
}
|
||||
assert(obj);
|
||||
obj->offset = offset;
|
||||
obj->length = length;
|
||||
}
|
||||
|
||||
/* copy out */
|
||||
void UnpackArray(Message* message, uint8_t* address, size_t size) {
|
||||
if (!ValidMessage(message)) return;
|
||||
void UnpackArray(ODK_Message* message, uint8_t* address, size_t size) {
|
||||
UnpackBytes(message, address, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* The message structure, which is separate from the buffer,
|
||||
* is initialized to reference the buffer
|
||||
*/
|
||||
void InitMessage(Message* message, uint8_t* buffer, size_t capacity) {
|
||||
if (message == NULL) return;
|
||||
memset(message, 0, sizeof(Message));
|
||||
message->base = buffer;
|
||||
message->capacity = capacity;
|
||||
message->size = 0;
|
||||
message->read_offset = 0;
|
||||
message->status = MESSAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the message to an empty state
|
||||
*/
|
||||
void ResetMessage(Message* message) {
|
||||
message->size = 0;
|
||||
message->read_offset = 0;
|
||||
message->status = MESSAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
uint8_t* GetBase(Message* message) {
|
||||
if (message == NULL) return NULL;
|
||||
return message->base;
|
||||
}
|
||||
|
||||
size_t GetCapacity(Message* message) {
|
||||
if (message == NULL) return 0;
|
||||
return message->capacity;
|
||||
}
|
||||
|
||||
size_t GetSize(Message* message) {
|
||||
if (message == NULL) return 0;
|
||||
return message->size;
|
||||
}
|
||||
|
||||
void SetSize(Message* message, size_t size) {
|
||||
if (message == NULL) return;
|
||||
if (size > message->capacity)
|
||||
message->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
else
|
||||
message->size = size;
|
||||
}
|
||||
|
||||
MessageStatus GetStatus(Message* message) { return message->status; }
|
||||
|
||||
void SetStatus(Message* message, MessageStatus status) {
|
||||
message->status = status;
|
||||
}
|
||||
|
||||
size_t GetOffset(Message* message) {
|
||||
if (message == NULL) return 0;
|
||||
return message->read_offset;
|
||||
}
|
||||
|
||||
size_t SizeOfMessageStruct() { return sizeof(Message); }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_SRC_SERIALIZATION_BASE_H_
|
||||
@@ -13,74 +13,24 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "odk_message.h"
|
||||
|
||||
#define SIZE_OF_MESSAGE_STRUCT 64
|
||||
void Pack_enum(ODK_Message* message, int value);
|
||||
void Pack_bool(ODK_Message* message, const bool* value);
|
||||
void Pack_uint16_t(ODK_Message* message, const uint16_t* value);
|
||||
void Pack_uint32_t(ODK_Message* message, const uint32_t* value);
|
||||
void Pack_uint64_t(ODK_Message* message, const uint64_t* value);
|
||||
void PackArray(ODK_Message* message, const uint8_t* base, size_t size);
|
||||
void Pack_OEMCrypto_Substring(ODK_Message* msg, const OEMCrypto_Substring* obj);
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* Point |msg| to stack-array |blk|.
|
||||
* |blk| is guaranteed large enough to hold a |Message| struct.
|
||||
* |blk| cannot be used in the same scope as a variable name.
|
||||
* |msg| points to valid memory in the same scope |AllocateMessage| is used.
|
||||
* Parameters:
|
||||
* msg: pointer to pointer to |Message| struct
|
||||
* blk: variable name for stack-array
|
||||
*/
|
||||
#define AllocateMessage(msg, blk) \
|
||||
uint8_t blk[SIZE_OF_MESSAGE_STRUCT]; \
|
||||
*(msg) = (Message*)(blk)
|
||||
|
||||
typedef struct _Message Message;
|
||||
|
||||
typedef enum {
|
||||
MESSAGE_STATUS_OK,
|
||||
MESSAGE_STATUS_UNKNOWN_ERROR,
|
||||
MESSAGE_STATUS_OVERFLOW_ERROR,
|
||||
MESSAGE_STATUS_UNDERFLOW_ERROR,
|
||||
MESSAGE_STATUS_PARSE_ERROR,
|
||||
MESSAGE_STATUS_NULL_POINTER_ERROR,
|
||||
MESSAGE_STATUS_API_VALUE_ERROR
|
||||
} MessageStatus;
|
||||
|
||||
bool ValidMessage(Message* message);
|
||||
|
||||
void Pack_enum(Message* message, int value);
|
||||
void Pack_bool(Message* message, const bool* value);
|
||||
void Pack_uint16_t(Message* message, const uint16_t* value);
|
||||
void Pack_uint32_t(Message* message, const uint32_t* value);
|
||||
void Pack_uint64_t(Message* message, const uint64_t* value);
|
||||
void PackArray(Message* message, const uint8_t* base, size_t size);
|
||||
void Pack_OEMCrypto_Substring(Message* msg, const OEMCrypto_Substring* obj);
|
||||
|
||||
int Unpack_enum(Message* message);
|
||||
void Unpack_bool(Message* message, bool* value);
|
||||
void Unpack_uint16_t(Message* message, uint16_t* value);
|
||||
void Unpack_uint32_t(Message* message, uint32_t* value);
|
||||
void Unpack_uint64_t(Message* message, uint64_t* value);
|
||||
void UnpackArray(Message* message, uint8_t* address,
|
||||
int Unpack_enum(ODK_Message* message);
|
||||
void Unpack_bool(ODK_Message* message, bool* value);
|
||||
void Unpack_uint16_t(ODK_Message* message, uint16_t* value);
|
||||
void Unpack_uint32_t(ODK_Message* message, uint32_t* value);
|
||||
void Unpack_uint64_t(ODK_Message* message, uint64_t* value);
|
||||
void UnpackArray(ODK_Message* message, uint8_t* address,
|
||||
size_t size); /* copy out */
|
||||
void Unpack_OEMCrypto_Substring(Message* msg, OEMCrypto_Substring* obj);
|
||||
|
||||
/*
|
||||
* Initialize a message structure to reference a separate buffer. The caller
|
||||
* is responsible for ensuring that the buffer remains allocated for the
|
||||
* lifetime of the message.
|
||||
*/
|
||||
void InitMessage(Message* message, uint8_t* buffer, size_t capacity);
|
||||
|
||||
/*
|
||||
* Reset an existing the message to an empty state
|
||||
*/
|
||||
void ResetMessage(Message* message);
|
||||
uint8_t* GetBase(Message* message);
|
||||
size_t GetCapacity(Message* message);
|
||||
size_t GetSize(Message* message);
|
||||
void SetSize(Message* message, size_t size);
|
||||
MessageStatus GetStatus(Message* message);
|
||||
void SetStatus(Message* message, MessageStatus status);
|
||||
size_t GetOffset(Message* message);
|
||||
|
||||
size_t SizeOfMessageStruct();
|
||||
void Unpack_OEMCrypto_Substring(ODK_Message* msg, OEMCrypto_Substring* obj);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
// *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
// We must define this macro to get RTLD_NEXT definition from <dlfcn.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#include "fuzzing/corpus_generator/odk_corpus_generator_helper.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#ifndef WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_
|
||||
#define WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
@@ -99,11 +99,9 @@ OEMCryptoResult odk_deserialize_RenewalResponse(
|
||||
// odk_kdo method, we call Unpack_ODK_PreparedRenewalRequest private method.
|
||||
// playback_time cannot be captured from publicly exposed API
|
||||
// ODK_ParseRenewal.
|
||||
uint8_t blk[SIZE_OF_MESSAGE_STRUCT];
|
||||
Message* msg = reinterpret_cast<Message*>(blk);
|
||||
InitMessage(msg, const_cast<uint8_t*>(buf), len);
|
||||
SetSize(msg, len);
|
||||
Unpack_ODK_PreparedRenewalRequest(msg, renewal_msg);
|
||||
ODK_Message msg = ODK_Message_Create(const_cast<uint8_t*>(buf), len);
|
||||
ODK_Message_SetSize(&msg, len);
|
||||
Unpack_ODK_PreparedRenewalRequest(&msg, renewal_msg);
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#ifndef WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_
|
||||
#define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#ifndef WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_
|
||||
#define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
#include "odk_attributes.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
// The custom mutator: Ensure that each input can be deserialized properly
|
||||
// by ODK function after mutation.
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
|
||||
size_t max_size,
|
||||
unsigned int seed UNUSED) {
|
||||
size_t max_size, unsigned int seed) {
|
||||
const size_t kProvisioningResponseArgsSize =
|
||||
sizeof(ODK_ParseProvisioning_Args);
|
||||
if (size < kProvisioningResponseArgsSize) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
#include "odk_attributes.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
// The custom mutator: Ensure that each input can be deserialized properly
|
||||
// by ODK function after mutation.
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
|
||||
size_t max_size,
|
||||
unsigned int seed UNUSED) {
|
||||
size_t max_size, unsigned int seed) {
|
||||
const size_t kRenewalResponseArgsSize = sizeof(ODK_ParseRenewal_Args);
|
||||
if (size < kRenewalResponseArgsSize) {
|
||||
return 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "odk.h"
|
||||
|
||||
#include <endian.h> // TODO(b/147944591): use this one? Or odk_endian.h?
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "odk_test_helper.h"
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
@@ -15,6 +13,7 @@
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "odk_endian.h"
|
||||
#include "odk_structs.h"
|
||||
#include "odk_structs_priv.h"
|
||||
|
||||
@@ -226,24 +225,27 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field) {
|
||||
}
|
||||
switch (field->type) {
|
||||
case ODK_UINT16: {
|
||||
const uint16_t u16 = htobe16(*static_cast<uint16_t*>(field->value));
|
||||
const uint16_t u16 =
|
||||
oemcrypto_htobe16(*static_cast<uint16_t*>(field->value));
|
||||
memcpy(buf, &u16, sizeof(u16));
|
||||
break;
|
||||
}
|
||||
case ODK_UINT32: {
|
||||
const uint32_t u32 = htobe32(*static_cast<uint32_t*>(field->value));
|
||||
const uint32_t u32 =
|
||||
oemcrypto_htobe32(*static_cast<uint32_t*>(field->value));
|
||||
memcpy(buf, &u32, sizeof(u32));
|
||||
break;
|
||||
}
|
||||
case ODK_UINT64: {
|
||||
const uint64_t u64 = htobe64(*static_cast<uint64_t*>(field->value));
|
||||
const uint64_t u64 =
|
||||
oemcrypto_htobe64(*static_cast<uint64_t*>(field->value));
|
||||
memcpy(buf, &u64, sizeof(u64));
|
||||
break;
|
||||
}
|
||||
case ODK_SUBSTRING: {
|
||||
OEMCrypto_Substring* s = static_cast<OEMCrypto_Substring*>(field->value);
|
||||
const uint32_t off = htobe32(s->offset);
|
||||
const uint32_t len = htobe32(s->length);
|
||||
const uint32_t off = oemcrypto_htobe32(s->offset);
|
||||
const uint32_t len = oemcrypto_htobe32(s->length);
|
||||
memcpy(buf, &off, sizeof(off));
|
||||
memcpy(buf + sizeof(off), &len, sizeof(len));
|
||||
break;
|
||||
@@ -271,19 +273,19 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf,
|
||||
case ODK_UINT16: {
|
||||
memcpy(field->value, buf, sizeof(uint16_t));
|
||||
uint16_t* u16p = static_cast<uint16_t*>(field->value);
|
||||
*u16p = be16toh(*u16p);
|
||||
*u16p = oemcrypto_be16toh(*u16p);
|
||||
break;
|
||||
}
|
||||
case ODK_UINT32: {
|
||||
memcpy(field->value, buf, sizeof(uint32_t));
|
||||
uint32_t* u32p = static_cast<uint32_t*>(field->value);
|
||||
*u32p = be32toh(*u32p);
|
||||
*u32p = oemcrypto_be32toh(*u32p);
|
||||
break;
|
||||
}
|
||||
case ODK_UINT64: {
|
||||
memcpy(field->value, buf, sizeof(uint64_t));
|
||||
uint64_t* u64p = static_cast<uint64_t*>(field->value);
|
||||
*u64p = be64toh(*u64p);
|
||||
*u64p = oemcrypto_be64toh(*u64p);
|
||||
break;
|
||||
}
|
||||
case ODK_SUBSTRING: {
|
||||
@@ -292,8 +294,8 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf,
|
||||
uint32_t len = 0;
|
||||
memcpy(&off, buf, sizeof(off));
|
||||
memcpy(&len, buf + sizeof(off), sizeof(len));
|
||||
s->offset = be32toh(off);
|
||||
s->length = be32toh(len);
|
||||
s->offset = oemcrypto_be32toh(off);
|
||||
s->length = oemcrypto_be32toh(len);
|
||||
break;
|
||||
}
|
||||
case ODK_DEVICEID:
|
||||
@@ -318,7 +320,7 @@ OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf,
|
||||
case ODK_UINT16: {
|
||||
uint16_t val;
|
||||
memcpy(&val, buf, sizeof(uint16_t));
|
||||
val = be16toh(val);
|
||||
val = oemcrypto_be16toh(val);
|
||||
std::cerr << field->name << ": " << val << " = 0x" << std::hex << val
|
||||
<< "\n";
|
||||
break;
|
||||
@@ -326,7 +328,7 @@ OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf,
|
||||
case ODK_UINT32: {
|
||||
uint32_t val;
|
||||
memcpy(&val, buf, sizeof(uint32_t));
|
||||
val = be32toh(val);
|
||||
val = oemcrypto_be32toh(val);
|
||||
std::cerr << field->name << ": " << val << " = 0x" << std::hex << val
|
||||
<< "\n";
|
||||
break;
|
||||
@@ -334,7 +336,7 @@ OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf,
|
||||
case ODK_UINT64: {
|
||||
uint64_t val;
|
||||
memcpy(&val, buf, sizeof(uint64_t));
|
||||
val = be64toh(val);
|
||||
val = oemcrypto_be64toh(val);
|
||||
std::cerr << field->name << ": " << val << " = 0x" << std::hex << val
|
||||
<< "\n";
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* source code may only be used and distributed under the Widevine
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Compute CRC32/MPEG2 Checksum. Needed for verification of WV Keybox.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// Compute CRC32 Checksum. Needed for verification of WV Keybox.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
#include <assert.h>
|
||||
|
||||
125
libwvdrmengine/oemcrypto/test/README.md
Normal file
125
libwvdrmengine/oemcrypto/test/README.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# OEMCrypto Unit Tests
|
||||
|
||||
## Basic Functionality Tests
|
||||
|
||||
Most unit tests in this category verify that the basic functionality of opening
|
||||
sessions, initializing and terminating the system, and reporting status work
|
||||
correctly.
|
||||
|
||||
## Decrypt Tests
|
||||
|
||||
The decrypt tests verify that encrypted data is correctly decrypted with the
|
||||
desired key. These tests cover a large variety of patterns, sample sizes, and
|
||||
subsample sizes.
|
||||
|
||||
## Secure Buffers
|
||||
|
||||
If OEMCrypto implements the function `OEMCrypto_AllocateSecureBuffer`, then all
|
||||
of the decrypt tests will also run with the output buffer being a secure
|
||||
buffer. If the function `OEMCrypto_SupportsDecryptHash` returns
|
||||
`OEMCrypto_CRC_Clear_Buffer`, then the secure buffer decryption will be verified
|
||||
with the CRC32 hash of the input data.
|
||||
|
||||
## Usage Table Tests
|
||||
|
||||
Usage table tests verify that the usage table is correctly procesed. The usage
|
||||
table is used to control reloading keys for offline playback, and for reporting
|
||||
secure stops for online playback.
|
||||
|
||||
## Duration Tests
|
||||
|
||||
Duration tests verify that license durations are enforced correctly. Most of
|
||||
this functionality can be met by keeping an accurate system time, and calling
|
||||
the ODK functions as described in the document "License Duration and Renewal".
|
||||
|
||||
## OEMCrypto Memory Unit Tests
|
||||
|
||||
### Objective
|
||||
|
||||
* Add OEMCrypto buffer overflow unit tests (indirect way of fuzzing) to verify
|
||||
OEMCrypto API behavior when the parameters passed to the API are out of
|
||||
range or not reasonable. The API can return an error code, but shouldn't
|
||||
crash.
|
||||
|
||||
* A lot of OEMCrypto APIs take buffers and their length as inputs to the APIs
|
||||
and we have added unit tests with buffers of varying lengths (small
|
||||
to huge) to verify API behavior which is an indirect and simplest way of
|
||||
fuzz testing to detect buffer overflows.
|
||||
|
||||
* Add the tests for OEMCrypto APIs with prefix `OEMCryptoMemory` in the
|
||||
following format. Huge length is set at 100 MB as of now.
|
||||
|
||||
```cpp
|
||||
for (size_t length=small_length; length<huge_length; length=length * 2) {
|
||||
Create buffer of size length.
|
||||
Call api expecting it not to crash or segfault.
|
||||
}
|
||||
```
|
||||
|
||||
* Add tests for OEMCrypto APIs with out of range values for length and offsets
|
||||
of OEMCryptoSubstring struct. This length and offset fields are used to read
|
||||
values from an input buffer in most of the APIs. This can cause buffer
|
||||
overflows if the length and offset fields are not validated against the
|
||||
input buffer.
|
||||
|
||||
### Background
|
||||
|
||||
* Security is the top priority for Widevine. We came up with a simple approach
|
||||
to catch most common issues with widevine's implementations. A simplest
|
||||
approach is to add OEMCrypto unit tests to verify OEMCrypto API behavior
|
||||
when the parameters are out of range, meaning for an unreasonable length
|
||||
which can cause buffer overflows. Most of the implementation either does not
|
||||
validate input length parameters or copies data to secure buffers out of TA
|
||||
space causing memory corruptions, buffer overflows. Partners who implement
|
||||
OEMCrypto implementations will run OEMCrypto unit tests as part of the
|
||||
process.
|
||||
|
||||
* We have added unit tests with parameters that can cause buffer overflows if
|
||||
the parameters are not validated. This way partners can catch issues
|
||||
earlier in the process when they run OEMCrypto unit tests. All the unit
|
||||
tests with prefix `OEMCryptoMemory` are added to test the above scenario.
|
||||
|
||||
### What to expect from these tests
|
||||
|
||||
* `OEMCryptoMemory*` tests are designed to fail if API doesn't have enough
|
||||
validations around input buffer lengths, parameters or OEMCryptoSubstring
|
||||
struct. If the API doesn't have validations which might lead to a crash, the
|
||||
test fails with a segfault or an appropriate crash message based on the API
|
||||
implementation.
|
||||
|
||||
* Find out for what buffer length, the API is crashing and then debugging the
|
||||
test against the OEMCrypto implementation should be able to provide
|
||||
information about the error.
|
||||
|
||||
* Another way to debug would be to compile the tests with sanitizer flags,
|
||||
which will be able to provide detailed information about the crash.
|
||||
|
||||
* Partners are expected to fix issues with the API so that the tests don't
|
||||
fail.
|
||||
|
||||
* As these tests run for varying lengths from small to huge buffer lengths,
|
||||
some of the tests might take longer to run(~3 minutes).
|
||||
|
||||
* `OEMCryptoMemoryInstallKeyboxForHugeKeyboxBuffer*` tests which tries to
|
||||
call install keybox API with varying buffer lengths. This test by default
|
||||
is not compiled as it overwrites the keybox on the device. Uncomment,
|
||||
compile and run the tests only if you have ability to recover the keybox
|
||||
on device where the test is ran.
|
||||
|
||||
## Filtering out tests
|
||||
|
||||
The source code will check for functionality of OEMCrypto and filter out tests
|
||||
that are not required. For example, if a device uses a keybox, then Provisioning
|
||||
3.0 tests are skipped, and vice versa.
|
||||
|
||||
If you wish to skip slow tests because you only want to verify basic
|
||||
functionality, then you can set the environment variable `GTEST_FILTER`,
|
||||
as documented
|
||||
[here](https://github.com/google/googletest/blob/master/docs/advanced.md#running-a-subset-of-the-tests).
|
||||
|
||||
For example, to skip the duration tests, buffer overflow tests and long running
|
||||
stress tests, you would set
|
||||
|
||||
```
|
||||
GTEST_FILTER="*-*Duration*:*TimingTest*:*Memory*:*Huge*:*NonceFlood*:*ManyUsageEntries*:*Defrag*"
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "FuzzedDataProvider.h"
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "log.h"
|
||||
#include "oemcrypto_fuzz_helper.h"
|
||||
#include "oemcrypto_fuzz_structs.h"
|
||||
#include "oemcrypto_overflow.h"
|
||||
|
||||
namespace wvoec {
|
||||
const size_t MAX_FUZZ_SAMPLE_SIZE = 5 * MB;
|
||||
@@ -137,13 +138,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
|
||||
// Copy sub sample data.
|
||||
sample_descriptions[i].subsamples = &subsamples[input_subsample_index];
|
||||
input_subsample_index += sample_descriptions[i].subsamples_length;
|
||||
if (AddOverflowUX(input_subsample_index,
|
||||
sample_descriptions[i].subsamples_length,
|
||||
&input_subsample_index)) {
|
||||
return 0;
|
||||
}
|
||||
if (input_subsample_index > subsamples.size()) return 0;
|
||||
} // Sample loop.
|
||||
|
||||
// Allocate input/output buffers for each sample description.
|
||||
vector<OEMCrypto_SharedMemory> input_buffer(total_input_data_length);
|
||||
RAND_bytes(input_buffer.data(), total_input_data_length);
|
||||
size_t input_buffer_index = 0;
|
||||
for (size_t i = 0; i < samples_length; i++) {
|
||||
sample_descriptions[i].buffers.input_data =
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#include "oemcrypto_fuzz_helper.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#ifndef OEMCRYPTO_FUZZ_HELPER_H_
|
||||
#define OEMCRYPTO_FUZZ_HELPER_H_
|
||||
@@ -36,9 +36,7 @@ class OEMCryptoLicenseAPIFuzz : public InitializeFuzz {
|
||||
session_.GenerateNonce();
|
||||
}
|
||||
|
||||
~OEMCryptoLicenseAPIFuzz() {
|
||||
session_.close();
|
||||
}
|
||||
~OEMCryptoLicenseAPIFuzz() { session_.close(); }
|
||||
|
||||
LicenseRoundTrip& license_messages() { return license_messages_; }
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#ifndef OEMCRYPTO_FUZZ_STRUCTS_H_
|
||||
#define OEMCRYPTO_FUZZ_STRUCTS_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "oemcrypto_fuzz_helper.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "FuzzedDataProvider.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "oemcrypto_fuzz_helper.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "oemcrypto_fuzz_helper.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "oemcrypto_fuzz_helper.h"
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dispatcher.h"
|
||||
#include "marshaller_base.h"
|
||||
#include "transport_interface.h"
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
void InitializeODKMessage(ODK_Message* message, uint8_t* data, size_t size) {
|
||||
ODK_Message_Impl* impl = (ODK_Message_Impl*)message;
|
||||
impl->base = data;
|
||||
impl->size = size;
|
||||
impl->capacity = size;
|
||||
impl->read_offset = 0;
|
||||
impl->status = MESSAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
void OpenOEMCryptoTASession() {
|
||||
ODK_Message request;
|
||||
ODK_Message* response = NULL;
|
||||
uint8_t response_buffer[0x1000];
|
||||
uint8_t request_body[] = {
|
||||
0x06, // TAG_UINT32
|
||||
0x09, 0x00, 0x00, 0x00, // API value (0x09)
|
||||
0x01, // TAG_BOOL
|
||||
0x00, // value (false)
|
||||
0x0a // TAG_EOM
|
||||
};
|
||||
|
||||
InitializeODKMessage(&request, request_body, sizeof(request_body));
|
||||
|
||||
ODK_DispatchMessage(&request, &response);
|
||||
if (response != NULL) ODK_Transport_DeallocateMessage(response);
|
||||
}
|
||||
|
||||
void InitializeOEMCryptoTA() {
|
||||
ODK_Message init_request;
|
||||
ODK_Message* init_response = NULL;
|
||||
uint8_t response_buffer[0x1000];
|
||||
uint8_t init_request_body[] = {
|
||||
0x06, // TAG_UINT32
|
||||
0x01, 0x00, 0x00, 0x00, // API value(0x01)
|
||||
0x0a // TAG_EOM
|
||||
};
|
||||
|
||||
InitializeODKMessage(&init_request, init_request_body,
|
||||
sizeof(init_request_body));
|
||||
|
||||
ODK_DispatchMessage(&init_request, &init_response);
|
||||
if (init_response != NULL) ODK_Transport_DeallocateMessage(init_response);
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
|
||||
ODK_InitializeDispatcher();
|
||||
InitializeOEMCryptoTA();
|
||||
OpenOEMCryptoTASession();
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
ODK_Message request;
|
||||
ODK_Message* response = NULL;
|
||||
unsigned char response_buffer[0x1000];
|
||||
|
||||
uint8_t* input = new uint8_t[size];
|
||||
memcpy(input, data, size);
|
||||
|
||||
InitializeODKMessage(&request, input, size);
|
||||
|
||||
ODK_DispatchMessage(&request, &response);
|
||||
if (response != NULL) ODK_Transport_DeallocateMessage(response);
|
||||
|
||||
delete[] input;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace wvoec
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "oemcrypto_fuzz_helper.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "oemcrypto_fuzz_helper.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "oec_decrypt_fallback_chain.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef CDM_OEC_DECRYPT_FALLBACK_CHAIN_H_
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// OEMCrypto device features for unit tests
|
||||
@@ -129,6 +129,7 @@ std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
|
||||
if (!generic_crypto) FilterOut(&filter, "*GenericCrypto*");
|
||||
if (!cast_receiver) FilterOut(&filter, "*CastReceiver*");
|
||||
if (!usage_table) FilterOut(&filter, "*UsageTable*");
|
||||
if (!usage_table) FilterOut(&filter, "*BadRange_pst*");
|
||||
if (derive_key_method == NO_METHOD) FilterOut(&filter, "*SessionTest*");
|
||||
if (provisioning_method
|
||||
!= OEMCrypto_OEMCertificate) FilterOut(&filter, "*Prov30*");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
// OEMCrypto unit tests
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
//
|
||||
#ifndef CDM_OEC_KEY_DERIVER_H_
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user