diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index e3633a2c..194b2ee6 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -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. diff --git a/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp b/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp index fe7e71b6..d8c83938 100644 --- a/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp +++ b/libwvdrmengine/cdm/core/test/duration_use_case_test.cpp @@ -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. diff --git a/libwvdrmengine/docs/Widevine_OEMCrypto_Version_Compatibility.pdf b/libwvdrmengine/docs/Widevine_OEMCrypto_Version_Compatibility.pdf index 996cc62e..20174fbe 100644 Binary files a/libwvdrmengine/docs/Widevine_OEMCrypto_Version_Compatibility.pdf and b/libwvdrmengine/docs/Widevine_OEMCrypto_Version_Compatibility.pdf differ diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index 4bbdfa67..4b8dc03b 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.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. /** @@ -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); diff --git a/libwvdrmengine/oemcrypto/include/level3.h b/libwvdrmengine/oemcrypto/include/level3.h index 9573c167..c4e7c435 100644 --- a/libwvdrmengine/oemcrypto/include/level3.h +++ b/libwvdrmengine/oemcrypto/include/level3.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. /********************************************************************* @@ -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" { diff --git a/libwvdrmengine/oemcrypto/include/level3_file_system.h b/libwvdrmengine/oemcrypto/include/level3_file_system.h index eceec5a3..232fbf8e 100644 --- a/libwvdrmengine/oemcrypto/include/level3_file_system.h +++ b/libwvdrmengine/oemcrypto/include/level3_file_system.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. /********************************************************************* diff --git a/libwvdrmengine/oemcrypto/include/oemcrypto_types.h b/libwvdrmengine/oemcrypto/include/oemcrypto_types.h index bf2158f6..4a5728c2 100644 --- a/libwvdrmengine/oemcrypto/include/oemcrypto_types.h +++ b/libwvdrmengine/oemcrypto/include/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. #ifndef WV_OEMCRYPTO_TYPES_H_ diff --git a/libwvdrmengine/oemcrypto/include/pst_report.h b/libwvdrmengine/oemcrypto/include/pst_report.h index 3d2c6ced..251ac525 100644 --- a/libwvdrmengine/oemcrypto/include/pst_report.h +++ b/libwvdrmengine/oemcrypto/include/pst_report.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. /********************************************************************* diff --git a/libwvdrmengine/oemcrypto/odk/Android.bp b/libwvdrmengine/oemcrypto/odk/Android.bp index 01af3332..45ec6608 100644 --- a/libwvdrmengine/oemcrypto/odk/Android.bp +++ b/libwvdrmengine/oemcrypto/odk/Android.bp @@ -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", diff --git a/libwvdrmengine/oemcrypto/odk/README b/libwvdrmengine/oemcrypto/odk/README index ba8c8c73..408fc448 100644 --- a/libwvdrmengine/oemcrypto/odk/README +++ b/libwvdrmengine/oemcrypto/odk/README @@ -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 diff --git a/libwvdrmengine/oemcrypto/odk/include/OEMCryptoCENCCommon.h b/libwvdrmengine/oemcrypto/odk/include/OEMCryptoCENCCommon.h index 5e54cc6b..d279c5c4 100644 --- a/libwvdrmengine/oemcrypto/odk/include/OEMCryptoCENCCommon.h +++ b/libwvdrmengine/oemcrypto/odk/include/OEMCryptoCENCCommon.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. /********************************************************************* @@ -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. */ diff --git a/libwvdrmengine/oemcrypto/odk/include/core_message_deserialize.h b/libwvdrmengine/oemcrypto/odk/include/core_message_deserialize.h index 93cf8002..76dccc5c 100644 --- a/libwvdrmengine/oemcrypto/odk/include/core_message_deserialize.h +++ b/libwvdrmengine/oemcrypto/odk/include/core_message_deserialize.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. /********************************************************************* diff --git a/libwvdrmengine/oemcrypto/odk/include/core_message_serialize.h b/libwvdrmengine/oemcrypto/odk/include/core_message_serialize.h index 619a0857..781259aa 100644 --- a/libwvdrmengine/oemcrypto/odk/include/core_message_serialize.h +++ b/libwvdrmengine/oemcrypto/odk/include/core_message_serialize.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. /********************************************************************* diff --git a/libwvdrmengine/oemcrypto/odk/include/core_message_serialize_proto.h b/libwvdrmengine/oemcrypto/odk/include/core_message_serialize_proto.h index b9dd34e0..ce5df09a 100644 --- a/libwvdrmengine/oemcrypto/odk/include/core_message_serialize_proto.h +++ b/libwvdrmengine/oemcrypto/odk/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. /********************************************************************* diff --git a/libwvdrmengine/oemcrypto/odk/include/core_message_types.h b/libwvdrmengine/oemcrypto/odk/include/core_message_types.h index 0f45f006..3d02aa91 100644 --- a/libwvdrmengine/oemcrypto/odk/include/core_message_types.h +++ b/libwvdrmengine/oemcrypto/odk/include/core_message_types.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. // clang-format off diff --git a/libwvdrmengine/oemcrypto/odk/include/odk.h b/libwvdrmengine/oemcrypto/odk/include/odk.h index 588f185a..4f0c9f69 100644 --- a/libwvdrmengine/oemcrypto/odk/include/odk.h +++ b/libwvdrmengine/oemcrypto/odk/include/odk.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. /** diff --git a/libwvdrmengine/oemcrypto/odk/include/odk_attributes.h b/libwvdrmengine/oemcrypto/odk/include/odk_attributes.h index 623a0571..72321b14 100644 --- a/libwvdrmengine/oemcrypto/odk/include/odk_attributes.h +++ b/libwvdrmengine/oemcrypto/odk/include/odk_attributes.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_ATTRIBUTES_H_ diff --git a/libwvdrmengine/oemcrypto/odk/include/odk_message.h b/libwvdrmengine/oemcrypto/odk/include/odk_message.h new file mode 100644 index 00000000..07abebb6 --- /dev/null +++ b/libwvdrmengine/oemcrypto/odk/include/odk_message.h @@ -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 +#include +#include + +/* + * 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_ diff --git a/libwvdrmengine/oemcrypto/odk/include/odk_structs.h b/libwvdrmengine/oemcrypto/odk/include/odk_structs.h index bd500d87..5794dd5c 100644 --- a/libwvdrmengine/oemcrypto/odk/include/odk_structs.h +++ b/libwvdrmengine/oemcrypto/odk/include/odk_structs.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 diff --git a/libwvdrmengine/oemcrypto/odk/include/odk_target.h b/libwvdrmengine/oemcrypto/odk/include/odk_target.h index cb2774fb..d1c0652d 100644 --- a/libwvdrmengine/oemcrypto/odk/include/odk_target.h +++ b/libwvdrmengine/oemcrypto/odk/include/odk_target.h @@ -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. diff --git a/libwvdrmengine/oemcrypto/odk/src/core_message_deserialize.cpp b/libwvdrmengine/oemcrypto/odk/src/core_message_deserialize.cpp index 47d4478c..e5c1bd38 100644 --- a/libwvdrmengine/oemcrypto/odk/src/core_message_deserialize.cpp +++ b/libwvdrmengine/oemcrypto/odk/src/core_message_deserialize.cpp @@ -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(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(blk); - InitMessage(msg, const_cast(buf), buf_length); - SetSize(msg, buf_length); + ODK_Message msg = ODK_Message_Create(const_cast(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; } diff --git a/libwvdrmengine/oemcrypto/odk/src/core_message_serialize.cpp b/libwvdrmengine/oemcrypto/odk/src/core_message_serialize.cpp index 0e05330a..177e39ca 100644 --- a/libwvdrmengine/oemcrypto/odk/src/core_message_serialize.cpp +++ b/libwvdrmengine/oemcrypto/odk/src/core_message_serialize.cpp @@ -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 buf(BUF_CAPACITY, 0); - uint8_t blk[SIZE_OF_MESSAGE_STRUCT]; - Message* msg = reinterpret_cast(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(buf.data()), message_length); return true; diff --git a/libwvdrmengine/oemcrypto/odk/src/core_message_serialize_proto.cpp b/libwvdrmengine/oemcrypto/odk/src/core_message_serialize_proto.cpp index 4b8da06e..224f8173 100644 --- a/libwvdrmengine/oemcrypto/odk/src/core_message_serialize_proto.cpp +++ b/libwvdrmengine/oemcrypto/odk/src/core_message_serialize_proto.cpp @@ -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" diff --git a/libwvdrmengine/oemcrypto/odk/src/odk.c b/libwvdrmengine/oemcrypto/odk/src/odk.c index 0bb6ab18..c128890d 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk.c +++ b/libwvdrmengine/oemcrypto/odk/src/odk.c @@ -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, diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_assert.h b/libwvdrmengine/oemcrypto/odk/src/odk_assert.h index 149021fd..0517818b 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_assert.h +++ b/libwvdrmengine/oemcrypto/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_ASSERT_H_ diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_endian.h b/libwvdrmengine/oemcrypto/odk/src/odk_endian.h index 00dc01ec..1e9f50d2 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_endian.h +++ b/libwvdrmengine/oemcrypto/odk/src/odk_endian.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 +#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 +#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); diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_message.c b/libwvdrmengine/oemcrypto/odk/src/odk_message.c new file mode 100644 index 00000000..ea0f9e4b --- /dev/null +++ b/libwvdrmengine/oemcrypto/odk/src/odk_message.c @@ -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 +#include +#include + +/* + * 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; +} diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_message_priv.h b/libwvdrmengine/oemcrypto/odk/src/odk_message_priv.h new file mode 100644 index 00000000..4a911649 --- /dev/null +++ b/libwvdrmengine/oemcrypto/odk/src/odk_message_priv.h @@ -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 +#include + +/* + * 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_ diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_overflow.c b/libwvdrmengine/oemcrypto/odk/src/odk_overflow.c index a03f0f61..0ebc0846 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_overflow.c +++ b/libwvdrmengine/oemcrypto/odk/src/odk_overflow.c @@ -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 @@ -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; +} diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_overflow.h b/libwvdrmengine/oemcrypto/odk/src/odk_overflow.h index 6f3f994e..e7257051 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_overflow.h +++ b/libwvdrmengine/oemcrypto/odk/src/odk_overflow.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_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 } diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_serialize.c b/libwvdrmengine/oemcrypto/odk/src/odk_serialize.c index ae53e735..35a5539e 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_serialize.c +++ b/libwvdrmengine/oemcrypto/odk/src/odk_serialize.c @@ -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); diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_serialize.h b/libwvdrmengine/oemcrypto/odk/src/odk_serialize.h index 73f4abd1..ca5b5401 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_serialize.h +++ b/libwvdrmengine/oemcrypto/odk/src/odk_serialize.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. /* @@ -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 diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_structs_priv.h b/libwvdrmengine/oemcrypto/odk/src/odk_structs_priv.h index 7b1f6de7..6b138f4d 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_structs_priv.h +++ b/libwvdrmengine/oemcrypto/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. #ifndef WIDEVINE_ODK_SRC_ODK_STRUCTS_PRIV_H_ diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_timer.c b/libwvdrmengine/oemcrypto/odk/src/odk_timer.c index 67c34700..c817bbbf 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_timer.c +++ b/libwvdrmengine/oemcrypto/odk/src/odk_timer.c @@ -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 diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_util.c b/libwvdrmengine/oemcrypto/odk/src/odk_util.c index 682bf8eb..76ee242a 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_util.c +++ b/libwvdrmengine/oemcrypto/odk/src/odk_util.c @@ -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" diff --git a/libwvdrmengine/oemcrypto/odk/src/odk_util.h b/libwvdrmengine/oemcrypto/odk/src/odk_util.h index 138791fc..def0865e 100644 --- a/libwvdrmengine/oemcrypto/odk/src/odk_util.h +++ b/libwvdrmengine/oemcrypto/odk/src/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_ diff --git a/libwvdrmengine/oemcrypto/odk/src/serialization_base.c b/libwvdrmengine/oemcrypto/odk/src/serialization_base.c index 1b32d055..3a0364c0 100644 --- a/libwvdrmengine/oemcrypto/odk/src/serialization_base.c +++ b/libwvdrmengine/oemcrypto/odk/src/serialization_base.c @@ -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 #include #include #include #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); } diff --git a/libwvdrmengine/oemcrypto/odk/src/serialization_base.h b/libwvdrmengine/oemcrypto/odk/src/serialization_base.h index 9e7776bf..0a8b2e28 100644 --- a/libwvdrmengine/oemcrypto/odk/src/serialization_base.h +++ b/libwvdrmengine/oemcrypto/odk/src/serialization_base.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_SERIALIZATION_BASE_H_ @@ -13,74 +13,24 @@ extern "C" { #include #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" diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/Android.bp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/Android.bp index 28465c39..3b8fe6d6 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/Android.bp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/Android.bp @@ -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 diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/Android.bp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/Android.bp index bcbbfd3b..78519cb0 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/Android.bp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/Android.bp @@ -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. // ---------------------------------------------------------------- diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator.c b/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator.c index 9a3e9853..0a2d0747 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator.c +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator.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. // We must define this macro to get RTLD_NEXT definition from diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator_helper.c b/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator_helper.c index 3a720d20..534b2457 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator_helper.c +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator_helper.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. #include "fuzzing/corpus_generator/odk_corpus_generator_helper.h" diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator_helper.h b/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator_helper.h index c2f164ae..d6c1e99a 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/corpus_generator/odk_corpus_generator_helper.h +++ b/libwvdrmengine/oemcrypto/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. #ifndef WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_ #define WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp index d87e4647..ef90a00b 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp @@ -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(blk); - InitMessage(msg, const_cast(buf), len); - SetSize(msg, len); - Unpack_ODK_PreparedRenewalRequest(msg, renewal_msg); + ODK_Message msg = ODK_Message_Create(const_cast(buf), len); + ODK_Message_SetSize(&msg, len); + Unpack_ODK_PreparedRenewalRequest(&msg, renewal_msg); return OEMCrypto_SUCCESS; } diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.h b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.h index fe90657b..34fe8fcd 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.h +++ b/libwvdrmengine/oemcrypto/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_HELPER_H_ #define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_structs.h b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_structs.h index 37d1b230..b35c56a0 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_structs.h +++ b/libwvdrmengine/oemcrypto/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. #ifndef WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_ #define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_request_fuzz.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_request_fuzz.cpp index 463c604a..d089c4ad 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_request_fuzz.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_request_fuzz.cpp @@ -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. */ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_response_fuzz.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_response_fuzz.cpp index 12398fd1..f3655248 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_response_fuzz.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_response_fuzz.cpp @@ -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. */ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_response_fuzz_with_mutator.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_response_fuzz_with_mutator.cpp index 42472fbd..880e1d88 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_response_fuzz_with_mutator.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_license_response_fuzz_with_mutator.cpp @@ -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. */ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_request_fuzz.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_request_fuzz.cpp index 984534e6..deac024a 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_request_fuzz.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_request_fuzz.cpp @@ -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. */ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_response_fuzz.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_response_fuzz.cpp index 90dc017c..3a0457d4 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_response_fuzz.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_response_fuzz.cpp @@ -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. */ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_response_fuzz_with_mutator.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_response_fuzz_with_mutator.cpp index 2be4a91b..52492534 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_response_fuzz_with_mutator.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_provisioning_response_fuzz_with_mutator.cpp @@ -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 #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) { diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_request_fuzz.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_request_fuzz.cpp index 602b37af..d715eeb6 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_request_fuzz.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_request_fuzz.cpp @@ -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. */ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_response_fuzz.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_response_fuzz.cpp index 8d669089..c0903758 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_response_fuzz.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_response_fuzz.cpp @@ -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. */ diff --git a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_response_fuzz_with_mutator.cpp b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_response_fuzz_with_mutator.cpp index 25fa7b00..d6a9dd4a 100644 --- a/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_response_fuzz_with_mutator.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_renewal_response_fuzz_with_mutator.cpp @@ -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 #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; diff --git a/libwvdrmengine/oemcrypto/odk/test/odk_core_message_test.cpp b/libwvdrmengine/oemcrypto/odk/test/odk_core_message_test.cpp index c8247592..24fbe6da 100644 --- a/libwvdrmengine/oemcrypto/odk/test/odk_core_message_test.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/odk_core_message_test.cpp @@ -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" diff --git a/libwvdrmengine/oemcrypto/odk/test/odk_test.cpp b/libwvdrmengine/oemcrypto/odk/test/odk_test.cpp index b6526df8..cf41b77a 100644 --- a/libwvdrmengine/oemcrypto/odk/test/odk_test.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/odk_test.cpp @@ -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 // TODO(b/147944591): use this one? Or odk_endian.h? - #include #include diff --git a/libwvdrmengine/oemcrypto/odk/test/odk_test_helper.cpp b/libwvdrmengine/oemcrypto/odk/test/odk_test_helper.cpp index 167d9e59..9eeb49c4 100644 --- a/libwvdrmengine/oemcrypto/odk/test/odk_test_helper.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/odk_test_helper.cpp @@ -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 - #include #include #include @@ -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(field->value)); + const uint16_t u16 = + oemcrypto_htobe16(*static_cast(field->value)); memcpy(buf, &u16, sizeof(u16)); break; } case ODK_UINT32: { - const uint32_t u32 = htobe32(*static_cast(field->value)); + const uint32_t u32 = + oemcrypto_htobe32(*static_cast(field->value)); memcpy(buf, &u32, sizeof(u32)); break; } case ODK_UINT64: { - const uint64_t u64 = htobe64(*static_cast(field->value)); + const uint64_t u64 = + oemcrypto_htobe64(*static_cast(field->value)); memcpy(buf, &u64, sizeof(u64)); break; } case ODK_SUBSTRING: { OEMCrypto_Substring* s = static_cast(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(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(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(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; diff --git a/libwvdrmengine/oemcrypto/odk/test/odk_test_helper.h b/libwvdrmengine/oemcrypto/odk/test/odk_test_helper.h index 1d90dc07..c32318e4 100644 --- a/libwvdrmengine/oemcrypto/odk/test/odk_test_helper.h +++ b/libwvdrmengine/oemcrypto/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. #ifndef WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_ diff --git a/libwvdrmengine/oemcrypto/odk/test/odk_timer_test.cpp b/libwvdrmengine/oemcrypto/odk/test/odk_timer_test.cpp index 15a6f78e..9bb0b547 100644 --- a/libwvdrmengine/oemcrypto/odk/test/odk_timer_test.cpp +++ b/libwvdrmengine/oemcrypto/odk/test/odk_timer_test.cpp @@ -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. */ diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp index b62cd39f..5b92ee0a 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h index c1ae01db..c2a88dcd 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.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. // // Reference implementation of OEMCrypto APIs diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties.cpp index a3bdf4e3..8c4bd22a 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_L1.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_L1.cpp index 5e92a88a..9e9b7c51 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_L1.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_L1.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_cert.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_cert.cpp index 7fd4e596..146a8290 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_cert.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_cert.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp index 96134b99..d2115ca1 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp index 9a6f1d47..d0f5f581 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h index 0fddd30f..f7f92c14 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.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. // // Reference implementation of OEMCrypto APIs diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_key_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_key_ref.cpp index 9d28eec5..19a80f28 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_key_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_key_ref.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_key_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_key_ref.h index c6c74416..a94f24fb 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_key_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_key_ref.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. // // Reference implementation of OEMCrypto APIs diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_keybox_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_keybox_ref.cpp index cfb070ad..987a5103 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_keybox_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_keybox_ref.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_keybox_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_keybox_ref.h index 47b8c070..c9831c60 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_keybox_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_keybox_ref.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. // // Reference implementation of OEMCrypto APIs diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp index 0f65f489..6aa2f19e 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp index 96f0b8ea..657867aa 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h index e01054eb..8811b9eb 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.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. // // Reference implementation of OEMCrypto APIs diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session_key_table.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session_key_table.cpp index 00c16ed8..0247bec4 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session_key_table.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session_key_table.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session_key_table.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session_key_table.h index ad74b873..d534510d 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session_key_table.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session_key_table.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. // // Reference implementation of OEMCrypto APIs diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp index d61ec052..b3750c1f 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.h index d112695b..7fdd1785 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.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. // // Reference implementation of OEMCrypto APIs diff --git a/libwvdrmengine/oemcrypto/ref/src/wvcrc.cpp b/libwvdrmengine/oemcrypto/ref/src/wvcrc.cpp index 192e783f..000ac260 100644 --- a/libwvdrmengine/oemcrypto/ref/src/wvcrc.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/wvcrc.cpp @@ -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. diff --git a/libwvdrmengine/oemcrypto/ref/src/wvcrc32.h b/libwvdrmengine/oemcrypto/ref/src/wvcrc32.h index 99677ec4..b1e0ee6b 100644 --- a/libwvdrmengine/oemcrypto/ref/src/wvcrc32.h +++ b/libwvdrmengine/oemcrypto/ref/src/wvcrc32.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. // // Compute CRC32 Checksum. Needed for verification of WV Keybox. diff --git a/libwvdrmengine/oemcrypto/renewal/derive_key.cpp b/libwvdrmengine/oemcrypto/renewal/derive_key.cpp index 9cde5a92..9a377dc3 100644 --- a/libwvdrmengine/oemcrypto/renewal/derive_key.cpp +++ b/libwvdrmengine/oemcrypto/renewal/derive_key.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/test/README.md b/libwvdrmengine/oemcrypto/test/README.md new file mode 100644 index 00000000..a85b663d --- /dev/null +++ b/libwvdrmengine/oemcrypto/test/README.md @@ -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 subsamples.size()) return 0; } // Sample loop. // Allocate input/output buffers for each sample description. vector 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 = diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.cc b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.cc index 3596d619..8939f118 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.cc +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.cc @@ -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" diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h index 7dc707ee..14c18f5c 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_helper.h +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/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_; } diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_structs.h b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_structs.h index 52fb400d..67dd588c 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_fuzz_structs.h +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/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. #ifndef OEMCRYPTO_FUZZ_STRUCTS_H_ #define OEMCRYPTO_FUZZ_STRUCTS_H_ diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_license_request_fuzz.cc b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_license_request_fuzz.cc index d100ddea..52d34938 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_license_request_fuzz.cc +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_license_request_fuzz.cc @@ -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" diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_entitled_content_keys_fuzz.cc b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_entitled_content_keys_fuzz.cc index 892d6e93..fbb33e67 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_entitled_content_keys_fuzz.cc +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_entitled_content_keys_fuzz.cc @@ -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" diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_license_fuzz.cc b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_license_fuzz.cc index e125ae04..73ba25cd 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_license_fuzz.cc +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_license_fuzz.cc @@ -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" diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_provisioning_fuzz.cc b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_provisioning_fuzz.cc index 739f79f4..757ab241 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_provisioning_fuzz.cc +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_provisioning_fuzz.cc @@ -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" diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_renewal_fuzz.cc b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_renewal_fuzz.cc index f521b477..1b6ecfc6 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_renewal_fuzz.cc +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_load_renewal_fuzz.cc @@ -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" diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_odkitee_dispatcher_fuzz.cc b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_odkitee_dispatcher_fuzz.cc new file mode 100644 index 00000000..1a3c770b --- /dev/null +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_odkitee_dispatcher_fuzz.cc @@ -0,0 +1,77 @@ +#include + +#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 diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_provisioning_request_fuzz.cc b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_provisioning_request_fuzz.cc index 1cda2abd..b66aab6d 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_provisioning_request_fuzz.cc +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_provisioning_request_fuzz.cc @@ -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" diff --git a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_renewal_request_fuzz.cc b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_renewal_request_fuzz.cc index 67ecb0a9..8b7fd79d 100644 --- a/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_renewal_request_fuzz.cc +++ b/libwvdrmengine/oemcrypto/test/fuzz_tests/oemcrypto_renewal_request_fuzz.cc @@ -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" diff --git a/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.cpp b/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.cpp index 7c589c51..b3d36dc5 100644 --- a/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.cpp @@ -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" diff --git a/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.h b/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.h index 2379dafc..06ca62f8 100644 --- a/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.h +++ b/libwvdrmengine/oemcrypto/test/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_ diff --git a/libwvdrmengine/oemcrypto/test/oec_device_features.cpp b/libwvdrmengine/oemcrypto/test/oec_device_features.cpp index b4988edd..1fab63f5 100644 --- a/libwvdrmengine/oemcrypto/test/oec_device_features.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_device_features.cpp @@ -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*"); diff --git a/libwvdrmengine/oemcrypto/test/oec_key_deriver.cpp b/libwvdrmengine/oemcrypto/test/oec_key_deriver.cpp index d2bff254..f6abdb6a 100644 --- a/libwvdrmengine/oemcrypto/test/oec_key_deriver.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_key_deriver.cpp @@ -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 diff --git a/libwvdrmengine/oemcrypto/test/oec_key_deriver.h b/libwvdrmengine/oemcrypto/test/oec_key_deriver.h index 7e05038a..65b4ad71 100644 --- a/libwvdrmengine/oemcrypto/test/oec_key_deriver.h +++ b/libwvdrmengine/oemcrypto/test/oec_key_deriver.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_KEY_DERIVER_H_ diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index f5d45775..243c7984 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -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 unit tests @@ -154,8 +154,7 @@ RoundTrip:: constexpr size_t small_size = 42; // arbitrary. uint32_t session_id = session()->session_id(); GetDefaultRequestSignatureAndCoreMessageLengths( - session_id, required_message_size_, small_size, &gen_signature_length, - &core_message_length); + session_id, small_size, &gen_signature_length, &core_message_length); // Used to test request APIs with varying lengths of core message. core_message_length = std::max(core_message_length, required_core_message_size_); @@ -192,9 +191,8 @@ RoundTrip:: template void GetDefaultRequestSignatureAndCoreMessageLengths( - uint32_t& session_id, size_t& required_message_size, - const size_t& small_size, size_t* gen_signature_length, - size_t* core_message_length) { + uint32_t& session_id, const size_t& small_size, + size_t* gen_signature_length, size_t* core_message_length) { vector data(small_size); for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF; ASSERT_EQ( @@ -504,9 +502,13 @@ void LicenseRoundTrip::FillAndVerifyCoreRequest( oemcrypto_core_message::deserialize::CoreLicenseRequestFromMessage( core_message_string, &core_request_)); EXPECT_EQ(global_features.api_version, core_request_.api_major_version); - // If we are testing the latest OEMCrypto version, make sure it is built with - // the latest ODK version, too: - if (global_features.api_version == ODK_MAJOR_VERSION) { + if (global_features.api_version == 16) { + // We support either 16.3 or 16.4 for OEMCrypto 16. + EXPECT_LE(3, core_request_.api_minor_version); + EXPECT_GE(4, core_request_.api_minor_version); + } else if (global_features.api_version == ODK_MAJOR_VERSION) { + // If we are testing the latest OEMCrypto version, make sure it is built + // with the latest ODK version, too: EXPECT_EQ(ODK_MINOR_VERSION, core_request_.api_minor_version); } if (expect_request_has_correct_nonce_) { diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.h b/libwvdrmengine/oemcrypto/test/oec_session_util.h index 264a8ae9..272e85e1 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.h +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.h @@ -2,7 +2,7 @@ #define CDM_OEC_SESSION_UTIL_H_ // 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 unit tests @@ -669,9 +669,8 @@ void WriteRequestApiCorpus(size_t signature_length, size_t core_message_length, vector& data); template void GetDefaultRequestSignatureAndCoreMessageLengths( - uint32_t& session_id, size_t& required_message_size, - const size_t& small_size, size_t* gen_signature_length, - size_t* core_message_length); + uint32_t& session_id, const size_t& small_size, + size_t* gen_signature_length, size_t* core_message_length); } // namespace wvoec #endif // CDM_OEC_SESSION_UTIL_H_ diff --git a/libwvdrmengine/oemcrypto/test/oec_test_data.h b/libwvdrmengine/oemcrypto/test/oec_test_data.h index 144c4d37..fbd202da 100644 --- a/libwvdrmengine/oemcrypto/test/oec_test_data.h +++ b/libwvdrmengine/oemcrypto/test/oec_test_data.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. // // Test data for OEMCrypto unit tests. diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_corpus_generator_helper.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_corpus_generator_helper.cpp index 0478de69..31b9bb52 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_corpus_generator_helper.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_corpus_generator_helper.cpp @@ -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_corpus_generator_helper.h" diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_corpus_generator_helper.h b/libwvdrmengine/oemcrypto/test/oemcrypto_corpus_generator_helper.h index 9086a0c1..7b7b399b 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_corpus_generator_helper.h +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_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 CDM_OEMCRYPTO_CORPUS_GENERATOR_HELPER_H_ #define CDM_OEMCRYPTO_CORPUS_GENERATOR_HELPER_H_ diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 264d63f3..07d2a1e7 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -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. // @@ -137,6 +137,11 @@ void TestHugeLengthDoesNotCrashAPI(oemcrypto_function f, !check_status); buffer_length *= 2) { sts = f(buffer_length); + if (check_status && sts != OEMCrypto_SUCCESS && + sts != OEMCrypto_ERROR_SHORT_BUFFER) { + LOGI("Test exits huge buffer loop for length:%zu, status:%d", + buffer_length, sts); + } } } @@ -170,6 +175,17 @@ const size_t kLargeMessageSize[] = { 8*KiB, 8*KiB, 16*KiB, 32*KiB}; // const size_t kAV1NumberSubsamples[] = { 72, 144, 288, 576}; // clang-format on +// Return a printable string from data. If all the characters are printable, +// then just use the string. Otherwise, convert to hex. +std::string MaybeHex(const uint8_t* data, size_t length) { + for (size_t i = 0; i < length; i++) { + if (!isprint(data[i])) return "0x" + wvcdm::HexEncode(data, length); + } + return std::string(reinterpret_cast(data), length); +} +std::string MaybeHex(const std::vector& data) { + return MaybeHex(data.data(), data.size()); +} } // namespace class OEMCryptoClientTest : public ::testing::Test, public SessionUtil { @@ -202,6 +218,17 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil { } }; +TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) { + Session s; + s.open(); + OEMCrypto_DestBufferDesc output_descriptor; + int secure_fd = kHugeRandomNumber; + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_FreeSecureBuffer(s.session_id(), &output_descriptor, + secure_fd)); + s.close(); +} + /// @addtogroup basic /// @{ @@ -212,15 +239,20 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil { */ TEST_F(OEMCryptoClientTest, VersionNumber) { const std::string log_message = - "OEMCrypto unit tests for API 16.4. Tests last updated 2020-10-07"; + "OEMCrypto unit tests for API 16.3 or 4. Tests last updated 2021-02-22"; cout << " " << log_message << "\n"; + cout << " " + << "These tests are part of Android S." + << "\n"; LOGI("%s", log_message.c_str()); // If any of the following fail, then it is time to update the log message // above. EXPECT_EQ(ODK_MAJOR_VERSION, 16); // Note on minor versions. Widevine requires version 16.3 or greater for CE // CDM and Android devices. For CE CDM devices that do not support usage - // tables, we strongly recommend 16.4. + // tables, we strongly recommend 16.4. Note: This is the version of the ODK + // library built into the tests, which might be different from the version + // that is pre-compiled into liboemcrypto.so. EXPECT_GE(ODK_MINOR_VERSION, 3); EXPECT_LE(ODK_MINOR_VERSION, 4); EXPECT_EQ(kCurrentAPI, 16u); @@ -229,7 +261,9 @@ TEST_F(OEMCryptoClientTest, VersionNumber) { ASSERT_EQ('L', level[0]); cout << " OEMCrypto Security Level is " << level << endl; uint32_t version = OEMCrypto_APIVersion(); - cout << " OEMCrypto API version is " << version << endl; + uint32_t minor_version = OEMCrypto_MinorAPIVersion(); + cout << " OEMCrypto API version is " << version << "." + << minor_version << endl; if (OEMCrypto_SupportsUsageTable()) { cout << " OEMCrypto supports usage tables" << endl; } else { @@ -661,8 +695,8 @@ TEST_F(OEMCryptoClientTest, ClearCopyTestAPI10) { OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); dest_buffer_descriptor.buffer.clear.address = output_buffer.data(); dest_buffer_descriptor.buffer.clear.address_length = output_buffer.size() - 1; - ASSERT_EQ( - OEMCrypto_ERROR_SHORT_BUFFER, + ASSERT_NE( + OEMCrypto_SUCCESS, OEMCrypto_CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), &dest_buffer_descriptor, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); @@ -896,8 +930,8 @@ TEST_F(OEMCryptoKeyboxTest, NormalGetDeviceId) { uint8_t dev_id[128] = {0}; size_t dev_id_len = 128; sts = OEMCrypto_GetDeviceID(dev_id, &dev_id_len); - cout << " NormalGetDeviceId: dev_id = " << dev_id - << " len = " << dev_id_len << endl; + cout << " NormalGetDeviceId: dev_id = " + << MaybeHex(dev_id, dev_id_len) << " len = " << dev_id_len << endl; ASSERT_EQ(OEMCrypto_SUCCESS, sts); } @@ -1039,7 +1073,7 @@ TEST_F(OEMCryptoProv30Test, GetDeviceId) { } ASSERT_EQ(OEMCrypto_SUCCESS, sts); dev_id.resize(dev_id_len); - cout << " NormalGetDeviceId: dev_id = " << dev_id.data() + cout << " NormalGetDeviceId: dev_id = " << MaybeHex(dev_id) << " len = " << dev_id_len << endl; ASSERT_EQ(OEMCrypto_SUCCESS, sts); } @@ -2355,6 +2389,39 @@ TEST_P(OEMCryptoLicenseTest, !kCheckStatus); } +TEST_P(OEMCryptoLicenseTest, + DecryptCENCForNumBytesClearPlusEncryptedOverflowsSize) { + LoadLicense(); + OEMCrypto_SelectKey(session_.session_id(), session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, + OEMCrypto_CipherMode_CTR); + + size_t input_buffer_size = 1; + vector in_buffer(input_buffer_size); + vector out_buffer(in_buffer.size()); + + OEMCrypto_SampleDescription sample_description; + OEMCrypto_SubSampleDescription subsample_description; + GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, + &subsample_description); + + OEMCrypto_SubSampleDescription* sub_samples = + const_cast( + sample_description.subsamples); + // If Decrypt cenc API does not check for overflow on clear + encrypted + // addition operation. This will result in 1 which will match with input data + // length, which causes validation to pass. + sub_samples[0].num_bytes_clear = 2; + sub_samples[0].num_bytes_encrypted = 0xFFFFFFFFFFFFFFFF; + + // Create the pattern description (always 0,0 for CTR) + OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; + // Try to decrypt the data + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_DecryptCENC(session_.session_id(), &sample_description, 1, + &pattern)); +} + TEST_P(OEMCryptoLicenseTest, OEMCryptoMemoryDecryptCENCForHugeNumBytesEncryptedAndBuffers) { TestDecryptCENCForHugeBufferLengths( @@ -3850,50 +3917,17 @@ class OEMCryptoSessionTestsDecryptTests OEMCrypto_SUCCESS); } - void TestDecryptCENC() { - OEMCryptoResult sts; + void TestDecryptCENC() { ASSERT_EQ(DecryptCENC(), OEMCrypto_SUCCESS); } - // OEMCrypto only supports providing a decrypt hash for one sample. - if (samples_.size() > 1) verify_crc_ = false; - - // If supported, check the decrypt hashes. - if (verify_crc_) { - const TestSample& sample = samples_[0]; - - uint32_t hash = - wvcrc32(sample.truth_buffer.data(), sample.truth_buffer.size()); - ASSERT_EQ(OEMCrypto_SetDecryptHash( - session_.session_id(), 1, - reinterpret_cast(&hash), sizeof(hash)), - OEMCrypto_SUCCESS); - } - - // Build an array of just the sample descriptions. - std::vector sample_descriptions; - sample_descriptions.reserve(samples_.size()); - for (TestSample& sample : samples_) { - // This must be deferred until this point in case the test modifies the - // buffer before testing decrypt. - sample.description.buffers.input_data = sample.encrypted_buffer.data(); - // Append to the description array. - sample_descriptions.push_back(sample.description); - } - - // Perform decryption using the test data that was previously set up. - sts = DecryptFallbackChain::Decrypt( - session_.session_id(), sample_descriptions.data(), - sample_descriptions.size(), cipher_mode_, &pattern_); - ASSERT_EQ(sts, OEMCrypto_SUCCESS); - - // Validate the decrypted data. + void ValidateDecryptedData() { for (TestSample& sample : samples_) { if (sample.description.buffers.output_descriptor.type == OEMCrypto_BufferType_Clear) { const size_t total_size = sample.description.buffers.input_data_length; // To verify there is no buffer overrun after decrypting, look at the - // padded bytes just after the data buffer that was written. It should - // not have changed from the original 0xaa that we set in MakeBuffer - // function. + // padded bytes just after the data buffer that was written. It + // should not have changed from the original 0xaa that we set in + // MakeBuffer function. if (decrypt_inplace_) { EXPECT_EQ(std::count(sample.encrypted_buffer.begin() + total_size, sample.encrypted_buffer.end(), 0xaa), @@ -3919,6 +3953,41 @@ class OEMCryptoSessionTestsDecryptTests } } + OEMCryptoResult DecryptCENC() { + // OEMCrypto only supports providing a decrypt hash for one sample. + if (samples_.size() > 1) verify_crc_ = false; + + // If supported, check the decrypt hashes. + if (verify_crc_) { + const TestSample& sample = samples_[0]; + + uint32_t hash = + wvcrc32(sample.truth_buffer.data(), sample.truth_buffer.size()); + OEMCrypto_SetDecryptHash(session_.session_id(), 1, + reinterpret_cast(&hash), + sizeof(hash)); + } + + // Build an array of just the sample descriptions. + std::vector sample_descriptions; + sample_descriptions.reserve(samples_.size()); + for (TestSample& sample : samples_) { + // This must be deferred until this point in case the test modifies the + // buffer before testing decrypt. + sample.description.buffers.input_data = sample.encrypted_buffer.data(); + // Append to the description array. + sample_descriptions.push_back(sample.description); + } + + // Perform decryption using the test data that was previously set up. + OEMCryptoResult result = DecryptFallbackChain::Decrypt( + session_.session_id(), sample_descriptions.data(), + sample_descriptions.size(), cipher_mode_, &pattern_); + if (result != OEMCrypto_SUCCESS) return result; + ValidateDecryptedData(); + return result; + } + // Parameters of test case OEMCrypto_CENCEncryptPatternDesc pattern_; OEMCryptoCipherMode cipher_mode_; @@ -4094,7 +4163,6 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSampleAPI16) { // max_sample_size. const size_t subsample_size = std::min(max_sample_size / max_num_subsamples + 1, max_subsample_size); - size_t bytes_remaining = max_sample_size; std::vector subsample_sizes; while (bytes_remaining > 0 && subsample_sizes.size() < max_num_subsamples) { @@ -4113,6 +4181,103 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSampleAPI16) { ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } +TEST_P(OEMCryptoSessionTestsDecryptTests, + OEMCryptoMemoryDecryptCENCForHugeNumberOfSubSamples) { + auto oemcrypto_function = [&](size_t number_of_subsamples) { + std::vector subsample_sizes; + while (number_of_subsamples-- > 0) { + subsample_sizes.push_back({1, 1}); + } + SetSubsampleSizes(subsample_sizes); + LoadLicense(); + MakeBuffers(); + EncryptData(); + OEMCryptoResult result = DecryptCENC(); + // Closing the session and opening it for next iteration. + // If it is last iteration, session will be closed in teardown method of + // class. + session_.close(); + session_.open(); + InstallTestRSAKey(&session_); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 1, 2 * MiB, kCheckStatus); +} + +TEST_P(OEMCryptoSessionTestsDecryptTests, + OEMCryptoMemoryCheckDecryptCENCStatusForHugeNumberOfSubSamples) { + size_t number_of_subsamples = 10000; + std::vector subsample_sizes; + while (number_of_subsamples-- > 0) { + subsample_sizes.push_back({100, 100}); + } + SetSubsampleSizes(subsample_sizes); + LoadLicense(); + MakeBuffers(); + EncryptData(); + // Build an array of just the sample descriptions. + std::vector sample_descriptions; + sample_descriptions.reserve(samples_.size()); + for (TestSample& sample : samples_) { + // This must be deferred until this point in case the test modifies the + // buffer before testing decrypt. + sample.description.buffers.input_data = sample.encrypted_buffer.data(); + // Append to the description array. + sample_descriptions.push_back(sample.description); + } + OEMCryptoResult result = OEMCrypto_DecryptCENC( + session_.session_id(), sample_descriptions.data(), 1, &pattern_); + LOGD("Large number of subsamples test has return code %d", result); +} + +TEST_P(OEMCryptoSessionTestsDecryptTests, + OEMCryptoMemoryCheckDecryptCENCStatusForHugeSubSample) { + std::vector subsample_sizes; + subsample_sizes.push_back({100000, 100000}); + SetSubsampleSizes(subsample_sizes); + LoadLicense(); + MakeBuffers(); + EncryptData(); + // Build an array of just the sample descriptions. + std::vector sample_descriptions; + sample_descriptions.reserve(samples_.size()); + for (TestSample& sample : samples_) { + // This must be deferred until this point in case the test modifies the + // buffer before testing decrypt. + sample.description.buffers.input_data = sample.encrypted_buffer.data(); + // Append to the description array. + sample_descriptions.push_back(sample.description); + } + OEMCryptoResult result = OEMCrypto_DecryptCENC( + session_.session_id(), sample_descriptions.data(), 1, &pattern_); + LOGD("Large subsample test has return code %d", result); +} + +TEST_P(OEMCryptoSessionTestsDecryptTests, + OEMCryptoMemoryDecryptCENCForHugeNumberOfSamples) { + auto oemcrypto_function = [&](size_t number_of_samples) { + std::vector> samples; + std::vector subsample_sizes; + subsample_sizes.push_back({1, 1}); + while (number_of_samples-- > 0) { + samples.push_back(subsample_sizes); + } + SetSampleSizes(samples); + LoadLicense(); + MakeBuffers(); + EncryptData(); + OEMCryptoResult result = DecryptCENC(); + // Closing the session and opening it for next iteration. + // If it is last iteration, session will be closed in teardown method of + // class. + session_.close(); + session_.open(); + InstallTestRSAKey(&session_); + return result; + }; + TestHugeLengthDoesNotCrashAPI(oemcrypto_function, 1, 2 * MiB, kCheckStatus); +} + // Based on the resource rating, OEMCrypto should be able to handle the maximum // subsample size. TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSubsample) { diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test_android.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test_android.cpp index 1d05553a..647017bc 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test_android.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test_android.cpp @@ -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 unit tests - extra tests required for Android platform. diff --git a/libwvdrmengine/oemcrypto/test/wvcrc.cpp b/libwvdrmengine/oemcrypto/test/wvcrc.cpp index 3336c77c..1f0fbcf1 100644 --- a/libwvdrmengine/oemcrypto/test/wvcrc.cpp +++ b/libwvdrmengine/oemcrypto/test/wvcrc.cpp @@ -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. diff --git a/libwvdrmengine/oemcrypto/test/wvcrc32.h b/libwvdrmengine/oemcrypto/test/wvcrc32.h index 24362119..9cf72af1 100644 --- a/libwvdrmengine/oemcrypto/test/wvcrc32.h +++ b/libwvdrmengine/oemcrypto/test/wvcrc32.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. // // Compute CRC32 Checksum. Needed for verification of WV Keybox.