320 lines
14 KiB
C
320 lines
14 KiB
C
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine
|
|
// License Agreement.
|
|
|
|
#ifndef WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
|
|
#define WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "OEMCryptoCENCCommon.h"
|
|
#include "odk_target.h"
|
|
|
|
/* The version of this library. */
|
|
#define ODK_MAJOR_VERSION 19
|
|
#define ODK_MINOR_VERSION 0
|
|
|
|
/* ODK Version string. Date changed automatically on each release. */
|
|
#define ODK_RELEASE_DATE "ODK v19.0 2023-10-13"
|
|
|
|
/* 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_
|