/* 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_ #include #include "OEMCryptoCENCCommon.h" #include "odk_target.h" /* The version of this library. */ #define ODK_MAJOR_VERSION 16 #define ODK_MINOR_VERSION 3 /* ODK Version string. Date changed automatically on each release. */ #define ODK_RELEASE_DATE "ODK v16.3 2020-06-02" /* 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 * * 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. * * 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. */ 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; /* * ODK_ClockValues Structure * * 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". * * 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. */ typedef struct { uint64_t time_of_license_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; /* * ODK_NonceValues Structure * * 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. * * 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. */ typedef struct { uint16_t api_minor_version; uint16_t api_major_version; uint32_t nonce; uint32_t session_id; } ODK_NonceValues; /* * ODK_ParsedLicense Structure * * 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. * * 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. */ 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 key_array_length; OEMCrypto_KeyObject key_array[ODK_MAX_NUM_KEYS]; } ODK_ParsedLicense; /* * ODK_ParsedProvisioning Structure * * 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. * * 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. */ 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; #endif /* WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_ */