Merge recent doc changes for OEMCrypto

This is a cherry pick of recent changes to OEMCrypto and ODK. Most of
these are part of the document migration to doxygen.

See http://go/wvgerrit/106005 and its parents for code reviews.

Bug: 144715340
Bug: 148232693
Bug: 167580674
Change-Id: I658f99c8117b974faed97322d61fac0f382283af
This commit is contained in:
Fred Gylys-Colwell
2020-09-11 13:30:58 -07:00
parent 28b13ef65e
commit 20bb84ffee
75 changed files with 5717 additions and 4488 deletions

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
/*********************************************************************
* OEMCryptoCENCCommon.h
@@ -20,7 +20,11 @@
extern "C" {
#endif
/// @addtogroup common_types
/// @{
/* clang-format off */
/** Error and result codes returned by OEMCrypto functions. */
typedef enum OEMCryptoResult {
OEMCrypto_SUCCESS = 0,
OEMCrypto_ERROR_INIT_FAILED = 1,
@@ -94,8 +98,7 @@ typedef enum OEMCryptoResult {
} OEMCryptoResult;
/* clang-format on */
/*
* OEMCrypto_Usage_Entry_Status.
/**
* Valid values for status in the usage table.
*/
typedef enum OEMCrypto_Usage_Entry_Status {
@@ -106,13 +109,14 @@ typedef enum OEMCrypto_Usage_Entry_Status {
kInactiveUnused = 4,
} OEMCrypto_Usage_Entry_Status;
/*
/**
* OEMCrypto_LicenseType is used in the license message to indicate if the key
* objects are for content keys, or for entitlement keys.
*/
typedef enum OEMCrypto_LicenseType {
OEMCrypto_ContentLicense = 0,
OEMCrypto_EntitlementLicense = 1
OEMCrypto_EntitlementLicense = 1,
OEMCrypto_LicenstType_MaxValue = OEMCrypto_EntitlementLicense,
} OEMCrypto_LicenseType;
/* Private key type used in the provisioning response. */
@@ -121,9 +125,7 @@ typedef enum OEMCrypto_PrivateKeyType {
OEMCrypto_ECC_Private_Key = 1,
} OEMCrypto_PrivateKeyType;
/*
* OEMCrypto_Substring
*
/**
* Used to indicate a substring of a signed message in OEMCrypto_LoadKeys and
* other functions which must verify that a parameter is contained within a
* signed message.
@@ -133,23 +135,22 @@ typedef struct {
size_t length;
} OEMCrypto_Substring;
/*
* OEMCrypto_KeyObject
/**
* Points to the relevant fields for a content key. The fields are extracted
* from the License Response message offered to OEMCrypto_LoadKeys(). Each
* field points to one of the components of the key. Key data, key control,
* and both IV fields are 128 bits (16 bytes):
* key_id - the unique id of this key.
* key_id_length - the size of key_id. OEMCrypto may assume this is at
* @param key_id: the unique id of this key.
* @param key_id_length: the size of key_id. OEMCrypto may assume this is at
* most 16. However, OEMCrypto shall correctly handle key id lengths
* from 1 to 16 bytes.
* key_data_iv - the IV for performing AES-128-CBC decryption of the
* @param key_data_iv: the IV for performing AES-128-CBC decryption of the
* key_data field.
* key_data - the key data. It is encrypted (AES-128-CBC) with the
* @param key_data - the key data. It is encrypted (AES-128-CBC) with the
* session's derived encrypt key and the key_data_iv.
* key_control_iv - the IV for performing AES-128-CBC decryption of the
* @param key_control_iv: the IV for performing AES-128-CBC decryption of the
* key_control field.
* key_control - the key control block. It is encrypted (AES-128-CBC) with
* @param key_control: the key control block. It is encrypted (AES-128-CBC) with
* the content key from the key_data field.
*
* The memory for the OEMCrypto_KeyObject fields is allocated and freed
@@ -163,8 +164,10 @@ typedef struct {
OEMCrypto_Substring key_control;
} OEMCrypto_KeyObject;
/// @}
#ifdef __cplusplus
}
#endif
#endif /* WIDEVINE_ODK_INCLUDE_OEMCRYPTOCENCCOMMON_H_ */
#endif // WIDEVINE_ODK_INCLUDE_OEMCRYPTOCENCCOMMON_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
/*********************************************************************
* core_message_deserialize.h
@@ -53,7 +53,17 @@ bool CoreProvisioningRequestFromMessage(
const std::string& oemcrypto_core_message,
ODK_ProvisioningRequest* core_provisioning_request);
} /* namespace deserialize */
} /* namespace oemcrypto_core_message */
/**
* Serializer counterpart is not used and is therefore not implemented.
*
* Parameters:
* [in] oemcrypto_core_message
* [out] core_common_request
*/
bool CoreCommonRequestFromMessage(const std::string& oemcrypto_core_message,
ODK_CommonRequest* core_common_request);
#endif /* WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_DESERIALIZE_H_ */
} // namespace deserialize
} // namespace oemcrypto_core_message
#endif // WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_DESERIALIZE_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
/*********************************************************************
* core_message_serialize.h
@@ -62,7 +62,7 @@ bool CreateCoreRenewalResponse(const ODK_RenewalRequest& core_request,
bool CreateCoreProvisioningResponse(const ODK_ParsedProvisioning& parsed_prov,
const ODK_ProvisioningRequest& core_request,
std::string* oemcrypto_core_message);
} /* namespace serialize */
} /* namespace oemcrypto_core_message */
} // namespace serialize
} // namespace oemcrypto_core_message
#endif /* WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_H_ */
#endif // WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
/*********************************************************************
* core_message_serialize_proto.h
@@ -23,7 +23,7 @@
namespace oemcrypto_core_message {
namespace serialize {
/* @ public create response (serializer) functions accepting proto input */
// @ public create response (serializer) functions accepting proto input
/**
* Counterpart (serializer) of ODK_ParseLicense (deserializer)
@@ -56,7 +56,7 @@ bool CreateCoreProvisioningResponseFromProto(
const ODK_ProvisioningRequest& core_request,
std::string* oemcrypto_core_message);
} /* namespace serialize */
} /* namespace oemcrypto_core_message */
} // namespace serialize
} // namespace oemcrypto_core_message
#endif /* WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_PROTO_H_ */
#endif // WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_PROTO_H_

View File

@@ -1,8 +1,8 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
/* clang-format off */
// clang-format off
/*********************************************************************
* core_message_types.h
*
@@ -38,6 +38,8 @@
* | | ODK_PrepareCoreRenewalRequest | | CoreRenewalRequestFromMessage |
* | +------------------------------------+ +-----------------------------------+
* | | ODK_PrepareCoreProvisioningRequest | | CoreProvisioningRequestFromMessage|
* | +------------------------------------+ +-----------------------------------+
* | | ODK_PrepareCommonRequest | | CoreCommonRequestFromMessage |
* +---+------------------------------------+---+-----------------------------------+
* | d | ODK_ParseLicense | s | CreateCoreLicenseResponse |
* | +------------------------------------+ +-----------------------------------+
@@ -47,7 +49,7 @@
* +---+------------------------------------+---+-----------------------------------+
*
*********************************************************************/
/* clang-format on */
// clang-format on
#ifndef WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_TYPES_H_
#define WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_TYPES_H_
@@ -57,7 +59,18 @@
namespace oemcrypto_core_message {
/* @ input/output structs */
// @ input/output structs
/**
* Output structure for CommonRequestFromMessage
* Input structure for CreateCommonResponse
*/
struct ODK_CommonRequest {
uint16_t api_minor_version;
uint16_t api_major_version;
uint32_t nonce;
uint32_t session_id;
};
/**
* Output structure for CoreLicenseRequestFromMessage
@@ -94,6 +107,6 @@ struct ODK_ProvisioningRequest {
std::string device_id;
};
} /* namespace oemcrypto_core_message */
} // namespace oemcrypto_core_message
#endif /* WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_TYPES_H_ */
#endif // WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_TYPES_H_

View File

@@ -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 */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
/*********************************************************************
* odk.h
*
* OEMCrypto v16 Core Message Serialization library
/**
* @mainpage OEMCrypto v16 Core Message Serialization library
*
* For Widevine Modular DRM, there are six message types between a server and
* a client device: license request and response, provisioning request and
@@ -34,12 +32,30 @@
* ODK library shall be sanitized by the OEMCrypto implementer to prevent
* modification by any process running the REE.
*
* See the documents "Widevine Core Message Serialization" and "License
* Duration and Renewal" for a detailed description of the ODK API. You can
* See the documents
* <a href="../odk">Widevine Core Message Serialization</a>
* and
* <a href="../../lic_duration_and_renewal">License Duration and Renewal</a>
* for a detailed description of the ODK API. You can
* find these documents in the widevine repository as
* docs/Widevine_Core_Message_Serialization.pdf and
* docs/License_Duration_and_Renewal.pdf
*
* @defgroup odk_parser Core Message Parsing and Verification
* Functions that parse core messages and verify they are valid.
* TODO(fredgc): add documentation for parsing functions.
*
* @defgroup odk_packer Core Message Creation
* Functions that create core messages.
* TODO(fredgc): add documentation for packing functions.
*
* @defgroup odk_timer Timer and Clock Functions
* Functions related to enforcing timer and duration restrictions.
* TODO(fredgc): add documentation for timers and clocks.
*
* @defgroup common_types Common Types
* Enumerations and structures that are used by several OEMCrypto and ODK
* functions.
*********************************************************************/
#ifndef WIDEVINE_ODK_INCLUDE_ODK_H_
@@ -54,26 +70,24 @@
extern "C" {
#endif
/*
* ODK_InitializeSessionValues
/// @addtogroup odk_timer
/// @{
/**
* This function initializes the session's data structures. It shall be
* called from OEMCrypto_OpenSession.
*
* Description:
* This function initializes the session's data structures. It shall be
* called from OEMCrypto_OpenSession.
* @param[out] timer_limits: the session's timer limits.
* @param[out] clock_values: the session's clock values.
* @param[out] nonce_values: the session's ODK nonce values.
* @param[in] api_major_version: the API version of OEMCrypto.
* @param[in] session_id: the session id of the newly created session.
*
* Parameters:
* [out] timer_limits: the session's timer limits.
* [out] clock_values: the session's clock values.
* [out] nonce_values: the session's ODK nonce values.
* [in] api_major_version: the API version of OEMCrypto.
* [in] session_id: the session id of the newly created session.
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_INVALID_CONTEXT
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits,
ODK_ClockValues* clock_values,
@@ -81,73 +95,61 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits,
uint32_t api_major_version,
uint32_t session_id);
/*
* ODK_SetNonceValues
/**
* This function sets the nonce value in the session's nonce structure. It
* shall be called from OEMCrypto_GenerateNonce.
*
* Description:
* This function sets the nonce value in the session's nonce structure. It
* shall be called from OEMCrypto_GenerateNonce.
* @param[in,out] nonce_values: the session's nonce data.
* @param[in] nonce: the new nonce that was just generated.
*
* Parameters:
* [in/out] nonce_values: the session's nonce data.
* [in] nonce: the new nonce that was just generated.
* @retval true on success
*
* Returns:
* true on success
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_SetNonceValues(ODK_NonceValues* nonce_values,
uint32_t nonce);
/*
* ODK_InitializeClockValues
*
* Description:
* This function initializes the clock values in the session clock_values
* structure. It shall be called from OEMCrypto_PrepAndSignLicenseRequest.
/**
* This function initializes the clock values in the session clock_values
* structure. It shall be called from OEMCrypto_PrepAndSignLicenseRequest.
*
* Parameters:
* [in/out] clock_values: the session's clock data.
* [in] system_time_seconds: the current time on OEMCrypto's monotonic clock.
* @param[in,out] clock_values: the session's clock data.
* @param[in] system_time_seconds: the current time on OEMCrypto's monotonic
* clock.
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_InitializeClockValues(ODK_ClockValues* clock_values,
uint64_t system_time_seconds);
/*
* ODK_ReloadClockValues
/**
* This function sets the values in the clock_values structure. It shall be
* called from OEMCrypto_LoadUsageEntry. When a usage entry from a v15 or
* earlier license is loaded, the value time_of_license_loaded shall be used
* in place of time_of_license_signed.
*
* Description:
* This function sets the values in the clock_values structure. It shall be
* called from OEMCrypto_LoadUsageEntry. When a usage entry from a v15 or
* earlier license is loaded, the value time_of_license_loaded shall be used
* in place of time_of_license_signed.
* @param[in,out] clock_values: the session's clock data.
* @param[in] time_of_license_signed: the value time_license_received from the
* loaded usage entry.
* @param[in] time_of_first_decrypt: the value time_of_first_decrypt from the
* loaded usage entry.
* @param[in] time_of_last_decrypt: the value time_of_last_decrypt from the
* loaded usage entry.
* @param[in] status: the value status from the loaded usage entry.
* @param[in] system_time_seconds: the current time on OEMCrypto's monotonic
* clock.
*
* Parameters:
* [in/out] clock_values: the session's clock data.
* [in] time_of_license_signed: the value time_license_received from the
* loaded usage entry.
* [in] time_of_first_decrypt: the value time_of_first_decrypt from the
* loaded usage entry.
* [in] time_of_last_decrypt: the value time_of_last_decrypt from the loaded
* usage entry.
* [in] status: the value status from the loaded usage entry.
* [in] system_time_seconds: the current time on OEMCrypto's monotonic clock.
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_INVALID_CONTEXT
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_ReloadClockValues(ODK_ClockValues* clock_values,
uint64_t time_of_license_signed,
@@ -156,173 +158,154 @@ OEMCryptoResult ODK_ReloadClockValues(ODK_ClockValues* clock_values,
enum OEMCrypto_Usage_Entry_Status status,
uint64_t system_time_seconds);
/*
* ODK_AttemptFirstPlayback
/**
* This updates the clock values, and determines if playback may start based
* on the given system time. It uses the values in clock_values to determine
* if this is the first playback for the license or the first playback for
* just this session.
*
* Description:
* This updates the clock values, and determines if playback may start based
* on the given system time. It uses the values in clock_values to determine
* if this is the first playback for the license or the first playback for
* just this session.
* This shall be called from the first call in a session to any of
* OEMCrypto_DecryptCENC or any of the OEMCrypto_Generic* functions.
*
* This shall be called from the first call in a session to any of
* OEMCrypto_DecryptCENC or any of the OEMCrypto_Generic* functions.
* If OEMCrypto uses a hardware timer, and this function returns
* ODK_SET_TIMER, then the timer should be set to the value pointed to by
* timer_value.
*
* If OEMCrypto uses a hardware timer, and this function returns
* ODK_SET_TIMER, then the timer should be set to the value pointed to by
* timer_value.
* @param[in] system_time_seconds: the current time on OEMCrypto's monotonic
* clock, in seconds.
* @param[in] timer_limits: timer limits specified in the license.
* @param[in,out] clock_values: the sessions clock values.
* @param[out] timer_value: set to the new timer value. Only used if the return
* value is ODK_SET_TIMER. This must be non-null if OEMCrypto uses a
* hardware timer.
*
* Parameters:
* [in] system_time_seconds: the current time on OEMCrypto's monotonic clock,
* in seconds.
* [in] timer_limits: timer limits specified in the license.
* [in/out] clock_values: the sessions clock values.
* [out] timer_value: set to the new timer value. Only used if the return
* value is ODK_SET_TIMER. This must be non-null if OEMCrypto uses a
* hardware timer.
*
* Returns:
* ODK_SET_TIMER: Success. The timer should be reset to the specified value
* and playback is allowed.
* ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
* @retval ODK_SET_TIMER: Success. The timer should be reset to the specified
* value and playback is allowed.
* @retval ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
* allowed.
* ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
* @retval ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_AttemptFirstPlayback(uint64_t system_time_seconds,
const ODK_TimerLimits* timer_limits,
ODK_ClockValues* clock_values,
uint64_t* timer_value);
/*
* ODK_UpdateLastPlaybackTime
/**
* Vendors that do not implement their own timer should call
* ODK_UpdateLastPlaybackTime regularly during playback. This updates the
* clock values, and determines if playback may continue based on the given
* system time. This shall be called from any of OEMCrypto_DecryptCENC or any
* of the OEMCrypto_Generic* functions.
*
* Description:
* Vendors that do not implement their own timer should call
* ODK_UpdateLastPlaybackTime regularly during playback. This updates the
* clock values, and determines if playback may continue based on the given
* system time. This shall be called from any of OEMCrypto_DecryptCENC or any
* of the OEMCrypto_Generic* functions.
* All Vendors (i.e. those that do or do not implement their own timer) shall
* call ODK_UpdateLastPlaybackTime from the function
* OEMCrypto_UpdateUsageEntry before updating the usage entry so that the
* clock values are accurate.
*
* All Vendors (i.e. those that do or do not implement their own timer) shall
* call ODK_UpdateLastPlaybackTime from the function
* OEMCrypto_UpdateUsageEntry before updating the usage entry so that the
* clock values are accurate.
* @param[in] system_time_seconds: the current time on OEMCrypto's monotonic
* clock, in seconds.
* @param[in] timer_limits: timer limits specified in the license.
* @param[in,out] clock_values: the sessions clock values.
*
* Parameters:
* [in] system_time_seconds: the current time on OEMCrypto's monotonic clock,
* in seconds.
* [in] timer_limits: timer limits specified in the license.
* [in/out] clock_values: the sessions clock values.
* @retval OEMCrypto_SUCCESS: Success. Playback is allowed.
* @retval ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
*
* Returns:
* OEMCrypto_SUCCESS: Success. Playback is allowed.
* ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_UpdateLastPlaybackTime(uint64_t system_time_seconds,
const ODK_TimerLimits* timer_limits,
ODK_ClockValues* clock_values);
/*
* ODK_DeactivateUsageEntry
*
* Description:
* This function modifies the session's clock values to indicate that the
* license has been deactivated. It shall be called from
* OEMCrypto_DeactivateUsageEntry
/**
* This function modifies the session's clock values to indicate that the
* license has been deactivated. It shall be called from
* OEMCrypto_DeactivateUsageEntry
*
* Parameters:
* [in/out] clock_values: the sessions clock values.
* @param[in,out] clock_values: the sessions clock values.
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_DeactivateUsageEntry(ODK_ClockValues* clock_values);
/*
* ODK_PrepareCoreLicenseRequest
/// @}
/// @addtogroup odk_packer
/// @{
/**
* Modifies the message to include a core license request at the beginning of
* the message buffer. The values in nonce_values are used to populate the
* message.
*
* Description:
* Modifies the message to include a core license request at the beginning of
* the message buffer. The values in nonce_values are used to populate the
* message.
* This shall be called by OEMCrypto from OEMCrypto_PrepAndSignLicenseRequest.
*
* This shall be called by OEMCrypto from OEMCrypto_PrepAndSignLicenseRequest.
* NOTE: if the message pointer is null and/or input core_message_size is
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* core_message_size to the size needed.
*
* NOTE: if the message pointer is null and/or input core_message_size is
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* core_message_size to the size needed.
* @param[in,out] message: Pointer to memory for the entire message. Modified by
* the ODK library.
* @param[in] message_length: length of the entire message buffer.
* @param[in,out] core_message_size: length of the core message at the beginning
* of the message. (in) size of buffer reserved for the core message, in
* bytes. (out) actual length of the core message, in bytes.
* @param[in] nonce_values: pointer to the session's nonce data.
*
* Parameters:
* [in/out] message: Pointer to memory for the entire message. Modified by
* the ODK library.
* [in] message_length: length of the entire message buffer.
* [in/out] core_message_size: length of the core message at the beginning of
* the message. (in) size of buffer reserved for the core message, in
* bytes. (out) actual length of the core message, in bytes.
* [in] nonce_values: pointer to the session's nonce data.
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
* OEMCrypto_ERROR_INVALID_CONTEXT
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_PrepareCoreLicenseRequest(
uint8_t* message, size_t message_length, size_t* core_message_size,
const ODK_NonceValues* nonce_values);
/*
* ODK_PrepareCoreRenewalRequest
/**
* Modifies the message to include a core renewal request at the beginning of
* the message buffer. The values in nonce_values, clock_values and
* system_time_seconds are used to populate the message. The nonce_values
* should match those from the license.
*
* Description:
* Modifies the message to include a core renewal request at the beginning of
* the message buffer. The values in nonce_values, clock_values and
* system_time_seconds are used to populate the message. The nonce_values
* should match those from the license.
* This shall be called by OEMCrypto from OEMCrypto_PrepAndSignRenewalRequest.
*
* This shall be called by OEMCrypto from OEMCrypto_PrepAndSignRenewalRequest.
* If status in clock_values indicates that a license has not been loaded,
* then this is a license release. The ODK library will change the value of
* nonce_values.api_major_version to 15. This will make
* OEMCrypto_PrepAndSignRenewalRequest sign just the message body, as it does
* for all legacy licenses.
*
* If status in clock_values indicates that a license has not been loaded,
* then this is a license release. The ODK library will change the value of
* nonce_values.api_major_version to 15. This will make
* OEMCrypto_PrepAndSignRenewalRequest sign just the message body, as it does
* for all legacy licenses.
* NOTE: if the message pointer is null and/or input core_message_size is
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* core_message_size to the size needed.
*
* NOTE: if the message pointer is null and/or input core_message_size is
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* core_message_size to the size needed.
* @param[in,out] message: Pointer to memory for the entire message. Modified by
* the ODK library.
* @param[in] message_length: length of the entire message buffer.
* @param[in,out] core_message_size: length of the core message at the beginning
* of the message. (in) size of buffer reserved for the core message, in
* bytes. (out) actual length of the core message, in bytes.
* @param[in,out] nonce_values: pointer to the session's nonce data.
* @param[in,out] clock_values: the session's clock values.
* @param[in] system_time_seconds: the current time on OEMCrypto's clock, in
* seconds.
*
* Parameters:
* [in/out] message: Pointer to memory for the entire message. Modified by
* the ODK library.
* [in] message_length: length of the entire message buffer.
* [in/out] core_message_size: length of the core message at the beginning of
* the message. (in) size of buffer reserved for the core message, in
* bytes. (out) actual length of the core message, in bytes.
* [in/out] nonce_values: pointer to the session's nonce data.
* [in/out] clock_values: the session's clock values.
* [in] system_time_seconds: the current time on OEMCrypto's clock, in
* seconds.
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
* OEMCrypto_ERROR_INVALID_CONTEXT
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
size_t message_length,
@@ -331,77 +314,72 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
ODK_ClockValues* clock_values,
uint64_t system_time_seconds);
/*
* ODK_PrepareCoreProvisioningRequest
/**
* Modifies the message to include a core provisioning request at the
* beginning of the message buffer. The values in nonce_values are used to
* populate the message.
*
* Description:
* Modifies the message to include a core provisioning request at the
* beginning of the message buffer. The values in nonce_values are used to
* populate the message.
* This shall be called by OEMCrypto from
* OEMCrypto_PrepAndSignProvisioningRequest.
*
* This shall be called by OEMCrypto from
* OEMCrypto_PrepAndSignProvisioningRequest.
* The buffer device_id shall be the same string returned by
* OEMCrypto_GetDeviceID. The device ID shall be unique to the device, and
* stable across reboots and factory resets for an L1 device.
*
* The buffer device_id shall be the same string returned by
* OEMCrypto_GetDeviceID. The device ID shall be unique to the device, and
* stable across reboots and factory resets for an L1 device.
* NOTE: if the message pointer is null and/or input core_message_size is
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* core_message_size to the size needed.
*
* NOTE: if the message pointer is null and/or input core_message_size is
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* core_message_size to the size needed.
* @param[in,out] message: Pointer to memory for the entire message. Modified by
* the ODK library.
* @param[in] message_length: length of the entire message buffer.
* @param[in,out] core_message_size: length of the core message at the beginning
* of the message. (in) size of buffer reserved for the core message, in
* bytes. (out) actual length of the core message, in bytes.
* @param[in] nonce_values: pointer to the session's nonce data.
* @param[in] device_id: For devices with a keybox, this is the device ID from
* the keybox. For devices with an OEM Certificate, this is a device
* unique id string.
* @param[in] device_id_length: length of device_id. The device ID can be at
* most 64 bytes.
*
* Parameters:
* [in/out] message: Pointer to memory for the entire message. Modified by
* the ODK library.
* [in] message_length: length of the entire message buffer.
* [in/out] core_message_size: length of the core message at the beginning of
* the message. (in) size of buffer reserved for the core message, in
* bytes. (out) actual length of the core message, in bytes.
* [in] nonce_values: pointer to the session's nonce data.
* [in] device_id: For devices with a keybox, this is the device ID from the
* keybox. For devices with an OEM Certificate, this is a device unique
* id string.
* [in] device_id_length: length of device_id. The device ID can be at most
* 64 bytes.
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
* OEMCrypto_ERROR_INVALID_CONTEXT
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
uint8_t* message, size_t message_length, size_t* core_message_size,
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
size_t device_id_length);
/*
* ODK_InitializeV15Values
/// @}
/// @addtogroup odk_timer
/// @{
/**
* This function sets all limits in the timer_limits struct to the
* key_duration and initializes the other values. The field
* nonce_values.api_major_version will be set to 15. It shall be called from
* OEMCrypto_LoadKeys when loading a legacy license.
*
* Description:
* This function sets all limits in the timer_limits struct to the
* key_duration and initializes the other values. The field
* nonce_values.api_major_version will be set to 15. It shall be called from
* OEMCrypto_LoadKeys when loading a legacy license.
* @param[out] timer_limits: The session's timer limits.
* @param[in,out] clock_values: The session's clock values.
* @param[in,out] nonce_values: The session's ODK nonce values.
* @param[in] key_duration: The duration from the first key's key control
* block. In practice, the key duration is the same for all keys and is
* the same as the license duration.
* @param[in] system_time_seconds: The current time on the system clock, as
* described in the document "License Duration and Renewal".
*
* Parameters:
* [out] timer_limits: The session's timer limits.
* [in/out] clock_values: The session's clock values.
* [in/out] nonce_values: The session's ODK nonce values.
* [in] key_duration: The duration from the first key's key control block. In
* practice, the key duration is the same for all keys and is the same
* as the license duration.
* [in] system_time_seconds: The current time on the system clock, as
* described in the document "License Duration and Renewal".
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_INVALID_CONTEXT
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_InitializeV15Values(ODK_TimerLimits* timer_limits,
ODK_ClockValues* clock_values,
@@ -409,40 +387,35 @@ OEMCryptoResult ODK_InitializeV15Values(ODK_TimerLimits* timer_limits,
uint32_t key_duration,
uint64_t system_time_seconds);
/*
* ODK_RefreshV15Values
/**
* This function updates the clock_values as needed if a v15 renewal is
* accepted. The field nonce_values.api_major_version is verified to be 15.
*
* Description:
* This function updates the clock_values as needed if a v15 renewal is
* accepted. The field nonce_values.api_major_version is verified to be 15.
* This is called from OEMCrypto_RefreshKeys for a valid license renewal.
* OEMCrypto shall pass in the current system time, and the key duration from
* the first object in the OEMCrypto_KeyRefreshObject.
*
* This is called from OEMCrypto_RefreshKeys for a valid license renewal.
* OEMCrypto shall pass in the current system time, and the key duration from
* the first object in the OEMCrypto_KeyRefreshObject.
* @param[in] timer_limits: The session's timer limits.
* @param[in,out] clock_values: The session's clock values.
* @param[in] nonce_values: The session's ODK nonce values.
* @param[in] system_time_seconds: The current time on the system clock, as
* described in the document "License Duration and Renewal".
* @param[in] new_key_duration: The duration from the first
* OEMCrypto_KeyRefreshObject in key_array.
* @param[out] timer_value: set to the new timer value. Only used if the return
* value is ODK_SET_TIMER. This must be non-null if OEMCrypto uses a
* hardware timer.
*
* Parameters:
* [in] timer_limits: The session's timer limits.
* [in/out] clock_values: The session's clock values.
* [in] nonce_values: The session's ODK nonce values.
* [in] system_time_seconds: The current time on the system clock, as
* described in the document "License Duration and Renewal".
* [in] new_key_duration: The duration from the first
* OEMCrypto_KeyRefreshObject in key_array.
* [out] timer_value: set to the new timer value. Only used if the return
* value is ODK_SET_TIMER. This must be non-null if OEMCrypto uses a
* hardware timer.
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_UNKNOWN_FAILURE
* ODK_SET_TIMER: Success. The timer should be reset to the specified value
* and playback is allowed.
* ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval ODK_SET_TIMER: Success. The timer should be reset to the specified
* value and playback is allowed.
* @retval ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
* allowed.
* ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
* @retval ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_RefreshV15Values(const ODK_TimerLimits* timer_limits,
ODK_ClockValues* clock_values,
@@ -451,67 +424,70 @@ OEMCryptoResult ODK_RefreshV15Values(const ODK_TimerLimits* timer_limits,
uint32_t new_key_duration,
uint64_t* timer_value);
/*
* ODK_ParseLicense
/// @}
/// @addtogroup odk_parser
/// @{
/**
* The function ODK_ParseLicense will parse the message and verify fields in
* the message.
*
* Description:
* The function ODK_ParseLicense will parse the message and verify fields in
* the message.
* If the message does not parse correctly, ODK_VerifyAndParseLicense will
* return ODK_ERROR_CORE_MESSAGE that OEMCrypto should return to the CDM
* layer above.
*
* If the message does not parse correctly, ODK_VerifyAndParseLicense will
* return ODK_ERROR_CORE_MESSAGE that OEMCrypto should return to the CDM
* layer above.
* If the API in the message is not 16, then ODK_UNSUPPORTED_API is returned.
*
* If the API in the message is not 16, then ODK_UNSUPPORTED_API is returned.
* If initial_license_load is true, and nonce_required in the license is
* true, then the ODK library shall verify that nonce_values->nonce and
* nonce_values->session_id are the same as those in the message. If
* verification fails, then it shall return OEMCrypto_ERROR_INVALID_NONCE.
*
* If initial_license_load is true, and nonce_required in the license is
* true, then the ODK library shall verify that nonce_values->nonce and
* nonce_values->session_id are the same as those in the message. If
* verification fails, then it shall return OEMCrypto_ERROR_INVALID_NONCE.
* If initial_license_load is false, and nonce_required is true, then
* ODK_ParseLicense will set the values in nonce_values from those in the
* message.
*
* If initial_license_load is false, and nonce_required is true, then
* ODK_ParseLicense will set the values in nonce_values from those in the
* message.
* The function ODK_ParseLicense will verify that each substring points to a
* location in the message body. The message body is the buffer starting at
* message + core_message_length with size message_length -
* core_message_length.
*
* The function ODK_ParseLicense will verify that each substring points to a
* location in the message body. The message body is the buffer starting at
* message + core_message_length with size message_length -
* core_message_length.
* If initial_license_load is true, then ODK_ParseLicense shall verify that
* the parameter request_hash matches request_hash in the parsed license. If
* verification fails, then it shall return ODK_ERROR_CORE_MESSAGE. This was
* computed by OEMCrypto when the license was requested.
*
* If initial_license_load is true, then ODK_ParseLicense shall verify that
* the parameter request_hash matches request_hash in the parsed license. If
* verification fails, then it shall return ODK_ERROR_CORE_MESSAGE. This was
* computed by OEMCrypto when the license was requested.
* If usage_entry_present is true, then ODK_ParseLicense shall verify that
* the pst in the license has a nonzero length.
*
* If usage_entry_present is true, then ODK_ParseLicense shall verify that
* the pst in the license has a nonzero length.
* @param[in] message: pointer to the message buffer.
* @param[in] message_length: length of the entire message buffer.
* @param[in] core_message_size: length of the core message, at the beginning of
* the message buffer.
* @param[in] initial_license_load: true when called for OEMCrypto_LoadLicense
* and false when called for OEMCrypto_ReloadLicense.
* @param[in] usage_entry_present: true if the session has a new usage entry
* associated with it created via OEMCrypto_CreateNewUsageEntry.
* @param[in] request_hash: the hash of the license request core message. This
* was computed by OEMCrypto when the license request was signed.
* @param[in,out] timer_limits: The session's timer limits. These will be
* updated.
* @param[in,out] clock_values: The session's clock values. These will be
* updated.
* @param[in,out] nonce_values: The session's nonce values. These will be
* updated.
* @param[out] parsed_license: the destination for the data.
*
* Parameters:
* [in] message: pointer to the message buffer.
* [in] message_length: length of the entire message buffer.
* [in] core_message_size: length of the core message, at the beginning of
* the message buffer.
* [in] initial_license_load: true when called for OEMCrypto_LoadLicense and
* false when called for OEMCrypto_ReloadLicense.
* [in] usage_entry_present: true if the session has a new usage entry
* associated with it created via OEMCrypto_CreateNewUsageEntry.
* [in] request_hash: the hash of the license request core message. This was
* computed by OEMCrypto when the license request was signed.
* [in/out] timer_limits: The session's timer limits. These will be updated.
* [in/out] clock_values: The session's clock values. These will be updated.
* [in/out] nonce_values: The session's nonce values. These will be updated.
* [out] parsed_license: the destination for the data.
* @retval OEMCrypto_SUCCESS
* @retval ODK_ERROR_CORE_MESSAGE: if the message did not parse correctly, or
* there were other incorrect values. An error should be returned to the
* CDM layer.
* @retval ODK_UNSUPPORTED_API
* @retval OEMCrypto_ERROR_INVALID_NONCE
*
* Returns:
* OEMCrypto_SUCCESS
* ODK_ERROR_CORE_MESSAGE: if the message did not parse correctly, or there
* were other incorrect values. An error should be returned to the CDM
* layer.
* ODK_UNSUPPORTED_API
* OEMCrypto_ERROR_INVALID_NONCE
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_ParseLicense(
const uint8_t* message, size_t message_length, size_t core_message_length,
@@ -520,59 +496,55 @@ OEMCryptoResult ODK_ParseLicense(
ODK_TimerLimits* timer_limits, ODK_ClockValues* clock_values,
ODK_NonceValues* nonce_values, ODK_ParsedLicense* parsed_license);
/*
* ODK_ParseRenewal
/**
* The function ODK_ParseRenewal will parse the message and verify its
* contents. If the message does not parse correctly, an error of
* ODK_ERROR_CORE_MESSAGE is returned.
*
* Description:
* The function ODK_ParseRenewal will parse the message and verify its
* contents. If the message does not parse correctly, an error of
* ODK_ERROR_CORE_MESSAGE is returned.
* ODK_ParseRenewal shall verify that all fields in nonce_values match those
* in the license. Otherwise it shall return OEMCrypto_ERROR_INVALID_NONCE.
*
* ODK_ParseRenewal shall verify that all fields in nonce_values match those
* in the license. Otherwise it shall return OEMCrypto_ERROR_INVALID_NONCE.
* After parsing the message, this function updates the clock_values based on
* the timer_limits and the current system time. If playback may not
* continue, then ODK_TIMER_EXPIRED is returned.
*
* After parsing the message, this function updates the clock_values based on
* the timer_limits and the current system time. If playback may not
* continue, then ODK_TIMER_EXPIRED is returned.
* If playback may continue, a return value of ODK_SET_TIMER or
* ODK_TIMER_EXPIRED is returned. If the return value is ODK_SET_TIMER, then
* playback may continue until the timer expires. If the return value is
* ODK_DISABLE_TIMER, then playback time is not limited.
*
* If playback may continue, a return value of ODK_SET_TIMER or
* ODK_TIMER_EXPIRED is returned. If the return value is ODK_SET_TIMER, then
* playback may continue until the timer expires. If the return value is
* ODK_DISABLE_TIMER, then playback time is not limited.
* If OEMCrypto uses a hardware timer, and this function returns
* ODK_SET_TIMER, then OEMCrypto shall set the timer to the value pointed to
* by timer_value.
*
* If OEMCrypto uses a hardware timer, and this function returns
* ODK_SET_TIMER, then OEMCrypto shall set the timer to the value pointed to
* by timer_value.
* @param[in] message: pointer to the message buffer.
* @param[in] message_length: length of the entire message buffer.
* @param[in] core_message_size: length of the core message, at the beginning of
* the message buffer.
* @param[in] nonce_values: pointer to the session's nonce data.
* @param[in] system_time_seconds: the current time on OEMCrypto's clock, in
* seconds.
* @param[in] timer_limits: timer limits specified in the license.
* @param[in,out] clock_values: the sessions clock values.
* @param[out] timer_value: set to the new timer value. Only used if the return
* value is ODK_SET_TIMER. This must be non-null if OEMCrypto uses a
* hardware timer.
*
* Parameters:
* [in] message: pointer to the message buffer.
* [in] message_length: length of the entire message buffer.
* [in] core_message_size: length of the core message, at the beginning of
* the message buffer.
* [in] nonce_values: pointer to the session's nonce data.
* [in] system_time_seconds: the current time on OEMCrypto's clock, in
* seconds.
* [in] timer_limits: timer limits specified in the license.
* [in/out] clock_values: the sessions clock values.
* [out] timer_value: set to the new timer value. Only used if the return
* value is ODK_SET_TIMER. This must be non-null if OEMCrypto uses a
* hardware timer.
*
* Returns:
* ODK_ERROR_CORE_MESSAGE: the message did not parse correctly, or there were
* other incorrect values. An error should be returned to the CDM layer.
* ODK_SET_TIMER: Success. The timer should be reset to the specified timer
* value.
* ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
* @retval ODK_ERROR_CORE_MESSAGE: the message did not parse correctly, or there
* were other incorrect values. An error should be returned to the CDM
* layer.
* @retval ODK_SET_TIMER: Success. The timer should be reset to the specified
* timer value.
* @retval ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
* allowed.
* ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
* ODK_UNSUPPORTED_API
* ODK_STALE_RENEWAL: This renewal is not the most recently signed. It is
* rejected.
* OEMCrypto_ERROR_INVALID_NONCE
* @retval ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
* @retval ODK_UNSUPPORTED_API
* @retval ODK_STALE_RENEWAL: This renewal is not the most recently signed. It
* is rejected.
* @retval OEMCrypto_ERROR_INVALID_NONCE
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
size_t core_message_length,
@@ -582,56 +554,54 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
ODK_ClockValues* clock_values,
uint64_t* timer_value);
/*
* ODK_ParseProvisioning
/**
* The function ODK_ParseProvisioning will parse the message and verify the
* nonce values match those in the license.
*
* Description:
* The function ODK_ParseProvisioning will parse the message and verify the
* nonce values match those in the license.
* If the message does not parse correctly, ODK_ParseProvisioning will return
* an error that OEMCrypto should return to the CDM layer above.
*
* If the message does not parse correctly, ODK_ParseProvisioning will return
* an error that OEMCrypto should return to the CDM layer above.
* If the API in the message is larger than 16, then ODK_UNSUPPORTED_API is
* returned.
*
* If the API in the message is larger than 16, then ODK_UNSUPPORTED_API is
* returned.
* ODK_ParseProvisioning shall verify that nonce_values->nonce and
* nonce_values->session_id are the same as those in the message. Otherwise
* it shall return OEMCrypto_ERROR_INVALID_NONCE.
*
* ODK_ParseProvisioning shall verify that nonce_values->nonce and
* nonce_values->session_id are the same as those in the message. Otherwise
* it shall return OEMCrypto_ERROR_INVALID_NONCE.
* The function ODK_ParseProvisioning will verify that each substring points
* to a location in the message body. The message body is the buffer starting
* at message + core_message_length with size message_length -
* core_message_length.
*
* The function ODK_ParseProvisioning will verify that each substring points
* to a location in the message body. The message body is the buffer starting
* at message + core_message_length with size message_length -
* core_message_length.
* @param[in] message: pointer to the message buffer.
* @param[in] message_length: length of the entire message buffer.
* @param[in] core_message_size: length of the core message, at the beginning of
* the message buffer.
* @param[in] nonce_values: pointer to the session's nonce data.
* @param[in] device_id: a pointer to a buffer containing the device ID of the
* device. The ODK function will verify it matches that in the message.
* @param[in] device_id_length: the length of the device ID.
* @param[out] parsed_response: destination for the parse data.
*
* Parameters:
* [in] message: pointer to the message buffer.
* [in] message_length: length of the entire message buffer.
* [in] core_message_size: length of the core message, at the beginning of
* the message buffer.
* [in] nonce_values: pointer to the session's nonce data.
* [in] device_id: a pointer to a buffer containing the device ID of the
* device. The ODK function will verify it matches that in the message.
* [in] device_id_length: the length of the device ID.
* [out] parsed_response: destination for the parse data.
* @retval OEMCrypto_SUCCESS
* @retval ODK_ERROR_CORE_MESSAGE: the message did not parse correctly, or there
* were other incorrect values. An error should be returned to the CDM
* layer.
* @retval ODK_UNSUPPORTED_API
* @retval OEMCrypto_ERROR_INVALID_NONCE
*
* Returns:
* OEMCrypto_SUCCESS
* ODK_ERROR_CORE_MESSAGE: the message did not parse correctly, or there were
* other incorrect values. An error should be returned to the CDM layer.
* ODK_UNSUPPORTED_API
* OEMCrypto_ERROR_INVALID_NONCE
*
* Version:
* This method is new in version 16 of the API.
* @version
* This method is new in version 16 of the API.
*/
OEMCryptoResult ODK_ParseProvisioning(
const uint8_t* message, size_t message_length, size_t core_message_length,
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
size_t device_id_length, ODK_ParsedProvisioning* parsed_response);
/// @}
#ifdef __cplusplus
}
#endif
#endif /* WIDEVINE_ODK_INCLUDE_ODK_H_ */
#endif // WIDEVINE_ODK_INCLUDE_ODK_H_

View File

@@ -0,0 +1,14 @@
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_INCLUDE_ODK_ATTRIBUTES_H_
#define WIDEVINE_ODK_INCLUDE_ODK_ATTRIBUTES_H_
#if defined(__GNUC__) || defined(__clang__)
#define UNUSED __attribute__((__unused__))
#else
#define UNUSED
#endif
#endif // WIDEVINE_ODK_INCLUDE_ODK_ATTRIBUTES_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
#define WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
@@ -15,51 +15,51 @@
#define ODK_MINOR_VERSION 3
/* ODK Version string. Date changed automatically on each release. */
#define ODK_RELEASE_DATE "ODK v16.3 2020-06-02"
#define ODK_RELEASE_DATE "ODK v16.3 2020-08-18"
/* The lowest version number for an ODK message. */
/* The lowest version number for an ODK message. */
#define ODK_FIRST_VERSION 16
/* Some useful constants. */
#define ODK_DEVICE_ID_LEN_MAX 64
#define ODK_SHA256_HASH_SIZE 32
/*
* ODK_TimerLimits Structure
/// @addtogroup odk_timer
/// @{
/**
* Timer limits are specified in a license and are used to determine when
* playback is allowed. See the document "License Duration and Renewal" for a
* discussion on the time restrictions that may be placed on a license. The
* fields in this structure are directly related to the fields in the core
* license message. The fields are set when OEMCrypto calls the function
* ODK_ParseLicense or ODK_InitializeV15Values.
*
* Description:
* Timer limits are specified in a license and are used to determine when
* playback is allowed. See the document "License Duration and Renewal" for a
* discussion on the time restrictions that may be placed on a license. The
* fields in this structure are directly related to the fields in the core
* license message. The fields are set when OEMCrypto calls the function
* ODK_ParseLicense or ODK_InitializeV15Values.
* @param soft_enforce_rental_duration: A boolean controlling the soft or hard
* enforcement of rental duration.
* @param soft_enforce_playback_duration: A boolean controlling the soft or hard
* enforcement of playback duration.
* @param earliest_playback_start_seconds: The earliest time that the first
* playback is allowed. Measured in seconds since the license request was
* signed. For most use cases, this is zero.
* @param rental_duration_seconds: Window of time for the allowed first
* playback. Measured in seconds since the earliest playback start. If
* soft_enforce_rental_duration is true, this applies only to the first
* playback. If soft_enforce_rental_duration is false, then this
* restricts any playback. A value of zero means no limit.
* @param total_playback_duration_seconds: Window of time for allowed playback.
* Measured in seconds since the first playback start. If
* soft_enforce_playback_duration is true, this applies only to the start
* of playback for any session. If soft_enforce_playback_duration is
* false, then this restricts any playback. A value of zero means no
* limit.
* @param initial_renewal_duration_seconds: Window of time for allowed playback.
* Measured in seconds since the first playback start. This value is only
* used to start the renewal timer. After a renewal message is loaded,
* the timer will be reset. A value of zero means no limit.
*
* Fields:
* soft_enforce_rental_duration: A boolean controlling the soft or hard
* enforcement of rental duration.
* soft_enforce_playback_duration: A boolean controlling the soft or hard
* enforcement of playback duration.
* earliest_playback_start_seconds: The earliest time that the first playback
* is allowed. Measured in seconds since the license request was signed. For
* most use cases, this is zero.
* rental_duration_seconds: Window of time for the allowed first playback.
* Measured in seconds since the earliest playback start. If
* soft_enforce_rental_duration is true, this applies only to the first
* playback. If soft_enforce_rental_duration is false, then this restricts
* any playback. A value of zero means no limit.
* total_playback_duration_seconds: Window of time for allowed playback.
* Measured in seconds since the first playback start. If
* soft_enforce_playback_duration is true, this applies only to the start of
* playback for any session. If soft_enforce_playback_duration is false, then
* this restricts any playback. A value of zero means no limit.
* initial_renewal_duration_seconds: Window of time for allowed playback.
* Measured in seconds since the first playback start. This value is only
* used to start the renewal timer. After a renewal message is loaded, the
* timer will be reset. A value of zero means no limit.
*
* Version:
* This struct changed in API version 16.2.
* @version
* This struct changed in API version 16.2.
*/
typedef struct {
bool soft_enforce_rental_duration;
@@ -70,47 +70,44 @@ typedef struct {
uint64_t initial_renewal_duration_seconds;
} ODK_TimerLimits;
/*
* ODK_ClockValues Structure
/**
* Clock values are modified when decryption occurs or when a renewal is
* processed. They are used to track the current status of the license --
* i.e. has playback started? When does the timer expire? See the section
* "Complete ODK API" of the document "Widevine Core Message Serialization"
* for a complete list of all fields in this structure. Most of these values
* shall be saved with the usage entry.
*
* Description:
* Clock values are modified when decryption occurs or when a renewal is
* processed. They are used to track the current status of the license --
* i.e. has playback started? When does the timer expire? See the section
* "Complete ODK API" of the document "Widevine Core Message Serialization"
* for a complete list of all fields in this structure. Most of these values
* shall be saved with the usage entry.
* All times are in seconds. Most of the fields in this structure are saved
* in the usage entry. This structure should be initialized when a usage
* entry is created or loaded, and should be used to save a usage entry. It
* is updated using the ODK functions listed below. The time values are based
* on OEMCrypto's system clock, as described in the document "License
* Duration and Renewal".
*
* All times are in seconds. Most of the fields in this structure are saved
* in the usage entry. This structure should be initialized when a usage
* entry is created or loaded, and should be used to save a usage entry. It
* is updated using the ODK functions listed below. The time values are based
* on OEMCrypto's system clock, as described in the document "License
* Duration and Renewal".
* @param time_of_license_signed: Time that the license request was signed,
* based on OEMCrypto's system clock. This value shall be stored and
* reloaded with usage entry as time_of_license_received.
* @param time_of_first_decrypt: Time of the first decrypt or call select key,
* based on OEMCrypto's system clock. This is 0 if the license has not
* been used to decrypt any data. This value shall be stored and reloaded
* with usage entry.
* @param time_of_last_decrypt: Time of the most recent decrypt call, based on
* OEMCrypto's system clock. This value shall be stored and reloaded with
* usage entry.
* @param time_of_renewal_request: Time of the most recent renewal request,
* based on OEMCrypto's system clock. This is used to verify that a
* renewal is not stale.
* @param time_when_timer_expires: Time that the current timer expires, based on
* OEMCrypto's system clock. If the timer is active, this is used by the
* ODK library to determine if it has expired.
* @param timer_status: Used internally by the ODK library to indicate the
* current timer status.
* @param status: The license or usage entry status. This value shall be stored
* and reloaded with usage entry.
*
* Fields:
* time_of_license_signed: Time that the license request was signed, based on
* OEMCrypto's system clock. This value shall be stored and reloaded with
* usage entry as time_of_license_received.
* time_of_first_decrypt: Time of the first decrypt or call select key, based
* on OEMCrypto's system clock. This is 0 if the license has not been used to
* decrypt any data. This value shall be stored and reloaded with usage entry.
* time_of_last_decrypt: Time of the most recent decrypt call, based on
* OEMCrypto's system clock. This value shall be stored and reloaded with
* usage entry.
* time_of_renewal_request: Time of the most recent renewal request, based on
* OEMCrypto's system clock. This is used to verify that a renewal is not
* stale.
* time_when_timer_expires: Time that the current timer expires, based on
* OEMCrypto's system clock. If the timer is active, this is used by the ODK
* library to determine if it has expired.
* timer_status: Used internally by the ODK library to indicate the current
* timer status.
* status: The license or usage entry status. This value shall be stored and
* reloaded with usage entry.
*
* Version:
* This struct changed in API version 16.2.
* @version
* This struct changed in API version 16.2.
*/
typedef struct {
uint64_t time_of_license_signed;
@@ -122,34 +119,30 @@ typedef struct {
enum OEMCrypto_Usage_Entry_Status status;
} ODK_ClockValues;
/*
* ODK_NonceValues Structure
/**
* Nonce values are used to match a license or provisioning request to a
* license or provisioning response. They are also used to match a renewal
* request and response to a license. For this reason, the api_version might
* be lower than that supported by OEMCrypto. The api_version matches the
* version of the license. Similarly the nonce and session_id match the
* session that generated the license request. For an offline license, these
* might not match the session that is loading the license. We use the nonce
* to prevent a license from being replayed. By also including a session_id
* in the license request and license response, we prevent an attack using
* the birthday paradox to generate nonce collisions on a single device.
*
* Description:
* Nonce values are used to match a license or provisioning request to a
* license or provisioning response. They are also used to match a renewal
* request and response to a license. For this reason, the api_version might
* be lower than that supported by OEMCrypto. The api_version matches the
* version of the license. Similarly the nonce and session_id match the
* session that generated the license request. For an offline license, these
* might not match the session that is loading the license. We use the nonce
* to prevent a license from being replayed. By also including a session_id
* in the license request and license response, we prevent an attack using
* the birthday paradox to generate nonce collisions on a single device.
* @param api_major_version: the API version of the license. This is initialized
* to the API version of the ODK library, but may be lower.
* @param api_minor_version: the minor version of the ODK library. This is used
* by the server to verify that device is not using an obsolete version
* of the ODK library.
* @param nonce: a randomly generated number used to prevent replay attacks.
* @param session_id: the session id of the session which signed the license or
* provisioning request. It is used to prevent replay attacks from one
* session to another.
*
* Fields:
* api_major_version: the API version of the license. This is initialized to
* the API version of the ODK library, but may be lower.
* api_minor_version: the minor version of the ODK library. This is used by
* the server to verify that device is not using an obsolete version of the
* ODK library.
* nonce: a randomly generated number used to prevent replay attacks.
* session_id: the session id of the session which signed the license or
* provisioning request. It is used to prevent replay attacks from one
* session to another.
*
* Version:
* This struct changed in API version 16.2.
* @version
* This struct changed in API version 16.2.
*/
typedef struct {
uint16_t api_minor_version;
@@ -158,29 +151,31 @@ typedef struct {
uint32_t session_id;
} ODK_NonceValues;
/*
* ODK_ParsedLicense Structure
/// @}
/// @addtogroup odk_parser
/// @{
/**
* The parsed license structure contains information from the license
* message. The function ODK_ParseLicense will fill in the fields of this
* message. All substrings are contained within the message body.
*
* Description:
* The parsed license structure contains information from the license
* message. The function ODK_ParseLicense will fill in the fields of this
* message. All substrings are contained within the message body.
* @param enc_mac_keys_iv: IV for decrypting new mac_key. Size is 128 bits.
* @param enc_mac_keys: encrypted mac_keys for generating new mac_keys. Size is
* 512 bits.
* @param pst: the Provider Session Token.
* @param srm_restriction_data: optional data specifying the minimum SRM
* version.
* @param license_type: specifies if the license contains content keys or
* entitlement keys.
* @param nonce_required: indicates if the license requires a nonce.
* @param timer_limits: time limits of the for the license.
* @param key_array_length: number of keys present.
* @param key_array: set of keys to be installed.
*
* Fields:
* enc_mac_keys_iv: IV for decrypting new mac_key. Size is 128 bits.
* enc_mac_keys: encrypted mac_keys for generating new mac_keys. Size is 512
* bits.
* pst: the Provider Session Token.
* srm_restriction_data: optional data specifying the minimum SRM version.
* license_type: specifies if the license contains content keys or
* entitlement keys.
* nonce_required: indicates if the license requires a nonce.
* timer_limits: time limits of the for the license.
* key_array_length: number of keys present.
* key_array: set of keys to be installed.
*
* Version:
* This struct changed in API version 16.2.
* @version
* This struct changed in API version 16.2.
*/
typedef struct {
OEMCrypto_Substring enc_mac_keys_iv;
@@ -194,22 +189,19 @@ typedef struct {
OEMCrypto_KeyObject key_array[ODK_MAX_NUM_KEYS];
} ODK_ParsedLicense;
/*
* ODK_ParsedProvisioning Structure
/**
* The parsed provisioning structure contains information from the license
* message. The function ODK_ParseProvisioning will fill in the fields of
* this message. All substrings are contained within the message body.
*
* Description:
* The parsed provisioning structure contains information from the license
* message. The function ODK_ParseProvisioning will fill in the fields of
* this message. All substrings are contained within the message body.
* @param key_type: indicates if this key is an RSA or ECC private key.
* @param enc_private_key: encrypted private key for the DRM certificate.
* @param enc_private_key_iv: IV for decrypting new private key. Size is 128
* bits.
* @param encrypted_message_key: used for provisioning 3.0 to derive keys.
*
* Fields:
* key_type: indicates if this key is an RSA or ECC private key.
* enc_private_key: encrypted private key for the DRM certificate.
* enc_private_key_iv: IV for decrypting new private key. Size is 128 bits.
* encrypted_message_key: used for provisioning 3.0 to derive keys.
*
* Version:
* This struct changed in API version 16.2.
* @version
* This struct changed in API version 16.2.
*/
typedef struct {
OEMCrypto_PrivateKeyType key_type;
@@ -218,4 +210,6 @@ typedef struct {
OEMCrypto_Substring encrypted_message_key; /* Used for Prov 3.0 */
} ODK_ParsedProvisioning;
#endif /* WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_ */
/// @}
#endif // WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_

View File

@@ -1,13 +1,13 @@
/* Copyright 2019 Google LLC. All rights reserved. This file is distributed */
/* under the Widevine Master License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file is distributed
// under the Widevine Master License Agreement.
/* Partners are expected to edit this file to support target specific code */
/* and limits. */
// Partners are expected to edit this file to support target specific code
// and limits.
#ifndef WIDEVINE_ODK_INCLUDE_ODK_TARGET_H_
#define WIDEVINE_ODK_INCLUDE_ODK_TARGET_H_
/* Maximum number of keys can be modified to suit target's resource tier. */
// Maximum number of keys can be modified to suit target's resource tier.
#define ODK_MAX_NUM_KEYS 32
#endif /* WIDEVINE_ODK_INCLUDE_ODK_TARGET_H_ */
#endif // WIDEVINE_ODK_INCLUDE_ODK_TARGET_H_

View File

@@ -39,8 +39,8 @@ bool ParseRequest(uint32_t message_type,
reinterpret_cast<const uint8_t*>(oemcrypto_core_message.c_str());
const size_t buf_length = oemcrypto_core_message.size();
Message* msg = nullptr;
AllocateMessage(&msg, message_block);
uint8_t blk[SIZE_OF_MESSAGE_STRUCT];
Message* msg = reinterpret_cast<Message*>(blk);
InitMessage(msg, const_cast<uint8_t*>(buf), buf_length);
SetSize(msg, buf_length);
@@ -70,7 +70,8 @@ bool ParseRequest(uint32_t message_type,
// For v16, a release and a renewal use the same message structure.
// However, for future API versions, the release might be a separate
// message. Otherwise, we expect an exact match of message types.
if (core_message.message_type != message_type &&
if (message_type != ODK_Common_Request_Type &&
core_message.message_type != message_type &&
!(message_type == ODK_Renewal_Request_Type &&
core_message.message_type == ODK_Release_Request_Type)) {
return false;
@@ -129,5 +130,13 @@ bool CoreProvisioningRequestFromMessage(
return true;
}
bool CoreCommonRequestFromMessage(const std::string& oemcrypto_core_message,
ODK_CommonRequest* common_request) {
const auto unpacker = Unpack_ODK_PreparedCommonRequest;
ODK_PreparedCommonRequest prepared_common = {};
return ParseRequest(ODK_Common_Request_Type, oemcrypto_core_message,
common_request, &prepared_common, unpacker);
}
} // namespace deserialize
} // namespace oemcrypto_core_message

View File

@@ -50,8 +50,8 @@ bool CreateResponse(uint32_t message_type, const S& core_request,
static constexpr size_t BUF_CAPACITY = 2048;
std::vector<uint8_t> buf(BUF_CAPACITY, 0);
Message* msg = nullptr;
AllocateMessage(&msg, message_block);
uint8_t blk[SIZE_OF_MESSAGE_STRUCT];
Message* msg = reinterpret_cast<Message*>(blk);
InitMessage(msg, buf.data(), buf.capacity());
packer(msg, &response);
if (!ValidMessage(msg)) {

View File

@@ -90,17 +90,14 @@ bool CreateCoreLicenseResponseFromProto(const std::string& serialized_license,
parsed_lic.enc_mac_keys = GetOecSubstring(serialized_license, k.key());
break;
}
case video_widevine::License_KeyContainer::CONTENT: {
any_content = true;
if (parsed_lic.key_array_length >= ODK_MAX_NUM_KEYS) {
return false;
}
uint32_t& n = parsed_lic.key_array_length;
parsed_lic.key_array[n++] = KeyContainerToOecKey(serialized_license, k);
break;
}
case video_widevine::License_KeyContainer::CONTENT:
case video_widevine::License_KeyContainer::OPERATOR_SESSION:
case video_widevine::License_KeyContainer::ENTITLEMENT: {
any_entitlement = true;
if (k.type() == video_widevine::License_KeyContainer::ENTITLEMENT) {
any_entitlement = true;
} else {
any_content = true;
}
if (parsed_lic.key_array_length >= ODK_MAX_NUM_KEYS) {
return false;
}

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "odk.h"
@@ -19,7 +19,7 @@
static OEMCryptoResult ODK_PrepareRequest(
uint8_t* message, size_t message_length, size_t* core_message_length,
uint32_t message_type, const ODK_NonceValues* nonce_values,
ODK_MessageType message_type, const ODK_NonceValues* nonce_values,
void* prepared_request_buffer, size_t prepared_request_buffer_length) {
if (nonce_values == NULL || core_message_length == NULL ||
prepared_request_buffer == NULL ||
@@ -27,8 +27,8 @@ static OEMCryptoResult ODK_PrepareRequest(
return ODK_ERROR_CORE_MESSAGE;
}
Message* msg = NULL;
AllocateMessage(&msg, message_block);
uint8_t blk[SIZE_OF_MESSAGE_STRUCT];
Message* msg = (Message*)blk;
InitMessage(msg, message, *core_message_length);
/* The core message should be at the beginning of the buffer, and with a
@@ -95,18 +95,24 @@ static OEMCryptoResult ODK_PrepareRequest(
static OEMCryptoResult ODK_ParseResponse(
const uint8_t* message, size_t message_length, size_t core_message_length,
uint32_t message_type, const ODK_NonceValues* nonce_values,
ODK_MessageType message_type, const ODK_NonceValues* nonce_values,
void* response_buffer, uint32_t response_buffer_length) {
if (message == NULL || response_buffer == NULL ||
core_message_length > message_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Message* msg = NULL;
AllocateMessage(&msg, message_block);
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
/* 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);
@@ -168,7 +174,7 @@ OEMCryptoResult ODK_PrepareCoreLicenseRequest(
return ODK_ERROR_CORE_MESSAGE;
}
ODK_PreparedLicenseRequest license_request = {
{0},
{0, 0, {}},
};
return ODK_PrepareRequest(
message, message_length, core_message_length, ODK_License_Request_Type,
@@ -197,7 +203,7 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
return OEMCrypto_SUCCESS;
}
ODK_PreparedRenewalRequest renewal_request = {{0}, 0};
ODK_PreparedRenewalRequest renewal_request = {{0, 0, {}}, 0};
/* First, we compute the time this request was made relative to the playback
* clock. */
if (clock_values->time_of_first_decrypt == 0) {
@@ -231,14 +237,14 @@ OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
return ODK_ERROR_CORE_MESSAGE;
}
ODK_PreparedProvisioningRequest provisioning_request = {
{0},
{0, 0, {}},
0,
{0},
};
if (device_id_length > sizeof(provisioning_request.device_id)) {
return ODK_ERROR_CORE_MESSAGE;
}
provisioning_request.device_id_length = device_id_length;
provisioning_request.device_id_length = (uint32_t)device_id_length;
if (device_id) {
memcpy(provisioning_request.device_id, device_id, device_id_length);
}
@@ -261,7 +267,9 @@ OEMCryptoResult ODK_ParseLicense(
return ODK_ERROR_CORE_MESSAGE;
}
ODK_LicenseResponse license_response = {{{0}}, parsed_license, {0}};
ODK_LicenseResponse license_response = {{{0, 0, {}}}, NULL, {0}};
license_response.parsed_license = parsed_license;
const OEMCryptoResult err = ODK_ParseResponse(
message, message_length, core_message_length, ODK_License_Response_Type,
NULL, &license_response, sizeof(ODK_LicenseResponse));
@@ -342,7 +350,7 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
}
ODK_RenewalResponse renewal_response = {
{{0}, 0},
{{0, 0, {}}, 0},
0,
};
const OEMCryptoResult err = ODK_ParseResponse(
@@ -378,8 +386,9 @@ OEMCryptoResult ODK_ParseProvisioning(
return ODK_ERROR_CORE_MESSAGE;
}
ODK_ProvisioningResponse provisioning_response = {{{0}, 0, {0}},
parsed_response};
ODK_ProvisioningResponse provisioning_response = {{{0, 0, {}}, 0, {0}}, NULL};
provisioning_response.parsed_provisioning = parsed_response;
if (device_id_length > ODK_DEVICE_ID_LEN_MAX) {
return ODK_ERROR_CORE_MESSAGE;
}

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_SRC_ODK_ASSERT_H_
#define WIDEVINE_ODK_SRC_ODK_ASSERT_H_
@@ -21,4 +21,4 @@ extern "C" {
}
#endif
#endif /* WIDEVINE_ODK_SRC_ODK_ASSERT_H_ */
#endif // WIDEVINE_ODK_SRC_ODK_ASSERT_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_SRC_ODK_ENDIAN_H_
#define WIDEVINE_ODK_SRC_ODK_ENDIAN_H_
@@ -15,7 +15,7 @@ extern "C" {
#define oemcrypto_be32toh be32toh
#define oemcrypto_htobe64 htobe64
#define oemcrypto_be64toh be64toh
#else /* defined(__linux__) || defined(__ANDROID__) */
#else /* defined(__linux__) || defined(__ANDROID__) */
uint32_t oemcrypto_htobe32(uint32_t u32);
uint32_t oemcrypto_be32toh(uint32_t u32);
uint64_t oemcrypto_htobe64(uint64_t u64);
@@ -26,4 +26,4 @@ uint64_t oemcrypto_be64toh(uint64_t u64);
}
#endif
#endif /* WIDEVINE_ODK_SRC_ODK_ENDIAN_H_ */
#endif // WIDEVINE_ODK_SRC_ODK_ENDIAN_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include <stddef.h>
#include <stdint.h>

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_SRC_ODK_OVERFLOW_H_
#define WIDEVINE_ODK_SRC_ODK_OVERFLOW_H_
@@ -20,4 +20,4 @@ int odk_add_overflow_ux(size_t a, size_t b, size_t* c);
}
#endif
#endif /* WIDEVINE_ODK_SRC_ODK_OVERFLOW_H_ */
#endif // WIDEVINE_ODK_SRC_ODK_OVERFLOW_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
/*
* This code is auto-generated, do not edit
@@ -193,6 +193,10 @@ void Unpack_ODK_PreparedProvisioningRequest(
UnpackArray(msg, &obj->device_id[0], sizeof(obj->device_id));
}
void Unpack_ODK_PreparedCommonRequest(Message* msg,
ODK_PreparedCommonRequest* obj) {
Unpack_ODK_CoreMessage(msg, &obj->core_message);
}
/* @@ odk deserialize */
void Unpack_ODK_LicenseResponse(Message* msg, ODK_LicenseResponse* obj) {

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
/*
* This code is auto-generated, do not edit
@@ -43,7 +43,10 @@ void Unpack_ODK_PreparedRenewalRequest(Message* msg,
void Unpack_ODK_PreparedProvisioningRequest(
Message* msg, ODK_PreparedProvisioningRequest* obj);
void Unpack_ODK_PreparedCommonRequest(Message* msg,
ODK_PreparedCommonRequest* obj);
#ifdef __cplusplus
} /* extern "C" */
} // extern "C"
#endif
#endif /* WIDEVINE_ODK_SRC_ODK_SERIALIZE_H_ */
#endif // WIDEVINE_ODK_SRC_ODK_SERIALIZE_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_SRC_ODK_STRUCTS_PRIV_H_
#define WIDEVINE_ODK_SRC_ODK_STRUCTS_PRIV_H_
@@ -22,9 +22,11 @@ typedef enum {
ODK_Provisioning_Request_Type = 5,
ODK_Provisioning_Response_Type = 6,
/* Reserve future message types to support forward compatibility. */
// Reserve future message types to support forward compatibility.
ODK_Release_Request_Type = 7,
ODK_Release_Response_Type = 8,
ODK_Common_Request_Type = 9,
ODK_Common_Response_Type = 10,
} ODK_MessageType;
typedef struct {
@@ -48,6 +50,10 @@ typedef struct {
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX];
} ODK_PreparedProvisioningRequest;
typedef struct {
ODK_CoreMessage core_message;
} ODK_PreparedCommonRequest;
typedef struct {
ODK_PreparedLicenseRequest request;
ODK_ParsedLicense* parsed_license;
@@ -64,33 +70,32 @@ typedef struct {
ODK_ParsedProvisioning* parsed_provisioning;
} ODK_ProvisioningResponse;
/* These are the sum of sizeof of each individual member of the request structs
*/
/* without any padding added by the compiler. Make sure they get updated when */
/* request structs change. Refer to test suite OdkSizeTest in */
/* ../test/odk_test.cpp for validations of each of the defined request sizes. */
// These are the sum of sizeof of each individual member of the request structs
// without any padding added by the compiler. Make sure they get updated when
// request structs change. Refer to test suite OdkSizeTest in
// ../test/odk_test.cpp for validations of each of the defined request sizes.
#define ODK_LICENSE_REQUEST_SIZE 20
#define ODK_RENEWAL_REQUEST_SIZE 28
#define ODK_PROVISIONING_REQUEST_SIZE 88
/* These are the possible timer status values. */
#define ODK_CLOCK_TIMER_STATUS_UNDEFINED 0 /* Should not happen. */
/* When the structure has been initialized, but no license is loaded. */
// These are the possible timer status values.
#define ODK_CLOCK_TIMER_STATUS_UNDEFINED 0 // Should not happen.
// When the structure has been initialized, but no license is loaded.
#define ODK_CLOCK_TIMER_STATUS_LICENSE_NOT_LOADED 1
/* After the license is loaded, before a successful decrypt. */
// After the license is loaded, before a successful decrypt.
#define ODK_CLOCK_TIMER_STATUS_LICENSE_LOADED 2
/* After the license is loaded, if a renewal has also been loaded. */
// After the license is loaded, if a renewal has also been loaded.
#define ODK_CLOCK_TIMER_STATUS_RENEWAL_LOADED 3
/* The first decrypt has occurred and the timer is active. */
// The first decrypt has occurred and the timer is active.
#define ODK_CLOCK_TIMER_STATUS_ACTIVE 4
/* The first decrypt has occurred and the timer is unlimited. */
// The first decrypt has occurred and the timer is unlimited.
#define ODK_CLOCK_TIMER_STATUS_UNLIMITED 5
/* The timer has transitioned from active to expired. */
// The timer has transitioned from active to expired.
#define ODK_CLOCK_TIMER_STATUS_EXPIRED 6
/* The license has been marked as inactive. */
// The license has been marked as inactive.
#define ODK_CLOCK_TIMER_STATUS_LICENSE_INACTIVE 7
/* A helper function for computing timer limits when a renewal is loaded. */
// A helper function for computing timer limits when a renewal is loaded.
OEMCryptoResult ODK_ComputeRenewalDuration(const ODK_TimerLimits* timer_limits,
ODK_ClockValues* clock_values,
uint64_t system_time_seconds,
@@ -101,4 +106,4 @@ OEMCryptoResult ODK_ComputeRenewalDuration(const ODK_TimerLimits* timer_limits,
}
#endif
#endif /* WIDEVINE_ODK_SRC_ODK_STRUCTS_PRIV_H_ */
#endif // WIDEVINE_ODK_SRC_ODK_STRUCTS_PRIV_H_

View File

@@ -1,11 +1,12 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include <stdint.h>
#include <string.h>
#include "odk.h"
#include "odk_attributes.h"
#include "odk_overflow.h"
#include "odk_structs_priv.h"
@@ -311,7 +312,7 @@ OEMCryptoResult ODK_ReloadClockValues(ODK_ClockValues* clock_values,
uint64_t time_of_first_decrypt,
uint64_t time_of_last_decrypt,
enum OEMCrypto_Usage_Entry_Status status,
uint64_t system_time_seconds) {
uint64_t system_time_seconds UNUSED) {
if (clock_values == NULL) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "odk_util.h"

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_SRC_ODK_UTIL_H_
#define WIDEVINE_ODK_SRC_ODK_UTIL_H_
@@ -23,6 +23,6 @@ int crypto_memcmp(const void* a, const void* b, size_t len);
bool ODK_NonceValuesEqual(const ODK_NonceValues* a, const ODK_NonceValues* b);
#ifdef __cplusplus
} /* extern "C" */
} // extern "C"
#endif
#endif /* WIDEVINE_ODK_SRC_ODK_UTIL_H_ */
#endif // WIDEVINE_ODK_SRC_ODK_UTIL_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "serialization_base.h"
@@ -9,7 +9,6 @@
#include <string.h>
#include "OEMCryptoCENCCommon.h"
#include "odk_assert.h"
#include "odk_overflow.h"
struct _Message {
@@ -20,13 +19,6 @@ struct _Message {
MessageStatus status;
};
/* TODO(b/150776214): this can be removed once AllocateMessage gets cleaned up
*/
/*
* odk_static_assert(SIZE_OF_MESSAGE_STRUCT >= sizeof(struct _Message),
* "SIZE_OF_MESSAGE_STRUCT too small");
*/
bool ValidMessage(Message* message) {
if (message == NULL) {
return false;
@@ -99,8 +91,8 @@ void PackArray(Message* message, const uint8_t* base, size_t size) {
}
void Pack_OEMCrypto_Substring(Message* msg, const OEMCrypto_Substring* obj) {
uint32_t offset = obj->offset;
uint32_t length = obj->length;
uint32_t offset = (uint32_t)obj->offset;
uint32_t length = (uint32_t)obj->length;
Pack_uint32_t(msg, &offset);
Pack_uint32_t(msg, &length);
}
@@ -198,21 +190,6 @@ void InitMessage(Message* message, uint8_t* buffer, size_t capacity) {
message->status = MESSAGE_STATUS_OK;
}
/*
* The message structure is in the first sizeof(Memory) bytes
* of the buffer
*/
Message* CreateMessage(uint8_t* buffer, size_t buffer_size) {
if (buffer == NULL || buffer_size < sizeof(Message)) return NULL;
Message* message = (Message*)buffer;
message->base = buffer + sizeof(Message);
message->capacity = buffer_size - sizeof(Message);
message->size = 0;
message->read_offset = 0;
message->status = MESSAGE_STATUS_OK;
return message;
}
/*
* Set the message to an empty state
*/

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_SRC_SERIALIZATION_BASE_H_
#define WIDEVINE_ODK_SRC_SERIALIZATION_BASE_H_
@@ -61,13 +61,6 @@ void UnpackArray(Message* message, uint8_t* address,
size_t size); /* copy out */
void Unpack_OEMCrypto_Substring(Message* msg, OEMCrypto_Substring* obj);
/*
* Create a message from a buffer. The message structure consumes the first
* sizeof(Message) bytes of the buffer. The caller is responsible for ensuring
* that the buffer remains allocated for the lifetime of the message.
*/
Message* CreateMessage(uint8_t* buffer, size_t buffer_size);
/*
* Initialize a message structure to reference a separate buffer. The caller
* is responsible for ensuring that the buffer remains allocated for the
@@ -90,7 +83,7 @@ size_t GetOffset(Message* message);
size_t SizeOfMessageStruct();
#ifdef __cplusplus
} /* extern "C" */
} // extern "C"
#endif
#endif /* WIDEVINE_ODK_SRC_SERIALIZATION_BASE_H_ */
#endif // WIDEVINE_ODK_SRC_SERIALIZATION_BASE_H_

View File

@@ -62,6 +62,9 @@ library and need to preload that before OEMCrypto unit tests run
* Preload the shared library before running OEMCrypto unit tests
```shell
$ cd oemcrypto/odk/test/fuzzing/corpus
$ mkdir license_request_corpus license_response_corpus renewal_request_corpus renewal_response_corpus provisioning_request_corpus provisioning_response_corpus
$ cd /path/to/cdm/repo
$ LD_PRELOAD=out/Default/lib/libodk_corpus_generator.so ./out/Default/oemcrypto_unittests
```

View File

@@ -1,8 +1,8 @@
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
/* We must define this macro to get RTLD_NEXT definition from <dlfcn.h> */
// We must define this macro to get RTLD_NEXT definition from <dlfcn.h>
#define _GNU_SOURCE
#include <dlfcn.h>
@@ -21,7 +21,7 @@ OEMCryptoResult ODK_PrepareCoreLicenseRequest(
message, message_length, core_message_length, nonce_values);
char* file_name = GetFileName("license_request_corpus");
/* License Request format expected by fuzzer - [Core License Request] */
// License Request format expected by fuzzer - [Core License Request]
AppendToFile(file_name, (const char*)message, *core_message_length);
free(file_name);
return oem_crypto_result;
@@ -50,9 +50,8 @@ OEMCryptoResult ODK_ParseLicense(
nonce_values, parsed_license);
char* file_name = GetFileName("license_response_corpus");
/* License Response format expected by fuzzer - [ODK_ParseLicense_Args][Core
*/
/* License Response] */
// License Response format expected by fuzzer - [ODK_ParseLicense_Args][Core
// License Response]
AppendToFile(file_name, (const char*)&parse_license_args,
sizeof(struct ODK_ParseLicense_Args));
AppendToFile(file_name, (const char*)message, core_message_length);
@@ -74,8 +73,8 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
nonce_values, clock_values, system_time_seconds);
char* file_name = GetFileName("renewal_request_corpus");
/* License Request format expected by fuzzer - [ODK_ClockValues][Core */
/* License Request] */
// License Request format expected by fuzzer - [ODK_ClockValues][Core
// License Request]
AppendToFile(file_name, (const char*)clock_values, sizeof(ODK_ClockValues));
AppendToFile(file_name, (const char*)message, *core_message_size);
free(file_name);
@@ -103,9 +102,8 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
timer_limits, clock_values, timer_value);
char* file_name = GetFileName("renewal_response_corpus");
/* Renewal Response format expected by fuzzer - [ODK_ParseRenewal_Args][Core
*/
/* Renewal Response] */
// Renewal Response format expected by fuzzer - [ODK_ParseRenewal_Args][Core
// Renewal Response]
AppendToFile(file_name, (const char*)&parse_renewal_args,
sizeof(struct ODK_ParseRenewal_Args));
AppendToFile(file_name, (const char*)message, core_message_length);
@@ -126,8 +124,8 @@ OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
nonce_values, device_id, device_id_length);
char* file_name = GetFileName("provisioning_request_corpus");
/* Provisioning Request format expected by fuzzer - [Core Provisioning */
/* Request] */
// Provisioning Request format expected by fuzzer - [Core Provisioning
// Request]
AppendToFile(file_name, (const char*)message, *core_message_length);
free(file_name);
return oem_crypto_result;
@@ -150,8 +148,8 @@ OEMCryptoResult ODK_ParseProvisioning(
device_id_length, parsed_response);
char* file_name = GetFileName("provisioning_response_corpus");
/* Provisioning Response format expected by fuzzer - */
/* [ODK_ParseProvisioning_Args][Core Provisioning Response] */
// Provisioning Response format expected by fuzzer -
// [ODK_ParseProvisioning_Args][Core Provisioning Response]
AppendToFile(file_name, (const char*)&parse_provisioning_args,
sizeof(struct ODK_ParseProvisioning_Args));
AppendToFile(file_name, (const char*)message, core_message_length);

View File

@@ -1,6 +1,6 @@
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "fuzzing/corpus_generator/odk_corpus_generator_helper.h"
void AppendToFile(const char* file_name, const char* message,

View File

@@ -1,6 +1,6 @@
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// 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_
@@ -15,5 +15,4 @@ void AppendToFile(const char* file_name, const char* message,
char* GetFileName(const char* directory);
#endif /* WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_ \
*/
#endif // WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_

View File

@@ -28,13 +28,13 @@ void ConvertDataToValidBools(ODK_ParsedLicense* t) {
&t->timer_limits.soft_enforce_rental_duration);
}
void ConvertDataToValidBools(ODK_PreparedRenewalRequest* t) {}
void ConvertDataToValidBools(ODK_PreparedRenewalRequest* t UNUSED) {}
void ConvertDataToValidBools(ODK_ParsedProvisioning* t) {}
void ConvertDataToValidBools(ODK_ParsedProvisioning* t UNUSED) {}
OEMCryptoResult odk_serialize_LicenseRequest(
const void* in, uint8_t* out, size_t* size,
const ODK_LicenseRequest& core_license_request,
const void* in UNUSED, uint8_t* out, size_t* size,
const ODK_LicenseRequest& core_license_request UNUSED,
const ODK_NonceValues* nonce_values) {
return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values);
}
@@ -50,7 +50,7 @@ OEMCryptoResult odk_serialize_RenewalRequest(
}
OEMCryptoResult odk_serialize_ProvisioningRequest(
const void* in, uint8_t* out, size_t* size,
const void* in UNUSED, uint8_t* out, size_t* size,
const ODK_ProvisioningRequest& core_provisioning,
const ODK_NonceValues* nonce_values) {
const std::string& device_id = core_provisioning.device_id;
@@ -99,8 +99,8 @@ 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.
Message* msg = nullptr;
AllocateMessage(&msg, message_block);
uint8_t blk[SIZE_OF_MESSAGE_STRUCT];
Message* msg = reinterpret_cast<Message*>(blk);
InitMessage(msg, const_cast<uint8_t*>(buf), len);
SetSize(msg, len);
Unpack_ODK_PreparedRenewalRequest(msg, renewal_msg);

View File

@@ -1,6 +1,6 @@
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_
#define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_
@@ -9,6 +9,7 @@
#include "core_message_serialize.h"
#include "fuzzing/odk_fuzz_structs.h"
#include "odk_attributes.h"
#include "odk_serialize.h"
namespace oemcrypto_core_message {
@@ -56,24 +57,23 @@ bool kdo_serialize_ProvisioningResponse(
const ODK_ParsedProvisioning& parsed_prov,
std::string* oemcrypto_core_message);
/* Idea behind having three different functions is: */
/* Only ODK_ParseLicense structure had fields which needed additional */
/* procession. Having a single function with templated parameter T was */
/* failing during compile time because other two structures doesn't have */
/* fields that need additional processing. Hence to reduce code redundance and
*/
/* make us of common FuzzerMutateResponse across three response fuzzers, */
/* three independent functions were defined and renewal and provisioning */
/* functions would be empty as no additional processing is needed for them. */
// Idea behind having three different functions is:
// Only ODK_ParseLicense structure had fields which needed additional
// procession. Having a single function with templated parameter T was
// failing during compile time because other two structures doesn't have
// fields that need additional processing. Hence to reduce code redundance and
// make us of common FuzzerMutateResponse across three response fuzzers,
// three independent functions were defined and renewal and provisioning
// functions would be empty as no additional processing is needed for them.
void ConvertDataToValidBools(ODK_ParsedLicense* t);
void ConvertDataToValidBools(ODK_PreparedRenewalRequest* t);
void ConvertDataToValidBools(ODK_ParsedProvisioning* t);
/* Forward-declare the libFuzzer's mutator callback. Mark it weak so that */
/* the program links successfully even outside of --config=asan-fuzzer */
/* (apparently the only config in which LLVM uses our custom mutator). */
// Forward-declare the libFuzzer's mutator callback. Mark it weak so that
// the program links successfully even outside of --config=asan-fuzzer
// (apparently the only config in which LLVM uses our custom mutator).
extern "C" size_t LLVMFuzzerMutate(uint8_t* Data, size_t Size, size_t MaxSize)
__attribute__((weak));
@@ -85,8 +85,8 @@ size_t FuzzerMutateResponse(uint8_t* data, size_t size, size_t max_size,
const size_t kCoreResponseSize = sizeof(T);
const size_t kTotalResponseSize = kArgsSize + kCoreResponseSize;
/* Deserializing data in order to make sure it deserializes properly. */
/* Input byte array format: [function arguments][data to parse]. */
// Deserializing data in order to make sure it deserializes properly.
// Input byte array format: [function arguments][data to parse].
std::shared_ptr<A> _args(new A());
A* args = _args.get();
memcpy(args, data, kArgsSize);
@@ -97,17 +97,16 @@ size_t FuzzerMutateResponse(uint8_t* data, size_t size, size_t max_size,
OEMCryptoResult result =
odk_deserialize_fun(buf, size - kArgsSize, args, &nonce_values, &t);
/* If data doesn't deserialize successfully, We copy random bytes into */
/* T and serialize using kdo function */
/* which will create a valid oemcrypto core message using */
/* nonce and request hash from function args. OEMCrypto core message acts as
*/
/* input to odk_kdo. */
// If data doesn't deserialize successfully, We copy random bytes into
// T and serialize using kdo function
// which will create a valid oemcrypto core message using
// nonce and request hash from function args. OEMCrypto core message acts as
// input to odk_kdo.
if (result != OEMCrypto_SUCCESS) {
if (max_size < kTotalResponseSize) {
return 0;
}
/* Initialize remaining bytes needed in data to zero. */
// Initialize remaining bytes needed in data to zero.
if (size < kTotalResponseSize) {
memset(data + size, 0, kTotalResponseSize - size);
}
@@ -115,24 +114,24 @@ size_t FuzzerMutateResponse(uint8_t* data, size_t size, size_t max_size,
memcpy(&t, buf, kCoreResponseSize);
}
/* Ask LLVM to run its usual mutations, hopefully giving us interesting */
/* inputs. We copy deserialized data into pointer data, run mutations */
/* and copy back the mutated data to args and t */
// Ask LLVM to run its usual mutations, hopefully giving us interesting
// inputs. We copy deserialized data into pointer data, run mutations
// and copy back the mutated data to args and t
memcpy(data + kArgsSize, &t, kCoreResponseSize);
LLVMFuzzerMutate(data, kTotalResponseSize, kTotalResponseSize);
memcpy(args, data, kArgsSize);
memcpy(&t, data + kArgsSize, kCoreResponseSize);
/* Convert boolean flags in parsed message to valid bytes to */
/* avoid errors from msan. Only needed for parsed license. */
// Convert boolean flags in parsed message to valid bytes to
// avoid errors from msan. Only needed for parsed license.
ConvertDataToValidBools(&t);
/* Serialize the data after mutation. */
// Serialize the data after mutation.
std::string oemcrypto_core_message;
if (!kdo_serialize_fun(args, t, &oemcrypto_core_message)) {
return 0;
}
/* Copy mutated and serialized oemcrypto_core_message to data */
/* so that it acts as input to odk_kdo function. */
// Copy mutated and serialized oemcrypto_core_message to data
// so that it acts as input to odk_kdo function.
memcpy(data + kArgsSize, oemcrypto_core_message.data(),
oemcrypto_core_message.size());
return kArgsSize + oemcrypto_core_message.size();
@@ -149,9 +148,9 @@ size_t FuzzerMutateResponse(uint8_t* data, size_t size, size_t max_size,
*/
template <typename A, typename T, typename F, typename G>
void odk_kdo(const F& odk_fun, const G& kdo_fun, const uint8_t* in,
const size_t size, const size_t args_size, uint8_t* out) {
const size_t size, const size_t args_size, uint8_t* out UNUSED) {
T t = {};
/* Input byte array format: [function arguments][data to parse] */
// Input byte array format: [function arguments][data to parse]
if (size < args_size) {
return;
}
@@ -187,8 +186,8 @@ static void kdo_odk(const F& kdo_fun, const G& odk_fun, const uint8_t* in,
if (size <= clock_value_size) {
return;
}
/* Input byte array format: [Clock Values][data to parse]. */
/* Only Renewal Request expects clock values to be present. */
// Input byte array format: [Clock Values][data to parse].
// Only Renewal Request expects clock values to be present.
std::string input(reinterpret_cast<const char*>(in) + clock_value_size,
size - clock_value_size);
T t = {};
@@ -202,5 +201,5 @@ static void kdo_odk(const F& kdo_fun, const G& odk_fun, const uint8_t* in,
return;
}
}
} /* namespace oemcrypto_core_message */
#endif /* WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_ */
} // namespace oemcrypto_core_message
#endif // WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_

View File

@@ -1,6 +1,6 @@
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_
#define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_
@@ -25,4 +25,4 @@ struct ODK_ParseProvisioning_Args {
size_t device_id_length;
uint8_t device_id[64];
};
#endif /* WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_ */
#endif // WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_

View File

@@ -12,7 +12,8 @@ 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) {
size_t max_size,
unsigned int seed UNUSED) {
const size_t kLicenseResponseArgsSize = sizeof(ODK_ParseLicense_Args);
if (size < kLicenseResponseArgsSize) {
return 0;

View File

@@ -6,13 +6,15 @@
#include <vector>
#include "fuzzing/odk_fuzz_helper.h"
#include "odk_attributes.h"
namespace oemcrypto_core_message {
// The custom mutator: Ensure that each input can be deserialized properly
// by ODK function after mutation.
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) {
size_t max_size,
unsigned int seed UNUSED) {
const size_t kProvisioningResponseArgsSize =
sizeof(ODK_ParseProvisioning_Args);
if (size < kProvisioningResponseArgsSize) {

View File

@@ -6,13 +6,15 @@
#include <vector>
#include "fuzzing/odk_fuzz_helper.h"
#include "odk_attributes.h"
namespace oemcrypto_core_message {
// The custom mutator: Ensure that each input can be deserialized properly
// by ODK function after mutation.
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) {
size_t max_size,
unsigned int seed UNUSED) {
const size_t kRenewalResponseArgsSize = sizeof(ODK_ParseRenewal_Args);
if (size < kRenewalResponseArgsSize) {
return 0;

View File

@@ -0,0 +1,37 @@
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "OEMCryptoCENCCommon.h"
#include "gtest/gtest.h"
#include "odk.h"
#include "third_party/absl/strings/escaping.h"
namespace wvodk_test {
TEST(CoreMessageTest, RenwalRequest) {
std::string oem =
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst"
"uvwxyzabcdefghijklmnopqrstuvwxyz";
const uint8_t* buf = reinterpret_cast<const uint8_t*>(oem.c_str());
uint8_t* message = const_cast<uint8_t*>(buf);
size_t message_length = 88;
size_t core_message_length = 88;
uint16_t api_minor_version = 16;
uint16_t api_major_version = 16;
uint32_t nonce = 0;
uint32_t timer_status = 2;
uint64_t time = 10;
enum OEMCrypto_Usage_Entry_Status status = kInactiveUsed;
ODK_NonceValues nonce_values{api_minor_version, api_major_version, nonce};
ODK_ClockValues clock_values{time, time, time, time,
time, timer_status, status};
uint64_t system_time_seconds = 100;
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreRenewalRequest(message, message_length,
&core_message_length, &nonce_values,
&clock_values, system_time_seconds));
// All messages have at least a five 4-byte fields.
char* m = reinterpret_cast<char*>(message);
VLOG(0) << absl::BytesToHexString(std::string(m, core_message_length));
}
} // namespace wvodk_test

View File

@@ -1,326 +0,0 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary
* source code may only be used and distributed under the Widevine Master
* License Agreement.
*/
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <functional>
#include <memory>
#include <vector>
#include "OEMCryptoCENCCommon.h"
#include "core_message_deserialize.h"
#include "core_message_serialize.h"
#include "core_message_types.h"
#include "odk.h"
#include "odk_serialize.h"
#include "odk_structs.h"
#include "odk_structs_priv.h"
typedef std::function<void(const uint8_t*, uint8_t*, size_t, size_t)>
roundtrip_fun;
using oemcrypto_core_message::ODK_LicenseRequest;
using oemcrypto_core_message::ODK_ProvisioningRequest;
using oemcrypto_core_message::ODK_RenewalRequest;
using oemcrypto_core_message::deserialize::CoreLicenseRequestFromMessage;
using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage;
using oemcrypto_core_message::deserialize::CoreRenewalRequestFromMessage;
using oemcrypto_core_message::serialize::CreateCoreLicenseResponse;
using oemcrypto_core_message::serialize::CreateCoreProvisioningResponse;
using oemcrypto_core_message::serialize::CreateCoreRenewalResponse;
// @ kdo deserialize; odk serialize
static OEMCryptoResult odk_serialize_LicenseRequest(
const void* in, uint8_t* out, size_t* size,
const ODK_LicenseRequest& core_license_request,
const ODK_NonceValues* nonce_values) {
return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values);
}
static OEMCryptoResult odk_serialize_RenewalRequest(
const void* in, uint8_t* out, size_t* size,
const ODK_RenewalRequest& core_renewal, ODK_NonceValues* nonce_values) {
ODK_ClockValues clock{};
memcpy(&clock, in, sizeof(ODK_ClockValues));
uint64_t system_time_seconds = core_renewal.playback_time_seconds;
return ODK_PrepareCoreRenewalRequest(out, SIZE_MAX, size, nonce_values,
&clock, system_time_seconds);
}
static OEMCryptoResult odk_serialize_ProvisioningRequest(
const void* in, uint8_t* out, size_t* size,
const ODK_ProvisioningRequest& core_provisioning,
const ODK_NonceValues* nonce_values) {
const std::string& device_id = core_provisioning.device_id;
return ODK_PrepareCoreProvisioningRequest(
out, SIZE_MAX, size, nonce_values,
reinterpret_cast<const uint8_t*>(device_id.data()), device_id.size());
}
/**
* Template arguments:
* T: kdo deserialize output/odk serialize input structure
* F: kdo deserialize function
* G: odk serialize function
*
* raw bytes -> F deserialize -> struct T -> G serialize -> raw bytes
*/
template <typename T, typename F, typename G>
static roundtrip_fun kdo_odk(const F& kdo_fun, const G& odk_fun) {
auto roundtrip = [&](const uint8_t* in, uint8_t* out, size_t size,
size_t clock_value_size) -> void {
if (size <= clock_value_size) {
return;
}
// Input byte array format: [Clock Values][data to parse]
std::string input(reinterpret_cast<const char*>(in) + clock_value_size,
size - clock_value_size);
T t = {};
if (!kdo_fun(input, &t)) {
return;
}
ODK_NonceValues nonce_values = {t.api_minor_version, t.api_major_version,
t.nonce, t.session_id};
OEMCryptoResult err = odk_fun(in, out, &size, t, &nonce_values);
if (OEMCrypto_SUCCESS != err) {
return;
}
assert(0 == memcmp(in + clock_value_size, out, size));
};
return roundtrip;
}
// @ odk deserialize; kdo serialize
namespace {
struct ODK_ParseLicense_Args {
ODK_NonceValues nonce_values;
uint8_t initial_license_load;
uint8_t usage_entry_present;
uint8_t request_hash[32];
ODK_TimerLimits timer_limits;
ODK_ClockValues clock_values;
};
struct ODK_ParseRenewal_Args {
ODK_NonceValues nonce_values;
uint64_t system_time;
ODK_TimerLimits timer_limits;
ODK_ClockValues clock_values;
};
struct ODK_ParseProvisioning_Args {
ODK_NonceValues nonce_values;
size_t device_id_length;
uint8_t device_id[64];
};
} // namespace
bool convert_byte_to_valid_boolean(const bool* in) {
const int value = *reinterpret_cast<const int*>(in);
return value != 0;
}
static OEMCryptoResult odk_deserialize_LicenseResponse(
const uint8_t* message, size_t core_message_length,
ODK_ParseLicense_Args* a, ODK_NonceValues* nonce_values,
ODK_ParsedLicense* parsed_lic) {
return ODK_ParseLicense(message, SIZE_MAX, core_message_length,
static_cast<bool>(a->initial_license_load),
static_cast<bool>(a->usage_entry_present),
a->request_hash, &a->timer_limits, &a->clock_values,
nonce_values, parsed_lic);
}
static bool kdo_serialize_LicenseResponse(const ODK_ParseLicense_Args* args,
const ODK_ParsedLicense& parsed_lic,
std::string* oemcrypto_core_message) {
const auto& nonce_values = args->nonce_values;
ODK_LicenseRequest core_request{nonce_values.api_minor_version,
nonce_values.api_major_version,
nonce_values.nonce, nonce_values.session_id};
std::string core_request_sha_256(
reinterpret_cast<const char*>(args->request_hash), 32);
return CreateCoreLicenseResponse(
parsed_lic, core_request, core_request_sha_256, oemcrypto_core_message);
}
static OEMCryptoResult odk_deserialize_RenewalResponse(
const uint8_t* buf, size_t len, ODK_ParseRenewal_Args* a,
ODK_NonceValues* nonce_values, ODK_PreparedRenewalRequest* renewal_msg) {
/* Address Sanitizer doesn't like values other than 0 OR 1 for boolean
* variables. Input from fuzzer can be parsed and any random bytes can be
* assigned to boolean variables. Using the workaround to mitigate sanitizer
* errors in fuzzer code and converting random bytes to 0 OR 1.
* This has no negative security impact*/
a->timer_limits.soft_enforce_playback_duration =
convert_byte_to_valid_boolean(
&a->timer_limits.soft_enforce_playback_duration);
a->timer_limits.soft_enforce_rental_duration = convert_byte_to_valid_boolean(
&a->timer_limits.soft_enforce_rental_duration);
uint64_t timer_value = 0;
OEMCryptoResult err =
ODK_ParseRenewal(buf, SIZE_MAX, len, nonce_values, a->system_time,
&a->timer_limits, &a->clock_values, &timer_value);
if (OEMCrypto_SUCCESS == err) {
Message* msg = nullptr;
AllocateMessage(&msg, message_block);
InitMessage(msg, const_cast<uint8_t*>(buf), len);
SetSize(msg, len);
Unpack_ODK_PreparedRenewalRequest(msg, renewal_msg);
assert(ValidMessage(msg));
}
return err;
}
static bool kdo_serialize_RenewalResponse(
const ODK_ParseRenewal_Args* args,
const ODK_PreparedRenewalRequest& renewal_msg,
std::string* oemcrypto_core_message) {
const auto& nonce_values = args->nonce_values;
ODK_RenewalRequest core_request{
nonce_values.api_minor_version, nonce_values.api_major_version,
nonce_values.nonce, nonce_values.session_id, renewal_msg.playback_time};
return CreateCoreRenewalResponse(
core_request, args->timer_limits.initial_renewal_duration_seconds,
oemcrypto_core_message);
}
static OEMCryptoResult odk_deserialize_ProvisioningResponse(
const uint8_t* buf, size_t len, ODK_ParseProvisioning_Args* a,
ODK_NonceValues* nonce_values, ODK_ParsedProvisioning* parsed_prov) {
return ODK_ParseProvisioning(buf, SIZE_MAX, len, nonce_values, a->device_id,
a->device_id_length, parsed_prov);
}
static bool kdo_serialize_ProvisioningResponse(
const ODK_ParseProvisioning_Args* args,
const ODK_ParsedProvisioning& parsed_prov,
std::string* oemcrypto_core_message) {
const auto& nonce_values = args->nonce_values;
if (args->device_id_length > sizeof(args->device_id)) {
return false;
}
ODK_ProvisioningRequest core_request{
nonce_values.api_minor_version, nonce_values.api_major_version,
nonce_values.nonce, nonce_values.session_id,
std::string(reinterpret_cast<const char*>(args->device_id),
args->device_id_length)};
return CreateCoreProvisioningResponse(parsed_prov, core_request,
oemcrypto_core_message);
}
/**
* Template arguments:
* A: struct holding function arguments
* T: odk deserialize output/kdo serialize input structure
* F: odk deserialize function
* G: kdo serialize function
*
* raw bytes -> F deserialize -> struct T -> G serialize -> raw bytes
*/
template <typename A, typename T, typename F, typename G>
static roundtrip_fun odk_kdo(const F& odk_fun, const G& kdo_fun) {
auto roundtrip = [&](const uint8_t* in, uint8_t* out, size_t size,
size_t args_size) -> void {
// Input byte array format: [function arguments][data to parse]
if (args_size > size) {
return;
}
T t = {};
const uint8_t* buf = in + args_size;
std::shared_ptr<A> _args(new A());
A* args = _args.get();
memcpy(args, in, args_size);
args->nonce_values.api_major_version = ODK_MAJOR_VERSION;
args->nonce_values.api_minor_version = ODK_MINOR_VERSION;
/*
* Input random bytes from autofuzz are interpreted by this script as
* [function args][data to parse]. Odk deserialize functions
* expect the nonce values in function args to match with those
* in data to parse which is not possible with random bytes.
* We follow two pass approach.
*
* 1st pass - We copy random bytes into struct t and call kdo serialize
* with function args which will create oemcrypto core message using nonce
* from function args. Now we have a valid oemcrypto core message which is
* formed using nonce_values from function args which acts as input bytes
* for 2nd pass
*
* 2nd pass - oemcrypto core message from 1st pass guarantees that
* nonce_values in [function args] and core message match. we call
* odk_deserialize using nonce from function args and oemcrypto core message
* from 1st pass. Then we call kdo function which generates oemcrypto core
* message2, which should be equal to oemcrypto_core_message which was input
* to 2nd pass
*/
// TODO(ellurubharath): Use structure aware fuzzing
// 1st pass
memcpy(&t, buf, sizeof(t));
std::string oemcrypto_core_message;
if (!kdo_fun(args, t, &oemcrypto_core_message)) {
return;
}
assert(oemcrypto_core_message.size() <= size);
// 2nd pass
ODK_NonceValues nonce_values = args->nonce_values;
OEMCryptoResult result =
odk_fun(reinterpret_cast<const uint8_t*>(oemcrypto_core_message.data()),
oemcrypto_core_message.size(), args, &nonce_values, &t);
if (result != OEMCrypto_SUCCESS) {
return;
}
std::string oemcrypto_core_message2;
if (!kdo_fun(args, t, &oemcrypto_core_message2)) {
return;
}
assert(oemcrypto_core_message == oemcrypto_core_message2);
};
return roundtrip;
}
// @ fuzz raw -> parsed -> raw
static void verify_roundtrip(const uint8_t* in, size_t size,
roundtrip_fun roundtrip, size_t args_size) {
std::vector<uint8_t> _out(size);
auto out = _out.data();
roundtrip(in, out, size, args_size);
}
// Entry point for fuzzer, data is random bytes program gets from autofuzzer
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
verify_roundtrip(data, size,
kdo_odk<ODK_LicenseRequest>(CoreLicenseRequestFromMessage,
odk_serialize_LicenseRequest),
0);
verify_roundtrip(data, size,
kdo_odk<ODK_RenewalRequest>(CoreRenewalRequestFromMessage,
odk_serialize_RenewalRequest),
sizeof(ODK_ClockValues));
verify_roundtrip(
data, size,
kdo_odk<ODK_ProvisioningRequest>(CoreProvisioningRequestFromMessage,
odk_serialize_ProvisioningRequest),
0);
verify_roundtrip(
data, size,
odk_kdo<ODK_ParseLicense_Args, ODK_ParsedLicense>(
odk_deserialize_LicenseResponse, kdo_serialize_LicenseResponse),
sizeof(ODK_ParseLicense_Args));
verify_roundtrip(
data, size,
odk_kdo<ODK_ParseRenewal_Args, ODK_PreparedRenewalRequest>(
odk_deserialize_RenewalResponse, kdo_serialize_RenewalResponse),
sizeof(ODK_ParseRenewal_Args));
verify_roundtrip(data, size,
odk_kdo<ODK_ParseProvisioning_Args, ODK_ParsedProvisioning>(
odk_deserialize_ProvisioningResponse,
kdo_serialize_ProvisioningResponse),
sizeof(ODK_ParseProvisioning_Args));
return 0;
}

View File

@@ -209,8 +209,10 @@ TEST(OdkTest, SerializeFieldsStress) {
TEST(OdkTest, NullRequestTest) {
size_t core_message_length = 0;
ODK_NonceValues nonce_values{0};
ODK_ClockValues clock_values{0};
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
ODK_ClockValues clock_values;
memset(&clock_values, 0, sizeof(clock_values));
// Assert that nullptr does not cause a core dump.
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreLicenseRequest(
@@ -250,10 +252,12 @@ TEST(OdkTest, NullResponseTest) {
uint8_t message[message_size] = {0};
size_t core_message_length = message_size;
uint8_t request_hash[ODK_SHA256_HASH_SIZE] = {0};
ODK_TimerLimits timer_limits{0};
ODK_TimerLimits timer_limits;
ODK_ParsedLicense parsed_license;
ODK_NonceValues nonce_values{0};
ODK_ClockValues clock_values{0};
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
ODK_ClockValues clock_values;
memset(&clock_values, 0, sizeof(clock_values));
// Assert that nullptr does not cause a core dump.
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
@@ -322,7 +326,8 @@ TEST(OdkTest, NullResponseTest) {
TEST(OdkTest, PrepareCoreLicenseRequest) {
uint8_t license_message[ODK_LICENSE_REQUEST_SIZE] = {0};
size_t core_message_length = sizeof(license_message);
ODK_NonceValues nonce_values{0};
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
EXPECT_EQ(OEMCrypto_SUCCESS, ODK_PrepareCoreLicenseRequest(
license_message, sizeof(license_message),
&core_message_length, &nonce_values));
@@ -331,7 +336,8 @@ TEST(OdkTest, PrepareCoreLicenseRequest) {
TEST(OdkTest, PrepareCoreLicenseRequestSize) {
uint8_t license_message[ODK_LICENSE_REQUEST_SIZE] = {0};
size_t core_message_length = sizeof(license_message);
ODK_NonceValues nonce_values{0};
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
// message length smaller than core message length
size_t core_message_length_invalid = core_message_length + 1;
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
@@ -349,8 +355,10 @@ TEST(OdkTest, PrepareCoreLicenseRequestSize) {
TEST(OdkTest, PrepareCoreRenewalRequest) {
uint8_t renewal_message[ODK_RENEWAL_REQUEST_SIZE] = {0};
size_t core_message_length = sizeof(renewal_message);
ODK_NonceValues nonce_values{0};
ODK_ClockValues clock_values{0};
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
ODK_ClockValues clock_values;
memset(&clock_values, 0, sizeof(clock_values));
constexpr uint64_t system_time_seconds = 10;
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreRenewalRequest(
@@ -363,7 +371,8 @@ TEST(OdkTest, PrepareCoreRenewalRequestTimer) {
size_t core_message_length = sizeof(renewal_message);
ODK_NonceValues nonce_values{2, 16, 0, 0};
constexpr uint64_t system_time_seconds = 10;
ODK_ClockValues clock_values_updated{0};
ODK_ClockValues clock_values_updated;
memset(&clock_values_updated, 0, sizeof(clock_values_updated));
// system time smaller than first decrypt time
clock_values_updated.time_of_first_decrypt = system_time_seconds + 1;
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
@@ -383,7 +392,8 @@ TEST(OdkTest, PrepareCoreRenewalRequestTimer) {
TEST(OdkTest, PrepareCoreProvisioningRequest) {
uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
size_t core_message_length = sizeof(provisioning_message);
ODK_NonceValues nonce_values{0};
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
EXPECT_EQ(
OEMCrypto_SUCCESS,
@@ -395,7 +405,8 @@ TEST(OdkTest, PrepareCoreProvisioningRequest) {
TEST(OdkTest, PrepareCoreProvisioningRequestDeviceId) {
uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
size_t core_message_length = sizeof(provisioning_message);
ODK_NonceValues nonce_values{0};
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
uint8_t device_id_invalid[ODK_DEVICE_ID_LEN_MAX + 1] = {0};
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreProvisioningRequest(
@@ -423,7 +434,8 @@ TEST(OdkTest, RenewalRequestRoundtrip) {
const std::vector<ODK_Field> extra_fields = {
{ODK_UINT64, &playback_time, "playback_time"},
};
ODK_ClockValues clock_values = {0};
ODK_ClockValues clock_values;
memset(&clock_values, 0, sizeof(clock_values));
clock_values.time_of_first_decrypt = playback_start;
auto odk_prepare_func = [&](uint8_t* const buf, size_t* size,
ODK_NonceValues* nonce_values) {
@@ -713,6 +725,17 @@ TEST(OdkSizeTest, ProvisioningRequest) {
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE, core_message_length);
}
// Verify the version string contains the right version numbers.
TEST(OdkTest, CheckReleaseVersion) {
// Here are the version numbers.
std::string expected_version = std::to_string(ODK_MAJOR_VERSION) + "." +
std::to_string(ODK_MINOR_VERSION);
// Here is the version string.
EXPECT_NE(std::string(ODK_RELEASE_DATE).find(expected_version),
std::string::npos)
<< "Version mismatch in odk_structs.h";
}
} // namespace
} // namespace wvodk_test

View File

@@ -1,6 +1,6 @@
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine Master */
/* License Agreement. */
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_
#define WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_
@@ -66,7 +66,7 @@ struct ODK_ProvisioningResponseParams {
std::vector<ODK_Field> extra_fields;
};
/* Default values in core_message for testing */
// Default values in core_message for testing
void ODK_SetDefaultCoreFields(ODK_CoreMessage* core_message,
uint32_t message_type);
void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params);
@@ -77,9 +77,9 @@ void ODK_SetDefaultProvisioningResponseParams(
size_t ODK_FieldLength(ODK_FieldType type);
size_t ODK_AllocSize(ODK_FieldType type);
/* Copy ODK_Field to buf */
// Copy ODK_Field to buf
OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field);
/* Load buf to ODK_Field */
// Load buf to ODK_Field
OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf, const ODK_Field* field);
OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf, const ODK_Field* field);
OEMCryptoResult ODK_IterFields(ODK_FieldMode mode, uint8_t* buf,
@@ -89,11 +89,11 @@ void ODK_ExpectEqualBuf(const void* s1, const void* s2, size_t n,
const std::vector<ODK_Field>& fields);
void ODK_ResetOdkFields(std::vector<ODK_Field>* fields);
/* Serialize core_message and extra_fields into buf */
// Serialize core_message and extra_fields into buf
void ODK_BuildMessageBuffer(ODK_CoreMessage* core_message,
const std::vector<ODK_Field>& extra_fields,
uint8_t** buf, uint32_t* buf_size);
} /* namespace wvodk_test */
} // namespace wvodk_test
#endif /* WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_ */
#endif // WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_

View File

@@ -35,6 +35,7 @@ TEST(OdkTimerBasicTest, NullTest) {
TEST(OdkTimerBasicTest, Init) {
// Verify that basic initialization sets all of the fields.
ODK_ClockValues clock_values;
memset(&clock_values, 0, sizeof(clock_values));
uint64_t time = 42;
ODK_InitializeClockValues(&clock_values, time);
EXPECT_EQ(clock_values.time_of_license_signed, time);
@@ -50,6 +51,7 @@ TEST(OdkTimerBasicTest, Reload) {
// Verify that reloading clock values uses the same values
// for fields that can be saved, and sets others to 0.
ODK_ClockValues clock_values;
memset(&clock_values, 0, sizeof(clock_values));
uint64_t time = 42u;
uint64_t lic_signed = 1u;
uint64_t first_decrypt = 2u;
@@ -1223,6 +1225,7 @@ TEST_F(ODKUseCase_LimitedDurationLicense, Case5) {
TEST_F(RenewalTest, V15Test) {
const uint32_t key_duration = 25;
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
const uint64_t license_loaded = GetSystemTime(10);
EXPECT_EQ(
ODK_InitializeV15Values(&timer_limits_, &clock_values_, &nonce_values,