// Copyright 2019 Google LLC. This file and proprietary // source code may only be used and distributed under the Widevine // License Agreement. #ifndef WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_ #define WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_ #ifdef __cplusplus extern "C" { #endif #include #include "OEMCryptoCENCCommon.h" #include "odk_target.h" /* The version of this library. */ #define ODK_MAJOR_VERSION 19 #define ODK_MINOR_VERSION 2 /* ODK Version string. Date changed automatically on each release. */ #define ODK_RELEASE_DATE "ODK v19.1 2024-03-25" /* 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 #define ODK_KEYBOX_RENEWAL_DATA_SIZE 1600 /* The max length of the encoded device info in CBOR format. Make sure it gets * updated when more device info is included. Refer to * https://www.rfc-editor.org/rfc/rfc8949.html#name-specification-of-the-cbor-e * for an estimation of the required length. */ #define ODK_DEVICE_INFO_LEN_MAX 768 /// @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. * * @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. * * @version * This struct changed in API version 16.2. */ typedef struct { bool soft_enforce_rental_duration; bool soft_enforce_playback_duration; uint64_t earliest_playback_start_seconds; uint64_t rental_duration_seconds; uint64_t total_playback_duration_seconds; uint64_t initial_renewal_duration_seconds; } ODK_TimerLimits; /** * 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". * * @param time_of_license_request_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. This is * also used to track the start of the rental clock time. * @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. * * @version * This struct changed in API version 16.2. */ typedef struct { uint64_t time_of_license_request_signed; uint64_t time_of_first_decrypt; uint64_t time_of_last_decrypt; uint64_t time_of_renewal_request; uint64_t time_when_timer_expires; uint32_t timer_status; enum OEMCrypto_Usage_Entry_Status status; } ODK_ClockValues; /** * 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. * * @version * This struct changed in API version 16.2. */ typedef struct { uint16_t api_minor_version; uint16_t api_major_version; uint32_t nonce; uint32_t session_id; } ODK_NonceValues; /// @} /// @addtogroup odk_parser /// @{ /** * This counter information is used by the license and provisioning servers to * keep track of requests. Values should be updated after every successful * provisioning request, license request, and decrypt call. * * @param provisioning_count: number of times a provisioning request was made on * this device in the current instance. May be reset to 0 on device power off. * @param license_count: number of times a license request was made on this * device in the current instance. May be reset to 0 on device power off. * @param decrypt_count: number of times OEMCrypto_DecryptCENC() has been called * on this device in the current instance. May be reset to 0 on device power * off. * @param master_generation_number: current master generation number value from * the OEMCrypto usage table. Persists across reboots. * @param soc_vendor: name of the system-on-a-chip vendor for the device, * limited to 16 bytes * @param chipset_model: name of the chipset on the device, limited to 16 bytes * @param major_version: major version of the TA binary. This is different from * the OEMCrypto version that is being implemented. * @param minor_version: minor version of the TA binary, if applicable. This is * different from the OEMCrypto version that is being implemented. * @param patch_version: patch version of the TA binary, if applicable. This is * different from the OEMCrypto version that is being implemented. * @param extra: unused in V18 * * @version * This struct was added in API version 18. */ typedef struct { uint64_t master_generation_number; uint32_t provisioning_count; uint32_t license_count; uint32_t decrypt_count; uint16_t major_version; uint16_t minor_version; uint16_t patch_version; uint8_t soc_vendor[16]; uint8_t chipset_model[16]; uint8_t extra[12]; } ODK_MessageCounterInfo; /** * 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 watermarking: indicates watermarking requirements of the license. * @param dtcp2_required: indicates dtcp2 requirements of the license. * @param renewal_delay_base: indicates which time is used for the renewal timer * and playback timer starting point. * @param key_array_length: number of keys present. * @param key_array: set of keys to be installed. * * @version * This struct changed in API version 18. */ typedef struct { OEMCrypto_Substring enc_mac_keys_iv; OEMCrypto_Substring enc_mac_keys; OEMCrypto_Substring pst; OEMCrypto_Substring srm_restriction_data; OEMCrypto_LicenseType license_type; bool nonce_required; ODK_TimerLimits timer_limits; uint32_t watermarking; OEMCrypto_DTCP2_CMI_Packet dtcp2_required; OEMCrypto_TimerDelayBase renewal_delay_base; uint32_t key_array_length; OEMCrypto_KeyObject key_array[ODK_MAX_NUM_KEYS]; } ODK_ParsedLicense; /** * 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 watermarking: indicates watermarking requirements of the license. * @param dtcp2_required: indicates dtcp2 requirements of the license. * @param renewal_delay_base: indicates which time is used for the renewal timer * and playback timer starting point. * @param key_array_length: number of keys present. * @param key_array: set of keys to be installed. This is a pointer to an array * to allow packing a number of keys greater than |ODK_MAX_NUM_KEYS|. * * @version * This struct changed in API version 18. */ typedef struct { OEMCrypto_Substring enc_mac_keys_iv; OEMCrypto_Substring enc_mac_keys; OEMCrypto_Substring pst; OEMCrypto_Substring srm_restriction_data; OEMCrypto_LicenseType license_type; bool nonce_required; ODK_TimerLimits timer_limits; uint32_t watermarking; OEMCrypto_DTCP2_CMI_Packet dtcp2_required; OEMCrypto_TimerDelayBase renewal_delay_base; uint32_t key_array_length; OEMCrypto_KeyObject* key_array; } ODK_Packing_ParsedLicense; /** * 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. * * @version * This struct changed in API version 16.2. */ typedef struct { OEMCrypto_PrivateKeyType key_type; OEMCrypto_Substring enc_private_key; OEMCrypto_Substring enc_private_key_iv; OEMCrypto_Substring encrypted_message_key; /* Used for Prov 3.0 */ } ODK_ParsedProvisioning; /// @} #ifdef __cplusplus } // extern "C" #endif #endif // WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_