Files
android/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h
Vicky Min 417a9c7b77 Add header functions for license release
Bug: 295956275
Change-Id: I223937ea25544cfb562bc063e75b359e4d908984
2024-02-22 14:33:03 -08:00

5928 lines
269 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine
// License Agreement.
/**
* @mainpage OEMCrypto API v18.4
*
* OEMCrypto is the low level library implemented by the OEM to provide key and
* content protection, usually in a separate secure memory or process space. The
* term *OEMCrypto* refers to both the API described here and the library
* implementing the API.
*
* For an overview of OEMCrypto functionality, please see
* [Widevine Modular DRM Security Integration Guide for Common
* Encryption](../index)
*
* The OEMCrypto API is divided into several sections.
*
* @defgroup initcontrol Initialization and Control API
* Initialization and set up OEMCrypto.
*
* @defgroup keyladder Crypto Key Ladder API
* The crypto key ladder is a mechanism for staging crypto keys for use by the
* hardware crypto engine.
*
* Keys are always encrypted for transmission. Before
* a key can be used, it must be decrypted (typically using the top key in the
* key ladder) and then added to the key ladder for upcoming decryption
* operations. The Crypto Key Ladder API requires the device to provide
* hardware support for AES-128 CTR and CBC modes and prevent clear keys from
* being exposed to the insecure OS.
*
* @defgroup decryption Decryption API
* Devices that implement the Key Ladder API must also support a secure decode
* or secure decode and rendering implementation.
*
* This can be done by either
* decrypting into buffers secured by hardware protections and providing these
* secured buffers to the decoder/renderer or by implementing decrypt operations
* in the decoder/renderer.
*
* In a Security Level 2 implementation where the video path is not protected,
* the audio and video streams are decrypted using OEMCrypto_DecryptCENC() and
* buffers are returned to the media player in the clear.
*
* Generic Modular DRM allows an application to encrypt, decrypt, sign and
* verify arbitrary user data using a content key. This content key is
* securely delivered from the server to the client device using the same
* factory installed root of trust as a media content keys.
*
*
* ![Generic Encrypt and Decrypt flow](fig2.svg)
*
* ![Generic Sign flow](fig3.svg)
*
* ![Generic Verify flow](fig4.svg)
*
* @defgroup factory_provision Factory Provisioning API
* Functions that are used to install the root of trust. This could be either a
* keybox or an OEM Certificate.
*
* Widevine keyboxes are used to establish a root of trust to secure content on
* a device that uses Provisioning 2.0. OEM Certificates are used to establish
* a root of trust to secure content on a device that uses Provisioning
* 3.0. Factory Provisioning a device is related to manufacturing methods. This
* section describes the API that installs the Widevine Keybox and the
* recommended methods for the OEM's factory provisioning procedure.
*
* Devices should support both a production keybox and a temporary test
* keybox. The production keybox is usually installed in the factory, or using
* OEMCrypto_WrapKeyboxOrOEMCert() and OEMCrypto_InstallKeyboxOrOEMCert(). The
* temporary keybox is a test keybox, and is loaded via
* OEMCrypto_LoadTestKeybox() by the unit tests. The test keybox will only be
* used temporarily while the unit tests are running, and will not be used by
* the general public. After the unit tests have been run, and
* OEMCrypto_Terminate() has been called, the production keybox should be active
* again.
*
* API functions marked as optional may be used by the OEM's factory
* provisioning procedure and implemented in the library, but are not called
* from the Widevine DRM Plugin during normal operation.
*
* @defgroup keybox Keybox and Provisioning 2.0 API
* Functions that are needed to for a device with a keybox.
*
* The OEMCrypto API allows for a device to be initially provisioned with a
* keybox or with an OEM certificate. See the section
* [Provisioning](../../index#provisioning) in the integration guide. In a
* Level 1 or Level 2 implementation, only the security processor may access the
* keys in the keybox. The following functions are for devices that are
* provisioned with a keybox, i.e. Provisioning 2.0.
*
* @defgroup oem_cert OEM Certificate and Provisioning 3.0 API
* Functions that are needed to for a device with an OEM Certificate.
*
* The OEMCrypto API allows for a device to be initially provisioned with a
* keybox or with an OEM certificate. See the section
* <a href="../../index#provisioning">Provisioning</a> in the integration guide.
* The functions in this section are for devices that are provisioned with an
* OEM Certificate, i.e. Provisioning 3.0.
*
* API functions marked as optional may be used by the OEM's factory
* provisioning procedure and implemented in the library, but are not called
* from the Widevine DRM Plugin during normal operation.
*
* @defgroup prov40 OEM Certificate and Provisioning 4.0 API
* Functions that are needed process a boot chain certificate.
*
* The OEMCrypto API allows for a device to be initially provisioned with a
* keybox or with an OEM certificate in the factory, or to use a boot chain
* derived by the device using a device specific key.
* See the section <a href="../../index#provisioning">Provisioning</a>
* in the integration guide.
* The functions in this section are for devices that are provisioned with a
* boot chain, i.e. Provisioning 4.0.
*
* @defgroup validation Validation and Feature Support API
* The OEMCrypto API is flexible enough to allow different devices to support
* different features. This section has functions that specify the level of
* support for various features. These values are reported to either the
* application or the license server.
*
* @defgroup drm_cert DRM Certificate Provisioning API
* This section of functions are used to provision the device with a DRM
* certificate. This certificate is obtained by a device in the field from a
* Google/Widevine provisioning server, or from a third party server running the
* Google/Widevine provisioning server SDK. Since the DRM certificate may be
* origin or application specific, a device may have several DRM certificates
* installed at a time. The DRM certificate is used to authenticate the device
* to a license server. In order to obtain a DRM certificate from a
* provisioning server, the device may authenticate itself using a keybox or
* using an OEM certificate.
*
* @defgroup usage_table Usage Table API
* The usage table is used to store license usage and allows a persistent
* license to be reloaded.
*
* @defgroup entitled Entitlement License API
* Functions that are needed for entitled and entitlement licenses.
*
* [Entitlement licensing](../../index#entitlement) is a way to provide access
* to content keys that may be stored elsewhere, such as in the content itself.
* This can be used to implement content key rotation without requiring new
* licenses, or access to multiple pieces of content with a single license.
*
* @defgroup test_verify Test and Verification API
* Functions that are designed to help test OEMCrypto and the device. They are
* not used during normal operation. Some functions, like those that test the
* full decrypt data path may be supported on a production device with no added
* risk of security loss.
*
* The following functions are used just for testing and verification of
* OEMCrypto and the CDM code.
*
* @defgroup common_types Common Types
* Enumerations and structures that are used by several OEMCrypto and ODK
* functions.
*/
#ifndef OEMCRYPTO_CENC_H_
#define OEMCRYPTO_CENC_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "OEMCryptoCENCCommon.h"
#ifdef __cplusplus
extern "C" {
#endif
/// @addtogroup keyladder
/// @{
/// This is the internal session identifier.
typedef uint32_t OEMCrypto_SESSION;
/// @}
/// @addtogroup decryption
/// @{
/**
* The memory referenced by OEMCrypto_SharedMemory* is safe to be placed in
* shared memory. The only data that should be placed into shared
* memory is the contents of input/output buffers, i.e. data that will
* not introduce security vulnerabilities if it is subject to
* modification while being accessed.
*/
typedef uint8_t OEMCrypto_SharedMemory;
/** Specifies destination buffer type.
*/
typedef enum OEMCryptoBufferType {
OEMCrypto_BufferType_Clear,
OEMCrypto_BufferType_Secure,
OEMCrypto_BufferType_Direct,
OEMCrypto_BufferType_MaxValue = OEMCrypto_BufferType_Direct,
} OEMCryptoBufferType;
/**
* This structure is used as parameters in the OEMCrypto_DecryptCENC() and
* OEMCrypto_CopyBuffer() functions. This describes the type and access
* information for the memory to receive decrypted data.
*
* The OEMCrypto API supports a range of client device architectures. Different
* architectures have different methods for acquiring and securing buffers that
* will hold portions of the audio or video stream after decryption. Three basic
* strategies are recognized for handling decrypted stream data:
*
* 1. Return the decrypted data in the clear into normal user memory
* (ClearBuffer). The caller uses normal memory allocation methods to
* acquire a buffer, and supplies the memory address of the buffer in
* the descriptor.
* 2. Place the decrypted data into protected memory (SecureBuffer). The
* caller uses a platform-specific method to acquire the protected
* buffer and a user-memory handle that references it. The handle is
* supplied to the decrypt call in the descriptor. If the buffer is
* filled with several OEMCrypto calls, the same handle will be used,
* and the offset will be incremented to indicate where the next write
* should take place.
* 3. Place the decrypted data directly into the audio or video decoder
* fifo (Direct). The caller will use platform-specific methods to
* initialize the fifo and the decoders. The decrypted stream data is
* not accessible to the caller. This is used on some platforms only.
*
* @param[in] type: A tag that indicates which variant of the union is valid for
* this instance of the structure. [variant] clear: This variant is valid
* when the type is OEMCrypto_BufferType_Clear. This OEMCrypto_DestBufferDesc
* indicates output should be written to a clear buffer.
* @param[in] clear_buffer: A pointer to the address in memory to begin writing
* output.
* @param[in] clear_buffer_length: The length of the buffer that is available to
* contain output. [variant] secure: This variant is valid when the type is
* OEMCrypto_BufferType_Secure. This OEMCrypto_DestBufferDesc indicates
* output should be written to a secure buffer. The decrypted output must
* never leave the secure area until it is output from the device.
* @param[in] secure_buffer: An opaque handle to a secure buffer. The meaning of
* this handle is platform-specific.
* @param[in] secure_buffer_length: The length of the data contained in the
* secure buffer.
* @param[in] offset: An offset indicating where in the secure buffer to start
* writing data. [variant] direct: This variant is valid when the type is
* OEMCrypto_BufferType_Direct. This OEMCrypto_DestBufferDesc indicates
* output should be written directly to the decoder.
* @param[in] is_video: A flag indicating if the data is video and should be
* sent to the video decoder. If this is false, the data can be assumed to be
* audio and sent to the audio decoder.
*
* @version
* This struct changed in API version 16.
*/
typedef struct {
OEMCryptoBufferType type;
union {
struct { // type == OEMCrypto_BufferType_Clear
OEMCrypto_SharedMemory* clear_buffer;
size_t clear_buffer_length;
} clear;
struct { // type == OEMCrypto_BufferType_Secure
void* secure_buffer;
size_t secure_buffer_length;
size_t offset;
} secure;
struct { // type == OEMCrypto_BufferType_Direct
bool is_video;
} direct;
} buffer;
} OEMCrypto_DestBufferDesc;
/**
* This structure is used as parameters in the OEMCrypto_DecryptCENC() function.
*
* @param[in] input_data: An unaligned pointer to this sample from the stream.
* @param[in] input_data_length: The length of this sample in the stream, in
* bytes.
* @param[in] output_descriptor: A caller-owned descriptor that specifies the
* handling of the decrypted byte stream. See OEMCrypto_DestbufferDesc for
* details.
*
* @version
* This struct changed in API version 16.
*/
typedef struct {
const OEMCrypto_SharedMemory* input_data; // source for encrypted data.
size_t input_data_length; // length of encrypted data.
OEMCrypto_DestBufferDesc output_descriptor; // destination for clear data.
} OEMCrypto_InputOutputPair;
/**
* This structure is used as parameters in the OEMCrypto_DecryptCENC()
* function. In the DASH specification, a sample is composed of multiple
* samples, and each subsample is composed of two regions. The first region is
* clear unprotected data. We also call this clear data or unencrypted
* data. Immediately following the clear region is the protected region. The
* protected region is encrypted or encrypted with a pattern. The pattern and
* number of bytes that are encrypted in the protected region is discussed in
* this document when we talk about the function OEMCryptoDecryptCENC. For
* historic reasons, this document also calls the protected region the encrypted
* region.
*
* @param[in] num_bytes_clear: The number of unprotected bytes in this
* subsample. The clear bytes come before the encrypted bytes.
* @param[in] num_bytes_encrypted: The number of protected bytes in this
* subsample. The protected bytes come after the clear bytes.
* @param[in] subsample_flags: bitwise flags indicating if this is the first,
* middle, or last subsample in a sample. 1 = first subsample, 2 = last
* subsample, 3 = both first and last subsample, 0 = neither first nor last
* subsample.
* @param[in] block_offset: This will only be non-zero for the 'cenc' scheme.
* If it is non-zero, the decryption block boundary is different from the
* start of the data. block_offset should be subtracted from data to compute
* the starting address of the first decrypted block. The bytes between the
* decryption block start address and data are discarded after decryption. It
* does not adjust the beginning of the source or destination data. This
* parameter satisfies 0 <= block_offset < 16.
*
* @version
* This struct changed in API version 16.
*/
typedef struct {
size_t num_bytes_clear;
size_t num_bytes_encrypted;
uint8_t subsample_flags; // is this the first/last subsample in a sample?
size_t block_offset; // used for CTR "cenc" mode only.
} OEMCrypto_SubSampleDescription;
#define OEMCrypto_FirstSubsample 1
#define OEMCrypto_LastSubsample 2
/**
* This structure is used as parameters in the OEMCrypto_DecryptCENC() function.
*
* @param[in] buffers: A structure containing information about the input and
* output buffers.
* @param[in] iv: A 16-byte array containing the IV for the initial subsample of
* the sample.
* @param[in] subsamples: A caller-owned array of OEMCrypto_SubSampleDescription
* structures. Each entry in this array describes one subsample in the
* sample.
* @param[in] subsamples_length: The length of the array pointed to by the
* subsamples parameter.
*
* @version
* This struct changed in API version 16.
*/
typedef struct {
OEMCrypto_InputOutputPair buffers; // The source and destination buffers.
uint8_t iv[16]; // The IV for the initial subsample.
const OEMCrypto_SubSampleDescription* subsamples; // subsamples array.
size_t subsamples_length; // the number of subsamples in the sample.
} OEMCrypto_SampleDescription;
/**
* This structure is used as parameters in the OEMCrypto_DecryptCENC() function.
*
* Fields:
* @param[in] encrypt: The number of 16-byte crypto blocks to encrypt.
* @param[in] skip: The number of 16-byte crypto blocks to leave in the clear.
*
* @version
* This struct changed in API version 16.
*/
typedef struct {
size_t encrypt; // number of 16 byte blocks to decrypt.
size_t skip; // number of 16 byte blocks to leave in clear.
} OEMCrypto_CENCEncryptPatternDesc;
/**
* OEMCryptoCipherMode is used in OEMCrypto_GetKeyHandle() to prepare a key for
* decryption.
*/
typedef enum OEMCryptoCipherMode {
// explicit cipher modes used for modular DRM
OEMCrypto_CipherMode_CENC,
OEMCrypto_CipherMode_CBCS,
// cipher modes used for CAS
OEMCrypto_CipherMode_CTR,
OEMCrypto_CipherMode_CBC,
OEMCrypto_CipherMode_CSA2,
OEMCrypto_CipherMode_CSA3,
OEMCrypto_CipherMode_OFB,
OEMCrypto_CipherMode_SCTE,
OEMCrypto_CipherMode_ECB,
OEMCrypto_CipherMode_MaxValue = OEMCrypto_CipherMode_ECB,
} OEMCryptoCipherMode;
/**
* This is a list of valid algorithms for OEMCrypto_Generic_* functions.
* Some are valid for encryption/decryption, and some for signing/verifying.
*/
typedef enum OEMCrypto_Algorithm {
OEMCrypto_AES_CBC_128_NO_PADDING = 0,
OEMCrypto_HMAC_SHA256 = 1,
OEMCrypto_Algorithm_MaxValue = 1,
} OEMCrypto_Algorithm;
/// @}
/// @addtogroup entitled
/// @{
/**
* Contains encrypted content key data for loading into the sessions keytable.
* The content key data is encrypted using AES-256-CBC encryption, with PKCS#7
* padding.
* @param entitlement_key_id: entitlement key id to be matched to key table.
* @param content_key_id: content key id to be loaded into key table.
* @param key_data_iv: the IV for performing AES-256-CBC decryption of the key
* data.
* @param key_data: encrypted content key data.
* @param content_iv: the IV for decrypting media content. Used by CAS only.
* @param cipher_mode: the encryption mode of the media content. Used by CAS
* only.
*/
typedef struct {
OEMCrypto_Substring entitlement_key_id;
OEMCrypto_Substring content_key_id;
OEMCrypto_Substring content_key_data_iv;
OEMCrypto_Substring content_key_data;
OEMCrypto_Substring content_iv;
OEMCryptoCipherMode cipher_mode;
} OEMCrypto_EntitledContentKeyObject;
/// @}
/// @addtogroup usage_table
/// @{
#if 0 // If your compiler supports __attribute__((packed)).
/**
* OEMCrypto_PST_Report is used to report an entry from the Usage Table.
*
* Platforms that have compilers that support packed structures, may use the
* following definition. Other platforms may use the header pst_report.h which
* defines a wrapper class.
*
* All fields are in network byte order.
*/
typedef struct {
uint8_t signature[20]; // -- HMAC SHA1 of the rest of the report.
uint8_t status; // current status of entry. (OEMCrypto_Usage_Entry_Status)
uint8_t clock_security_level;
uint8_t pst_length;
uint8_t padding; // make int64's word aligned.
int64_t seconds_since_license_received; // now - time_of_license_received
int64_t seconds_since_first_decrypt; // now - time_of_first_decrypt
int64_t seconds_since_last_decrypt; // now - time_of_last_decrypt
uint8_t pst[];
} __attribute__((packed)) OEMCrypto_PST_Report;
#endif
/**
* Valid values for clock_security_level in OEMCrypto_PST_Report.
*/
typedef enum OEMCrypto_Clock_Security_Level {
kInsecureClock = 0,
kMonotonicClock = 1,
kSecureTimer = 1, // DEPRECATED. Do not use.
kSecureClock = 2,
kHardwareSecureClock = 3
} OEMCrypto_Clock_Security_Level;
typedef uint8_t RSA_Padding_Scheme;
// RSASSA-PSS with SHA1.
#define kSign_RSASSA_PSS ((RSA_Padding_Scheme)0x1)
// PKCS1 with block type 1 padding (only).
#define kSign_PKCS1_Block1 ((RSA_Padding_Scheme)0x2)
/// @}
/// @addtogroup validation
/// @{
/**
* OEMCrypto_HDCP_Capability is used in the key control block to enforce HDCP
* level, and in GetHDCPCapability for reporting.
*/
typedef enum OEMCrypto_HDCP_Capability {
HDCP_NONE = 0, // No HDCP supported, no secure data path.
HDCP_V1 = 1, // HDCP version 1.x
HDCP_V2 = 2, // HDCP version 2.0 Type 1.
HDCP_V2_1 = 3, // HDCP version 2.1 Type 1.
HDCP_V2_2 = 4, // HDCP version 2.2 Type 1.
HDCP_V2_3 = 5, // HDCP version 2.3 Type 1.
// For backwards compatibility, these values are added after the V2 fields.
// However, it is optional for devices and they can still report HDCP_V1.
HDCP_V1_0 = 6,
HDCP_V1_1 = 7,
HDCP_V1_2 = 8,
HDCP_V1_3 = 9,
HDCP_V1_4 = 10,
HDCP_NO_DIGITAL_OUTPUT = 0xff // No digital output.
} OEMCrypto_HDCP_Capability;
/**
* OEMCrypto_DTCP2_Capability is used in OEMCrypto_GetDTCP2Capability
* for reporting the level of DTCP2 support for a device.
*/
typedef enum OEMCrypto_DTCP2_Capability {
OEMCrypto_NO_DTCP2 = 0, // DTCP2 is not supported.
OEMCrypto_DTCP2_V1 = 1, // At least v1 of DTCP2 is supported.
} OEMCrypto_DTCP2_Capability;
/**
Return value for OEMCrypto_GetProvisioningMethod().
*/
typedef enum OEMCrypto_ProvisioningMethod {
OEMCrypto_ProvisioningError = 0, // Device cannot be provisioned.
// Device has baked in DRM certificate (level 3 only).
OEMCrypto_DrmCertificate = 1,
// Device has factory installed unique keybox.
OEMCrypto_Keybox = 2,
// Device has factory installed OEM certificate.
OEMCrypto_OEMCertificate = 3,
// Device has Boot Certificate Chain (BCC).
OEMCrypto_BootCertificateChain = 4
} OEMCrypto_ProvisioningMethod;
/**
Return value for OEMCrypto_GetWatermarkingSupport().
*/
typedef enum OEMCrypto_WatermarkingSupport {
OEMCrypto_WatermarkingError = 0,
OEMCrypto_WatermarkingNotSupported = 1,
OEMCrypto_WatermarkingConfigurable = 2,
OEMCrypto_WatermarkingAlwaysOn = 3,
} OEMCrypto_WatermarkingSupport;
/**
Return value for OEMCrypto_GetSignatureHashAlgorithm().
*/
typedef enum OEMCrypto_SignatureHashAlgorithm {
OEMCrypto_SHA1 = 0,
OEMCrypto_SHA2_256 = 1,
OEMCrypto_SHA2_384 = 2,
OEMCrypto_SHA2_512 = 3,
} OEMCrypto_SignatureHashAlgorithm;
/**
* Flags indicating public/private key types supported.
*/
#define OEMCrypto_Supports_RSA_2048bit 0x1
#define OEMCrypto_Supports_RSA_3072bit 0x2
#define OEMCrypto_Supports_RSA_CAST 0x10
#define OEMCrypto_Supports_ECC_secp256r1 0x100
#define OEMCrypto_Supports_ECC_secp384r1 0x200
#define OEMCrypto_Supports_ECC_secp521r1 0x400
/**
* Flags indicating full decrypt path hash supported.
*/
#define OEMCrypto_Hash_Not_Supported 0
#define OEMCrypto_CRC_Clear_Buffer 1
#define OEMCrypto_Partner_Defined_Hash 2
/**
* Return values from OEMCrypto_GetAnalogOutputFlags.
*/
#define OEMCrypto_No_Analog_Output 0x0
#define OEMCrypto_Supports_Analog_Output 0x1
#define OEMCrypto_Can_Disable_Analog_Ouptput 0x2
#define OEMCrypto_Supports_CGMS_A 0x4
// Unknown_Analog_Output is used only for backwards compatibility.
#define OEMCrypto_Unknown_Analog_Output (1 << 31)
/// @}
/**
* Obfuscation Renames.
*
* The function signatures of each oecc obfuscated name should remain static
* across multiple versions. When we want to change the function signature of a
* function, we will give the new signature a new oecc number and keep the
* original oecc name with the original function signature. This allows us to
* maintain backwards compatibility when the CDM loads an older version of
* liboemcrypto.so using dlopen.
*/
// clang-format off
#define OEMCrypto_Initialize _oecc01
#define OEMCrypto_Terminate _oecc02
#define OEMCrypto_InstallKeybox _oecc03
// Rename InstallKeybox to InstallKeyboxOrOEMCert.
#define OEMCrypto_InstallRootKeyCertificate _oecc03
#define OEMCrypto_InstallKeyboxOrOEMCert _oecc03
#define OEMCrypto_GetKeyData _oecc04
#define OEMCrypto_IsKeyboxValid _oecc05
// Rename IsKeyboxValid to IsKeyboxOrOEMCertValid.
#define OEMCrypto_IsRootKeyCertificateValid _oecc05
#define OEMCrypto_IsKeyboxOrOEMCertValid _oecc05
#define OEMCrypto_GetRandom _oecc06
#define OEMCrypto_GetDeviceID _oecc07
#define OEMCrypto_WrapKeybox _oecc08
// Rename WrapKeybox to WrapKeyboxOrOEMCert
#define OEMCrypto_WrapRootKeyCertificate _oecc08
#define OEMCrypto_WrapKeyboxOrOEMCert _oecc08
#define OEMCrypto_OpenSession _oecc09
#define OEMCrypto_CloseSession _oecc10
#define OEMCrypto_DecryptCTR_V10 _oecc11
#define OEMCrypto_GenerateDerivedKeys_V15 _oecc12
#define OEMCrypto_GenerateSignature _oecc13
#define OEMCrypto_GenerateNonce _oecc14
#define OEMCrypto_LoadKeys_V8 _oecc15
#define OEMCrypto_RefreshKeys_V14 _oecc16
#define OEMCrypto_SelectKey_V13 _oecc17
#define OEMCrypto_RewrapDeviceRSAKey _oecc18
#define OEMCrypto_LoadDeviceRSAKey _oecc19
#define OEMCrypto_GenerateRSASignature_V8 _oecc20
#define OEMCrypto_DeriveKeysFromSessionKey_V18 _oecc21
#define OEMCrypto_APIVersion _oecc22
#define OEMCrypto_SecurityLevel_V16 _oecc23
#define OEMCrypto_Generic_Encrypt_V17 _oecc24
#define OEMCrypto_Generic_Decrypt_V17 _oecc25
#define OEMCrypto_Generic_Sign_V17 _oecc26
#define OEMCrypto_Generic_Verify_V17 _oecc27
#define OEMCrypto_GetHDCPCapability_V9 _oecc28
#define OEMCrypto_SupportsUsageTable _oecc29
#define OEMCrypto_UpdateUsageTable _oecc30
#define OEMCrypto_DeactivateUsageEntry_V12 _oecc31
#define OEMCrypto_ReportUsage _oecc32
#define OEMCrypto_DeleteUsageEntry _oecc33
#define OEMCrypto_DeleteOldUsageTable _oecc34
#define OEMCrypto_LoadKeys_V9_or_V10 _oecc35
#define OEMCrypto_GenerateRSASignature _oecc36
#define OEMCrypto_GetMaxNumberOfSessions _oecc37
#define OEMCrypto_GetNumberOfOpenSessions _oecc38
#define OEMCrypto_IsAntiRollbackHwPresent _oecc39
#define OEMCrypto_CopyBuffer_V14 _oecc40
#define OEMCrypto_QueryKeyControl _oecc41
#define OEMCrypto_LoadTestKeybox_V13 _oecc42
#define OEMCrypto_ForceDeleteUsageEntry _oecc43
#define OEMCrypto_GetHDCPCapability _oecc44
#define OEMCrypto_LoadTestRSAKey _oecc45
#define OEMCrypto_Security_Patch_Level _oecc46
#define OEMCrypto_LoadKeys_V11_or_V12 _oecc47
#define OEMCrypto_DecryptCENC_V15 _oecc48
#define OEMCrypto_GetProvisioningMethod _oecc49
#define OEMCrypto_GetOEMPublicCertificate_V15 _oecc50
#define OEMCrypto_RewrapDeviceRSAKey30 _oecc51
#define OEMCrypto_SupportedCertificates _oecc52
#define OEMCrypto_IsSRMUpdateSupported _oecc53
#define OEMCrypto_GetCurrentSRMVersion _oecc54
#define OEMCrypto_LoadSRM _oecc55
#define OEMCrypto_LoadKeys_V13 _oecc56
#define OEMCrypto_RemoveSRM _oecc57
#define OEMCrypto_CreateUsageTableHeader _oecc61
#define OEMCrypto_LoadUsageTableHeader _oecc62
#define OEMCrypto_CreateNewUsageEntry _oecc63
#define OEMCrypto_LoadUsageEntry _oecc64
#define OEMCrypto_UpdateUsageEntry _oecc65
#define OEMCrypto_DeactivateUsageEntry _oecc66
#define OEMCrypto_ShrinkUsageTableHeader _oecc67
#define OEMCrypto_MoveEntry _oecc68
#define OEMCrypto_CopyOldUsageEntry _oecc69
#define OEMCrypto_CreateOldUsageEntry _oecc70
#define OEMCrypto_GetAnalogOutputFlags _oecc71
#define OEMCrypto_LoadTestKeybox _oecc78
#define OEMCrypto_LoadEntitledContentKeys_V14 _oecc79
#define OEMCrypto_SelectKey _oecc81
#define OEMCrypto_LoadKeys_V14 _oecc82
#define OEMCrypto_LoadKeys _oecc83
#define OEMCrypto_SetSandbox _oecc84
#define OEMCrypto_ResourceRatingTier _oecc85
#define OEMCrypto_SupportsDecryptHash _oecc86
#define OEMCrypto_InitializeDecryptHash _oecc87
#define OEMCrypto_SetDecryptHash_V18 _oecc88
#define OEMCrypto_GetHashErrorCode _oecc89
#define OEMCrypto_BuildInformation_V16 _oecc90
#define OEMCrypto_RefreshKeys _oecc91
#define OEMCrypto_LoadEntitledContentKeys_V16 _oecc92
#define OEMCrypto_CopyBuffer _oecc93
#define OEMCrypto_MaximumUsageTableHeaderSize _oecc94
#define OEMCrypto_GenerateDerivedKeys_V18 _oecc95
#define OEMCrypto_PrepAndSignLicenseRequest _oecc96
#define OEMCrypto_PrepAndSignRenewalRequest _oecc97
#define OEMCrypto_PrepAndSignProvisioningRequest _oecc98
#define OEMCrypto_LoadLicense_V18 _oecc99
#define OEMCrypto_LoadRenewal _oecc101
#define OEMCrypto_LoadProvisioning_V18 _oecc102
#define OEMCrypto_LoadOEMPrivateKey _oecc103
#define OEMCrypto_GetOEMPublicCertificate _oecc104
#define OEMCrypto_DecryptCENC_V17 _oecc105
#define OEMCrypto_LoadDRMPrivateKey _oecc107
#define OEMCrypto_MinorAPIVersion _oecc108
#define OEMCrypto_AllocateSecureBuffer _oecc109
#define OEMCrypto_FreeSecureBuffer _oecc110
#define OEMCrypto_CreateEntitledKeySession _oecc111
#define OEMCrypto_RemoveEntitledKeySession _oecc112
#define OEMCrypto_GenerateOTARequest _oecc113
#define OEMCrypto_ProcessOTAKeybox _oecc114
#define OEMCrypto_OPK_SerializationVersion _oecc115
#define OEMCrypto_GetBootCertificateChain _oecc116
#define OEMCrypto_GenerateCertificateKeyPair _oecc117
#define OEMCrypto_InstallOemPrivateKey _oecc118
#define OEMCrypto_ReassociateEntitledKeySession _oecc119
#define OEMCrypto_LoadCasECMKeys _oecc120
#define OEMCrypto_LoadEntitledContentKeys _oecc121
#define OEMCrypto_ProductionReady _oecc122
#define OEMCrypto_Idle _oecc123
#define OEMCrypto_Wake _oecc124
#define OEMCrypto_BuildInformation _oecc125
#define OEMCrypto_SecurityLevel _oecc126
#define OEMCrypto_ReuseUsageEntry _oecc127
#define OEMCrypto_GetDTCP2Capability _oecc128
#define OEMCrypto_GetWatermarkingSupport _oecc129
#define OEMCrypto_GetOEMKeyToken _oecc130
#define OEMCrypto_GetDeviceInformation _oecc131
#define OEMCrypto_SetMaxAPIVersion _oecc132
#define OEMCrypto_GetKeyHandle _oecc133
#define OEMCrypto_DecryptCENC _oecc134
#define OEMCrypto_Generic_Encrypt _oecc135
#define OEMCrypto_Generic_Decrypt _oecc136
#define OEMCrypto_Generic_Sign _oecc137
#define OEMCrypto_Generic_Verify _oecc138
#define OEMCrypto_GetSignatureHashAlgorithm _oecc139
#define OEMCrypto_EnterTestMode _oecc140
#define OEMCrypto_GetDeviceSignedCsrPayload _oecc141
#define OEMCrypto_FactoryInstallBCCSignature _oecc142
#define OEMCrypto_SetDecryptHash _oecc143
#define OEMCrypto_LoadLicense _oecc144
#define OEMCrypto_LoadProvisioning _oecc145
#define OEMCrypto_LoadProvisioningCast _oecc146
#define OEMCrypto_PrepAndSignLicenseRelease _oecc147
#define OEMCrypto_GetUsageEntryInfo _oecc148
// clang-format on
/// @addtogroup initcontrol
/// @{
/** Specifies whether system is in idle mode.
*/
typedef enum OEMCrypto_IdleState {
OEMCrypto_NoCryptoActivity = 0, // The system is not idle, but OEMCrypto is.
OEMCrypto_CpuSuspend = 1,
} OEMCrypto_IdleState;
/**
* This tells OEMCrypto which sandbox the current process belongs to. Any
* persistent memory used to store the generation number should be associated
* with this sandbox id. OEMCrypto can assume that this sandbox will be tied
* to the current process or VM until OEMCrypto_Terminate() is called. See the
* section [VM and Sandbox Support](../../index#sandbox) for more details.
*
* If OEMCrypto does not support sandboxes, it will return
* OEMCrypto_ERROR_NOT_IMPLEMENTED. On most platforms, this function will
* just return OEMCrypto_ERROR_NOT_IMPLEMENTED. If OEMCrypto supports
* sandboxes, this function returns OEMCrypto_SUCCESS on success, and
* OEMCrypto_ERROR_UNKNOWN_FAILURE on failure.
*
* The CDM layer will call OEMCrypto_SetSandbox() once before
* OEMCrypto_Initialize(). After this function is called and returns success,
* it will be OEMCrypto's responsibility to keep calls to usage table
* functions separate, and to accept a call to OEMCrypto_Terminate() for each
* sandbox.
*
* @param[in] sandbox_id: a short string unique to the current sandbox.
* @param[in] sandbox_id_length: length of sandbox_id.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INIT_FAILED failed to initialize crypto hardware
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED sandbox functionality not supported
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system. It is called once before
* OEMCrypto_Initialize().
*
* @version
* This method is new in version 15 of the API.
*/
OEMCryptoResult OEMCrypto_SetSandbox(const uint8_t* sandbox_id,
size_t sandbox_id_length);
/**
* Initialize the crypto firmware/hardware.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INIT_FAILED failed to initialize crypto hardware
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system.
*
* @version
* This method is supported by all API versions.
*/
OEMCryptoResult OEMCrypto_Initialize(void);
/**
* Specify the maximum OEMCrypto API version supported by the CDM layer above
* OEMCrypto. If OEMCrypto can support multiple versions then it must restrict
* itself to this version number. If OEMCrypto only supports one version, then
* it may ignore this function and return
* ERROR_NOT_IMPLEMENTED. OEMCrypto_SetMaxAPIVersion will be called after
* OEMCrypto_Initialize() and before any other functions.
*
* @param[in] max_version: the maximum version of OEMCrypto supported by CDM
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED function not implemented
* @retval other any other error
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system.
*
* @version
* This method is new in API version 18.
*/
OEMCryptoResult OEMCrypto_SetMaxAPIVersion(uint32_t max_version);
/**
* Closes the crypto operation and releases all related resources.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_TERMINATE_FAILED failed to de-initialize crypto
* hardware
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system. No other functions will be called before the
* system is re-initialized.
*
* @version
* This method is supported by all API versions.
*/
OEMCryptoResult OEMCrypto_Terminate(void);
/**
* If possible, OEMCrypto may reduce power consumption or other resources. For
* example, it may be possible to reduce the CPU clock rates. When the system
* is in idle mode, then the CDM will not call OEMCrypto_GetHDCPCapability.
*
* This function is not required -- OEMCrypto may ignore this function. It is
* only used to improve performance. This function may return
* OEMCrypto_ERROR_NOT_IMPLEMENTED to indicate it is not supported.
*
* OEMCrypto_Idle may be called multiple times with no call to OEMCrypto_Wake
* in between. A call to OEMCrypto_Idle with different values of
* OEMCrypto_IdleState or os_specific_code may happen in any order. It is
* OEMCryptos responsibility to choose the appropriate behavior for improving
* power consumption. In particular, OEMCrypto may be notified of the
* OEMCrypto_NoCryptoActivity state before or after a notification of the
* OEMCrypto_CpuSuspend state, or OEMCrypto_NoCryptoActivity may not be notified
* at all. On some platforms, a call with OEMCrypto_CpuSuspend may never
* happen.
*
* The acceptable values of `os_specific_code` must be coordinated between the
* OS and the OEMCrypto vendor. On some platforms, for example Android, only
* the value of 0 will be used. For other platforms, it is the responsibility
* of the OEM device maker to coordinate with the SOC to define acceptable
* values of `os_specific_code`.
*
* @param[in] state: The idle state. This indicates if the call came from
* the OS or the CDM.
* @param[in] os_specific_code: Specified by the platform or OS for extra
* sleep information.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system. No other functions will be called before the
* system is re-initialized.
*
* @version
* This method is supported by all API versions.
*/
OEMCryptoResult OEMCrypto_Idle(OEMCrypto_IdleState state,
uint32_t os_specific_code);
/**
* The new function OEMCrypto_Wake will be called to indicate that crypto
* operations will resume. A call to OEMCrypto_Wake after the system is already
* awake shall have no effect. If OEMCrypto cannot recover from being idle, it
* may return OEMCrypto_ERROR_SESSION_LOST_STATE or
* OEMCrypto_ERROR_SYSTEM_INVALIDATED.
*
* The CDM layer may postpone a call to OEMCrypto_Wake until Widevine activity
* is starting. This may happen long after the CPU wakes up.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system. No other functions will be called before the
* system is re-initialized.
*
* @version
* This method is supported by all API versions.
*/
OEMCryptoResult OEMCrypto_Wake(void);
/// @}
/// @addtogroup keyladder
/// @{
/**
* Open a new crypto security engine context. The security engine hardware
* and firmware shall acquire resources that are needed to support the
* session, and return a session handle that identifies that session in
* future calls.
*
* This function shall call ODK_InitializeSessionValues to initialize the
* session's clock values, timer values, and nonce values.
* ODK_InitializeSessionValues is described in the document "License Duration
* and Renewal", to initialize the session's clock values.
*
* @param[out] session: an opaque handle that the crypto firmware uses to
* identify the session.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_TOO_MANY_SESSIONS failed because too many sessions
* are open
* @retval OEMCrypto_ERROR_OPEN_SESSION_FAILED there is a resource issue or the
* security engine is not properly initialized.
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Session Initialization Function" and will not be called
* simultaneously with any other function, as if the CDM holds a write lock
* on the OEMCrypto system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session);
/**
* Closes the crypto security engine session and frees any associated
* resources. If this session is associated with a Usage Entry, all resident
* memory associated with it will be freed. It is the CDM layer's
* responsibility to call OEMCrypto_UpdateUsageEntry() before closing the
* session.
*
* @param[in] session: handle for the session to be closed.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_SESSION no open session with that id.
* @retval OEMCrypto_ERROR_CLOSE_SESSION_FAILED illegal/unrecognized handle or
* the security engine is not properly initialized.
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Session Initialization Function" and will not be called
* simultaneously with any other function, as if the CDM holds a write lock
* on the OEMCrypto system.
*
* @version
* This method changed in API version 13.
*/
OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session);
/**
* Generates a 32-bit nonce to detect possible replay attack on the key
* control block. The nonce is stored in secure memory and will be used in
* the license or provisioning request.
*
* Because the nonce will be used to prevent replay attacks, it is desirable
* that a rogue application cannot rapidly call this function until a
* repeated nonce is created randomly. This is called a nonce flood. With
* this in mind, if more than 200 nonces are requested within one second,
* OEMCrypto will return an error after the 200th and not generate any more
* nonces for the rest of the second. After an error, if the application
* waits at least one second before requesting more nonces, then OEMCrypto
* will reset the error condition and generate valid nonces again.
*
* The nonce should be stored in the session's ODK_NonceValue field by
* calling the function ODK_SetNonceValue(&nonce_values, nonce). The ODK
* functions are documented in "Widevine Core Message Serialization".
*
* This function shall only be called at most once per open session. It shall
* only be called before signing either a provisioning request or a license
* request. If an attempt is made to generate a nonce while in the wrong
* state, an error of OEMCrypto_ERROR_INVALID_CONTEXT is returned.
*
* @param[in] session: handle for the session to be used.
* @param[out] nonce: pointer to memory to receive the computed nonce.
*
* Results:
* nonce: the nonce is also stored in secure memory.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Session Initialization Function" and will not be called
* simultaneously with any other function, as if the CDM holds a write lock
* on the OEMCrypto system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
uint32_t* nonce);
/**
* OEMCrypto will use ODK_PrepareCoreLicenseRequest to prepare the core
* message. If it returns OEMCrypto_SUCCESS, then OEMCrypto shall sign the
* message body using the DRM certificate's private key. If it returns an
* error, the error should be returned by OEMCrypto to the CDM layer.
* ODK_PrepareCoreLicenseRequest is described in the document "Widevine Core
* Message Serialization".
*
* The message body is the buffer starting at message + core_message_size,
* and with length message_length - core_message_size.
*
* If the session's private RSA key has an "allowed_schemes" bit field, then
* it must be 0x1 (RSASSA-PSS with SHA1). If not, then an error of
* OEMCrypto_ERROR_SIGNATURE_FAILURE shall be returned.
*
* OEMCrypto shall also call the function ODK_InitializeClockValues,
* described in the document "License Duration and Renewal", to initialize
* the session's clock values.
*
* Refer to the Signing Messages Sent to a Server section above for more
* details about the signature algorithm.
*
* Starting in OEMCrypto v19, the |message| buffer must be hashed using SHA512
* before signing.
*
* NOTE: if signature pointer is null and/or input signature_length is zero,
* this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* signature_length to the size needed to receive the output signature.
*
* @param[in] session: handle for the session to be used.
* @param[in,out] message: Pointer to memory for the entire message. Modified by
* OEMCrypto via 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[out] signature: pointer to memory to receive the computed signature.
* @param[in,out] signature_length: (in) length of the signature buffer, in
* bytes. (out) actual length of the signature, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough
* to hold the signature.
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_INVALID_KEY if the session's private key is not a
* DRM key.
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 17.
*/
OEMCryptoResult OEMCrypto_PrepAndSignLicenseRequest(
OEMCrypto_SESSION session, uint8_t* message, size_t message_length,
size_t* core_message_size, uint8_t* signature, size_t* signature_length);
/**
* This function replaces both OEMCrypto_DeactivateUsageEntry and
* OEMCrypto_ReportUsage. As with other OEMCrypto_PrepAndSign* functions, it
* first verifies that the core_message_size is the right size. If not, it
* returns OEMCrypto_ERROR_SHORT_BUFFER.
* OEMCrypto will change the status of the usage entry to InactiveUsed if it was
* Active, or InactiveUnused if it was Unused. This also increments the entry's
* generation number by 2, and the header's master generation number. The
* corresponding generation number in the usage table header is also incremented
* so that it matches the one in the entry.
*
* OEMCrypto will use ODK_PrepareCoreLicenseRelease to prepare the core
* message. If it returns OEMCrypto_SUCCESS, then OEMCrypto shall sign the
* message body using the DRM certificate's private key. If it returns an
* error, the error should be returned by OEMCrypto to the CDM layer.
* ODK_PrepareCoreLicenseRelease is described in the document "Widevine Core
* Message Serialization".
*
* This function generates a HMAC-SHA256 signature using the mac_key[client]
* for license release signing under the license server protocol for CENC.
*
* The key used for signing should be the mac_key[client] that was generated
* for this session or loaded for this session by
* OEMCrypto_LoadLicense() or OEMCrypto_LoadUsageEntry().
*
* NOTE: if signature pointer is null and/or input signature_length is zero,
* this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* signature_length to the size needed to receive the output signature.
*
* @param[in] session: handle for the session to be used.
* @param[in,out] message: Pointer to memory for the entire message. Modified by
* OEMCrypto via 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[out] signature: pointer to memory to receive the computed signature.
* @param[in,out] signature_length: (in) length of the signature buffer, in
* bytes. (out) actual length of the signature, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough
* to hold the signature.
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED since OEMCrypto does not implement
* license release before v19
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 19.
*/
OEMCryptoResult OEMCrypto_PrepAndSignLicenseRelease(
OEMCrypto_SESSION session, uint8_t* message, size_t message_length,
size_t* core_message_size, uint8_t* signature, size_t* signature_length);
/**
* OEMCrypto will use ODK_PrepareCoreRenewalRequest, as described in the
* document "Widevine Core Message Serialization", to prepare the core
* message.
*
* If it returns an error, the error should be returned by OEMCrypto to the
* CDM layer. If it returns OEMCrypto_SUCCESS, then OEMCrypto computes the
* signature using the renewal mac key which was delivered in the license via
* LoadLicense.
*
* If nonce_values.api_level is 16, then OEMCrypto shall compute the
* signature of the entire message using the session's client renewal mac
* key. The entire message is the buffer starting at message with length
* message_length.
*
* If nonce_values.api_major_version is 15, then OEMCrypto shall compute the
* signature of the message body using the session's client renewal mac key.
* The message body is the buffer starting at message+core_message_size with
* length message_length - core_message_size. If the session has not had a
* license loaded, it will use the usage entries client mac key to sign the
* message body.
*
* This function generates a HMAC-SHA256 signature using the mac_key[client]
* for license request signing under the license server protocol for CENC.
*
* The key used for signing should be the mac_key[client] that was generated
* for this session or loaded for this session by
* OEMCrypto_LoadLicense() or OEMCrypto_LoadUsageEntry().
*
* Refer to the Signing Messages Sent to a Server section above for more
* details.
*
* If a usage entry has been loaded, but keys have not been loaded through
* OEMCrypto_LoadLicense(), then the derived mac keys and the keys in the usage
* entry may be different. In this case, the mac keys specified in the usage
* entry should be used.
*
* NOTE: if signature pointer is null and/or input signature_length is zero,
* this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* signature_length to the size needed to receive the output signature.
*
* @param[in] session: handle for the session to be used.
* @param[in,out] message: Pointer to memory for the entire message. Modified by
* OEMCrypto via 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[out] signature: pointer to memory to receive the computed signature.
* @param[in,out] signature_length: (in) length of the signature buffer, in
* bytes. (out) actual length of the signature, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough
* to hold the signature.
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest(
OEMCrypto_SESSION session, uint8_t* message, size_t message_length,
size_t* core_message_size, uint8_t* signature, size_t* signature_length);
/**
* Install a set of keys for performing decryption in the current session.
*
* First, OEMCrypto should generate three secondary keys, mac_key[server],
* mac_key[client], and encryption_key, for handling signing and content key
* derivation under the license server protocol for CENC.
*
* Then OEMCrypto shall verify the signature of the message using
* HMAC-SHA256 with the derived mac_key[server]. The signature verification
* shall use a constant-time algorithm (a signature mismatch will always take
* the same time as a successful comparison). The signature is over the
* entire message buffer starting at message with length message_length. If
* the signature verification fails, ignore all other arguments and return
* OEMCrypto_ERROR_SIGNATURE_FAILURE. Otherwise, add the keys to the session
* context.
*
* Refer to the Verification of Messages from a Server section above for more
* details.
*
* The function ODK_ParseLicense is called to parse the message. If it
* returns an error, OEMCrypto shall return that error to the CDM layer. The
* function ODK_ParseLicense is described in the document "Widevine Core
* Message Serialization".
*
* Below, all fields are found in the struct ODK_ParsedLicense parsed_license
* returned by ODK_ParseLicense.
*
* The keys will be decrypted using the current encrypt_key (AES-128-CBC) and
* the IV given in the KeyObject. If the API version of the license is less
* than 17, each key control block will be decrypted using the first 128 bits
* of the corresponding content key (AES-128-CBC) and the IV given in the
* KeyObject. In v17 licenses, the key control block is not decrypted.
*
* If its length is not zero, enc_mac_keys will be used to create new
* mac_keys. After all keys have been decrypted and validated, the new
* mac_keys are decrypted with the current encrypt_key and the offered IV.
* The new mac_keys replaces the current mac_keys for future signing renewal
* requests and loading renewal responses. The first 256 bits of the mac_keys
* become the mac_key[server] and the following 256 bits of the mac_keys
* become the mac_key[client]. If enc_mac_keys is null, then there will not
* be a call to OEMCrypto_LoadRenewal() for this session and the current
* mac_keys may be deleted.
*
* If the field license_type is OEMCrypto_ContentLicense, then the fields
* key_id and key_data in an OEMCrypto_KeyObject are loaded in to the
* content_key_id and content_key_data fields of the key table entry. In this
* case, entitlement key ids and entitlement key data is left blank.
*
* If the field license_type is OEMCrypto_EntitlementLicense, then the
* fields key_id and key_data in an OEMCrypto_KeyObject are loaded in to the
* entitlement_key_id and entitlement_key_data fields of the key table entry.
* In this case, content key ids and content key data will be loaded later
* with a call to OEMCrypto_LoadEntitledContentKeys().
*
* OEMCrypto may assume that the key_id_length is at most 16. However,
* OEMCrypto shall correctly handle key id lengths from 1 to 16 bytes.
*
* OEMCrypto shall handle multiple keys, as described in the document
* [Resource Rating Tiers](/widevine/drm/feature/resource-rating).
*
* After a call to OEMCrypto_LoadLicense(), oemcrypto should clear the
* encrypt_key for the session.
*
* @verification
* The following checks should be performed. If any check fails, an error is
* returned, and none of the keys are loaded.
* 13. The signature of the message shall be computed, and the API shall
* verify the computed signature matches the signature passed in. If
* not, return OEMCrypto_ERROR_SIGNATURE_FAILURE. The signature
* verification shall use a constant-time algorithm (a signature
* mismatch will always take the same time as a successful comparison).
* 14. If there already is a license loaded into this session, return
* OEMCrypto_ERROR_LICENSE_RELOAD.
* 15. The enc_mac_keys substring must either have zero length, or satisfy
* the range check. I.e. (offset < message_length) && (offset + length
* <= message_length) && (offset <= offset + length), and offset + length
* does not cause an integer overflow. If it does not have zero length,
* then enc_mac_keys_iv must not have zero length, and must also satisfy
* the range check. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. If
* the length is zero, then OEMCrypto may assume that the offset is also
* zero.
* 16. The API shall verify that each substring in each KeyObject points to
* a location in the message. I.e. (offset < message_length) &&
* (offset + length <= message_length) && (offset <= offset + length),
* and offset + length does not cause an integer overflow, for each of
* key_id, key_data_iv, key_data, key_control_iv, key_control. If not,
* return OEMCrypto_ERROR_INVALID_CONTEXT.
* 17. Each key's control block, after decryption, shall have a valid
* verification field. If not, return OEMCrypto_ERROR_INVALID_CONTEXT.
* 18. If any key control block has the Nonce_Enabled bit set, that key's
* Nonce field shall match a nonce in the cache. If not, return
* OEMCrypto_ERROR_INVALID_NONCE. If there is a match, remove that
* nonce from the cache. Note that all the key control blocks in a
* particular call shall have the same nonce value.
* 19. If any key control block has the Require_AntiRollback_Hardware bit
* set, and the device does not protect the usage table from rollback,
* then do not load the keys and return OEMCrypto_ERROR_UNKNOWN_FAILURE.
* 20. If the key control block has a nonzero Replay_Control, then the
* verification described below is also performed.
* 21. If the key control block has the bit SRMVersionRequired is set, then
* the verification described below is also performed. If the SRM
* requirement is not met, then the key control block's HDCP_Version
* will be changed to 0xF - local display only.
* 22. If key_array_length == 0, then return
* OEMCrypto_ERROR_INVALID_CONTEXT.
* 23. If this session is associated with a usage table entry, and that
* entry is marked as "inactive" (either kInactiveUsed or
* kInactiveUnused), then the keys are not loaded, and the error
* OEMCrypto_ERROR_LICENSE_INACTIVE is returned.
* 24. The data in enc_mac_keys_iv is not identical to the 16 bytes before
* enc_mac_keys. If it is, return OEMCrypto_ERROR_INVALID_CONTEXT.
* 25. IF ODK_ParseLicense returns ODK_TIMER_EXPIRED, return
* OEMCrypto_ERROR_KEY_EXPIRED. If ODK_ParseLicense returns ODK_SET_TIMER
* or ODK_DISABLE_TIMER, the playback timer has started and OEMCrypto
* should treat this as if a Decrypt call has been made.
*
* Usage Table and Provider Session Token (pst)
* The function ODK_ParseLicense takes several parameters that may need more
* explanation.
* The parameter usage_entry_present shall be set to true if a usage entry
* was created or loaded for this session. This parameter is used by
* ODK_ParseLicense for usage entry verification.
* The parameter initial_license_load shall be false if the usage entry was
* loaded. If there is no usage entry or if the usage entry was created with
* OEMCrypto_CreateNewUsageEntry(), then initial_license_load shall be true.
* If a usage entry is present, then it shall be verified after the call to
* ODK_ParseLicense.
* If initial_license_load is true:
* 1. OEMCrypto shall copy the PST from the parsed license to the usage
* entry.
* 2. OEMCrypto shall verify that the server and client mac keys were
* updated by the license. The server and client mac keys shall be
* copied to the usage entry.
* If initial_license_load is false:
* 1. OEMCrypto shall verify the PST from the parsed license matches that
* in the usage entry. If not, then an error OEMCrypto_ERROR_WRONG_PST
* is returned.
* 2. OEMCrypto shall verify that the server and client mac keys were
* updated by the license. OEMCrypto shall verify that the server and
* client mac keys match those in the usage entry. If not the error
* OEMCrypto_ERROR_WRONG_KEYS is returned.
* If a key control block has a nonzero value for Replay_Control, then all
* keys in this license will have the same value for Replay_Control. In this
* case, the following additional checks are performed.
* - The substring pst must have nonzero length and must satisfy the range
* check described above. If not, return
* OEMCrypto_ERROR_INVALID_CONTEXT.
* - The session must be associated with a usage table entry, either
* created via OEMCrypto_CreateNewUsageEntry() or loaded via
* OEMCrypto_LoadUsageEntry().
* - If Replay_Control is 1 = Nonce_Required, then OEMCrypto will perform a
* nonce check as described above. OEMCrypto will verify that the
* usage entry is newly created with OEMCrypto_CreateNewUsageEntry(). If
* an existing entry was reloaded, an error
* OEMCrypto_ERROR_INVALID_CONTEXT is returned and no keys are loaded.
* OEMCrypto will then copy the pst and the mac keys to the usage entry,
* and set the status to Unused. The license received time of the entry
* will be updated to the current time, and the status will be set to
* Unused. This Replay_Control prevents the license from being loaded
* more than once, and will be used for online streaming.
* - If Replay_Control is 2 = "Require existing Session Usage table entry
* or Nonce", then OEMCrypto will behave slightly differently on the
* first call to LoadLicense for this license.
* * If the usage entry was created with OEMCrypto_CreateNewUsageEntry()
* for this session, then OEMCrypto will verify the nonce for each
* key. OEMCrypto will copy the pst and mac keys to the usage
* entry. The license received time of the entry will be updated
* to the current time, and the status will be set to Unused.
* * If the usage entry was loaded with OEMCrypto_LoadUsageEntry() for
* this session, then OEMCrypto will NOT verify the nonce for each
* key. Instead, it will verify that the pst passed in matches
* that in the entry. Also, the entry's mac keys will be verified
* against the current session's mac keys. This allows an offline
* license to be reloaded but maintain continuity of the playback
* times from one session to the next.
* * If the nonce is not valid and a usage entry was not loaded, the
* return error is OEMCrypto_ERROR_INVALID_NONCE.
* * If the loaded usage entry has a pst that does not match,
* OEMCrypto returns the error OEMCrypto_ERROR_WRONG_PST.
* * If the loaded usage entry has mac keys that do not match the
* license, OEMCrypto returns the error OEMCrypto_ERROR_WRONG_KEYS.
* Note: If LoadLicense updates the mac keys, then the new updated mac keys will
* be used with the Usage Entry -- i.e. the new keys are stored in the
* usage table when creating a new entry, or the new keys are verified
* against those in the usage table if there is an existing entry. If
* LoadLicense does not update the mac keys, the existing session mac keys are
* used.
* Sessions that are associated with an entry will need to be able to update
* and verify the status of the entry, and the time stamps in the entry.
* Devices that do not support the Usage Table will return
* OEMCrypto_ERROR_INVALID_CONTEXT if the Replay_Control is nonzero.
* SRM Restriction Data
* If any key control block has the flag SRMVersionRequired set, then the
* following verification is also performed.
* 4. The substring srm_restriction_data must have nonzero length and must
* satisfy the range check described above. If not, return
* OEMCrypto_ERROR_INVALID_CONTEXT.
* 5. The first 8 bytes of srm_restriction_data must match the string
* "HDCPDATA". If not, return OEMCrypto_ERROR_INVALID_CONTEXT.
* 6. The next 4 bytes of srm_restriction_data will be converted from
* network byte order. If the current SRM installed on the device has a
* version number less than this, then the SRM requirement is not met.
* If the device does not support SRM files, or OEMCrypto cannot
* determine the current SRM version number, then the SRM requirement is
* not met.
* Note: if the current SRM version requirement is not met, LoadLicense will
* still succeed and the keys will be loaded. However, those keys with the
* SRMVersionRequired bit set will have their HDCP_Version increased to 0xF -
* local display only. Any future call to OEMCrypto_GetKeyHandle() for these
* keys while there is an external display will return
* OEMCrypto_ERROR_INSUFFICIENT_HDCP at that time.
*
* @param[in] session: crypto session identifier.
* @param[in] context: pointer to memory containing context data.
* @param[in] context_length: length of the context, in bytes.
* @param[in] derivation_key: pointer to memory containing derivation key.
* @param[in] derivation_key_length: length of the derivation_key, in bytes.
* @param[in] message: pointer to memory containing data.
* @param[in] message_length: length of the message, in bytes.
* @param[in] core_message_length: length of the core submessage, in bytes.
* @param[in] signature: pointer to memory containing the signature.
* @param[in] signature_length: length of the signature, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE
* @retval OEMCrypto_ERROR_INVALID_NONCE
* @retval OEMCrypto_ERROR_TOO_MANY_KEYS
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_LICENSE_RELOAD
* @retval OEMCrypto_ERROR_KEY_EXPIRED
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_LoadLicense(
OEMCrypto_SESSION session, const uint8_t* context, size_t context_length,
const uint8_t* derivation_key, size_t derivation_key_length,
const uint8_t* message, size_t message_length, size_t core_message_length,
const uint8_t* signature, size_t signature_length);
/**
* Updates the clock values and resets the renewal timer for the current
* session.
*
* OEMCrypto shall verify the signature of the entire message using the
* session's renewal mac key for the server. The entire message is the buffer
* starting at message with length message_length. If the signature does not
* match, OEMCrypto returns OEMCrypto_ERROR_SIGNATURE_FAILURE.
*
* OEMCrypto shall verify that nonce_values.api_major_version is 16. If not,
* return the error OEMCrypto_ERROR_INVALID_CONTEXT.
*
* If the signature passes, OEMCrypto shall use the function
* ODK_ParseRenewal, as described in the document "Widevine Core Message
* Serialization" to parse and verify the message. If ODK_ParseRenewal
* returns an error OEMCrypto returns the error to the CDM layer.
*
* The function ODK_ParseRenewal updates the clock values for the session,
* and may return ODK_SET_TIMER, ODK_DISABLE_TIMER or ODK_TIMER_EXPIRED on
* success. These values shall be handled by OEMCrypto, as discussed in the
* document "License Duration and Renewal".
*
* NOTE: OEMCrypto_LoadLicense() must be called first to load the keys into
* the session.
*
* @verification
* The signature of the message shall be computed using mac_key[server], and
* the API shall verify the computed signature matches the signature passed
* in. If not, return OEMCrypto_ERROR_SIGNATURE_FAILURE. The signature
* verification shall use a constant-time algorithm (a signature mismatch
* will always take the same time as a successful comparison).
*
* @param[in] session: handle for the session to be used.
* @param[in] message: pointer to memory containing message to be verified.
* @param[in] message_length: length of the message, in bytes.
* @param[in] core_message_length: length of the core submessage, in bytes.
* @param[in] signature: pointer to memory containing the signature.
* @param[in] signature_length: length of the signature, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE
* @retval OEMCrypto_ERROR_INVALID_NONCE
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval ODK_STALE_RENEWAL
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 12.
*/
OEMCryptoResult OEMCrypto_LoadRenewal(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
size_t core_message_length,
const uint8_t* signature,
size_t signature_length);
/**
* Returns the decrypted key control block for the given content_key_id. This
* function is for application developers to debug license server and key
* timelines. It only returns a key control block if LoadLicense was successful,
* otherwise it returns OEMCrypto_ERROR_NO_CONTENT_KEY. The developer of the
* OEMCrypto library must be careful that the keys themselves are not
* accidentally revealed.
*
* Note: returns control block in original, network byte order. If OEMCrypto
* converts fields to host byte order internally for storage, it should
* convert them back. Since OEMCrypto might not store the nonce or validation
* fields, values of 0 may be used instead.
*
* @verification
* The following checks should be performed.
* 1. If key_id is null, return OEMCrypto_ERROR_INVALID_CONTEXT.
* 2. If key_control_block_length is null, return
* OEMCrypto_ERROR_INVALID_CONTEXT.
* 3. If *key_control_block_length is less than the length of a key control
* block, set it to the correct value, and return
* OEMCrypto_ERROR_SHORT_BUFFER.
* 4. If key_control_block is null, return OEMCrypto_ERROR_INVALID_CONTEXT.
* 5. If the specified key has not been loaded, return
* OEMCrypto_ERROR_NO_CONTENT_KEY.
*
* @param[in] session: handle for the crypto or entitled key session to be used.
* @param[in] content_key_id: The unique id of the key of interest.
* @param[in] content_key_id_length: The length of key_id, in bytes. From 1 to
* 16, inclusive.
* @param[out] key_control_block: A caller-owned buffer.
* @param[in,out] key_control_block_length. The length of key_control_block
* buffer.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is changed in API version 17.
*/
OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session,
const uint8_t* content_key_id,
size_t content_key_id_length,
uint8_t* key_control_block,
size_t* key_control_block_length);
/// @}
/// @addtogroup entitled
/// @{
/**
* This method creates an entitled key session.
* OEMCrypto is required to support at least one entitled key session per
* license. For CAS support, we also require that OEMCrypto support at least
* six entitled key sessions per license.
*
* @param[in] oec_session: handle for the OEMCrypto session to be associated
* with the created entitled key session.
* @param[out] key_session: id of the created entitled key session.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_TOO_MANY_SESSIONS
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this oec_session. It will not be called simultaneously with
* initialization or usage table functions. It is as if the CDM holds a write
* lock for this session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_CreateEntitledKeySession(
OEMCrypto_SESSION oec_session, OEMCrypto_SESSION* key_session);
/**
* This method which removes an entitled key session.
*
* @param[in] key_session: id of the entitled key session to be removed.
*
* Returns:
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_RemoveEntitledKeySession(
OEMCrypto_SESSION key_session);
/**
* Load content keys into an entitled session which is associated with an
* entitlement sessions. This function will only be called for an entitled
* session after a call to OEMCrypto_LoadLicense() has been called on the
* associated entitlement session. This function may be called multiple times
* for the same session.
*
* If the session is not an entitled session, return
* OEMCrypto_ERROR_INVALID_CONTEXT and perform no work.
*
* For each key object in key_array, OEMCrypto shall look up the entry in the
* key table for the entitlement session with the corresponding
* entitlement_key_id.
*
* 1. If no entry is found, return OEMCrypto_KEY_NOT_ENTITLED.
* 2. If the entry already has a content_key_id and content_key_data, that
* id and data are erased.
* 3. The content_key_id from the key_array is copied to the entry's
* content_key_id.
* 4. The content_key_data decrypted using the entitlement_key_data as a
* key for AES-256-CBC with an IV of content_key_data_iv. Notice that
* the entitlement key will be an AES 256 bit key. The clear content key
* data will be stored in the entry's content_key_data.
* Entries in the key table that do not correspond to anything in the
* key_array are not modified or removed.
*
* For devices that use a hardware key ladder, it may be more convenient to
* store the encrypted content key data in the key table, and decrypt it when
* the function OEMCrypto_GetKeyHandle() is called.
*
* @param[in] session: handle for the entitled key session to be used.
* @param[in] message: pointer to memory containing message to be verified.
* @param[in] message_length: length of the message, in bytes.
* @param[in] key_array_length: number of keys present.
* @param[in] key_array: set of key updates.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_KEY_NOT_ENTITLED
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session, or its entitlement session. It will not be called
* simultaneously with initialization or usage table functions. It is as if
* the CDM holds a write lock for this session, and a read lock on the
* OEMCrypto system.
*
* @version
* This method changed in API version 17.
*/
OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
size_t key_array_length,
const OEMCrypto_EntitledContentKeyObject* key_array);
/**
* This method associates an existing entitled key session to the specified
* OEMCrypto session.
*
* @param[in] key_session: id of the entitled key session.
* @param[in] oec_session: handle for the OEMCrypto session to be associated
* with the entitled key session.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
* @retval OEMCrypto_ERROR_INVALID_SESSION
*
* @threading
* This is a "Session Initialization Function" and will not be called
* simultaneously with any other function, as if the CDM holds a write lock
* on the OEMCrypto system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_ReassociateEntitledKeySession(
OEMCrypto_SESSION key_session, OEMCrypto_SESSION oec_session);
/**
* The OEMCrypto_LoadCasECMKeys method is added to load content keys into an
* entitled key session, which already has entitlement keys loaded. Used only by
* CAS.
*
* This function will only be called for a session after a call to
* OEMCrypto_LoadLicense with the license_type equal to
* OEMCrypto_EntitlementLicense, and a call to
* OEMCrypto_CreateEntitledKeySession initializing the entitled key session.
* This function may be called multiple times for the same session.
*
* For each key object, odd and even, OEMCrypto shall look up the entry in the
* key table with the corresponding entitlement_key_id. Before the
* entitlement_key is used:
* 1) If no entry is found, return OEMCrypto_KEY_NOT_ENTITLED.
* 2) Check the entitlement keys key control block use. If failed, return
* corresponding error code such as OEMCrypto_ERROR_ANALOG_OUTPUT,
* OEMCrypto_ERROR_INSUFFICIENT_HDCP.
* 3) If the entitlement keys control block has a nonzero Duration field,
* then the API shall verify that the duration is greater than the
* sessions elapsed time clock before the key is used. OEMCrypto will
* return OEMCrypto_ERROR_KEY_EXPIRED.
* 4) The content_key_data decrypted using the entitlement_key_data as a key
* for AES-256-CBC with an IV of content_key_data_iv. Wrapped content is
* padded using PKCS#7 padding. Notice that the entitlement key will be an
* AES 256 bit key. The clear content key data will be stored in the
* entrys content_key_data.
* 5) The decrypted content key data may be set in a hardware KeySlot,
* together with content iv and cipher mode information, which can be used
* by the Descrambler in TunerHal. The entitled key session ID may be used
* as the key token to uniquely identify the content key in KeySlot.
*
* @param[in] session: handle for the entitled key session to be used.
* @param[in] message: pointer to memory containing message to be verified.
* @param[in] message_length: length of the message, in bytes.
* @param[in] even_key: key update for the even ecm key. May be null if the key
* does not change.
* @param[in] odd_key: key update for the odd ecm key. May be null if the key
* does not change.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_KEY_NOT_ENTITLED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
* @retval OEMCrypto_ERROR_KEY_EXPIRED
* @retval OEMCrypto_ERROR_ANALOG_OUTPUT
* @retval OEMCrypto_ERROR_INSUFFICIENT_HDCP
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_LoadCasECMKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const OEMCrypto_EntitledContentKeyObject* even_key,
const OEMCrypto_EntitledContentKeyObject* odd_key);
/**
* Retrieves the key token associated with the input entitled key session. This
* method is currently used only by CAS, where key token is a means to share
* vendor specific crypto info with other frameworks (e.g. Descrambler in
* Android TunerHAL) that are also under control of the vendor.
*
* @param[in] key_session: handle for the entitled key session to be used.
* @param[out] key_token: where the key token is stored.
* @param[in,out] key_token_length: length of the key token, in bytes.
*
* @retval OEMCrypto_SUCCESS on success
* @retval OEMCrypto_ERROR_SHORT_BUFFER if buffer_length is too small.
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
*
* @threading
* This is an "Initialization and Termination Function" and will not be called
* simultaneously with any other function, as if the CDM holds a write lock on
* the OEMCrypto system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_GetOEMKeyToken(OEMCrypto_SESSION key_session,
uint8_t* key_token,
size_t* key_token_length);
/// @}
/// @addtogroup decryption
/// @{
/**
* Select a content key and install it in the hardware key ladder for
* subsequent decryption operations. (e.g. OEMCrypto_DecryptCENC(), generic
* crypto functions) The specified key must have been previously imported via
* OEMCrypto_LoadLicense() or OEMCrypto_LoadEntitledContentKeys(). Write a
* handle that can be used to refer to the installed key into the buffer pointed
* to by the key_handle parameter and set key_handle_length to the size of the
* data written to key_handle.
*
* If key_handle is NULL or key_handle_length is too small to hold the handle,
* write the number of bytes needed to hold a key handle to key_handle_length
* and return OEMCrypto_ERROR_SHORT_BUFFER. Do not install the key in this case.
*
* If the session has an entry in the Usage Table and the status of the entry is
* "unused", then change the status to "active" and set the
* time_of_first_decrypt.
*
* A key control block is associated with the key and the session, and is
* used to configure the session context. The Key Control data is documented
* in "Key Control Block Definition".
*
* Step 1: Lookup the content key data via the offered key_id. The key data
* includes the key value, and the key control block.
*
* Step 2: Latch the content key into the hardware key ladder. Set permission
* flags based on the key's control block.
*
* Step 3: use the latched content key to decrypt (AES-128-CTR or
* AES-128-CBC) buffers passed in via OEMCrypto_DecryptCENC(). If the key is
* 256 bits it will be used for OEMCrypto_Generic_Sign() or
* OEMCrypto_Generic_Verify() as specified in the key control block. If the key
* will be used for OEMCrypto_Generic_Encrypt() or OEMCrypto_Generic_Decrypt()
* then the cipher mode will always be OEMCrypto_CipherMode_CBCS.
*
* #### Bypass Decrypt
*
* Platforms that wish to support Bypass Decrypt should latch the key into
* secure crypto hardware such that it can be fed by the chosen bypass method.
* For more information on Bypass Decrypt, see the
* [Bypass Decrypt](../../bypass) documentation.
*
* If the device is bypassing, it must update the ODK clock values in this
* function call. If this is the first use of a key for this session, then
* OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock
* values and verify playback is allowed. If this is not the first use of a key
* for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See
* [ODK Clocks and Timers](../../odk-timers) for handling the return value of
* these ODK functions. The hardware that the key is latched into must be able
* to enforce that the key expires and becomes unusable after the amount of
* time returned by ODK in the timer_value field.
*
* The format of the key handle is opaque to Widevine and platform-specific. It
* should contain whatever information the platform will need to find the key in
* the hardware on the bypass decryption path, as well as in
* OEMCrypto_DecryptCENC() and the generic crypto functions. A key slot number
* is generally not sufficient, as this could lead to the wrong key being used
* if that slot later has a different key loaded into it.
*
* The key handle must not contain the actual cryptographic key.
*
* #### Non-Bypass Decrypt
*
* For platforms that do not need to support Bypass Decrypt, a mode compatible
* with previous versions of OEMCrypto is available. These devices may latch the
* key to the session and continue to use this key for this session until
* OEMCrypto_GetKeyHandle() is called again, or until OEMCrypto_CloseSession()
* is called.
*
* The "key handle" in this mode is the session ID. Platforms should request a
* 4-byte key handle buffer and copy the session ID into it.
*
* @verification
* 1. If the key id is not found in the keytable for this session, then the
* key state is not changed and OEMCrypto shall return
* OEMCrypto_ERROR_NO_CONTENT_KEY.
* 2. If the key control block has the bit Disable_Analog_Output set, then
* the device should disable analog video output. If the device has
* analog video output that cannot be disabled, then the key is not
* selected, and OEMCrypto_ERROR_ANALOG_OUTPUT is returned. This step is
* optional -- OEMCrypto_GetKeyHandle() may return OEMCrypto_SUCCESS and
* delay the error until a call to OEMCrypto_DecryptCENC().
* 3. If the key control block has HDCP required, and the device cannot
* enforce HDCP, then the key is not selected, and
* OEMCrypto_ERROR_INSUFFICIENT_HDCP is returned. This step is optional
* -- OEMCrypto_GetKeyHandle() may return OEMCrypto_SUCCESS and delay the
* error until a call to OEMCrypto_DecryptCENC().
* 4. If the key control block has a nonzero value for HDCP_Version, and
* the device cannot enforce at least that version of HDCP, then the key
* is not selected, and OEMCrypto_ERROR_INSUFFICIENT_HDCP is returned.
*
* @param[in] session: handle for the crypto or entitled key session to be used.
* @param[in] content_key_id: pointer to the content Key ID.
* @param[in] content_key_id_length: length of the content Key ID, in bytes.
* From 1 to 16, inclusive.
* @param[in] cipher_mode: whether the key should be prepared for CTR mode or
* CBC mode when used in later calls to DecryptCENC. This should be ignored
* when the key is used for Generic Crypto calls.
* @param[out] key_handle: pointer to a buffer in which the key handle should be
* stored. May be NULL on the first call in order to find required buffer
* size.
* @param[in,out] key_handle_length: (in) length of the key_handle buffer, in
* bytes. (out) actual length of the key handle written to the key_handle
* buffer, in bytes. May not be NULL.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER if the buffer is NULL or too small
* @retval OEMCrypto_ERROR_KEY_EXPIRED if the session's timer has expired
* @retval OEMCrypto_ERROR_INVALID_SESSION crypto session ID invalid or not open
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY failed to decrypt device key
* @retval OEMCrypto_ERROR_NO_CONTENT_KEY failed to decrypt content key
* @retval OEMCrypto_ERROR_CONTROL_INVALID invalid or unsupported control input
* @retval OEMCrypto_ERROR_KEYBOX_INVALID cannot decrypt and read from Keybox
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_ANALOG_OUTPUT
* @retval OEMCrypto_ERROR_INSUFFICIENT_HDCP
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 18.
*/
OEMCryptoResult OEMCrypto_GetKeyHandle(OEMCrypto_SESSION session,
const uint8_t* content_key_id,
size_t content_key_id_length,
OEMCryptoCipherMode cipher_mode,
uint8_t* key_handle,
size_t* key_handle_length);
/**
* Decrypts or copies a series of input payloads into output buffers using
* the installed key indicated by the key handle parameter. The input payload
* is delivered in the form of samples. The samples are subdivided into
* subsamples. "Samples" and "subsamples" are defined as in the ISO Common
* Encryption standard (ISO/IEC 23001-7:2016). The samples parameter contains
* a list of samples, each of which has its own input and output buffers.
* Each sample contains a buffers field that contains the input and output
* buffers in its input_data and output fields, respectively.
*
* Each sample contains an array of subsample descriptions in its subsamples
* field. Each subsample is defined as a number of clear bytes followed by a
* number of encrypted bytes. Subsamples are consecutive inside the sample;
* the clear bytes of the second subsample begin immediately after the
* encrypted bytes of the first subsample. This follows the definition in the
* ISO-CENC standard.
*
* Decryption mode is AES-128-CTR or AES-128-CBC depending on the value of
* cipher_mode previously passed in to OEMCrypto_GetKeyHandle(). For the
* encrypted portion of subsamples, the content key associated with the handle
* is latched in the active hardware key ladder and is used for the decryption
* operation. For the clear portion of subsamples, the data is simply copied.
*
* After decryption, all the input_data bytes are copied to the location
* described by the output field. The output field is an
* OEMCrypto_DestBufferDesc, which could be one of:
*
* 1. The structure OEMCrypto_DestBufferDesc contains a pointer to a clear
* text buffer. The OEMCrypto library shall verify that key control
* allows data to be returned in clear text. If it is not authorized,
* this method should return an error.
* 2. The structure OEMCrypto_DestBufferDesc contains a handle to a secure
* buffer.
* 3. The structure OEMCrypto_DestBufferDesc indicates that the data should
* be sent directly to the decoder and renderer.
*
* Depending on your platform's needs, you may not need to support all three
* of these options.
*
* SINGLE-SAMPLE DECRYPTION AND SINGLE-SUBSAMPLE DECRYPTION:
*
* If the OEMCrypto implementation is not able to handle the amount of
* samples and subsamples passed into it, it should return
* OEMCrypto_ERROR_BUFFER_TOO_LARGE, in which case the CDM can respond by
* breaking the samples up into smaller pieces and trying to decrypt each of
* them individually. It is possible that the CDM will break the samples
* array up into pieces that are still too large, in which case OEMCrypto may
* return OEMCrypto_ERROR_BUFFER_TOO_LARGE again.
*
* If the OEMCrypto implementation cannot handle multiple samples at once, it
* may return OEMCrypto_ERROR_BUFFER_TOO_LARGE any time it receives more than
* one sample in a single call to OEMCrypto_DecryptCENC().
*
* Similarly, if the OEMCrypto implementation cannot handle multiple
* subsamples at once, it may return OEMCrypto_ERROR_BUFFER_TOO_LARGE any
* time it receives more than one subsample in a single call to
* OEMCrypto_DecryptCENC().
*
* The exact way that the CDM code breaks up the samples array is not
* guaranteed by this specification. The CDM may break down the array of
* samples into many arrays each containing one sample. The CDM may break
* down samples into subsamples and pass individual subsamples into
* OEMCrypto, just like in OEMCrypto v15. The CDM may break down individual
* subsamples into smaller subsamples, just like in OEMCrypto v15.
*
* If OEMCrypto requests that the CDM break samples into subsamples, the
* "samples" passed into OEMCrypto_DecryptCENC() will no longer be full
* samples. When a full sample is passed into OEMCrypto_DecryptCENC(), the
* first subsample in the subsample array will have the
* OEMCrypto_FirstSubsample flag set in its subsample_flags field and the
* last subsample array will have the OEMCrypto_LastSubsample flag set in its
* subsample_flags field. If this is not the case, OEMCrypto will need to
* accumulate more subsamples from successive calls to OEMCrypto_DecryptCENC
* to receive the full sample.
*
* The first subsample in the sample will always have OEMCrypto_FirstSubsample
* set and the last subsample will always have the OEMCrypto_LastSubsample flag
* set, even if those subsamples are passed in separate calls to
* OEMCrypto_DecryptCENC(). This is the same as in OEMCrypto v15. The decrypted
* data will not be used until after the subsample with the flag
* OEMCrypto_LastSubsample has been sent to OEMCrypto. This can be relied on by
* OEMCrypto for optimization by not doing decrypt until the last subsample has
* been received. However, a device that can do decrypt of more than one
* subsample at a time will always have better performance if it can receive
* those subsamples in one OEMCrypto_DecryptCENC() call rather than as
* individual subsamples.
*
* Although the exact way that the CDM code breaks up the samples array when
* it receives OEMCrypto_ERROR_BUFFER_TOO_LARGE is not guaranteed by this
* specification, here is a sample way it might work:
*
* 1. It tries to pass the array of samples to OEMCrypto_DecryptCENC().
* 2. If OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE, it tries to
* pass each sample individually into OEMCrypto_DecryptCENC().
* 3. If OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE, it tries to
* pass the clear and encrypted parts of each subsample individually
* into OEMCrypto_DecryptCENC(). At this point, (and in the subsequent
* steps) it is replicating the behavior of OEMCrypto v15 and lower.
* 4. If OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE, it breaks each
* piece of a subsample into smaller pieces, down to the minimum
* subsample size required by the device's resource rating tier. It
* passes these pieces into OEMCrypto_DecryptCENC().
* 5. If OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE, the device has
* failed to meet its resource rating tier requirements. It returns an
* error.
* Because this process requires a lot of back-and-forth between the CDM and
* OEMCrypto, partners are strongly recommended to support decrypting full
* samples or even multiple samples in their OEMCrypto implementation.
*
* ISO-CENC SCHEMES:
*
* The ISO Common Encryption standard (ISO/IEC 23001-7:2016) defines four
* "schemes" that may be used to encrypt content: 'cenc', 'cens', 'cbc1', and
* 'cbcs'. Starting with v16, OEMCrypto only supports 'cenc' and 'cbcs'. The
* schemes 'cens' and 'cbc1' are not supported.
*
* The decryption mode, either OEMCrypto_CipherMode_CENC or
* OEMCrypto_CipherMode_CBCS, was already specified in the call to
* OEMCrypto_GetKeyHandle(). The encryption pattern is specified by the fields
* in the parameter pattern. A description of partial encryption patterns for
* 'cbcs' can be found in the ISO-CENC standard, section 10.4.
*
* 'cenc' SCHEME:
*
* The 'cenc' scheme is OEMCrypto_CipherMode_CENC without an encryption
* pattern. All the bytes in the encrypted portion of each subsample are
* encrypted. In the pattern parameter, both the encrypt and skip fields will
* be zero.
*
* The length of a crypto block in AES-128 is 16 bytes. In the 'cenc' scheme,
* if an encrypted subsample has a length that is not a multiple of 16 bytes,
* then all the bytes of the encrypted subsample must be decrypted, but the
* next encrypted subsample will begin by completing the incomplete crypto
* block from the previous encrypted subsample. The following diagram
* provides an example:
*
* ![Drawing of block offset](fig5.svg)
*
* To help with this, the block_offset field of each subsample will contain
* the number of bytes the initial crypto block of that subsample should be
* offset by. In the example above, the block_offset for the first subsample
* would be 0 and the block_offset for the second subsample would be 12.
* 'cenc' is the only mode that allows for a nonzero block_offset. This field
* satisfies 0 <= block_offset < 16.
*
* 'cbcs' SCHEME:
*
* The 'cbcs' scheme is OEMCrypto_CipherMode_CBCS with an encryption pattern.
* Only some of the bytes in the encrypted portion of each subsample are
* encrypted. In the pattern parameter, the encrypt and skip fields will
* usually be non-zero. This mode allows devices to decrypt FMP4 HLS content,
* SAMPLE-AES HLS content, as well as content using the DASH 'cbcs' scheme.
*
* The skip field of OEMCrypto_CENCEncryptPatternDesc may also be zero. If
* the skip field is zero, then patterns are not in use and all crypto blocks
* in the encrypted part of the subsample are encrypted. It is not valid for
* the encrypt field to be zero.
*
* The length of a crypto block in AES-128 is 16 bytes. In the 'cbcs' scheme,
* if the encrypted part of a subsample has a length that is not a multiple
* of 16 bytes, then the final bytes that do not make up a full crypto block
* are clear and should never be decrypted. The following diagram provides an
* example:
*
* ![CBCS Scheme](fig6.svg)
*
* Whether any given protected block is actually encrypted also depends on
* the pattern. But the bytes at the end that do not make up a full crypto
* block will never be encrypted, regardless of what the pattern is. Even if
* the pattern says to decrypt every protected block, these bytes are clear
* and should not be decrypted.
*
* Of course, if the encrypted subsample has a length that is a multiple of
* 16 bytes, all the bytes in it are protected, and they may need to be
* decrypted following the pattern. The following diagram provides an example:
*
* ![CBCS Scheme - final partial block](fig7.svg)
*
* INITIALIZATION VECTOR BETWEEN SUBSAMPLES:
*
* The IV is specified for the initial subsample in a sample in the iv field
* of the OEMCrypto_SampleDescription. OEMCrypto is responsible for correctly
* updating the IV for subsequent subsamples according to the ISO Common
* Encryption standard (ISO/IEC 23001-7:2016). Section 9.5.2.3 covers 'cenc'
* and section 9.5.2.5 covers 'cbcs'. A summary of the ISO-CENC behavior
* follows:
*
* For 'cenc', the IV at the end of each subsample carries forward to the
* next subsample and becomes the IV at the beginning of the next subsample.
* If the subsample ends on a crypto block boundary, then the IV should be
* incremented as normal at the end of the crypto block. If the subsample
* ends in the middle of a crypto block, the same IV should continue to be
* used until the crypto block is completed in the next subsample. Only
* increment the IV after the partial crypto block is completed.
*
* For 'cbcs', the IV is reset at the beginning of each subsample. Each
* subsample should start with the IV that was passed into
* OEMCrypto_DecryptCENC().
*
* To phrase it another way: In 'cenc', the encrypted portions of the
* subsamples can be concatenated to form one continuous ciphertext. In
* 'cbcs', each encrypted portion of a subsample is a separate ciphertext.
* Each separate ciphertext begins with the IV specified in the iv field of
* the OEMCrypto_SampleDescription.
*
* INITIALIZATION VECTOR WITHIN SUBSAMPLES:
*
* Once it has the IV for each subsample, OEMCrypto is responsible for
* correctly updating the IV for each crypto block of each encrypted
* subsample portion, as outlined in the ISO Common Encryption standard
* (ISO/IEC 23001-7:2016). Section 9.5.1 includes general information about
* IVs in subsample decryption. A summary of the ISO-CENC behavior follows:
*
* For 'cenc', the subsample's IV is the counter value to be used for the
* initial encrypted block of the subsample. The IV length is the AES block
* size. For subsequent encrypted AES blocks, OEMCrypto must calculate the IV
* by incrementing the lower 64 bits (byte 8-15) of the IV value used for the
* previous block. The counter rolls over to zero when it reaches its maximum
* value (0xFFFFFFFFFFFFFFFF). The upper 64 bits (byte 0-7) of the IV do not
* change.
*
* For 'cbcs', the subsample's IV is the initialization vector for the
* initial encrypted block of the subsample. Within each subsample, each
* crypto block is used as the IV for the next crypto block, as prescribed by
* AES-CBC.
*
* NOTES:
*
* If the destination buffer is secure, an offset may be specified.
* OEMCrypto_DecryptCENC() begins storing data buffers.output.secure.offset
* bytes after the beginning of the secure buffer.
*
* OEMCrypto cannot assume that the buffers of consecutive samples are
* consecutive in memory.
*
* A subsample may consist entirely of encrypted bytes or clear bytes. In
* this case, the clear or the encrypted part of the subsample will be zero,
* indicating that no bytes of that kind appear in the subsample.
*
* The ISO-CENC spec implicitly limits both the skip and encrypt values to be
* 4 bits, so they are at most 15.
*
* ![CTR Mode - no skip pattern](fig8.svg)
*
* If OEMCrypto assembles all of the encrypted subsample portions into a
* single buffer and then decrypts it in one pass, it can assume that the
* block offset is 0.
*
* ![CTR Mode - with skip pattern](fig9.svg)
*
* @verification
* The total size of all the subsamples cannot exceed the total size of the
* input buffer. OEMCrypto integrations should validate this and return
* OEMCrypto_ERROR_UNKNOWN_FAILURE if the subsamples are larger than the
* input buffer. No decryption should be performed in this case.
* If the subsamples all contain only clear bytes, then no further
* verification is performed.
* The following checks should be performed if any subsamples contain any
* encrypted bytes. If any check fails, an error is returned, and no
* decryption is performed.
* 1. If the current key's control block has the Data_Path_Type bit set,
* then the API shall verify that the output buffer is secure or direct.
* If not, return OEMCrypto_ERROR_DECRYPT_FAILED.
* 2. If the current key control block has the bit Disable_Analog_Output
* set, then the device should disable analog video output. If the
* device has analog video output that cannot be disabled, then
* OEMCrypto_ERROR_ANALOG_OUTPUT is returned. (See note on delayed
* error conditions below)
* 3. If the current key's control block has the HDCP bit set, then the API
* shall verify that the buffer will be displayed locally, or output
* externally using HDCP only. If not, return
* OEMCrypto_ERROR_INSUFFICIENT_HDCP. (See note on delayed error
* conditions below)
* 4. If the current key's control block has a nonzero value for
* HDCP_Version, then the current version of HDCP for the device and the
* display combined will be compared against the version specified in
* the control block. If the current version is not at least as high as
* that in the control block, and the device is not able to restrict
* displays with HDCP levels lower than what's in the control block,
* return OEMCrypto_ERROR_INSUFFICIENT_HDCP. If the device is able to
* restrict those displays, return
* OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION. (See note on delayed
* error conditions below)
* 5. If the current key has an entry in the Usage Table, and the status of
* that entry is either kInactiveUsed or kInactiveUnused, then return the
* error OEMCrypto_ERROR_LICENSE_INACTIVE.
* 6. If a Decrypt Hash has been initialized via OEMCrypto_SetDecryptHash(),
* and the current key's control block does not have the
* Allow_Hash_Verification bit set, then do not compute a hash and
* return OEMCrypto_ERROR_UNKNOWN_FAILURE.
*
* #### Delayed Error Conditions
*
* On some devices, the HDCP subsystem is not directly connected to the
* OEMCrypto TA. This means that returning the error
* OEMCrypto_ERROR_INSUFFICIENT_HDCP at the time of the decrypt call is a
* performance hit. However, some devices have the ability to tag output
* buffers with security requirements, such as the required HDCP level.
* For those devices, when a call to OEMCrypto_DecryptCENC() is made using a
* key that requires HDCP output, and if the HDCP level on the output does
* not meet the required level.
* - OEMCrypto may tag the output buffer as requiring HDCP at the required
* level and return OEMCrypto_SUCCESS.
* - Output shall not be sent to the display.
* - On the second or third call to OEMCrypto_DecryptCENC() with the same
* key, OEMCrypto shall return OEMCrypto_ERROR_INSUFFICIENT_HDCP.
* For those devices, when a call to OEMCrypto_DecryptCENC() is made using a
* key that requires HDCP output, and if the HDCP level on some of the
* displays does not meet the required level.
* - OEMCrypto may tag the output buffer as requiring HDCP at the required
* level and return OEMCrypto_SUCCESS.
* - Output shall only be sent to the display with sufficient output
* control, e.g. the local display.
* - On the second or third call to OEMCrypto_DecryptCENC() with the same
* key, OEMCrypto shall return OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION.
* In either case, a call to OEMCrypto_GetHDCPCapability() shall return the
* current HDCP level.
*
* #### Bypass Decrypt
*
* Platforms that wish to support Bypass Decrypt are still required to implement
* this function so that the decrypt path can be tested. It is acceptable for
* this function to invoke the bypass mechanism instead of calling into the
* OEMCrypto TA. For more information on Bypass Decrypt, see the
* [Bypass Decrypt](../../bypass) documentation.
*
* #### Non-Bypass Decrypt
*
* For platforms that do not need to support Bypass Decrypt, a mode compatible
* with previous versions of OEMCrypto is available. The "key handle" created by
* OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be
* used the same as the session ID previously passed to OEMCrypto_DecryptCENC().
*
* If the device is not bypassing, it must update the ODK clock values in this
* function call. If this is the first use of a key for this session, then
* OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock
* values and verify playback is allowed. If this is not the first use of a key
* for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See
* [ODK Clocks and Timers](../../odk-timers) for handling the return value of
* these ODK functions.
*
* @param[in] key_handle: pointer to a buffer containing the key handle for a
* key previously installed with OEMCrypto_GetKeyHandle().
* @param[in] key_handle_length: length of the data in the key_handle buffer, in
* bytes.
* @param[in] samples: A caller-owned array of OEMCrypto_SampleDescription
* structures. Each entry in this array contains one sample of the content.
* @param[in] samples_length: The length of the array pointed to by the samples
* parameter.
* @param[in] pattern: A caller-owned structure indicating the encrypt/skip
* pattern as specified in the ISO-CENC standard.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_DECRYPT_FAILED
* @retval OEMCrypto_ERROR_KEY_EXPIRED
* @retval OEMCrypto_ERROR_INSUFFICIENT_HDCP
* @retval OEMCrypto_ERROR_ANALOG_OUTPUT
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE if the input buffer is too large,
* and should be partitioned.
* @retval OEMCrypto_ERROR_SHORT_BUFFER if the destination buffer is shorter
* than the source
* @retval OEMCrypto_ERROR_OUTPUT_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
* @retval OEMCrypto_ERROR_UNSUPPORTED_CIPHER
*
* @buffer_size
* OEMCrypto shall support subsample sizes and total input buffer sizes as
* specified by its resource rating tier.
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size. If OEMCrypto returns
* OEMCrypto_ERROR_BUFFER_TOO_LARGE, the CDM will break the buffer into
* smaller chunks. For high performance devices, OEMCrypto should handle
* larger buffers. We encourage OEMCrypto implementers not to artificially
* restrict the maximum buffer size.
* If OEMCrypto detects that the output data is too large, and breaking the
* buffer into smaller subsamples will not work, then it returns
* OEMCrypto_ERROR_OUTPUT_TOO_LARGE. This error will bubble up to the
* application, which can decide to skip the current frame of video or to
* switch to a lower resolution.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for the session containing the key. It will not be called simultaneously
* with initialization or usage table functions. It is as if the CDM holds a
* write lock for the key's session, and a read lock on the OEMCrypto system.
*
* The threading guarantees for this function are only guaranteed when the
* function is called through the Widevine CDM. If the platform uses Bypass
* Decrypt in a way that still calls this function, the OS may call this
* function in ways that violate these threading guarantees.
*
* @version
* This method changed in API version 18. This method changed its name in API
* version 11.
*/
OEMCryptoResult OEMCrypto_DecryptCENC(
const uint8_t* key_handle, size_t key_handle_length,
const OEMCrypto_SampleDescription* samples, // an array of samples.
size_t samples_length, // the number of samples.
const OEMCrypto_CENCEncryptPatternDesc* pattern);
/**
* Copies the payload in the buffer referenced by the *data parameter into
* the buffer referenced by the out_buffer parameter. The data is simply
* copied. The definition of OEMCrypto_DestBufferDesc and subsample_flags are
* the same as in OEMCrypto_DecryptCENC(), above.
*
* The main difference between this and DecryptCENC is that this function may be
* used before a license is loaded into a session. In particular, an application
* will use this to copy the clear leader of a video to a secure buffer while
* the license request is being generated, sent to the server, and the response
* is being processed. This functionality is needed because an application may
* not have read or write access to a secure destination buffer.
*
* NOTES:
*
* This method may be called several times before the data is used. The first
* buffer in a chunk of data will have the OEMCrypto_FirstSubsample bit set
* in subsample_flags. The last buffer in a chunk of data will have the
* OEMCrypto_LastSubsample bit set in subsample_flags. The data will not be
* used until after OEMCrypto_LastSubsample has been set. If an
* implementation copies data immediately, it may ignore subsample_flags.
*
* If the destination buffer is secure, an offset may be specified.
* CopyBuffer begins storing data out_buffer->secure.offset bytes after the
* beginning of the secure buffer.
*
* @verification
* The following checks should be performed.
* 1. If either data or out_buffer is null, return
* OEMCrypto_ERROR_INVALID_CONTEXT.
*
* @param[in] session: crypto session identifier.
* @param[in] data_addr: An unaligned pointer to the buffer to be copied.
* @param[in] data_addr_length: The length of the buffer, in bytes.
* @param[in] out_buffer_descriptor: A caller-owned descriptor that specifies
* the handling of the byte stream. See OEMCrypto_DestBufferDesc for details.
* @param[in] subsample_flags: bitwise flags indicating if this is the first,
* middle, or last subsample in a chunk of data. 1 = first subsample, 2 =
* last subsample, 3 = both first and last subsample, 0 = neither first nor
* last subsample.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE if the input buffer is too large,
* and should be partitioned.
* @retval OEMCrypto_ERROR_SHORT_BUFFER if the destination buffer is shorter
* than the source
* @retval OEMCrypto_ERROR_OUTPUT_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @buffer_size
* OEMCrypto shall support subsample sizes and sample sizes as specified in
* OEMCrypto_ResourceRatingTier(). This function will only be given a single
* sample. OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the
* buffer is larger than the supported size. If OEMCrypto returns
* OEMCrypto_ERROR_BUFFER_TOO_LARGE, the calling function must break the
* buffer into smaller chunks. For high performance devices, OEMCrypto should
* handle larger buffers. We encourage OEMCrypto implementers not to
* artificially restrict the maximum buffer size. If OEMCrypto detects that
* the output data is too large, and breaking the buffer into smaller
* subsamples will not work, then it returns
* OEMCrypto_ERROR_OUTPUT_TOO_LARGE. This error will bubble up to the
* application, which can decide to skip the current frame of video or to
* switch to a lower resolution.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is changed in API version 15.
*/
OEMCryptoResult OEMCrypto_CopyBuffer(
OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* data_addr,
size_t data_addr_length,
const OEMCrypto_DestBufferDesc* out_buffer_descriptor,
uint8_t subsample_flags);
/**
* This function encrypts a generic buffer of data using the given key.
*
* OEMCrypto shall be able to handle buffers at least 100 KiB long.
*
* #### Bypass Decrypt
*
* Platforms that wish to support Bypass Decrypt are still required to implement
* this function. For more information on Bypass Decrypt, see the
* [Bypass Decrypt](../../bypass) documentation.
*
* #### Non-Bypass Decrypt
*
* For platforms that do not need to support Bypass Decrypt, a mode compatible
* with previous versions of OEMCrypto is available. The "key handle" created by
* OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be
* used the same as the session ID previously passed to OEMCrypto_DecryptCENC().
*
* If the device is not bypassing, it must update the ODK clock values in this
* function call. If this is the first use of a key for this session, then
* OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock
* values and verify playback is allowed. If this is not the first use of a key
* for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See
* [ODK Clocks and Timers](../../odk-timers) for handling the return value of
* these ODK functions.
*
* @verification
* The following checks should be performed. If any check fails, an error is
* returned, and the data is not encrypted.
* 1. The control bit for the key shall have the Allow_Encrypt set. If not,
* return OEMCrypto_ERROR_UNKNOWN_FAILURE.
* 2. If the key has an entry in the Usage Table, and the status of that
* entry is either kInactiveUsed or kInactiveUnused, then return the
* error OEMCrypto_ERROR_LICENSE_INACTIVE.
*
* @param[in] key_handle: pointer to a buffer containing the key handle for a
* key previously installed with OEMCrypto_GetKeyHandle().
* @param[in] key_handle_length: length of the data in the key_handle buffer, in
* bytes.
* @param[in] in_buffer: pointer to memory containing data to be encrypted.
* @param[in] in_buffer_length: length of the buffer, in bytes. The algorithm
* may restrict in_buffer_length to be a multiple of block size.
* @param[in] iv: IV for encrypting data. Size is 128 bits.
* @param[in] algorithm: Specifies which encryption algorithm to use.
* Currently, only CBC 128 mode is allowed for encryption.
* @param[out] out_buffer: pointer to buffer in which encrypted data should be
* stored.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_KEY_EXPIRED
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
*
* @buffer_size
* OEMCrypto shall support buffer sizes of at least 100 KiB for generic
* crypto operations.
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for the session containing the key. It will not be called simultaneously
* with initialization or usage table functions. It is as if the CDM holds a
* write lock for the key's session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 18.
*/
OEMCryptoResult OEMCrypto_Generic_Encrypt(
const uint8_t* key_handle, size_t key_handle_length,
const OEMCrypto_SharedMemory* in_buffer, size_t in_buffer_length,
const uint8_t* iv, OEMCrypto_Algorithm algorithm,
OEMCrypto_SharedMemory* out_buffer);
/**
* This function decrypts a generic buffer of data using the given key.
*
* OEMCrypto should be able to handle buffers at least 100 KiB long.
*
* #### Bypass Decrypt
*
* Platforms that wish to support Bypass Decrypt are still required to implement
* this function. For more information on Bypass Decrypt, see the
* [Bypass Decrypt](../../bypass) documentation.
*
* #### Non-Bypass Decrypt
*
* For platforms that do not need to support Bypass Decrypt, a mode compatible
* with previous versions of OEMCrypto is available. The "key handle" created by
* OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be
* used the same as the session ID previously passed to OEMCrypto_DecryptCENC().
*
* If the device is not bypassing, it must update the ODK clock values in this
* function call. If this is the first use of a key for this session, then
* OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock
* values and verify playback is allowed. If this is not the first use of a key
* for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See
* [ODK Clocks and Timers](../../odk-timers) for handling the return value of
* these ODK functions.
*
* @verification
* The following checks should be performed. If any check fails, an error is
* returned, and the data is not decrypted.
* 1. The control bit for the key shall have the Allow_Decrypt set. If not,
* return OEMCrypto_ERROR_DECRYPT_FAILED.
* 2. If the key's control block has the Data_Path_Type bit set, then return
* OEMCrypto_ERROR_DECRYPT_FAILED.
* 3. If the key has an entry in the Usage Table, and the status of that
* entry is either kInactiveUsed or kInactiveUnused, then return the
* error OEMCrypto_ERROR_LICENSE_INACTIVE.
*
* @param[in] key_handle: pointer to a buffer containing the key handle for a
* key previously installed with OEMCrypto_GetKeyHandle().
* @param[in] key_handle_length: length of the data in the key_handle buffer, in
* bytes.
* @param[in] in_buffer: pointer to memory containing data to be encrypted.
* @param[in] in_buffer_length: length of the buffer, in bytes. The algorithm
* may restrict in_buffer_length to be a multiple of block size.
* @param[in] iv: IV for encrypting data. Size is 128 bits.
* @param[in] algorithm: Specifies which encryption algorithm to use.
* Currently, only CBC 128 mode is allowed for decryption.
* @param[out] out_buffer: pointer to buffer in which decrypted data should be
* stored.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_KEY_EXPIRED
* @retval OEMCrypto_ERROR_DECRYPT_FAILED
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
*
* @buffer_size
* OEMCrypto shall support buffer sizes of at least 100 KiB for generic
* crypto operations.
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for the session containing the key. It will not be called simultaneously
* with initialization or usage table functions. It is as if the CDM holds a
* write lock for the key's session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 18.
*/
OEMCryptoResult OEMCrypto_Generic_Decrypt(
const uint8_t* key_handle, size_t key_handle_length,
const OEMCrypto_SharedMemory* in_buffer, size_t in_buffer_length,
const uint8_t* iv, OEMCrypto_Algorithm algorithm,
OEMCrypto_SharedMemory* out_buffer);
/**
* This function signs a generic buffer of data using the given key.
*
* #### Bypass Decrypt
*
* Platforms that wish to support Bypass Decrypt are still required to implement
* this function. For more information on Bypass Decrypt, see the
* [Bypass Decrypt](../../bypass) documentation.
*
* #### Non-Bypass Decrypt
*
* For platforms that do not need to support Bypass Decrypt, a mode compatible
* with previous versions of OEMCrypto is available. The "key handle" created by
* OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be
* used the same as the session ID previously passed to OEMCrypto_DecryptCENC().
*
* If the device is not bypassing, it must update the ODK clock values in this
* function call. If this is the first use of a key for this session, then
* OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock
* values and verify playback is allowed. If this is not the first use of a key
* for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See
* [ODK Clocks and Timers](../../odk-timers) for handling the return value of
* these ODK functions.
*
* @verification
* The following checks should be performed. If any check fails, an error is
* returned, and the data is not signed.
* 1. The control bit for the key shall have the Allow_Sign set.
* 2. If the key has an entry in the Usage Table, and the status of that
* entry is either kInactiveUsed or kInactiveUnused, then return the
* error OEMCrypto_ERROR_LICENSE_INACTIVE.
*
* @param[in] key_handle: pointer to a buffer containing the key handle for a
* key previously installed with OEMCrypto_GetKeyHandle().
* @param[in] key_handle_length: length of the data in the key_handle buffer, in
* bytes.
* @param[in] buffer: pointer to memory containing data to be encrypted.
* @param[in] buffer_length: length of the buffer, in bytes.
* @param[in] algorithm: Specifies which algorithm to use.
* @param[out] signature: pointer to buffer in which signature should be
* stored. May be null on the first call in order to find required buffer
* size.
* @param[in,out] signature_length: (in) length of the signature buffer, in
* bytes. (out) actual length of the signature
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_KEY_EXPIRED
* @retval OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough
* to hold the output signature.
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
*
* @buffer_size
* OEMCrypto shall support buffer sizes of at least 100 KiB for generic
* crypto operations.
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for the session containing the key. It will not be called simultaneously
* with initialization or usage table functions. It is as if the CDM holds a
* write lock for the key's session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 18.
*/
OEMCryptoResult OEMCrypto_Generic_Sign(const uint8_t* key_handle,
size_t key_handle_length,
const OEMCrypto_SharedMemory* buffer,
size_t buffer_length,
OEMCrypto_Algorithm algorithm,
OEMCrypto_SharedMemory* signature,
size_t* signature_length);
/**
* This function verifies the signature of a generic buffer of data using the
* given key.
*
* #### Bypass Decrypt
*
* Platforms that wish to support Bypass Decrypt are still required to implement
* this function. For more information on Bypass Decrypt, see the
* [Bypass Decrypt](../../bypass) documentation.
*
* #### Non-Bypass Decrypt
*
* For platforms that do not need to support Bypass Decrypt, a mode compatible
* with previous versions of OEMCrypto is available. The "key handle" created by
* OEMCrypto_GetKeyHandle() is the session ID, as described above, and can be
* used the same as the session ID previously passed to OEMCrypto_DecryptCENC().
*
* If the device is not bypassing, it must update the ODK clock values in this
* function call. If this is the first use of a key for this session, then
* OEMCrypto shall call ODK_AttemptFirstPlayback to update the session's clock
* values and verify playback is allowed. If this is not the first use of a key
* for this session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See
* [ODK Clocks and Timers](../../odk-timers) for handling the return value of
* these ODK functions.
*
* @verification
* The following checks should be performed. If any check fails, an error is
* returned.
* 1. The control bit for the key shall have the Allow_Verify set.
* 2. The signature of the message shall be computed, and the API shall
* verify the computed signature matches the signature passed in. If
* not, return OEMCrypto_ERROR_SIGNATURE_FAILURE.
* 3. The signature verification shall use a constant-time algorithm (a
* signature mismatch will always take the same time as a successful
* comparison).
* 4. If the key has an entry in the Usage Table, and the status of that
* entry is either kInactiveUsed or kInactiveUnused, then return the
* error OEMCrypto_ERROR_LICENSE_INACTIVE.
*
* @param[in] key_handle: pointer to a buffer containing the key handle for a
* key previously installed with OEMCrypto_GetKeyHandle().
* @param[in] key_handle_length: length of the data in the key_handle buffer, in
* bytes.
* @param[in] buffer: pointer to memory containing data to be encrypted.
* @param[in] buffer_length: length of the buffer, in bytes.
* @param[in] algorithm: Specifies which algorithm to use.
* @param[in] signature: pointer to buffer in which signature resides.
* @param[in] signature_length: length of the signature buffer, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_KEY_EXPIRED
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION
*
* @buffer_size
* OEMCrypto shall support buffer sizes of at least 100 KiB for generic
* crypto operations.
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for the session containing the key. It will not be called simultaneously
* with initialization or usage table functions. It is as if the CDM holds a
* write lock for the key's session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 18.
*/
OEMCryptoResult OEMCrypto_Generic_Verify(
const uint8_t* key_handle, size_t key_handle_length,
const OEMCrypto_SharedMemory* buffer, size_t buffer_length,
OEMCrypto_Algorithm algorithm, const OEMCrypto_SharedMemory* signature,
size_t signature_length);
/// @}
/// @addtogroup factory_provision
/// @{
/**
* A device should be provisioned at the factory with either an OEM
* Certificate or a keybox. We will call this data the root of trust. During
* manufacturing, the root of trust should be encrypted with the OEM root key
* and stored on the file system in a region that will not be erased during
* factory reset. This function may be used by legacy systems that use the
* two-step WrapKeyboxOrOEMCert()/InstallKeyboxOrOEMCert() approach. When the
* Widevine DRM plugin initializes, it will look for a wrapped root of trust
* in the file /factory/wv.keys and install it into the security processor by
* calling OEMCrypto_InstallKeyboxOrOEMCert().
*
* ![OEMCrypto_WrapKeyboxOrOEMCert Operation](fig1.svg)
*
* OEMCrypto_WrapKeyboxOrOEMCert() is used to generate an OEM-encrypted root
* of trust that may be passed to OEMCrypto_InstallKeyboxOrOEMCert() for
* provisioning. The root of trust may be either passed in the clear or
* previously encrypted with a transport key. If a transport key is supplied,
* the keybox is first decrypted with the transport key before being wrapped
* with the OEM root key. This function is only needed if the root of trust
* provisioning method involves saving the keybox or OEM Certificate to the
* file system.
*
* @param[in] keybox_or_cert: pointer to root of trust data to encrypt -- this
* is either a keybox or an OEM Certificate private key. May be NULL on the
* first call to test the size of the wrapped keybox. The keybox may either
* be clear or previously encrypted.
* @param[in] keybox_or_cert_length: length the keybox or cert data in bytes
* @param[out] wrapped_keybox_or_cert: Pointer to wrapped keybox or cert
* @param[in,out] wrapped_keybox_or_cert_length: Pointer to the length of the
* wrapped keybox or certificate key in bytes
* @param[in] transport_key: Optional. AES transport key. If provided, the
* keybox_or_cert parameter was previously encrypted with this key. The
* keybox will be decrypted with the transport key using AES-CBC and a null
* IV.
* @param[in] transport_key_length: Optional. Number of bytes in the
* transport_key, if used.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_WRITE_KEYBOX failed to encrypt the keybox
* @retval OEMCrypto_ERROR_SHORT_BUFFER if keybox is provided as NULL, to
* determine the size of the wrapped keybox
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system.
*
* @version
* This method is supported in all API versions.
*/
OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert(
const uint8_t* keybox_or_cert, size_t keybox_or_cert_length,
uint8_t* wrapped_keybox_or_cert, size_t* wrapped_keybox_or_cert_length,
const uint8_t* transport_key, size_t transport_key_length);
/**
* Decrypts a wrapped root of trust and installs it in the security
* processor. The root of trust is unwrapped then encrypted with the OEM root
* key. This function is called from the Widevine DRM plugin at
* initialization time if there is no valid root of trust installed. It looks
* for wrapped data in the file /factory/wv.keys and if it is present, will
* read the file and call OEMCrypto_InstallKeyboxOrOEMCert() with the
* contents of the file. This function is only needed if the factory
* provisioning method involves saving the keybox or OEM Certificate to the
* file system.
*
* ![InstallKeyboxOrOEMCert](fig10.svg)
*
* @param[in] keybox_or_cert: pointer to encrypted data as input
* @param[in] keybox_or_cert_length: length of the data in bytes
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_BAD_MAGIC
* @retval OEMCrypto_ERROR_BAD_CRC
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system.
*
* @version
* This method is supported in all API versions.
*/
OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(const uint8_t* keybox_or_cert,
size_t keybox_or_cert_length);
/**
* Install a factory generated signature for the BCC. This is for devices that
* use Provisioning 4.0, with the signing option in the factory. With the
* signing option, the BCC is extracted from the device in the factory. Instead
* of being uploaded to the Widevine server, the BCC is signed by a certificate
* that the manufacturer shares with Widevine. The signature is then installed
* on the device is a secure location. The signature must not be erased during
* factory reset.
*
* This signature should be returned as `addition_signature` in a call to the
* function `OEMCrypto_GetBootCertificateChain()`.
*
* Devices that do not support Provisioning 4.0, or only support Provisioning
* 4.0 Option 1 should return OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
*
* @param[in] signature: pointer to data as input
* @param[in] signature_length: length of the data in bytes
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system.
*
* @version
* This method is new in API version 18.3.
*/
OEMCryptoResult OEMCrypto_FactoryInstallBCCSignature(const uint8_t* signature,
size_t signature_length);
/**
* This function is for OEMCrypto to tell the layer above what provisioning
* method it uses: keybox or OEM certificate.
*
* @retval OEMCrypto_DrmCertificate means the device has a DRM certificate built
* into the system. This cannot be used by level 1 devices. This
* provisioning method is deprecated and should not be used on new
* devices. OEMCertificate provisioning should be used instead.
* @retval OEMCrypto_Keybox means the device has a unique keybox. For level 1
* devices this keybox must be securely installed by the device
* manufacturer.
* @retval OEMCrypto_OEMCertificate means the device has a factory installed OEM
* certificate. This is also called Provisioning 3.0.
* @retval OEMCrypto_ProvisioningError indicates a serious problem with the
* OEMCrypto library.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new API version 12.
*/
OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod(void);
/**
* If the device has a keybox, this validates the Widevine Keybox loaded into
* the security processor device. This method verifies two fields in the
* keybox:
*
* - Verify the MAGIC field contains a valid signature (such as,
* 'k''b''o''x').
* - Compute the CRC using CRC-32-POSIX-1003.2 standard and compare the
* checksum to the CRC stored in the Keybox.
* The CRC is computed over the entire Keybox excluding the 4 bytes of the
* CRC (for example, Keybox[0..123]). For a description of the fields stored
* in the keybox, see Keybox Definition in the
* [Provisioning 2.0](../../index#prov20) section of the integration guide.
*
* If the device has an OEM Certificate, this validates the certificate
* private key.
*
* On devices that support OEMCrypto_GenerateOTARequest() and
* OEMCrypto_ProcessOTAKeybox(), this function may return
* OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING when a valid keybox is not present.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_BAD_MAGIC
* @retval OEMCrypto_ERROR_BAD_CRC
* @retval OEMCrypto_ERROR_KEYBOX_INVALID
* @retval OEMCrypto_ERROR_INVALID_KEY
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is supported in all API versions.
*/
OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void);
/**
* Return a device unique id. For devices with a keybox, retrieve the
* DeviceID from the Keybox. For devices that have an OEM Certificate, or if
* provisioning 4 is used, it should set the device ID to a device-unique
* string, such as the device serial number or a hash of the device public key
* in boot certificate chain. The ID should be device-unique and it should be
* stable -- i.e. it should not change across a device reboot or a system
* upgrade. This shall match the device id found in the core provisioning
* request message. The maximum length of the device id is 64 bytes. The
* device ID field in a keybox is 32 bytes.
*
* @param[out] device_id: pointer to the buffer that receives the Device ID.
* @param[in,out] device_id_length - on input, size of the caller's device ID
* buffer. On output, the number of bytes written into the buffer.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return
* device ID
* @retval OEMCrypto_ERROR_NO_DEVICEID failed to return Device Id
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is supported in all API versions.
*/
OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* device_id,
size_t* device_id_length);
/// @}
/// @addtogroup keybox
/// @{
/**
* Return the Key Data field from the Keybox.
*
* @param[out] key_data: pointer to the buffer to hold the Key Data field from
* the Keybox
* @param[in,out] key_data_length: on input, the allocated buffer size. On
* output, the number of bytes in Key Data
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return
* KeyData
* @retval OEMCrypto_ERROR_NO_KEYDATA
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED: this function is for
* Provisioning 2.0 only.
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is supported in all API versions.
*/
OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* key_data,
size_t* key_data_length);
/// @}
/// @addtogroup test_verify
/// @{
/**
* Temporarily use the specified test keybox until the next call to
* OEMCrypto_Terminate(). This allows a standard suite of unit tests to be run
* on a production device without permanently changing the keybox. Using the
* test keybox is not persistent. OEMCrypto cannot assume that this keybox is
* the same as previous keyboxes used for testing.
*
* Devices that use an OEM Certificate instead of a keybox (i.e. Provisioning
* 3.0) do not need to support this functionality, and may return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* @param[in] buffer: pointer to memory containing test keybox, in binary form.
* @param[in] buffer_length: length of the buffer, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED this function is for
* Provisioning 2.0 only.
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system. It is called after OEMCrypto_Initialize() and
* after OEMCrypto_GetProvisioningMethod() and only if the provisoining method
* is OEMCrypto_Keybox,
*
* @version
* This method changed in API version 14.
*/
OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
size_t buffer_length);
/// @}
/// @addtogroup oem_cert
/// @{
/**
* After a call to this function, all session functions using an RSA key
* should use the OEM certificate's private RSA key. See the section
* discussing [Provisioning 3.0](../../index#prov30) section of the integration
* guide.
*
* @param[in] session: this function affects the specified session only.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED this function is for
* Provisioning 3.0 only.
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new API version 16.
*/
OEMCryptoResult OEMCrypto_LoadOEMPrivateKey(OEMCrypto_SESSION session);
/**
* This function should place the OEM public certificate in the buffer
* public_cert. See the section discussing
* [Provisioning 3.0](../../index#prov30) section of the integration guide.
*
* If the buffer is not large enough, OEMCrypto should update
* public_cert_length and return OEMCrypto_ERROR_SHORT_BUFFER.
*
* @param[out] public_cert: the buffer where the public certificate is stored.
* @param[in,out] public_cert_length: on input, this is the available size of
* the buffer. On output, this is the number of bytes needed for the
* certificate.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED this function is for
* Provisioning 3.0 only.
* @retval OEMCrypto_ERROR_SHORT_BUFFER
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new API version 16.
*/
OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(uint8_t* public_cert,
size_t* public_cert_length);
/// @}
/// @addtogroup validation
/// @{
/** Specifies OEMCrypto security level.
*/
typedef enum OEMCrypto_Security_Level {
OEMCrypto_Level_Unknown = 0,
OEMCrypto_Level1 = 1,
OEMCrypto_Level2 = 2,
OEMCrypto_Level3 = 3,
} OEMCrypto_Security_Level;
/**
* This function returns the current API version number. The version number
* allows the calling application to avoid version mis-match errors, because
* this API is part of a shared library.
*
* There is a possibility that some API methods will be backwards compatible,
* or backwards compatible at a reduced security level.
*
* There is no plan to introduce forward-compatibility. Applications will
* reject a library with a newer version of the API.
*
* The version specified in this document is 16. Any OEM that returns this
* version number guarantees it passes all unit tests associated with this
* version.
*
* @return
* The supported API, as specified in the header file OEMCryptoCENC.h.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in each API version.
*/
uint32_t OEMCrypto_APIVersion(void);
/**
* This function returns the current API minor version number. The version
* number allows the calling application to avoid version mis-match errors,
* because this API is part of a shared library.
*
* The minor version specified in this document is 2. Any OEM that returns
* this version number guarantees it passes all unit tests associated with
* this version.
*
* @return
* The supported API, as specified in the header file OEMCryptoCENC.h.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in each API version.
*/
uint32_t OEMCrypto_MinorAPIVersion(void);
/**
* Stores the build information of the OEMCrypto library in a buffer. This
* string should be updated with each release or OEMCrypto build.
*
* It may be used for logging or bug tracking and may be bubbled up to the
* app so that it may track metrics on errors.
*
* The returned string must be JSON formatted. It shall also contain the
* following top level values [data types in brackets]:
* - "soc_vendor" [string]: SOC manufacturer name
* - "soc_model" [string]: SOC model name
* - "ta_ver" [string]: TA version in string format eg "1.12.3+tag", "2.0"
* - "uses_opk" [bool]: Whether TA was built with Widevine's OPK
* - "tee_os" [string]: Trusted OS intended to run the TA, eg "Trusty", "QSEE",
* "OP-TEE"
* - "tee_os_ver" [string]: Version of Trusted OS intended to run the TA
* - "is_debug" [bool]: Whether this is a debug build of the TA. Debug builds
* can enter Test Mode via OEMCrypto_EnterTestMode(), while production builds
* cannot. Debug builds are not released to the public.
*
* While not required, the following top level fields are recommended:
* - "implementer" [string]: Name of company or entity that provides OEMCrypto.
* Important if not SOC vendor.
* - "git_commit" [string]: Git commit hash of the code repository that
* produced the TA build. Useful for implementers to distinguish the state of
* different TA builds.
* - "build_timestamp" [string]: ISO 8601 formatted timestamp of the time the
* TA was compiled, eg "YYYY-MM-DDTHH:MM:SS"
* - "is_factory_mode" [bool]: Whether this was built with FACTORY_MODE_ONLY
* defined
*
* While not required, another optional top level struct can be added to the
* build information string to provide information about liboemcrypto.so:
* - "ree" {
* - "liboemcrypto_ver" [string]: liboemcrypto.so version in string format
* eg "2.15.0+tag". Note that this is separate from the "ta_ver" field
* above, since this section is specific to the liboemcrypto.so binary.
* - "git_commit" [string]: git hash of code that compiled liboemcrypto.so
* - "build_timestamp" [string]: ISO 8601 timestamp for when
* liboemcrypto.so was built
* }
*
* The JSON string can contain other values, structs, arrays, etc in addition to
* the above, if desired.
*
* If buffer_length is not enough, the function will return
* OEMCrypto_ERROR_SHORT_BUFFER. Before returning OEMCrypto_ERROR_SHORT_BUFFER,
* the function should set buffer_length to the length of buffer needed. If the
* write is successful, buffer_length will be set to the number of bytes
* written.
*
* The returned data shall be no larger than 1024 bytes. If the buffer length is
* larger, this function will return OEMCrypto_ERROR_BUFFER_TOO_LARGE and set
* |buffer_length| to 1024.
*
* @param[out] buffer: pointer to the buffer that receives build information
* @param[in,out] buffer_length: length of the data buffer in bytes
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small.
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is too large.
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE any other failure.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in each API version.
*/
OEMCryptoResult OEMCrypto_BuildInformation(char* buffer, size_t* buffer_length);
/**
* This function returns the current patch level of the software running in
* the trusted environment. The patch level is defined by the OEM, and is
* only incremented when a security update has been added.
*
* See the section [Security Patch Level](../../index#security_patch_level)
* for more details.
*
* @return
* The OEM defined version number.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method was introduced in API version 11.
*/
uint8_t OEMCrypto_Security_Patch_Level(void);
/**
* Returns a string specifying the security level of the library.
*
* Since this function is spoofable, it is not relied on for security
* purposes. It is for information only.
*
* @return A security level enum. Values are OEMCrypto_Level_Unknown,
* OEMCrypto_Level1, OEMCrypto_Level2 and OEMCrypto_Level3.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 17.
*/
OEMCrypto_Security_Level OEMCrypto_SecurityLevel(void);
/**
* Returns the maximum HDCP version supported by the device, and the HDCP
* version supported by the device and any connected display.
*
* Valid values for HDCP_Capability are:
*
* The value 0xFF means the device is using a local, secure, data path
* instead of HDMI output. Notice that HDCP must use flag Type 1: all
* downstream devices will also use the same version or higher.
*
* The maximum HDCP level should be the maximum value that the device can
* enforce. For example, if the device has an HDCP 1.0 port and an HDCP 2.0
* port, and the first port can be disabled, then the maximum is HDCP 2.0. If
* the first port cannot be disabled, then the maximum is HDCP 1.0. The
* maximum value can be used by the application or server to decide if a
* license may be used in the future. For example, a device may be connected
* to an external display while an offline license is downloaded, but the
* user intends to view the content on a local display. The user will want to
* download the higher quality content.
*
* The current HDCP level should be the level of HDCP currently negotiated
* with any connected receivers or repeaters either through HDMI or a
* supported wireless format. If multiple ports are connected, the current
* level should be the minimum HDCP level of all ports. If the key control
* block requires an HDCP level equal to or lower than the current HDCP
* level, the key is expected to be usable. If the key control block requires
* a higher HDCP level, the key is expected to be forbidden.
*
* When a key has version HDCP_V2_3 required in the key control block, the
* transmitter must have HDCP version 2.3 and have negotiated a connection
* with a version 2.2 or 2.3 receiver or repeater. The transmitter must
* configure the content stream to be Type 1. Since the transmitter cannot
* distinguish between 2.2 and 2.3 downstream receivers when connected to a
* repeater, it may transmit to both 2.2 and 2.3 receivers, but not 2.1
* receivers.
*
* For example, if the transmitter is 2.3, and is connected to a receiver
* that supports 2.3 then the current level is HDCP_V2_3. If the transmitter
* is 2.3 and is connected to a 2.3 repeater, the current level is HDCP_V2_3
* even though the repeater can negotiate a connection with a 2.2 downstream
* receiver for a Type 1 Content Stream.
*
* As another example, if the transmitter can support 2.3, but a receiver
* supports 2.0, then the current level is HDCP_V2.
*
* When a license requires HDCP, a device may use a wireless protocol to
* connect to a display only if that protocol supports the version of HDCP as
* required by the license. Both WirelessHD (formerly WiFi Display) and
* Miracast support HDCP.
*
* @param[out] current: this is the current HDCP version, based on the device
* itself, and the display to which it is connected.
* @param[out] maximum: this is the maximum supported HDCP version for the
* device, ignoring any attached device.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 10.
*/
OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability* current,
OEMCrypto_HDCP_Capability* maximum);
/**
* Returns the DTCP2 support for a device.
*
* @param[out] capability: this will be set to 0 if DTCP2 is not supported,
* and 1 if the device supports at least v1 of DTCO2.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_GetDTCP2Capability(
OEMCrypto_DTCP2_Capability* capability);
/**
* This is used to determine if the device can support a usage table. Since
* this function is spoofable, it is not relied on for security purposes. It
* is for information only. The usage table is described in the section above.
*
* @return
* Returns true if the device can maintain a usage table. Returns false
* otherwise.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 9.
*/
bool OEMCrypto_SupportsUsageTable(void);
/**
* Estimates the maximum usage table size. If the device does not have a
* fixed size, this returns an estimate. A maximum size of 0 means the header
* is constrained only by dynamic memory allocation.
*
* Widevine requires the size to be at least 300 entries.
*
* @return
* Returns an estimate for the maximum size of the usage table header.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 16.
*/
size_t OEMCrypto_MaximumUsageTableHeaderSize(void);
/**
* Indicate whether there is hardware protection to detect and/or prevent the
* rollback of the usage table. For example, if the usage table contents is
* stored entirely on a secure file system that the user cannot read or write
* to. Another example is if the usage table has a generation number and the
* generation number is stored in secure memory that is not user accessible.
*
* @return Returns true if oemcrypto uses anti-rollback hardware. Returns false
* otherwise.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 10.
*/
bool OEMCrypto_IsAntiRollbackHwPresent(void);
/**
* Returns the current number of open sessions. The CDM and OEMCrypto
* consumers can query this value so they can use resources more effectively.
*
* @param[out] count: this is the current number of opened sessions.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 10.
*/
OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(size_t* count);
/**
* Returns the maximum number of concurrent OEMCrypto sessions supported by
* the device. The CDM and OEMCrypto consumers can query this value so they
* can use resources more effectively. If the maximum number of sessions
* depends on a dynamically allocated shared resource, the returned value
* should be a best estimate of the maximum number of sessions.
*
* OEMCrypto shall support a minimum of 10 sessions. Some applications use
* multiple sessions to pre-fetch licenses, so high end devices should
* support more sessions -- we recommend a minimum of 50 sessions.
*
* @param[out] max: this is the max number of supported sessions.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 12.
*/
OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* max);
/**
* Returns the type of certificates keys that this device supports. With very
* few exceptions, all devices should support at least 2048 bit RSA keys.
* High end devices should also support 3072 bit RSA keys. Devices that are
* cast receivers should also support RSA cast receiver certificates.
*
* Beginning with OEMCrypto v14, the provisioning server may deliver to the
* device an RSA key that uses the Carmichael totient. This does not change
* the RSA algorithm -- however the product of the private and public keys is
* not necessarily the Euler number \phi (n). OEMCrypto should not reject
* such keys.
*
* @return
* Returns the bitwise or of the following flags. It is likely that high end
* devices will support both 2048 and 3072 bit keys while the widevine
* servers transition to new key sizes.
* - 0x1 = OEMCrypto_Supports_RSA_2048bit - the device can load a DRM
* certificate with a 2048 bit RSA key.
* - 0x2 = OEMCrypto_Supports_RSA_3072bit - the device can load a DRM
* certificate with a 3072 bit RSA key.
* - 0x10 = OEMCrypto_Supports_RSA_CAST - the device can load a CAST
* certificate. These certificates are used with
* OEMCrypto_GenerateRSASignature() with padding type set to 0x2, PKCS1
* with block type 1 padding.
* - 0x100 = OEMCrypto_Supports_ECC_secp256r1 - Elliptic Curve secp256r1
* - 0x200 = OEMCrypto_Supports_ECC_secp384r1 - Elliptic Curve secp384r1
* - 0x400 = OEMCrypto_Supports_ECC_secp521r1 - Elliptic Curve secp521r1
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 16.
*/
uint32_t OEMCrypto_SupportedCertificates(void);
/**
* Returns the version number of the current SRM file. If the device does not
* support SRM files, this will return OEMCrypto_ERROR_NOT_IMPLEMENTED. If
* the device only supports local displays, it would return
* OEMCrypto_LOCAL_DISPLAY_ONLY. If the device has an SRM, but cannot use
* OEMCrypto to update the SRM, then this function would set version to be
* the current version number, and return OEMCrypto_SUCCESS, but it would
* return false from OEMCrypto_IsSRMUpdateSupported().
*
* @param[out] version: current SRM version number.
*
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_LOCAL_DISPLAY_ONLY to indicate version was not set, and
* is not needed.
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 13.
*/
OEMCryptoResult OEMCrypto_GetCurrentSRMVersion(uint16_t* version);
/**
* Returns whether the device supports analog output or not. This information
* will be sent to the license server, and may be used to determine the type
* of license allowed. This function is for reporting only. It is paired with
* the key control block flags Disable_Analog_Output and CGMS.
*
* @return
* Returns a bitwise OR of all possible return values.
* * 0x0 = OEMCrypto_No_Analog_Output: the device has no analog output.
* * 0x1 = OEMCrypto_Supports_Analog_Output: the device does have analog
* output.
* * 0x2 = OEMCrypto_Can_Disable_Analog_Ouptput: the device does have
* analog output, but it will disable analog output if required by the
* key control block.
* * 0x4 = OEMCrypto_Supports_CGMS_A: the device supports signaling 2-bit
* CGMS-A, if required by the key control block
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 14.
*/
uint32_t OEMCrypto_GetAnalogOutputFlags(void);
/**
* This function returns a positive number indicating which resource rating
* it supports. This value will bubble up to the application level as a
* property. This will allow applications to estimate what resolution and
* bandwidth the device is expected to support.
*
* OEMCrypto unit tests and Android GTS tests will verify that devices do
* support the resource values specified in the table below at the tier
* claimed by the device. If a device claims to be a low end device, the
* OEMCrypto unit tests will only verify the low end performance values.
*
* OEMCrypto implementers should consider the numbers in the table to be minimum
* values.
*
* These performance parameters are for OEMCrypto only. In particular,
* bandwidth and codec resolution are determined by the platform.
*
* See the document [Resource Rating]
* (https://developers.google.com/widevine/drm/feature/resource-rating)
* for more information and for the table of parameters.
*
*
* Here is an additional note on the number of subsamples:
*
* The table specifies the number of subsamples that partition the content when
* it is encrypted. However, if OEMCrypto_DecryptCENC() returns
* OEMCrypto_ERROR_BUFFER_TOO_LARGE, the layer above OEMCrypto will break the
* sample into more subsamples.
*
* The minimum subsample buffer size is the smallest buffer that the CDM layer
* above OEMCrypto will use when breaking a sample into subsamples. As mentioned
* above, the CDM layer will only break a sample into smaller subsamples if
* OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE. Because this might be a
* performance problem, OEMCrypto implementers are encouraged to process larger
* subsamples and to process multiple subsamples in a single call to
* DecryptCENC.
*
* The message size limit applies to all functions that sign or verify a
* message: OEMCrypto_PrepAndSignLicenseRequest(),
* OEMCrypto_PrepAndSignRenewalRequest(),
* OEMCrypto_PrepAndSignProvisioningRequest(), and OEMCrypto_LoadLicense().
*
*
* @return
* Returns an integer indicating which resource tier the device supports.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 15.
*/
uint32_t OEMCrypto_ResourceRatingTier(void);
/**
* Returns OEMCrypto_SUCCESS if the device is production ready. This is a
* new reporting mechanism that reports that OEMCrypto is production ready.
* For example, the SOC delivers OEMCrypto to the OEM which functions
* correctly whether debugging or antirollback is turned on or not. The OEM
* has the option to turn on TEE software antirollback if they wish. If anti
* rollback is off, or if debugging is enabled, then this function will
* return failure.
*
* The OEMCrypto implementer may choose any other error code if the device
* is not production ready. The motivation for this new feature is to allow
* SOCs to signal to OEMs that hardening has not been done on a system.
* During development of a device, it is fine for this function to return an
* error. During development, we expect devices to have debugging turned on.
* However, once the device is ready for production, all hardening should be
* turned on.
*
* The intention is that certification tests, such as Androids GTS test suite,
* will verify that a device is production ready. Being production ready will
* not be a requirement to pass OEMCrypto unit tests, but the status will be
* logged as part of the tests.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_ProductionReady(void);
/**
* Returns OEMCrypto_WatermarkingAlwaysOn or OEMCrypto_WatermarkingConfigurable
* if the device supports watermarking. If the device does not support
* watermarking but the license has watermarking set to accept it,
* OEMCrypto_LoadLicense should return the error
* OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE, which is a new error code in v17.
*
* If watermarking can be turned on or off for individual streams, then
* OEMCrypto should honor the settings for each license individually.
*
* If watermarking can only be turned on or off on a system wide level, then
* the most recent license should be honored. The watermarking feature should
* be turned on or off when a license is loaded. If this conflicts with a
* license that had been loaded earlier, then keys from the earlier license may
* not be used. In this case, either OEMCrypto_GetKeyHandle or
* OEMCrypto_DecryptCENC will return OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE to
* indicate that the watermarking status has changed and the license is no
* longer usable.
*
* @retval OEMCrypto_WatermarkingError
* @retval OEMCrypto_WatermarkingNotSupported
* @retval OEMCrypto_WatermarkingConfigurable
* @retval OEMCrypto_WatermarkingAlwaysOn
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 17.
*/
OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport(void);
/**
* Queries the hash algorithm that the device will use when performing
* RSASSA-PSS or ECDSA with the private key currently loaded in the given
* session.
*
* For RSA keys, SHA-1 was used for all OEMCrypto versions prior to 18, but
* SHA-256 is strongly recommended for all devices. SHA-384 and SHA-512 are not
* supported with RSA keys.
*
* For ECC keys, the algorithm chosen depends on the curve used to generate the
* key, as outlined in the OEMCrypto Integration Guide. SHA-1 is not supported
* with ECC keys.
*
* For devices that do not support ECC, it is acceptable for this function to
* return a hardcoded value, since the answer does not depend on the currently
* loaded private key.
*
* @param[in] session: crypto session identifier.
* @param[out] algorithm: the algorithm the device will use.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 18.
*/
OEMCryptoResult OEMCrypto_GetSignatureHashAlgorithm(
OEMCrypto_SESSION session, OEMCrypto_SignatureHashAlgorithm* algorithm);
/// @}
/// @addtogroup drm_cert
/// @{
/**
* Load and parse a provisioning response, and then rewrap the private key
* for storage on the filesystem. We recommend that the OEM use a strong
* encryption key and signing key algorithm.
*
* First, OEMCrypto shall verify the signature of the message using the correct
* algorithm depending on if the device supports Provisioning 2.0, 3.0 or 4.0.
*
* For Provisioning 2.0, OEMCrypto shall use the provisioning request to derive
* mac_key[server] and verify the signature of the message using HMAC-SHA256.
* The signature verification shall use a constant-time algorithm (a signature
* mismatch will always take the same time as a successful comparison). The
* signature is over the entire message buffer starting at message with length
* message_length. If the signature verification fails, ignore all other
* arguments and return OEMCrypto_ERROR_SIGNATURE_FAILURE.
*
* For Provisioning 3.0 and 4.0, the signature is not verified.
*
* After the signature is verified,
* the function ODK_ParseProvisioning is called to parse the message. If it
* returns an error, OEMCrypto shall return that error to the CDM layer. The
* function ODK_ParseProvisioning is described in the document "Widevine Core
* Message Serialization".
*
* Below, all fields are found in the struct ODK_ParsedLicense parsed_license
* returned by ODK_ParsedProvisioning.
*
* After decrypting `parsed_response->enc_private_key`, If the first four bytes
* of the buffer are the string "SIGN", then the actual RSA key begins on the
* 9th byte of the buffer. The second four bytes of the buffer is the 32 bit
* field "allowed_schemes" of type RSA_Padding_Scheme, which is used in
* OEMCrypto_GenerateRSASignature(). The value of allowed_schemes must also be
* wrapped with RSA key. We recommend storing the magic string "SIGN" with
* the key to distinguish keys that have a value for allowed_schemes from
* those that should use the default allowed_schemes. Devices that do not
* support the alternative signing algorithms may refuse to load these keys
* and return an error of OEMCrypto_ERROR_NOT_IMPLEMENTED. The main use case
* for these alternative signing algorithms is to support devices that use
* X509 certificates for authentication when acting as a ChromeCast receiver.
* This is not needed for devices that wish to send data to a ChromeCast.
*
* If the first four bytes of the buffer `enc_private_key` are not the string
* "SIGN", then this key may not be used with OEMCrypto_GenerateRSASignature().
*
* Verification and Algorithm:
* The following checks should be performed. If any check fails, an error is
* returned, and the key is not loaded.
* 1. Check that all the pointer values passed into it are within the
* buffer specified by message and message_length.
* 2. Verify that (in) wrapped_private_key_length is large enough to hold
* the rewrapped key, returning OEMCrypto_ERROR_SHORT_BUFFER otherwise.
* 3. Verify the message signature, using the derived signing key
* (mac_key[server]).
* 4. The function ODK_ParseProvisioning is called to parse the message.
* 5. Decrypt enc_private_key in the buffer private_key using the session's
* derived encryption key (enc_key). Use enc_private_key_iv as the initial
* vector for AES_128-CBC mode, with PKCS#5 padding. The private_key should
* be kept in secure memory and protected from the user.
* 6. If the first four bytes of the buffer private_key are the string "SIGN",
* then the actual RSA key begins on the 9th byte of the buffer. The
* second four bytes of the buffer is the 32 bit field
* "allowed_schemes", of type RSA_Padding_Scheme, which is used in
* OEMCrypto_GenerateRSASignature(). The value of allowed_schemes must
* also be wrapped with RSA key. We recommend storing the magic string
* "SIGN" with the key to distinguish keys that have a value for
* allowed_schemes from those that should use the default
* allowed_schemes. Devices that do not support the alternative signing
* algorithms may refuse to load these keys and return an error of
* OEMCrypto_ERROR_NOT_IMPLEMENTED. The main use case for these
* alternative signing algorithms is to support devices that use X.509
* certificates for authentication when acting as a ChromeCast receiver.
* This is not needed for devices that wish to send data to a ChromeCast.
* 7. If the first four bytes of the buffer private_key are not the string
* "SIGN", this key may not be used with OEMCrypto_GenerateRSASignature().
* 8. After possibly skipping past the first 8 bytes signifying the allowed
* signing algorithm, the rest of the buffer private_key contains an ECC
* private key or an RSA private key in PKCS#8 binary DER encoded
* format. The OEMCrypto library shall verify that this private key is
* valid.
* 9. Re-encrypt the device private key with an internal key (such as one
* derived by the OEM key or Widevine Keybox key) and the generated IV
* using AES-128-CBC with PKCS#5 padding. The data should also be
* signed. This algorithm is just a suggestion. The implementer may use any
* suitable encrypting and validation algorithm with a key that ties it to
* the device.
* 10. Copy the rewrapped key to the buffer specified by wrapped_private_key
* and the size of the wrapped key to wrapped_private_key_length.
*
* @param[in] session: crypto session identifier.
* @param[in] provision_request: the initial provisioning request.
* @param[in] provision_request_length: length of provision_request, in bytes.
* @param[in] message: pointer to memory containing data.
* @param[in] message_length: length of the message, in bytes.
* @param[in] core_message_length: length of the core submessage, in bytes.
* @param[in] signature: pointer to memory containing the signature.
* @param[in] signature_length: length of the signature, in bytes.
* @param[out] wrapped_private_key: pointer to buffer in which encrypted RSA or
* ECC private key should be stored. May be null on the first call in order
* to find required buffer size.
* @param[in,out] wrapped_private_key_length: (in) length of the encrypted
* private key, in bytes. (out) actual length of the encrypted private key
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_KEY
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE
* @retval OEMCrypto_ERROR_INVALID_NONCE
* @retval OEMCrypto_ERROR_SHORT_BUFFER
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_LoadProvisioning(
OEMCrypto_SESSION session, const uint8_t* provision_request,
size_t provision_request_length, const uint8_t* message,
size_t message_length, size_t core_message_length, const uint8_t* signature,
size_t signature_length, uint8_t* wrapped_private_key,
size_t* wrapped_private_key_length);
/**
* Load and parse a provisioning response, and then rewrap the private key. We
* recommend that the OEM use a strong encryption key and signing key algorithm.
*
* This is the same as OEMCrypto_LoadProvisioning except it is for CAST devices.
* This should return OEMCrypto_ERROR_NOT_IMPLEMENTED for non-CAST devices.
*
* @param[in] session: crypto session identifier.
* @param[in] derivation_key: session key, encrypted with the public RSA key
* (from the DRM certifcate) using RSA-OAEP.
* @param[in] derivation_key_length: length of derivation_key, in bytes.
* @param[in] provision_request: the initial provisioning request.
* @param[in] provision_request_length: length of provision_request, in bytes.
* @param[in] message: pointer to memory containing data.
* @param[in] message_length: length of the message, in bytes.
* @param[in] core_message_length: length of the core submessage, in bytes.
* @param[in] signature: pointer to memory containing the signature.
* @param[in] signature_length: length of the signature, in bytes.
* @param[out] wrapped_private_key: pointer to buffer in which encrypted RSA or
* ECC private key should be stored. May be null on the first call in order
* to find required buffer size.
* @param[in,out] wrapped_private_key_length: (in) length of the encrypted
* private key, in bytes. (out) actual length of the encrypted private key
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_KEY
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE
* @retval OEMCrypto_ERROR_INVALID_NONCE
* @retval OEMCrypto_ERROR_SHORT_BUFFER
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method was added in API version 19.
*/
OEMCryptoResult OEMCrypto_LoadProvisioningCast(
OEMCrypto_SESSION session, const uint8_t* derivation_key,
size_t derivation_key_length, const uint8_t* provision_request,
size_t provision_request_length, const uint8_t* message,
size_t message_length, size_t core_message_length, const uint8_t* signature,
size_t signature_length, uint8_t* wrapped_private_key,
size_t* wrapped_private_key_length);
/**
* Loads a wrapped RSA or ECC private key to secure memory for use by this
* session in future calls to OEMCrypto_PrepAndSignLicenseRequest() or
* OEMCrypto_LoadLicense(). The wrapped private key will be the
* one verified and wrapped by OEMCrypto_LoadProvisioning(). The private key
* should be stored in secure memory.
*
* If the bit field "allowed_schemes" was wrapped with this RSA key, its
* value will be loaded and stored with the RSA key, and the key may be used
* with calls to OEMCrypto_GenerateRSASignature(). If there was not a bit field
* wrapped with the RSA key, the key will be used for
* OEMCrypto_PrepAndSignLicenseRequest() or OEMCrypto_LoadLicense()
*
* @verification
* The following checks should be performed. If any check fails, an error is
* returned, and the RSA key is not loaded.
* 1. The wrapped key has a valid signature, as described in
* OEMCrypto_LoadProvisioning().
* 2. The decrypted key is a valid private RSA key.
* 3. If a value for allowed_schemes is included with the key, it is a
* valid value.
*
* @param[in] session: crypto session identifier.
* @param[in] key_type: indicates either an RSA or ECC key for devices that
* support both.
* @param[in] wrapped_private_key: wrapped device private key (RSA or ECC).
* This is the wrapped key generated by OEMCrypto_LoadProvisioning().
* @param[in] wrapped_private_key_length: length of the wrapped key buffer, in
* bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_KEY
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(OEMCrypto_SESSION session,
OEMCrypto_PrivateKeyType key_type,
const uint8_t* wrapped_private_key,
size_t wrapped_private_key_length);
/**
* Some platforms do not support keyboxes or OEM Certificates. On those
* platforms, there is a DRM certificate baked into the OEMCrypto library.
* This is unusual, and is only available for L3 devices. In order to debug
* and test those devices, they should be able to switch to the test DRM
* certificate.
*
* Temporarily use the standard test RSA key until the next call to
* OEMCrypto_Terminate(). This allows a standard suite of unit tests to be run
* on a production device without permanently changing the key. Using the
* test key is not persistent.
*
* The test key can be found in the OEMCrypto unit test, in PKCS8 form as the
* constant kTestRSAPKCS8PrivateKeyInfo2_2048.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED devices that use a keybox should
* not implement this function
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system.
*
* @version
* This method is new in API version 10.
*/
OEMCryptoResult OEMCrypto_LoadTestRSAKey(void);
/**
* The OEMCrypto_GenerateRSASignature() method is only used for devices that are
* CAST receivers. This function is called after OEMCrypto_LoadDRMPrivateKey()
* for the same session.
*
* The parameter padding_scheme has two possible legacy values:
*
* 0x1 - RSASSA-PSS with SHA1.
*
* 0x2 - PKCS1 with block type 1 padding (only).
*
* The only supported padding scheme is 0x2 since version 16 of this API. In
* this second case, the "message" is already a digest, so no further hashing
* is applied, and the message_length can be no longer than 83 bytes. If the
* message_length is greater than 83 bytes OEMCrypto_ERROR_SIGNATURE_FAILURE
* shall be returned.
*
* The second padding scheme is for devices that use X509 certificates for
* authentication. The main example is devices that work as a Cast receiver,
* like a ChromeCast, not for devices that wish to send to the Cast device,
* such as almost all Android devices. OEMs that do not support X509
* certificate authentication need not implement this function and can return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* @verification
* Both the padding_scheme and the RSA key's allowed_schemes must be 0x2. If
* not, then the signature is not computed and the error
* OEMCrypto_ERROR_INVALID_KEY is returned.
*
* @param[in] session: crypto session identifier.
* @param[in] message: pointer to memory containing message to be signed.
* @param[in] message_length: length of the message, in bytes.
* @param[out] signature: buffer to hold the message signature. On return, it
* will contain the message signature generated with the device private RSA
* key using RSASSA-PSS. Will be null on the first call in order to find
* required buffer size.
* @param[in,out] signature_length: (in) length of the signature buffer, in
* bytes. (out) actual length of the signature
* @param[in] padding_scheme: specify which scheme to use for the signature.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER if the signature buffer is too small.
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_INVALID_KEY
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED if algorithm > 0, and the device
* does not support that algorithm.
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_GenerateRSASignature(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
uint8_t* signature, size_t* signature_length,
RSA_Padding_Scheme padding_scheme);
/**
* OEMCrypto will use ODK_PrepareCoreProvisioningRequest() or
* ODK_PrepareCoreProvisioning40Request(), as described in the document
* "Widevine Core Message Serialization", to prepare the core message.
* ODK_PrepareCoreProvisioningRequest() for Provisioning 2 or 3, and
* ODK_PrepareCoreProvisioning40Request() for Provisioning 4. If the ODK
* function returns an error, the error should be returned by OEMCrypto to the
* CDM layer. If it returns OEMCrypto_SUCCESS, then OEMCrypto shall compute the
* signature of the entire message. The entire message is the buffer starting at
* message with length message_length.
*
* For a device that has a keybox, i.e. Provisioning 2.0, OEMCrypto will sign
* the request with the session's derived client mac key using the message.
*
* For Provisioning 3.0, i.e. a device that has a baked in OEM Certificate,
* OEMCrypto will sign the request with the private key associated with the OEM
* Certificate. The key shall have been loaded by a previous call to
* OEMCrypto_LoadDRMPrivateKey().
*
* For Provisioning 4.0, i.e. a device that uses a Boot Chain Certificate to
* request and OEM cert, a request for an OEM cert is signed by the OEM private
* key. A request for a DRM cert is signed by the DRM private key. The DRM cert
* that was generated on the device in OEMCrypto_GenerateCertificateKeyPair() is
* signed by the OEM cert private key.
*
* Refer to the Signing Messages Sent to a Server section above for more
* details.
*
* NOTE: if signature pointer is null and/or input signature_length is zero,
* this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
* signature_length to the size needed to receive the output signature.
*
* @param[in] session: handle for the session to be used.
* @param[in,out] message: Pointer to memory for the entire message. Modified by
* OEMCrypto via 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[out] signature: pointer to memory to receive the computed signature.
* @param[in,out] signature_length: (in) length of the signature buffer, in
* bytes. (out) actual length of the signature, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough
* to hold the signature.
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
* OEMCrypto_ResourceRatingTier().
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_PrepAndSignProvisioningRequest(
OEMCrypto_SESSION session, uint8_t* message, size_t message_length,
size_t* core_message_size, uint8_t* signature, size_t* signature_length);
/// @}
/// @addtogroup usage_table
/// @{
/**
* This creates a new Usage Table Header with no entries. If there is already
* a generation number stored in secure storage, it will be incremented by 1
* and used as the new Master Generation Number. This will only be called if
* the CDM layer finds no existing usage table on the file system. OEMCrypto
* will encrypt and sign the new, empty, header and return it in the provided
* buffer.
*
* The new entry should be created with a status of kUnused and all times
* times should be set to 0.
*
* Devices that do not implement a Session Usage Table may return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* @param[out] header_buffer: pointer to memory where encrypted usage table
* header is written.
* @param[in,out] header_buffer_length: (in) length of the header_buffer, in
* bytes. (out) actual length of the header_buffer
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER if header_buffer_length is too small
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE if any active entries are currently
* loaded
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 13.
*/
OEMCryptoResult OEMCrypto_CreateUsageTableHeader(uint8_t* header_buffer,
size_t* header_buffer_length);
/**
* This loads the Usage Table Header. The buffer's signature is verified and
* the buffer is decrypted. OEMCrypto will verify the verification string. If
* the Master Generation Number is more than 1 off, the table is considered
* bad, the headers are NOT loaded, and the error
* OEMCrypto_ERROR_GENERATION_SKEW is returned. If the generation number is
* off by 1, the warning OEMCrypto_WARNING_GENERATION_SKEW is returned but
* the header is still loaded. This warning may be logged by the CDM layer.
*
* @param[in] buffer: pointer to memory containing encrypted usage table header.
* @param[in] buffer_length: length of the buffer, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED some devices do not implement usage
* tables.
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_WARNING_GENERATION_SKEW if the generation number is off
* by exactly 1.
* @retval OEMCrypto_ERROR_GENERATION_SKEW if the generation number is off by
* more than 1.
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE if the signature failed.
* @retval OEMCrypto_ERROR_BAD_MAGIC verification string does not match.
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_LoadUsageTableHeader(const uint8_t* buffer,
size_t buffer_length);
/**
* This creates a new usage entry. The size of the header will be increased
* by 8 bytes, and secure volatile memory will be allocated for it. The new
* entry will be associated with the given session. The status of the new
* entry will be set to "unused". OEMCrypto will set *usage_entry_number to
* be the index of the new entry. The first entry created will have index 0.
* The new entry will be initialized with a generation number equal to the
* master generation number, which will also be stored in the header's new
* slot. Then the master generation number will be incremented. Since each
* entry's generation number is less than the master generation number, the
* new entry will have a generation number that is larger than all other
* entries and larger than all previously deleted entries. This helps prevent
* a rogue application from deleting an entry and then loading an old version
* of it.
*
* If the session already has a usage entry associated with it, the error
* OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES is returned. It is an error to attempt
* to create or load a second usage entry into a session that already has a
* usage entry.
*
* @param[in] session: handle for the session to be used.
* @param[out] usage_entry_number: index of new usage entry.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED some devices do not implement usage
* tables.
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES if there is no room in
* memory to increase the size of the usage table header. The CDM layer
* can delete some entries and then try again, or it can pass the error
* up to the application.
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES if there already is a usage
* entry loaded into this session
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 13.
*/
OEMCryptoResult OEMCrypto_CreateNewUsageEntry(OEMCrypto_SESSION session,
uint32_t* usage_entry_number);
/**
* This allows a session to take an existing usage entry. The effect of this
* call is identical to that of creating an entry via
* OEMCrypto_CreateUsageEntry(), except that the usage table header does not
* change size. All information related to the previous entry should be cleared
* from the header. The new entry will be initialized with a generation number
* equal to the master generation number, which will also be stored in the
* headers existing slot. Then the master generation number will be
* incremented.
*
* If the session already has a usage entry associated with it, the error
* OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES is returned.
*
* @param[in] session: handle for the session to be used.
* @param[in] usage_entry_number: index of new usage entry.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED some devices do not implement usage
* tables.
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES if there already is a usage
* entry loaded into this session
* @retval OEMCrypto_ERROR_INVALID_SESSION when entry number is in use by
* another session
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 17.
*/
OEMCryptoResult OEMCrypto_ReuseUsageEntry(OEMCrypto_SESSION session,
uint32_t usage_entry_number);
/**
* This loads a usage entry saved previously by UpdateUsageEntry. The
* signature at the beginning of the buffer is verified and the buffer will
* be decrypted. Then the verification field in the entry will be verified.
* The index in the entry must match the index passed in. The generation
* number in the entry will be compared against the entry's corresponding
* generation number in the header. If it is off by 1, a warning is returned,
* but the entry is still loaded. This warning may be logged by the CDM
* layer. If the generation number is off by more than 1, an error is
* returned and the entry is not loaded.
*
* OEMCrypto shall call ODK_ReloadClockValues, as described in "License
* Duration and Renewal" to set the session's clock values.
*
* If the entry is already loaded into another open session, then this fails and
* returns OEMCrypto_ERROR_INVALID_SESSION. If the session already has a usage
* entry associated with it, the error OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES is
* returned. It is also an error to try to reload the same usage entry into the
* same open session twice.
*
* Before version API 16, the usage entry stored the time that the license
* was loaded. This value is now interpreted as the time that the licence
* request was signed. This can be achieved by simply renaming the field and
* using the same value when reloading an older entry.
*
* @param[in] session: handle for the session to be used.
* @param[in] usage_entry_number: index of existing usage entry.
* @param[in] buffer: pointer to memory containing encrypted usage table entry.
* @param[in] buffer_length: length of the buffer, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED some devices do not implement usage
* tables.
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE index beyond end of table.
* @retval OEMCrypto_ERROR_INVALID_SESSION entry associated with another
* session or the index is wrong.
* @retval OEMCrypto_WARNING_GENERATION_SKEW if the generation number is off
* by exactly 1.
* @retval OEMCrypto_ERROR_GENERATION_SKEW if the generation number is off by
* more than 1.
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE if the signature failed.
* @retval OEMCrypto_ERROR_BAD_MAGIC verification string does not match.
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES if there already is a usage
* entry loaded into this session
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 13.
*/
OEMCryptoResult OEMCrypto_LoadUsageEntry(OEMCrypto_SESSION session,
uint32_t usage_entry_number,
const uint8_t* buffer,
size_t buffer_length);
/**
* Updates the session's usage entry and fills buffers with the encrypted and
* signed entry and usage table header.
*
* OEMCrypto shall call ODK_UpdateLastPlaybackTime to update the session's
* clock values, as discussed in the document "License Duration and Renewal".
* The values in the session's clock values structure are copied to the usage
* entry.
*
* OEMCrypto shall update all time and status values in the entry, and then
* increment the entry's generation number. The corresponding generation
* number in the usage table header is also incremented so that it matches
* the one in the entry. The master generation number in the usage table
* header is incremented and the master generation number is copied to secure
* persistent storage. OEMCrypto will encrypt and sign the entry into the
* entry_buffer, and it will encrypt and sign the usage table header into the
* header_buffer. Some actions, such as the first decrypt and deactivating an
* entry, will also increment the entry's generation number as well as
* changing the entry's status and time fields. The first decryption will
* change the status from Inactive to Active, and it will set the time stamp
* "first decrypt".
*
* If the usage entry has the flag ForbidReport set, then the flag is
* cleared. It is the responsibility of the CDM layer to call this function and
* save the usage table before the next call to OEMCrypto_ReportUsage() and
* before the CDM is terminated. Failure to do so will result in generation
* number skew, which will invalidate all of the usage table.
*
* If either entry_buffer_length or header_buffer_length is not large enough,
* they are set to the needed size, and return OEMCrypto_ERROR_SHORT_BUFFER.
* In this case, the entry is not updated, ForbidReport is not cleared,
* generation numbers are not incremented, and no other work is done.
*
* @param[in] session: handle for the session to be used.
* @param[out] header_buffer: pointer to memory where encrypted usage table
* header is written.
* @param[in,out] header_buffer_length: (in) length of the header_buffer, in
* bytes. (out) actual length of the header_buffer
* @param[out] entry_buffer: pointer to memory where encrypted usage table entry
* is written.
* @param[in,out] entry_buffer_length: (in) length of the entry_buffer, in
* bytes. (out) actual length of the entry_buffer
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED some devices do not implement usage
* tables.
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_UpdateUsageEntry(
OEMCrypto_SESSION session, OEMCrypto_SharedMemory* header_buffer,
size_t* header_buffer_length, OEMCrypto_SharedMemory* entry_buffer,
size_t* entry_buffer_length);
/**
* This deactivates the usage entry associated with the current session. This
* means that the status of the usage entry is changed to InactiveUsed if it
* was Active, or InactiveUnused if it was Unused. This also increments the
* entry's generation number, and the header's master generation number. The
* corresponding generation number in the usage table header is also
* incremented so that it matches the one in the entry. The entry's flag
* ForbidReport will be set. This flag prevents an application from
* generating a report of a deactivated license without first saving the
* entry.
*
* OEMCrypto shall call ODK_DeactivateUsageEntry to update the session's
* clock values, as discussed in the document "License Duration and Renewal".
*
* It is allowed to call this function multiple times. If the state is
* already InactiveUsed or InactiveUnused, then this function does not change
* the entry or its state.
*
* @param[in] session: handle for the session to be used.
* @param[in] pst: pointer to memory containing Provider Session Token.
* @param[in] pst_length: length of the pst, in bytes.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_CONTEXT an entry was not created or loaded,
* or the pst does not match.
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @buffer_size
* OEMCrypto shall support pst sizes of at least 255 bytes.
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 16.
*/
OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length);
/**
* All fields of OEMCrypto_PST_Report are in network byte order.
*
* If the buffer_length is not sufficient to hold a report structure, set
* buffer_length and return OEMCrypto_ERROR_SHORT_BUFFER.
*
* If an entry was not loaded or created with OEMCrypto_CreateNewUsageEntry() or
* OEMCrypto_LoadUsageEntry() return the error
* OEMCrypto_ERROR_INVALID_CONTEXT. If the pst does not match that in the entry,
* return OEMCrypto_ERROR_WRONG_PST.
*
* If the usage entry's flag ForbidReport is set, indicating the entry has
* not been saved since the entry was deactivated, then the error
* OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE is returned and a report is not
* generated. Similarly, if any key in the session has been used since the
* last call to OEMCrypto_UpdateUsageEntry(), then the report is not generated,
* and OEMCrypto returns the error OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE.
*
* The pst_report is filled out by subtracting the times in the Usage Entry
* from the current time on the secure clock. This design was chosen to avoid
* a requirement to sync the device's secure clock with any external clock.
*
* ![Usage Report Timeline](fig11.svg)
*
* Valid values for status are:
*
* - 0 = kUnused -- the keys have not been used to decrypt.
* - 1 = kActive -- the keys have been used, and have not been deactivated.
* - 2 = kInactive - deprecated. Use kInactiveUsed or kInactiveUnused.
* - 3 = kInactiveUsed -- the keys have been marked inactive after being
* active.
* - 4 = kInactiveUnused -- they keys have been marked inactive, but were
* never active.
* The clock_security_level is reported as follows:
*
* - 0 = Insecure Clock - clock just uses system time.
* - 1 = Secure Timer - clock runs from a secure timer which is initialized
* from system time when OEMCrypto becomes active and cannot be modified
* by user software or the user while OEMCrypto is active. A secure
* timer cannot run backwards, even while OEMCrypto is not active.
* - 2 = Secure Clock - Real-time clock set from a secure source that
* cannot be modified by user software regardless of whether OEMCrypto
* is active or inactive. The clock time can only be modified by
* tampering with the security software or hardware.
* - 3 = Hardware Secure Clock - Real-time clock set from a secure source
* that cannot be modified by user software and there are security
* features that prevent the user from modifying the clock in hardware,
* such as a tamper proof battery.
*
* ![Secure Clock versus Secure Timer versus Insecure Clock](fig12.svg)
*
* After pst_report has been filled in, the HMAC SHA1 signature is computed
* for the buffer from bytes 20 to the end of the pst field. The signature is
* computed using the mac_key[client] which is stored in the usage table. The
* HMAC SHA1 signature is used to prevent a rogue application from using
* OMECrypto_GenerateSignature to forge a Usage Report.
*
* Before version 16 of this API, seconds_since_license_received was reported
* instead of seconds_since_license_signed. For any practical bookkeeping
* purposes, these events are essentially at the same time.
*
* Devices that do not implement a Session Usage Table may return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* @param[in] session: handle for the session to be used.
* @param[in] pst: pointer to memory containing Provider Session Token.
* @param[in] pst_length: length of the pst, in bytes.
* @param[out] buffer: pointer to buffer in which usage report should be
* stored. May be null on the first call in order to find required buffer
* size.
* @param[in,out] buffer_length: (in) length of the report buffer, in bytes.
* (out) actual length of the report
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER if report buffer is not large enough
* to hold the output report.
* @retval OEMCrypto_ERROR_INVALID_SESSION no open session with that id.
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE if no call to UpdateUsageEntry
* since last call to Deactivate or since key use.
* @retval OEMCrypto_ERROR_WRONG_PST report asked for wrong pst.
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @buffer_size
* OEMCrypto shall support pst sizes of at least 255 bytes.
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
* larger than the supported size.
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method changed in API version 13.
*/
OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
const uint8_t* pst, size_t pst_length,
uint8_t* buffer, size_t* buffer_length);
/**
* Fetches information from a license release without performing any signatures
* or deactivating the license.
*
* @param[in] session: handle for the session to be used.
* @param[out] status: the enumeration of OEMCrypto_Usage_Entry_Status.
* @param[out] seconds_since_license_received: the time since the license being
* requested in seconds.
* @param[out] seconds_since_first_decrypt: the time since playback has
* started in seconds.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INVALID_SESSION no open session with that id.
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 19.
*/
OEMCryptoResult OEMCrypto_GetUsageEntryInfo(
OEMCrypto_SESSION session, OEMCrypto_Usage_Entry_Status* status,
int64_t* seconds_since_license_received,
int64_t* seconds_since_first_decrypt);
/**
* Moves the entry associated with the current session from one location in
* the usage table header to another. This function is used by the CDM layer
* to defragment the usage table. This does not modify any data in the entry,
* except the index and the generation number. The index in the session's
* usage entry will be changed to new_index. The generation number in
* session's usage entry and in the header for new_index will be increased to
* the master generation number, and then the master generation number is
* incremented. If there was an existing entry at the new location, it will
* be overwritten. It is an error to call this when the entry that was at
* new_index is associated with a currently open session. In this case, the
* error code OEMCrypto_ERROR_ENTRY_IN_USE is returned. It is the CDM layer's
* responsibility to call UpdateUsageEntry after moving an entry. It is an
* error for new_index to be beyond the end of the existing usage table
* header.
*
* Devices that do not implement a Session Usage Table may return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* @param[in] session: handle for the session to be used.
* @param[in] new_index: new index to be used for the session's usage entry
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_ENTRY_IN_USE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 13.
*/
OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session,
uint32_t new_index);
/**
* This shrinks the usage table and the header. This function is used by the CDM
* layer after it has defragmented the usage table and can delete unused
* entries. It is an error if any open session is associated with an entry that
* will be erased - the error OEMCrypto_ERROR_ENTRY_IN_USE shall be returned in
* this case, and the header shall not be modified. If new_entry_count is larger
* than the current size, then the header is not changed and the error
* OEMCrypto_ERROR_UNKNOWN_FAILURE is returned. If the header has not been
* previously loaded, then OEMCrypto_ERROR_UNKNOWN_FAILURE is returned.
* OEMCrypto will increment the master generation number in the header and store
* the new value in secure persistent storage. Then, OEMCrypto will encrypt and
* sign the header into the provided buffer. The generation numbers of all
* remaining entries will remain unchanged. The next time
* OEMCrypto_CreateNewUsageEntry() is called, the new entry will have an index
* of new_entry_count.
*
* Devices that do not implement a Session Usage Table may return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* If header_buffer_length is not large enough to hold the new table, it is
* set to the needed value, the generation number is not incremented, and
* OEMCrypto_ERROR_SHORT_BUFFER is returned.
*
* If the header has not been loaded or created, return the error
* OEMCrypto_ERROR_UNKNOWN_FAILURE.
*
* @param[in] new_entry_count: number of entries to be in the new header.
* @param[out] header_buffer: pointer to memory where encrypted usage table
* header is written.
* @param[in,out] header_buffer_length: (in) length of the header_buffer, in
* bytes. (out) actual length of the header_buffer
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_SHORT_BUFFER
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_ENTRY_IN_USE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Usage Table Function" and will not be called simultaneously
* with any other function, as if the CDM holds a write lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 13.
*/
OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(uint32_t new_entry_count,
uint8_t* header_buffer,
size_t* header_buffer_length);
/// @}
/// @addtogroup prov40
/// @{
/**
* Get the serialized boot certificate chain in CBOR format used in
* provisioning 4.
*
* @param[out] bcc: pointer to the buffer that receives the serialized boot
* certificate chain in CBOR format.
* @param[in,out] bcc_length - on input, size of the caller's bcc buffer. On
* output, the number of bytes written into the buffer.
* @param[out] additional_signature: pointer to the buffer that receives
* additional device key signature (certificate chain). This field is only
* used by the signing model where a vendor certificate is available on the
* device.
* @param[in,out] additional_signature_length - on input, size of the caller's
* additional_signature buffer. On output, the number of bytes written into
* the buffer.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_SHORT_BUFFER if any of the buffers is too small to
* return the bcc or additional_signature.
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED if provisioning 4 is not supported.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_GetBootCertificateChain(
uint8_t* bcc, size_t* bcc_length, uint8_t* additional_signature,
size_t* additional_signature_length);
/**
* Generates a key pair used in OEM and DRM certificate provisioning. The public
* key is supposed to be certified by the server. The private key is wrapped
* with the encryption key so it can be stored in the file system.
*
* The |public_key_signature| output is formatted differently depending
* on whether or not an OEM private key has been loaded.
*
* If an OEM private key is unavailable, the request is assumed to be for OEM
* certificate provisioning. In this case, the public key is signed by the
* device private key. The format of |public_key_signature| in this case is a
* COSE_Sign1 CBOR array. The format is described in RFC 8152 Section 4.2 and
* 4.4, as well as Android IRemotelyProvisionedComponent.aidl (under
* "SignedData<Data>")
*
* ~~~
* |public_key_signature|: COSE_Sign1 CBOR array
* [
* protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 /
* AlgorithmES384 },
* unprotected: {},
* payload: bstr .cbor Data / nil,
* signature: bstr ; PureEd25519(priv_key, Sig_structure) /
* ; ECDSA(priv_key, Sig_structure)
* ]
* ~~~
*
* Notes:
* 1. The payload field in the COSE_Sign1 struct is the public key generated
* by OEMCrypto_GenerateCertificateKeyPair
* 2. The signature field in the COSE_Sign1 struct is the concatenation of the
* (R,S) values from the EC/Ed signature. If either R or S is smaller than
* the key size, it is left-padded with 0 to match the key size as
* described in RFC 8152. This signature is not DER encoded.
* 3. The signature is generated by calling the selected EC signing function
* (PureEd25519 or one of the supported ECDSA algorithms) on
* `Sig_structure`, which is a CBOR array described below. The payload
* field in Sig_structure is the same as the payload in the above
* COSE_Sign1 CBOR array.
*
* ~~~
* Sig_structure: CBOR array
* [
* context: "Signature1",
* protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 /
* AlgorithmES384 },
* external_aad: bstr .size 0,
* payload: bstr .cbor Data / nil,
* ]
* ~~~
*
* If an OEM private key is available, the request is assumed to be for DRM
* certificate provisioning and the public key is signed by the OEM private key.
* If the OEM private key is an RSA key, then |public_key_signature| is the raw
* output of the RSA sign operation with RSASSA-PSS padding. If the OEM private
* key is an ECC key, then |public_key_signature| is the ASN.1 DER-encoded (R,S)
* signature as specified in RFC 3279 2.2.3.
*
* After this function completes successfully, the session will hold a private
* key and will be ready for a call to
* OEMCrypto_PrepAndSignProvisioningRequest(). In particular, when this
* function is used to generate a DRM Certificate key pair, the session will be
* ready to sign a provisioning request with the DRM Cert private key. When this
* function is used to generate an OEM Certificate key pair, the session will be
* ready to sign a provisioning request with the OEM Cert private key.
*
* The public key shall be an ASN.1 DER-encoded SubjectPublicKeyInfo as
* specified in RFC 5280. Widevine recommends ECC keys for Provisioning 4.0, but
* an RSA key may also be used. If the key is an RSA key, then the encoding
* should use "rsaEncryption" (OID 1.2.840.113549.1.1.1), and not RSASSA-PSS.
*
* @param[in] session: session id.
* @param[out] public_key: pointer to the buffer that receives the public key
* that is to be certified by the server. The key must be an ASN.1
* DER-encoded SubjectPublicKeyInfo as specified in RFC 5280.
* @param[in,out] public_key_length: on input, size of the caller's public_key
* buffer. On output, the number of bytes written into the buffer.
* @param[out] public_key_signature: pointer to the buffer that receives the
* signature of the public key. The format depends on whether an OEM private
* key has been loaded.
* @param[in,out] public_key_signature_length: on input, size of the caller's
* public_key_signature buffer. On output, the number of bytes written into
* the buffer.
* @param[out] wrapped_private_key: pointer to the buffer that receives the
* encrypted private key. It is encrypted by the device encryption key.
* @param[in,out] wrapped_private_key_length: on input, size of the caller's
* wrapped_private_key buffer. On output, the number of bytes written into
* the buffer.
* @param[out] key_type: the type of the generated key pair (RSA or ECC).
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_SHORT_BUFFER if any of the buffer |public_key|,
* |public_key_signature| or |wrapped_private_key_size| is too small.
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_GenerateCertificateKeyPair(
OEMCrypto_SESSION session, uint8_t* public_key, size_t* public_key_length,
uint8_t* public_key_signature, size_t* public_key_signature_length,
uint8_t* wrapped_private_key, size_t* wrapped_private_key_length,
OEMCrypto_PrivateKeyType* key_type);
/**
* Get the serialized device information in CBOR map format. This is for devices
* that use Provisioning 4.0, with the device key uploading option in the
* factory.
*
* The device
* information may contain, for example, device make and model, "fused" status,
* and other properties, which is intended to be 1) uploaded during device
* manufacture in the factory, 2) checked by the server to verify that the
* provisioning request is coming from the expected device in the fields, based
* on the values previously uploaded and registered.
*
* Devices that do not support Provisioning 4.0, or do not support
* Provisioning 4.0 Uploading Option should return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* @param[out] device_info: pointer to the buffer that receives the serialized
* device information in CBOR map format.
* @param[in,out] device_info_length: on input, size of the caller's
* device_info buffer. On output, the number of bytes written into the buffer.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_SHORT_BUFFER if device_info_length is too small to
* return the device_info.
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED if provisioning 4 is not supported,
* or device information is not available on the platform.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 18.
*/
OEMCryptoResult OEMCrypto_GetDeviceInformation(uint8_t* device_info,
size_t* device_info_length);
/**
* Get the serialized signed Certificate Signing Request (CSR) payload in
* COSE_Sign1 format. This is for devices that use Provisioning 4.0, with the
* device key uploading option in the factory.
*
* With the uploading option, the RKP factory extraction tool provided by Google
* makes a call to this function to collect the signed CSR payload for
* generating the CSR to be uploaded to the device database. The CSR payload is
* signed by the leaf cert of the Boot Certificate Chain.
*
* The format of a CSR payload before COSE_Sign1 is a CBOR array described in
* Android IRemotelyProvisionedComponent.aidl (under "CsrPayload"):
*
* ~~~
* CsrPayload = [ ; CBOR Array defining the payload for CSR.
* version: 3, ; The CsrPayload CDDL Schema version.
* CertificateType: "widevine" ; The type of certificate being requested.
* DeviceInfo, ; Defined in Android DeviceInfo.aidl
* KeysToSign: [] ; Empty list
* ]
* ~~~
*
* The type of CertificateType is tstr and the value should always be
* "widevine". The type of KeysToSign is CBOR array and the value is not used,
* which should be left as an empty list. Note that the DeviceInfo above is a
* CBOR map structure defined in DeviceInfo.aidl, which can be constructed from
* the input |encoded_device_info|. DeviceInfo must be canonicalized according
* to the specification in RFC 7049. The required fields from DeviceInfo.aidl
* are: brand, manufacturer, product, model, device, vb_state, bootloader_state,
* vbmeta_digest, security_level.
*
* Once CsrPayload is prepared, together with |challenge| it is signed by the
* leaf cert of BCC, in the format of:
*
* ~~~
* |signed_csr_payload| = SignedData<[
* challenge: bstr .size (0..64),
* bstr .cbor CsrPayload,
* ]>
* ~~~
*
* This function should output |signed_csr_payload| in the format of
* SignedData<Data>, which is a COSE_Sign1 CBOR and is defined in Android
* IRemotelyProvisionedComponent.aidl (under "SignedData<Data>"):
*
* ~~~
* SignedData<Data> = [
* protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 /
* AlgorithmES384 },
* unprotected: {},
* payload: bstr .cbor Data / nil,
* signature: bstr ; PureEd25519(priv_key, Sig_structure) /
* ; ECDSA(priv_key, Sig_structure)
* ]
* ~~~
*
* Also see OEMCrypto_GenerateCertificateKeyPair() for more details of
* SignedData<Data> and Sig_structure.
*
* Data in the payload field of SignedData<Data> is a CBOR array:
*
* ~~~
* Data = [
* challenge: bstr .size (0..64),
* bstr .cbor CsrPayload,
* ]
* ~~~
*
* Devices that do not support Provisioning 4.0, or do not support
* Provisioning 4.0 Uploading Option should return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* @param[in] challenge: pointer to the buffer containing a byte string to be
* signed. It is generated by the RKP factory extraction tool.
* @param[in] challenge_length: size of the challenge buffer.
* @param[in] encoded_device_info: pointer to the buffer containing the
* serialized device information in CBOR map format. It should be returned as
* `device_info` in a call to the function `OEMCrypto_GetDeviceInformation()`.
* @param[in] encoded_device_info_length: size of the encoded_device_info
* buffer.
* @param[out] signed_csr_payload: pointer to the buffer that receives the
* serialized signed CSR payload in COSE_Sign1 format.
* @param[in,out] signed_csr_payload_length: on input, size of the caller's
* signed_csr_payload buffer. On output, the number of bytes written into the
* buffer.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_CONTEXT if challenge_length or
* encoded_device_info_length is 0, or any pointer is NULL
* @retval OEMCrypto_ERROR_SHORT_BUFFER if signed_csr_payload_length is too
* small to return the signed_csr_payload.
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED if provisioning 4 is not supported,
* or device information is not available on the platform.
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 18.
*/
OEMCryptoResult OEMCrypto_GetDeviceSignedCsrPayload(
const uint8_t* challenge, size_t challenge_length,
const uint8_t* encoded_device_info, size_t encoded_device_info_length,
uint8_t* signed_csr_payload, size_t* signed_csr_payload_length);
/**
* Loads an OEM private key to a session. The key will be used in signing DRM
* certificate request, or the public key generated by calling
* OEMCrypto_GenerateCertificateKeyPair.
*
* @param[in] session: session id.
* @param[in] key_type: type of the leaf key (RSA or ECC).
* @param[in] wrapped_private_key: the encrypted private key. This is the
* wrapped key generated by OEMCrypto_GenerateCertificateKeyPair.
* @param[in] wrapped_private_key_length: length of |wrapped_private_key| in
* bytes.
*
* @retval OEMCrypto_SUCCESS
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
* @retval OEMCrypto_ERROR_NO_DEVICE_KEY
* @retval OEMCrypto_ERROR_INVALID_SESSION
* @retval OEMCrypto_ERROR_INVALID_KEY
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 17.
*/
OEMCryptoResult OEMCrypto_InstallOemPrivateKey(
OEMCrypto_SESSION session, OEMCrypto_PrivateKeyType key_type,
const uint8_t* wrapped_private_key, size_t wrapped_private_key_length);
/// @}
/// @addtogroup test_verify
/// @{
/**
* Enter Test Mode. This enables OEMCrypto test functionality. Without a call to
* this function, none of the test functions](./test-verify) shall be
* enabled. After this function has been called, OEMCrypto will not use the
* production keybox. Once OEMCrypto has entered Test Mode, it will not leave
* Test Mode until the next reboot.
*
* If the device is not in Test Mode, it will be in Production Mode and
* OEMCrypto will use a production root of trust (keybox or OEM Certificate) if
* available. In Production Mode, none of the test functions are enabled.
*
* Widevine recommends shipping a Production Only version of OEMCrypto on
* released devices. A Production Only version of OEMCrypto will have all test
* functions disabled. In this case, OEMCrypto_EnterTestMode() will return
* OEMCRYPTO_ERROR_NOT_IMPLEMENTED.
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED OEMCrypto is a production build, and
* does not support debug or test-only functions.
*
* @threading
* This is an "Initialization and Termination Function" and will not be
* called simultaneously with any other function, as if the CDM holds a write
* lock on the OEMCrypto system. It is called once after
* OEMCrypto_Initialize(), and before any other test-only functions are
* called.
*
* @version
* This method is new in API version 18.
*/
OEMCryptoResult OEMCrypto_EnterTestMode(void);
/**
* Returns the type of hash function supported for Full Decrypt Path Testing.
* A hash type of OEMCrypto_Hash_Not_Supported = 0 means this feature is not
* supported. OEMCrypto is not required by Google to support this feature,
* but support will greatly improve automated testing. A hash type of
* OEMCrypto_CRC_Clear_Buffer = 1 means the device will be able to compute
* the CRC 32 checksum of the decrypted content in the secure buffer after a
* call to OEMCrypto_DecryptCENC(). Google intends to provide test applications
* on some platforms, such as Android, that will automate decryption testing
* using the CRC 32 checksum of all frames in some test content.
*
* If an SOC vendor cannot support CRC 32 checksums of decrypted output, but
* can support some other hash or checksum, then the function should return
* OEMCrypto_Partner_Defined_Hash = 2 and those partners should modify the
* test application to compute the appropriate hash. An application that
* computes the CRC 32 hashes of test content and builds a hash file in the
* correct format will be provided by Widevine. The source of this
* application will be provided so that partners may modify it to compute
* their own hash format and generate their own hashes.
*
* @retval OEMCrypto_Hash_Not_Supported = 0;
* @retval OEMCrypto_CRC_Clear_Buffer = 1;
* @retval OEMCrypto_Partner_Defined_Hash = 2;
*
* @threading
* This is a "Property Function" and may be called simultaneously with any
* other property function or session function, but not any initialization or
* usage table function, as if the CDM holds a read lock on the OEMCrypto
* system.
*
* @version
* This method is new in API version 15.
*/
uint32_t OEMCrypto_SupportsDecryptHash(void);
/**
* Set the hash value for the next frame to be decrypted. This function is
* called before the first subsample is passed to OEMCrypto_DecryptCENC(), when
* the subsample_flag has the bit OEMCrypto_FirstSubsample set. The hash is
* over all of the frame or sample: encrypted and clear subsamples
* concatenated together, up to, and including the subsample with the
* subsample_flag having the bit OEMCrypto_LastSubsample set. If hashing the
* output is not supported, then this will return
* OEMCrypto_ERROR_NOT_IMPLEMENTED. If the hash is ill formed or there are
* other error conditions, this returns OEMCrypto_ERROR_UNKNOWN_FAILURE. The
* length of the hash will be 4 bytes (32 bits) for the default CRC32 hash.
*
* This may be called before the first call to OEMCrypto_GetKeyHandle. In that
* case, this function cannot verify that the key control block allows hash
* verification. The function DecryptCENC should verify that the key control bit
* allows hash verification when it is called. If an attempt is made to compute
* a hash when the selected key does not have the bit Allow_Hash_Verification
* set, then a hash should not be computed, and OEMCrypto_GetHashErrorCode()
* should return the error OEMCrypto_ERROR_UNKNOWN_FAILURE.
*
* OEMCrypto should compute the hash of the frame and then compare it with
* the correct value. If the values differ, then OEMCrypto should latch in an
* error and save the frame number of the bad hash. It is allowed for
* OEMCrypto to postpone computation of the hash until the frame is
* displayed. This might happen if the actual decryption operation is carried
* out by a later step in the video pipeline, or if you are using a partner
* specified hash of the decoded frame. For this reason, an error state must
* be saved until the call to OEMCrypto_GetHashErrorCode() is made.
*
* @param[in] session: session id for current decrypt operation
* @param[in] frame_number: frame number for the recent DecryptCENC sample.
* @param[in] crc32: CRC of previously decrypted frame.
*
* @retval OEMCrypto_SUCCESS if the hash was set
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED function not implemented
* @retval OEMCrypto_ERROR_INVALID_SESSION session not open
* @retval OEMCrypto_ERROR_SHORT_BUFFER hash_length too short for supported
* hash type
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE hash_length too long for supported
* hash type
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE other error
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 15.
*/
OEMCryptoResult OEMCrypto_SetDecryptHash(OEMCrypto_SESSION session,
uint32_t frame_number, uint32_t crc32);
/**
* If the hash set in OEMCrypto_SetDecryptHash() did not match the computed
* hash, then an error code was saved internally. This function returns that
* error and the frame number of the bad hash. This will be called
* periodically, but might not be in sync with the decrypt loop. OEMCrypto
* shall not reset the error state to "no error" once any frame has failed
* verification. It should be initialized to "no error" when the session is
* first opened. If there is more than one bad frame, it is the implementer's
* choice if it is more useful to return the number of the first bad frame,
* or the most recent bad frame.
*
* If the hash could not be computed -- either because the
* Allow_Hash_Verification was not set in the key control block, or because
* there were other issues -- this function should return
* OEMCrypto_ERROR_UNKNOWN_FAILURE.
*
* @param[in] session: session id for operation.
* @param[out] failed_frame_number: frame number for sample with incorrect hash.
*
* @retval OEMCrypto_SUCCESS if all frames have had a correct hash
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_BAD_HASH if any frame had an incorrect hash
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE if the hash could not be computed
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 15.
*/
OEMCryptoResult OEMCrypto_GetHashErrorCode(OEMCrypto_SESSION session,
uint32_t* failed_frame_number);
/**
* Allocates a secure buffer and fills out the destination buffer information
* in output_descriptor. The integer secure_fd may also be set to indicate
* the source of the buffer. OEMCrypto may use the secure_fd to help track
* the buffer if it wishes. The unit tests will pass a pointer to the same
* destination buffer description and the same secure_fd to
* OEMCrypto_FreeSecureBuffer when the buffer is to be freed.
*
* This is especially helpful if the hash functions above are supported. This
* will only be used by the OEMCrypto unit tests, so we recommend returning
* OEMCrypto_ERROR_NOT_IMPLEMENTED for production devices if performance is
* an issue. If OEMCrypto_ERROR_NOT_IMPLEMENTED is returned, then secure
* buffer unit tests will be skipped.
*
* @param[in] session: session id for operation.
* @param[in] buffer_size: the requested buffer size.
* @param[out] output_descriptor: the buffer descriptor for the created
* buffer. This will be passed into the OEMCrypto_DecryptCENC() function.
* @param[out] secure_fd: a pointer to platform dependent file or buffer
* descriptor. This will be passed to OEMCrypto_FreeSecureBuffer().
*
* @retval OEMCrypto_SUCCESS if the buffer was created
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_OUTPUT_TOO_LARGE
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 16.
*/
OEMCryptoResult OEMCrypto_AllocateSecureBuffer(
OEMCrypto_SESSION session, size_t buffer_size,
OEMCrypto_DestBufferDesc* output_descriptor, int* secure_fd);
/**
* Frees a secure buffer that had previously been created with
* OEMCrypto_AllocateSecureBuffer(). Any return value except OEMCrypto_SUCCESS
* will cause the unit test using secure buffers to fail.
*
* @param[in] session: session id for operation.
* @param[in,out] output_descriptor: the buffer descriptor modified by
* OEMCrypto_AllocateSecureBuffer()
* @param[in] secure_fd: The integer returned by
* OEMCrypto_AllocateSecureBuffer()
*
* @retval OEMCrypto_SUCCESS if the buffer was freed
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
*
* @threading
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* @version
* This method is new in API version 16.
*/
OEMCryptoResult OEMCrypto_FreeSecureBuffer(
OEMCrypto_SESSION session, OEMCrypto_DestBufferDesc* output_descriptor,
int secure_fd);
/// @}
/*
* OEMCrypto_OPK_SerializationVersion
*
* Note: This is an undocumented function. It is only required and used by the
* OPK implementation of OEMCrypto. It is not in a documentation group and does
* not show up on the devsite documentation page.
*
* Check the serialization protocol version used by the OEMCrypto Porting Kit
* (OPK). If the OPK is not used, this function must return
* OEMCrypto_ERROR_NOT_IMPLEMENTED. The serialization version is expressed as
* |major.minor|, where |major| and |minor| are integers. The TEE and REE
* serialization versions must match in order for OEMCrypto to communicate
* with the TEE. If the serialization versions do not match, calls to other
* OEMCrypto functions will return OPK_ERROR_INCOMPATIBLE_VERSION. A match is
* achieved if the |major| fields of the TEE and REE versions are the
* same. Differences in only the |minor| fields indicates that the protocols
* are different but are still compatible.
*
* @param[in,out] ree_major: pointer to memory to recieve the REE's |major|
* version. On input, *ree_major may be zero to request the serialization
* version of the REE. If *ree_major is non-zero, this function will test the
* TEE's compatibility using the specified REE major version.
* @param[in,out] ree_minor: pointer to memory to recieve the REE's |minor|
* version. On input, *ree_minor may be zero to request the serialization
* version of the REE. If *ree_minor is non-zero, this function will test the
* TEE's compatibility using the specified REE minor version.
* @param[out] tee_major: pointer to memory to recieve the TEE's |major| version
* @param[out] tee_minor: pointer to memory to recieve the TEE's |minor| version
*
* @retval OEMCrypto_SUCCESS success
* @retval OPK_ERROR_INCOMPATIBLE_VERSION
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
*/
OEMCryptoResult OEMCrypto_OPK_SerializationVersion(uint32_t* ree_major,
uint32_t* ree_minor,
uint32_t* tee_major,
uint32_t* tee_minor);
/****************************************************************************/
/****************************************************************************/
/* The following functions are optional. They are only used if the device
* supports OTA keybox provisioning. Widevine does not allow all devices to
* support OTA provisioning. Using an OTA provisioned keybox usually lowers a
* device's security profile in the DCSL. Please work with your Widevine Partner
* Engineer before implementing these functions to make sure you understand the
* security implications of using Keybox OTA Provisioning.
*/
/**
* Generate an OTA Keybox provisioning request. The format of the
* message is specified in the document Keybox OTA Reprovisioning. If
* use_test_key is true, then the debug model key and id should be
* used. Widevine does not allow all devices to support OTA
* provisioning. Using an OTA provisioned keybox usually lowers a device's
* security profile in the DCSL.
*
* @param[in] session: handle for the session to be used.
* @param[out] buffer: where the provisioning request is stored.
* @param[in,out] buffer_length: length of the request, in bytes.
* @param[in] use_test_key: If non-zero, use the debug model key. This is used
* for testing the workflow.
*
* @retval OEMCrypto_SUCCESS on success
* @retval OEMCrypto_ERROR_SHORT_BUFFER if buffer_length is too small.
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* Any other error will be logged.
*
* @threading
* This is an "Initialization and Termination Function" and will not be called
* simultaneously with any other function, as if the CDM holds a write lock on
* the OEMCrypto system. It will be called only after
* OEMCrypto_IsKeyboxOrOEMCertValid() returns
* OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING immediately after initialization,
* and before any session is opened.
*
* @version
* This method is new in API version 16.
*/
OEMCryptoResult OEMCrypto_GenerateOTARequest(OEMCrypto_SESSION session,
uint8_t* buffer,
size_t* buffer_length,
uint32_t use_test_key);
/**
* The buffer will be parsed as an OTA Keybox provisioning message, as
* described in the document OTA Keybox Reprovisioning. The
* signature will be verified. The keybox will be decrypted and verified. If
* |use_test_key| is false, the keybox will be installed permanently.
*
* If |use_test_key| is true, do not use the real model key, use the debug
* model key specified in OTA Keybox Reprovisioning.
*
* @param[in] session: handle for the session to be used.
* @param[in] buffer: pointer to provisioning response.
* @param[in] buffer_length: length of the buffer, in bytes.
* @param[in] use_test_key: If non-zero, use the debug model key. This is used
* for testing the workflow.
*
* @retval OEMCrypto_SUCCESS on success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_SIGNATURE_FAILURE signature of message was wrong.
* @retval OEMCrypto_ERROR_KEYBOX_INVALID if the keybox was unpacked, but is
* invalid.
* @retval OEMCrypto_ERROR_WRITE_KEYBOX could not save keybox.
* Any other error will be logged.
*
* @threading
* This is an "Initialization and Termination Function" and will not be called
* simultaneously with any other function, as if the CDM holds a write lock on
* the OEMCrypto system. It will only be called after
* OEMCrypto_GenerateOTARequest().
*
* @version
* This method is new in API version 16.
*/
OEMCryptoResult OEMCrypto_ProcessOTAKeybox(OEMCrypto_SESSION session,
const uint8_t* buffer,
size_t buffer_length,
uint32_t use_test_key);
/****************************************************************************/
/****************************************************************************/
/* The following functions are deprecated. They are not required for the
* current version of OEMCrypto. They are being declared here to help with
* backwards compatibility.
*/
/*
* OEMCrypto_SetDecryptHash
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_SetDecryptHash_V18(OEMCrypto_SESSION session,
uint32_t frame_number,
const uint8_t* hash,
size_t hash_length);
/*
* OEMCrypto_GenerateSignature
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_GenerateSignature(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length);
/*
* OEMCrypto_RewrapDeviceRSAKey30
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
OEMCrypto_SESSION session, const uint32_t* unaligned_nonce,
const uint8_t* encrypted_message_key, size_t encrypted_message_key_length,
const uint8_t* enc_rsa_key, size_t enc_rsa_key_length,
const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key,
size_t* wrapped_rsa_key_length);
/*
* OEMCrypto_RewrapDeviceRSAKey
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
const uint32_t* unaligned_nonce, const uint8_t* enc_rsa_key,
size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv,
uint8_t* wrapped_rsa_key, size_t* wrapped_rsa_key_length);
/*
* OEMCrypto_UpdateUsageTable
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_UpdateUsageTable(void);
/*
* OEMCrypto_DeleteUsageEntry
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_DeleteUsageEntry(
OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length,
const uint8_t* message, size_t message_length, const uint8_t* signature,
size_t signature_length);
/*
* OEMCrypto_ForceDeleteUsageEntry
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst,
size_t pst_length);
/*
* OEMCrypto_CopyOldUsageEntry
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_CopyOldUsageEntry(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length);
/*
* OEMCrypto_DeleteOldUsageTable
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_DeleteOldUsageTable(void);
/*
* OEMCrypto_CreateOldUsageEntry
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_CreateOldUsageEntry(
uint64_t time_since_license_received, uint64_t time_since_first_decrypt,
uint64_t time_since_last_decrypt, OEMCrypto_Usage_Entry_Status status,
uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst,
size_t pst_length);
/*
* OEMCrypto_GenerateDerivedKeys_V15
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_GenerateDerivedKeys_V15(
OEMCrypto_SESSION session, const uint8_t* mac_key_context,
uint32_t mac_key_context_length, const uint8_t* enc_key_context,
uint32_t enc_key_context_length);
typedef struct {
size_t encrypt; // number of 16 byte blocks to decrypt.
size_t skip; // number of 16 byte blocks to leave in clear.
size_t offset; // offset into the pattern in blocks for this call.
} OEMCrypto_CENCEncryptPatternDesc_V15;
/*
* OEMCrypto_DecryptCENC_V15
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_DecryptCENC_V15(
OEMCrypto_SESSION session, const uint8_t* data_addr,
size_t data_addr_length, bool is_encrypted, const uint8_t* iv,
size_t block_offset, // used for CTR "cenc" mode only.
OEMCrypto_DestBufferDesc* out_buffer,
const OEMCrypto_CENCEncryptPatternDesc_V15* pattern,
uint8_t subsample_flags);
/*
* OEMCrypto_GetOEMPublicCertificate_V15
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_GetOEMPublicCertificate_V15(
OEMCrypto_SESSION session, uint8_t* public_cert,
size_t* public_cert_length);
/*
* OEMCrypto_LoadDeviceRSAKey
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
const uint8_t* wrapped_rsa_key,
size_t wrapped_rsa_key_length);
/*
* OEMCrypto_BuildInformation_V16
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
const char* OEMCrypto_BuildInformation_V16(void);
/*
* OEMCrypto_SecurityLevel_V16
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
const char* OEMCrypto_SecurityLevel_V16(void);
typedef struct {
OEMCrypto_Substring entitlement_key_id;
OEMCrypto_Substring content_key_id;
OEMCrypto_Substring content_key_data_iv;
OEMCrypto_Substring content_key_data;
} OEMCrypto_EntitledContentKeyObject_V16;
/*
* OEMCrypto_LoadEntitledContentKeys_V16
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_LoadEntitledContentKeys_V16(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
size_t key_array_length,
const OEMCrypto_EntitledContentKeyObject_V16* key_array);
/**
* OEmCrypto_IsSRIMUpdateSupported
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
bool OEMCrypto_IsSRMUpdateSupported(void);
/**
* OEMCrypto_LoadSRM
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length);
/**
* OEMCrypto_RemoveSRM
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_RemoveSRM(void);
/**
* OEMCrypto_LoadKeys
* @deprecated
* OEMCrypto_LoadKeys is only used to load a v15 license or renewal.
*/
OEMCryptoResult OEMCrypto_LoadKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys,
size_t key_array_length, const OEMCrypto_KeyObject* key_array,
OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data,
OEMCrypto_LicenseType license_type);
typedef struct {
OEMCrypto_Substring key_id;
OEMCrypto_Substring key_control_iv;
OEMCrypto_Substring key_control;
} OEMCrypto_KeyRefreshObject;
/**
* OEMCrypto_RefreshKeys
* @deprecated
* OEMCrypto_RefreshKeys is only used to load a v15 license or renewal.
*/
OEMCryptoResult OEMCrypto_RefreshKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length, size_t num_keys,
const OEMCrypto_KeyRefreshObject* key_array);
/**
* OEMCrypto_GetRandom
* @deprecated
* OEMCrypto_GetRandom is not needed to export random numbers.
*/
OEMCryptoResult OEMCrypto_GetRandom(uint8_t* random_data,
size_t random_data_length);
/**
* OEMCrypto_SelectKey
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
const uint8_t* content_key_id,
size_t content_key_id_length,
OEMCryptoCipherMode cipher_mode);
/**
* OEMCrypto_DecryptCENC_V17
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_DecryptCENC_V17(
OEMCrypto_SESSION session, const OEMCrypto_SampleDescription* samples,
size_t samples_length, const OEMCrypto_CENCEncryptPatternDesc* pattern);
/**
* OEMCrypto_Generic_Encrypt_V17
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_Generic_Encrypt_V17(
OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* in_buffer,
size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm,
OEMCrypto_SharedMemory* out_buffer);
/**
* OEMCrypto_Generic_Decrypt_V17
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_Generic_Decrypt_V17(
OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* in_buffer,
size_t in_buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm,
OEMCrypto_SharedMemory* out_buffer);
/**
* OEMCrypto_Generic_Sign_V17
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_Generic_Sign_V17(OEMCrypto_SESSION session,
const OEMCrypto_SharedMemory* buffer,
size_t buffer_length,
OEMCrypto_Algorithm algorithm,
OEMCrypto_SharedMemory* signature,
size_t* signature_length);
/**
* OEMCrypto_Generic_Verify_V17
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_Generic_Verify_V17(
OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* buffer,
size_t buffer_length, OEMCrypto_Algorithm algorithm,
const OEMCrypto_SharedMemory* signature, size_t signature_length);
/**
* OEMCrypto_GenerateDerivedKeys_V18
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_GenerateDerivedKeys_V18(
OEMCrypto_SESSION session, const OEMCrypto_SharedMemory* mac_key_context,
size_t mac_key_context_length,
const OEMCrypto_SharedMemory* enc_key_context,
size_t enc_key_context_length);
/**
* OEMCrypto_DeriveKeysFromSessionKey_V18
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey_V18(
OEMCrypto_SESSION session, const uint8_t* derivation_key,
size_t derivation_key_length, const OEMCrypto_SharedMemory* mac_key_context,
size_t mac_key_context_length,
const OEMCrypto_SharedMemory* enc_key_context,
size_t enc_key_context_length);
/**
* OEMCrypto_LoadLicense_V18
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_LoadLicense_V18(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
size_t core_message_length,
const uint8_t* signature,
size_t signature_length);
/**
* OEMCrypto_LoadProvisioning_V18
* @deprecated
* Not required for the current version of OEMCrypto. Declared here to
* help with backward compatibility.
*/
OEMCryptoResult OEMCrypto_LoadProvisioning_V18(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
size_t core_message_length, const uint8_t* signature,
size_t signature_length, uint8_t* wrapped_private_key,
size_t* wrapped_private_key_length);
/****************************************************************************/
/****************************************************************************/
#ifdef __cplusplus
}
#endif
#endif // OEMCRYPTO_CENC_H_