2001 lines
84 KiB
C
2001 lines
84 KiB
C
// Copyright 2013 Google Inc. All Rights Reserved.
|
||
|
||
/*********************************************************************
|
||
* OEMCryptoCENC.h
|
||
*
|
||
* Reference APIs needed to support Widevine's crypto algorithms.
|
||
*********************************************************************/
|
||
|
||
#ifndef OEMCRYPTO_CENC_H_
|
||
#define OEMCRYPTO_CENC_H_
|
||
|
||
#include <stdbool.h>
|
||
#include <stddef.h>
|
||
#include <stdint.h>
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
typedef uint32_t OEMCrypto_SESSION;
|
||
|
||
typedef enum OEMCryptoResult {
|
||
OEMCrypto_SUCCESS = 0,
|
||
OEMCrypto_ERROR_INIT_FAILED = 1,
|
||
OEMCrypto_ERROR_TERMINATE_FAILED = 2,
|
||
OEMCrypto_ERROR_OPEN_FAILURE = 3,
|
||
OEMCrypto_ERROR_CLOSE_FAILURE = 4,
|
||
OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED = 5,
|
||
OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED = 6,
|
||
OEMCrypto_ERROR_SHORT_BUFFER = 7,
|
||
OEMCrypto_ERROR_NO_DEVICE_KEY = 8,
|
||
OEMCrypto_ERROR_NO_ASSET_KEY = 9,
|
||
OEMCrypto_ERROR_KEYBOX_INVALID = 10,
|
||
OEMCrypto_ERROR_NO_KEYDATA = 11,
|
||
OEMCrypto_ERROR_NO_CW = 12,
|
||
OEMCrypto_ERROR_DECRYPT_FAILED = 13,
|
||
OEMCrypto_ERROR_WRITE_KEYBOX = 14,
|
||
OEMCrypto_ERROR_WRAP_KEYBOX = 15,
|
||
OEMCrypto_ERROR_BAD_MAGIC = 16,
|
||
OEMCrypto_ERROR_BAD_CRC = 17,
|
||
OEMCrypto_ERROR_NO_DEVICEID = 18,
|
||
OEMCrypto_ERROR_RNG_FAILED = 19,
|
||
OEMCrypto_ERROR_RNG_NOT_SUPPORTED = 20,
|
||
OEMCrypto_ERROR_SETUP = 21,
|
||
OEMCrypto_ERROR_OPEN_SESSION_FAILED = 22,
|
||
OEMCrypto_ERROR_CLOSE_SESSION_FAILED = 23,
|
||
OEMCrypto_ERROR_INVALID_SESSION = 24,
|
||
OEMCrypto_ERROR_NOT_IMPLEMENTED = 25,
|
||
OEMCrypto_ERROR_NO_CONTENT_KEY = 26,
|
||
OEMCrypto_ERROR_CONTROL_INVALID = 27,
|
||
OEMCrypto_ERROR_UNKNOWN_FAILURE = 28,
|
||
OEMCrypto_ERROR_INVALID_CONTEXT = 29,
|
||
OEMCrypto_ERROR_SIGNATURE_FAILURE = 30,
|
||
OEMCrypto_ERROR_TOO_MANY_SESSIONS = 31,
|
||
OEMCrypto_ERROR_INVALID_NONCE = 32,
|
||
OEMCrypto_ERROR_TOO_MANY_KEYS = 33,
|
||
OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED = 34,
|
||
OEMCrypto_ERROR_INVALID_RSA_KEY = 35,
|
||
OEMCrypto_ERROR_KEY_EXPIRED = 36,
|
||
OEMCrypto_ERROR_INSUFFICIENT_RESOURCES = 37,
|
||
OEMCrypto_ERROR_INSUFFICIENT_HDCP = 38,
|
||
} OEMCryptoResult;
|
||
|
||
/*
|
||
* OEMCrypto_DestBufferDesc
|
||
* 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.
|
||
* 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.
|
||
*
|
||
* Specific fields are as follows:
|
||
*
|
||
* (type == OEMCrypto_BufferType_Clear)
|
||
* address - Address of start of user memory buffer.
|
||
* max_length - Size of user memory buffer.
|
||
* (type == OEMCrypto_BufferType_Secure)
|
||
* buffer - handle to a platform-specific secure buffer.
|
||
* max_length - Size of platform-specific secure buffer.
|
||
* (type == OEMCrypto_BufferType_Direct)
|
||
* is_video - If true, decrypted bytes are routed to the video
|
||
* decoder. If false, decrypted bytes are routed to the
|
||
* audio decoder.
|
||
*/
|
||
typedef enum OEMCryptoBufferType {
|
||
OEMCrypto_BufferType_Clear,
|
||
OEMCrypto_BufferType_Secure,
|
||
OEMCrypto_BufferType_Direct
|
||
} OEMCryptoBufferType;
|
||
|
||
typedef struct {
|
||
OEMCryptoBufferType type;
|
||
union {
|
||
struct { // type == OEMCrypto_BufferType_Clear
|
||
uint8_t* address;
|
||
size_t max_length;
|
||
} clear;
|
||
struct { // type == OEMCrypto_BufferType_Secure
|
||
void* handle;
|
||
size_t max_length;
|
||
size_t offset;
|
||
} secure;
|
||
struct { // type == OEMCrypto_BufferType_Direct
|
||
bool is_video;
|
||
} direct;
|
||
} buffer;
|
||
} OEMCrypto_DestBufferDesc;
|
||
|
||
/*
|
||
* OEMCrypto_KeyObject
|
||
* Points to the relevant fields for a content key. The fields are extracted
|
||
* from the License Response message offered to OEMCrypto_LoadKeys(). Each
|
||
* field points to one of the components of the key. Key data, key control,
|
||
* and both IV fields are 128 bits (16 bytes):
|
||
* key_id - the unique id of this key.
|
||
* key_id_length - the size of key_id.
|
||
* key_data_iv - the IV for performing AES-128-CBC decryption of the
|
||
* key_data field.
|
||
* key_data - the key data. It is encrypted (AES-128-CBC) with the
|
||
* session's derived encrypt key and the key_data_iv.
|
||
* key_control_iv - the IV for performing AES-128-CBC decryption of the
|
||
* key_control field.
|
||
* key_control - the key control block. It is encrypted (AES-128-CBC) with
|
||
* the content key from the key_data field.
|
||
*
|
||
* The memory for the OEMCrypto_KeyObject fields is allocated and freed
|
||
* by the caller of OEMCrypto_LoadKeys().
|
||
*/
|
||
typedef struct {
|
||
const uint8_t* key_id;
|
||
size_t key_id_length;
|
||
const uint8_t* key_data_iv;
|
||
const uint8_t* key_data;
|
||
size_t key_data_length;
|
||
const uint8_t* key_control_iv;
|
||
const uint8_t* key_control;
|
||
} OEMCrypto_KeyObject;
|
||
|
||
/*
|
||
* OEMCrypto_KeyRefreshObject
|
||
* Points to the relevant fields for renewing a content key. The fields are
|
||
* extracted from the License Renewal Response message offered to
|
||
* OEMCrypto_RefreshKeys(). Each field points to one of the components of
|
||
* the key.
|
||
* key_id - the unique id of this key.
|
||
* key_control_iv - the IV for performing AES-128-CBC decryption of the
|
||
* key_control field. 16 bytes.
|
||
* key_control - the key control block. It is encrypted (AES-128-CBC) with
|
||
* the content key from the key_data field. 16 bytes.
|
||
*
|
||
* The key_data is unchanged from the original OEMCrypto_LoadKeys() call. Some
|
||
* Key Control Block fields, especially those related to key lifetime, may
|
||
* change.
|
||
*
|
||
* The memory for the OEMCrypto_KeyRefreshObject fields is allocated and freed
|
||
* by the caller of OEMCrypto_RefreshKeys().
|
||
*/
|
||
typedef struct {
|
||
const uint8_t* key_id;
|
||
size_t key_id_length;
|
||
const uint8_t* key_control_iv;
|
||
const uint8_t* key_control;
|
||
} OEMCrypto_KeyRefreshObject;
|
||
|
||
/*
|
||
* OEMCrypto_Algorithm
|
||
* 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;
|
||
|
||
/*
|
||
* Flags indicating data endpoints in OEMCrypto_DecryptCTR.
|
||
*/
|
||
#define OEMCrypto_FirstSubsample 1
|
||
#define OEMCrypto_LastSubsample 2
|
||
|
||
/*
|
||
* OEMCrypto_Usage_Entry_Status.
|
||
* Valid values for status in the usage table.
|
||
*/
|
||
typedef enum OEMCrypto_Usage_Entry_Status {
|
||
kUnused = 0,
|
||
kActive = 1,
|
||
kInactive = 2
|
||
} OEMCrypto_Usage_Entry_Status;
|
||
|
||
/*
|
||
* OEMCrypto_PST_Report is used to report an entry from the Usage Table.
|
||
*/
|
||
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;
|
||
|
||
/*
|
||
* OEMCrypto_Clock_Security_Level.
|
||
* Valid values for clock_security_level in OEMCrypto_PST_Report.
|
||
*/
|
||
typedef enum OEMCrypto_Clock_Security_Level {
|
||
kInsecureClock = 0,
|
||
kSecureTimer = 1,
|
||
kSecureClock = 2,
|
||
kHardwareSecureClock = 3
|
||
} OEMCrypto_Clock_Security_Level;
|
||
|
||
typedef enum RSA_Padding_Scheme {
|
||
kSign_RSASSA_PSS = 0x1, // RSASSA-PSS with SHA1.
|
||
kSign_PKCS1_Block1 = 0x2, // PKCS1 with block type 1 padding (only).
|
||
} RSA_Padding_Scheme;
|
||
|
||
|
||
/*
|
||
* Obfuscation Renames.
|
||
*/
|
||
#define OEMCrypto_Initialize _oecc01
|
||
#define OEMCrypto_Terminate _oecc02
|
||
#define OEMCrypto_InstallKeybox _oecc03
|
||
#define OEMCrypto_GetKeyData _oecc04
|
||
#define OEMCrypto_IsKeyboxValid _oecc05
|
||
#define OEMCrypto_GetRandom _oecc06
|
||
#define OEMCrypto_GetDeviceID _oecc07
|
||
#define OEMCrypto_WrapKeybox _oecc08
|
||
#define OEMCrypto_OpenSession _oecc09
|
||
#define OEMCrypto_CloseSession _oecc10
|
||
#define OEMCrypto_DecryptCTR _oecc11
|
||
#define OEMCrypto_GenerateDerivedKeys _oecc12
|
||
#define OEMCrypto_GenerateSignature _oecc13
|
||
#define OEMCrypto_GenerateNonce _oecc14
|
||
#define OEMCrypto_LoadKeys_V8 _oecc15
|
||
#define OEMCrypto_RefreshKeys _oecc16
|
||
#define OEMCrypto_SelectKey _oecc17
|
||
#define OEMCrypto_RewrapDeviceRSAKey _oecc18
|
||
#define OEMCrypto_LoadDeviceRSAKey _oecc19
|
||
#define OEMCrypto_GenerateRSASignature_V8 _oecc20
|
||
#define OEMCrypto_DeriveKeysFromSessionKey _oecc21
|
||
#define OEMCrypto_APIVersion _oecc22
|
||
#define OEMCrypto_SecurityLevel _oecc23
|
||
#define OEMCrypto_Generic_Encrypt _oecc24
|
||
#define OEMCrypto_Generic_Decrypt _oecc25
|
||
#define OEMCrypto_Generic_Sign _oecc26
|
||
#define OEMCrypto_Generic_Verify _oecc27
|
||
#define OEMCrypto_GetHDCPCapability _oecc28
|
||
#define OEMCrypto_SupportsUsageTable _oecc29
|
||
#define OEMCrypto_UpdateUsageTable _oecc30
|
||
#define OEMCrypto_DeactivateUsageEntry _oecc31
|
||
#define OEMCrypto_ReportUsage _oecc32
|
||
#define OEMCrypto_DeleteUsageEntry _oecc33
|
||
#define OEMCrypto_DeleteUsageTable _oecc34
|
||
#define OEMCrypto_LoadKeys _oecc35
|
||
#define OEMCrypto_GenerateRSASignature _oecc36
|
||
|
||
/*
|
||
* OEMCrypto_Initialize
|
||
*
|
||
* Description:
|
||
* Initialize the crypto firmware/hardware.
|
||
*
|
||
* Parameters:
|
||
* N/A
|
||
*
|
||
* Threading:
|
||
* No other function calls will be made while this function is running. This
|
||
* function will not be called again before OEMCrypto_Terminate.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_INIT_FAILED failed to initialize crypto hardware
|
||
*
|
||
* Version:
|
||
* This method is supported by all API versions.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_Initialize(void);
|
||
|
||
/*
|
||
* OEMCrypto_Terminate
|
||
*
|
||
* Description:
|
||
* Closes the crypto operation and releases all related resources.
|
||
*
|
||
* Parameters:
|
||
* N/A
|
||
*
|
||
* Threading:
|
||
* No other OEMCrypto calls are made while this function is running. After
|
||
* this function is called, no other OEMCrypto calls will be made until another
|
||
* call to OEMCrypto_Initialize is made.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_TERMINATE_FAILED failed to de-initialize crypto hardware
|
||
*
|
||
* Version:
|
||
* This method is supported by all API versions.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_Terminate(void);
|
||
|
||
/*
|
||
* OEMCrypto_OpenSession
|
||
*
|
||
* Description:
|
||
* 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.
|
||
*
|
||
* Parameters:
|
||
* session (out) - an opaque handle that the crypto firmware uses to identify the
|
||
* session.
|
||
*
|
||
* Threading:
|
||
* No other Open/Close session calls will be made while this function is
|
||
* running. Functions on existing sessions may be called while this function
|
||
* is active.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_TOO_MANY_SESSIONS failed because too many sessions are open
|
||
* OEMCrypto_ERROR_OPEN_SESSION_FAILED failed to initialize the crypto session
|
||
*
|
||
* Version:
|
||
* This method changed in API version 5.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION *session);
|
||
|
||
/*
|
||
* OEMCrypto_CloseSession
|
||
*
|
||
* Description:
|
||
* Closes the crypto security engine session and frees any associated resources.
|
||
*
|
||
* Parameters:
|
||
* session (in) - handle for the session to be closed.
|
||
*
|
||
* Threading:
|
||
* No other Open/Close session calls will be made while this function is
|
||
* running. Functions on existing sessions may be called while this function
|
||
* is active.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_INVALID_SESSION no open session with that id.
|
||
* OEMCrypto_ERROR_CLOSE_SESSION_FAILED failed to terminate the crypto session
|
||
*
|
||
* Version:
|
||
* This method changed in API version 5.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session);
|
||
|
||
/*
|
||
* OEMCrypto_GenerateDerivedKeys
|
||
*
|
||
* Description:
|
||
* Generates three secondary keys -- mac_key_server, mac_key_client, and
|
||
* encrypt_key -- for handling signing and content key decryption under the
|
||
* license server protocol for AES CTR mode.
|
||
*
|
||
* Refer to document "Widevine Modular DRM Security Integration Guide for
|
||
* CENC" for details. This function computes the AES-128-CMAC of the
|
||
* enc_key_context and stores it in secure memory as the encrypt_key. It
|
||
* then computes four cycles of AES-128-CMAC of the mac_key_context and
|
||
* stores it in the mac_keys. The first two cycles are used for
|
||
* mac_key_server and the second two cycles are used for mac_key_client.
|
||
* These three keys will be stored until the next call to LoadKeys.
|
||
*
|
||
* Parameters:
|
||
* session (in) - handle for the session to be used.
|
||
* mac_key_context (in) - pointer to memory containing context data for
|
||
* computing the HMAC generation key.
|
||
* mac_key_context_length (in) - length of the HMAC key context data, in bytes.
|
||
* enc_key_context (in) - pointer to memory containing context data for
|
||
* computing the encryption key.
|
||
* enc_key_context_length (in) - length of the encryption key context data, in
|
||
* bytes.
|
||
*
|
||
*
|
||
* Results:
|
||
* mac_key_server: the 256 bit mac key is generated and stored in secure memory.
|
||
* mac_key_client: the 256 bit mac key is generated and stored in secure memory.
|
||
* enc_key: the 128 bit encryption key is generated and stored in secure memory.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 8.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_GenerateDerivedKeys(
|
||
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);
|
||
|
||
/*
|
||
* OEMCrypto_GenerateNonce
|
||
*
|
||
* Description:
|
||
* 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
|
||
* for the next call to LoadKeys.
|
||
*
|
||
* 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. With this in mind, if more than 20
|
||
* nonces are requested within one second, OEMCrypto will return an error
|
||
* after the 20th 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.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* nonce (out) - pointer to memory to received the computed nonce.
|
||
*
|
||
* Results:
|
||
* nonce: the nonce is also stored in secure memory. At least 4 nonces should be
|
||
* stored for each session.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 5.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_GenerateNonce(
|
||
OEMCrypto_SESSION session,
|
||
uint32_t* nonce);
|
||
|
||
/*
|
||
* OEMCrypto_GenerateSignature
|
||
*
|
||
* Description:
|
||
* Generates a HMAC-SHA256 signature for license request signing under the
|
||
* license server protocol for AES CTR mode. This uses the key mac_key_client.
|
||
*
|
||
* NOTE: OEMCrypto_GenerateDerivedKeys() must be called first to establish the
|
||
* mac_key_client.
|
||
*
|
||
* Refer to document "Widevine Modular DRM Security Integration Guide for
|
||
* CENC" for details.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* message (in) - pointer to memory containing message to be signed.
|
||
* message_length (in) - length of the message, in bytes.
|
||
* signature (out) - pointer to memory to received the computed signature. May be
|
||
* null on the first call in order to find required buffer size.
|
||
* signature_length (in/out) - (in) length of the signature buffer, in bytes.
|
||
* (out) actual length of the signature, in bytes.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough to hold
|
||
* buffer.
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 5.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_GenerateSignature(
|
||
OEMCrypto_SESSION session,
|
||
const uint8_t* message,
|
||
size_t message_length,
|
||
uint8_t* signature,
|
||
size_t* signature_length);
|
||
|
||
/*
|
||
* OEMCrypto_LoadKeys
|
||
*
|
||
* Description:
|
||
* Installs a set of keys for performing decryption in the current session.
|
||
*
|
||
* The relevant fields have been extracted from the License Response protocol
|
||
* message, but the entire message and associated signature are provided so
|
||
* the message can be verified (using HMAC-SHA256 with the derived
|
||
* mac_key_server). If the signature verification fails, ignore all other
|
||
* arguments and return OEMCrypto_ERROR_SIGNATURE_FAILURE. Otherwise, add the
|
||
* keys to the session context.
|
||
*
|
||
* The keys will be decrypted using the current encrypt_key (AES-128-CBC) and
|
||
* the IV given in the KeyObject. 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.
|
||
*
|
||
* If it is not null, 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 calls to OEMCrypto_RefreshKeys(). 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_RefreshKeys for this session and
|
||
* the current mac_keys should remain unchanged.
|
||
*
|
||
* The mac_key and encrypt_key were generated and stored by the previous call
|
||
* to OEMCrypto_GenerateDerivedKeys(). The nonce was generated and stored by
|
||
* the previous call to OEMCrypto_GenerateNonce().
|
||
*
|
||
* This session’s elapsed time clock is started at 0. The clock will be used
|
||
* in OEMCrypto_DecryptCTR().
|
||
*
|
||
* NOTE: OEMCrypto_GenerateDerivedKeys() must be called first to establish the
|
||
* mac_key and encrypt_key.
|
||
*
|
||
* Refer to document "Widevine Modular DRM Security Integration Guide for
|
||
* CENC" for details.
|
||
*
|
||
* Verification:
|
||
* The following checks should be performed. If any check fails, an error is
|
||
* returned, and none of the keys are loaded.
|
||
*
|
||
* 1. 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).
|
||
*
|
||
* 2. The enc_mac_keys pointer must be either null, or point inside the
|
||
* message. If the pointer enc_mac_keys is not null, [e]the API shall verify
|
||
* that the two pointers enc_mac_keys_iv and enc_mac_keys point to locations in
|
||
* the message. I.e. (message <= p && p < message+message_length)for p in
|
||
* each of enc_mac_keys_iv, enc_mac_keys. If not, return
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT.
|
||
*
|
||
* 3. The API shall verify that each pointer in each KeyObject points to a
|
||
* location in the message. I.e. (message <= p && p < message+message_length)
|
||
* for p in each of key_id, key_data_iv, key_data, key_control_iv,
|
||
* key_control. If not, return OEMCrypto_ERROR_INVALID_CONTEXT.
|
||
*
|
||
* 4. Each key’s control block, after decryption, shall have a valid
|
||
* verification field. If not, return OEMCrypto_ERROR_INVALID_CONTEXT.
|
||
*
|
||
* 5. If any key control block has the Nonce_Enabled bit set, that key’s Nonce
|
||
* field shall match the nonce generated by the current nonce. 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.
|
||
*
|
||
* 6. If the key control block has a nonzero Replay_Control, then the
|
||
* verification described below is also performed.
|
||
*
|
||
* Usage Table and Provider Session Token (pst):
|
||
*
|
||
* If a key control block has a nonzero value for Replay_Control, then all keys
|
||
* in this license will have the same value. In this case, the following
|
||
* additional checks are performed.
|
||
*
|
||
* The pointer pst must not be null, and must point to a location in the
|
||
* message. If not, return OEMCrypto_ERROR_INVALID_CONTEXT.
|
||
*
|
||
* - If Replay_Control is 1 = Nonce_Required, then OEMCrypto will perform a
|
||
* nonce check as described above. OEMCrypto will verify that the table does
|
||
* not already have an entry for the value of pst passed in as a parameter ---
|
||
* if an entry already exists, an error OEMCrypto_ERROR_INVALID_CONTEXT is
|
||
* returned and no keys are loaded. OEMCrypto will then create a new entry in
|
||
* the table, and mark this session as using this new entry. This 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 check the Session Usage table for an existing
|
||
* entry with the same pst.
|
||
*
|
||
* --- If the pst is not in the table yet, a new entry will be created in the
|
||
* table and this session shall use the new entry. In that case, the nonce
|
||
* will be verified for each key.
|
||
*
|
||
* --- If an existing usage table entry is found, then this session will use
|
||
* that entry. In that case, the nonce will not be verified for each key.
|
||
* 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 an existing entry is not found, the return
|
||
* error is OEMCrypto_ERROR_INVALID_NONCE.
|
||
*
|
||
* Note: If LoadKeys updates the mac keys, then the new updated mac keys will
|
||
* be used in the Usage Table. If LoadKeys does not update the mac keys, the
|
||
* existing session mac keys are stored in the usage table.
|
||
*
|
||
* 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.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* message (in) - pointer to memory containing message to be verified.
|
||
* message_length (in) - length of the message, in bytes.
|
||
* signature (in) - pointer to memory containing the signature.
|
||
* signature_length (in) - length of the signature, in bytes.
|
||
* enc_mac_keys_iv (in) - IV for decrypting new mac_key. Size is 128 bits.
|
||
* enc_mac_keys (in) - encrypted mac_keys for generating new mac_keys. Size is
|
||
* 512 bits.
|
||
* num_keys (in) - number of keys present.
|
||
* key_array (in) - set of keys to be installed.
|
||
* pst (in) - the Provider Session Token.
|
||
* pst_length (in) - the length of pst.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT
|
||
* OEMCrypto_ERROR_SIGNATURE_FAILURE
|
||
* OEMCrypto_ERROR_INVALID_NONCE
|
||
* OEMCrypto_ERROR_TOO_MANY_KEYS
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
|
||
const uint8_t* message,
|
||
size_t message_length,
|
||
const uint8_t* signature,
|
||
size_t signature_length,
|
||
const uint8_t* enc_mac_keys_iv,
|
||
const uint8_t* enc_mac_keys,
|
||
size_t num_keys,
|
||
const OEMCrypto_KeyObject* key_array,
|
||
const uint8_t* pst,
|
||
size_t pst_length);
|
||
|
||
/*
|
||
* OEMCrypto_RefreshKeys
|
||
*
|
||
* Description:
|
||
* Updates an existing set of keys for continuing decryption in the
|
||
* current session.
|
||
*
|
||
* The relevant fields have been extracted from the Renewal Response protocol
|
||
* message, but the entire message and associated signature are provided so the
|
||
* message can be verified (using HMAC-SHA256 with the current
|
||
* mac_key[server]). If any verification step fails, an error is returned.
|
||
* Otherwise, the key table in trusted memory is updated using the key_control
|
||
* block. When updating an entry in the table, only the duration, nonce, and
|
||
* nonce_enabled fields are used. All other key control bits are not modified.
|
||
*
|
||
* NOTE: OEMCrypto_GenerateDerivedKeys() or OEMCrypto_LoadKeys() must be called
|
||
* first to establish the mac_key[server].
|
||
*
|
||
* This session’s elapsed time clock is reset to 0 when this function is called.
|
||
* The elapsed time clock is used in OEMCrypto_DecryptCTR().
|
||
*
|
||
* This function does not add keys to the key table. It is only used to update a
|
||
* key control block license duration. Refer to the License Signing and
|
||
* Verification section above for more details. This function is used to update
|
||
* the duration of a key, only. It is not used to update key control bits.
|
||
*
|
||
* If the KeyRefreshObject’s key_control_iv is null, then the key_control is not
|
||
* encrypted. If the key_control_iv is specified, then key_control is encrypted
|
||
* with the first 128 bits of the corresponding content key.
|
||
*
|
||
* If the KeyRefreshObject’s key_id is null, then this refresh object should be
|
||
* used to update the duration of all keys for the current session. In this
|
||
* case, key_control_iv will also be null and the control block will not be
|
||
* encrypted.
|
||
*
|
||
*
|
||
* Verification:
|
||
* The following checks should be performed. If any check fails, an error is
|
||
* returned, and none of the keys are loaded.
|
||
*
|
||
* 1. 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).
|
||
*
|
||
* 2. The API shall verify that each pointer in each KeyObject points to a
|
||
* location in the message, or is null. I.e. (message <= p && p <
|
||
* message+message_length) for p in each of key_id,key_control_iv,
|
||
* key_control. If not, return OEMCrypto_ERROR_INVALID_CONTEXT.
|
||
*
|
||
* 3. Each key’s control block shall have a valid verification field. If not,
|
||
* return OEMCrypto_ERROR_INVALID_CONTEXT.
|
||
*
|
||
* 4. If the key control block has the Nonce_Enabled bit set, the Nonce field
|
||
* shall match one of the nonces 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.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* message (in) - pointer to memory containing message to be verified.
|
||
* message_length (in) - length of the message, in bytes.
|
||
* signature (in) - pointer to memory containing the signature.
|
||
* signature_length (in) - length of the signature, in bytes.
|
||
* num_keys (in) - number of keys present.
|
||
* key_array (in) - set of key updates.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT
|
||
* OEMCrypto_ERROR_INVALID_NONCE
|
||
* OEMCrypto_ERROR_SIGNATURE_FAILURE
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 8.
|
||
*/
|
||
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_SelectKey
|
||
*
|
||
* Description:
|
||
* Select a content key and install it in the hardware key ladder for
|
||
* subsequent decryption operations (OEMCrypto_DecryptCTR()) for this session.
|
||
* The specified key must have been previously "installed" via
|
||
* OEMCrypto_LoadKeys() or OEMCrypto_RefreshKeys().
|
||
*
|
||
* 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 and timers based on the key's control block.
|
||
*
|
||
* Step 3: use the latched content key to decrypt (AES-128-CTR) buffers passed in
|
||
* via OEMCrypto_DecryptCTR(). 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. Continue to use this key until OEMCrypto_SelectKey() is called
|
||
* again, or until OEMCrypto_CloseSession() is called.
|
||
*
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier
|
||
* key_id (in) - pointer to the Key ID
|
||
* key_id_length (in) - length of the Key ID in bytes
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_INVALID_SESSION crypto session ID invalid or not open
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY failed to decrypt device key
|
||
* OEMCrypto_ERROR_NO_CONTENT_KEY failed to decrypt content key
|
||
* OEMCrypto_ERROR_CONTROL_INVALID invalid or unsupported control input
|
||
* OEMCrypto_ERROR_KEYBOX_INVALID cannot decrypt and read from Keybox
|
||
* OEMCrypto_ERROR_KEY_EXPIRED
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 8.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
|
||
const uint8_t* key_id,
|
||
size_t key_id_length);
|
||
|
||
/*
|
||
* OEMCrypto_DecryptCTR
|
||
*
|
||
* Description:
|
||
* Decrypts (AES-128-CTR) or copies the payload in the buffer referenced by the
|
||
* data_addr parameter into the buffer referenced by the out_buffer parameter,
|
||
* using the session context indicated by the session parameter. If is_encrypted
|
||
* is true, the content key associated with the session is latched in the active
|
||
* hardware key ladder and is used for the decryption operation. If is_encrypted
|
||
* is false, the data is simply copied.
|
||
*
|
||
* After decryption, the data_length bytes are copied to the location described
|
||
* by out_buffer. This could be one of
|
||
*
|
||
* 1. The structure out_buffer 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 out_buffer contains a handle to a secure buffer.
|
||
*
|
||
* 3. The structure out_buffer indicates that the data should be sent directly to
|
||
* the decoder and rendered.
|
||
*
|
||
* NOTES:
|
||
* IV points to the counter value to be used for the initial
|
||
* encrypted block of the input buffer. The IV length is the AES
|
||
* block size. For subsequent encrypted AES blocks the IV is
|
||
* calculated 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.
|
||
*
|
||
* This method may be called several times before the decrypted data is used.
|
||
* For this reason, the parameter subsample_flags may be used to optimize
|
||
* decryption. 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 decrypted data will not be used until after
|
||
* OEMCrypto_LastSubsample has been set. If an implementation decrypts data
|
||
* immediately, it may ignore subsample_flags.
|
||
*
|
||
* If the destination buffer is secure, an offset may be specified. DecryptCTR
|
||
* begins storing data out_buffer->secure.offset bytes after the beginning of the
|
||
* secure buffer.
|
||
*
|
||
* If the session has an entry in the Usage Table, then OEMCrypto will update the
|
||
* time_of_last_decrypt. If the status of the entry is “unused”, then change the
|
||
* status to “active” and set the time_of_first_decrypt.[f]
|
||
*
|
||
*
|
||
* Verification:
|
||
* The following checks should be performed if is_encrypted is true. If any
|
||
* check fails, an error is returned, and no decryption is performed.
|
||
*
|
||
* 1. If the current key’s control block has a nonzero Duration field, then the
|
||
* API shall verify that the duration is greater than the session’s elapsed time
|
||
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED[g].
|
||
*
|
||
* 2. 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.
|
||
*
|
||
* 3. If the current key’s control block has the HDCP bit set, then the API shall
|
||
* verify that the buffer will be output using HDCP only. If not, return
|
||
* OEMCrypto_ERROR_DECRYPT_FAILED.
|
||
*
|
||
* 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, then
|
||
* return OEMCrypto_ERROR_INSUFFICIENT_HDCP.
|
||
*
|
||
* 1. If the current session has an entry in the Usage Table, and the status of
|
||
* that entry is “inactive”, then return OEMCrypto_ERROR_INVALID_SESSION.[h]
|
||
*
|
||
* If the flag is_encrypted is false, then no verification is performed. This
|
||
* call shall copy clear data even when there are no keys loaded, or there is no
|
||
* selected key.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* data_addr (in) - An unaligned pointer to this segment of the stream.
|
||
* data_length (in) - The length of this segment of the stream, in bytes.
|
||
* is_encrypted (in) - True if the buffer described by data_addr, data_length is
|
||
* encrypted. If is_encrypted is false, only the data_addr
|
||
* and data_length parameters are used. The iv and offset
|
||
* arguments are ignored.
|
||
* iv (in) - The initial value block to be used for content decryption.
|
||
* block_offset (in) - If non-zero, the decryption block boundary is different
|
||
* from the start of the data. block_offset should be
|
||
* subtracted from data_addr to compute the starting address
|
||
* of the first decrypted block. The bytes between the
|
||
* decryption block start address and data_addr are discarded
|
||
* after decryption. It does not adjust the beginning of the
|
||
* source or destination data. This parameter satisfies
|
||
* 0 <= block_offset < 16.
|
||
* out_buffer (in) - A caller-owned descriptor that specifies the handling of the
|
||
* decrypted byte stream. See OEMCrypto_DestbufferDesc for details.
|
||
* subsample_flags (in) - 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.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT
|
||
* OEMCrypto_ERROR_DECRYPT_FAILED
|
||
* OEMCrypto_ERROR_KEY_EXPIRED
|
||
* OEMCrypto_ERROR_INSUFFICIENT_HDCP
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
|
||
const uint8_t *data_addr,
|
||
size_t data_length,
|
||
bool is_encrypted,
|
||
const uint8_t *iv,
|
||
size_t block_offset,
|
||
const OEMCrypto_DestBufferDesc* out_buffer,
|
||
uint8_t subsample_flags);
|
||
|
||
/*
|
||
* OEMCrypto_WrapKeybox
|
||
*
|
||
* Description:
|
||
* During manufacturing, the keybox 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. As described in section 5.5.4, the keybox may be directly encrypted
|
||
* and stored on the device in a single step, or it may use the two-step
|
||
* WrapKeybox/InstallKeybox approach. When the Widevine DRM plugin initializes,
|
||
* it will look for a wrapped keybox in the file /factory/wv.keys and install it
|
||
* into the security processor by calling OEMCrypto_InstallKeybox().
|
||
*
|
||
* OEMCrypto_WrapKeybox() is used to generate an OEM-encrypted keybox that may be
|
||
* passed to OEMCrypto_InstallKeybox() for provisioning. The keybox 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 provisioning method involves saving the keybox to the file system.
|
||
*
|
||
* Parameters:
|
||
* keybox (in) - pointer to Keybox data to encrypt. May be NULL on the first
|
||
* call to test size of wrapped keybox. The keybox may either be clear or
|
||
* previously encrypted.
|
||
* keyboxLength (in) - length the keybox data in bytes
|
||
* wrappedKeybox (out) – Pointer to wrapped keybox
|
||
* wrappedKeyboxLength (out) – Pointer to the length of the wrapped keybox in bytes
|
||
* transportKey (in) – Optional. AES transport key. If provided, the keybox
|
||
* parameter was previously encrypted with this key. The keybox will be
|
||
* decrypted with the transport key using AES-CBC and a null IV.
|
||
* transportKeyLength (in) – Optional. Number of bytes in the transportKey, if used.
|
||
*
|
||
* Threading:
|
||
* This function is not called simultaneously with any other functions
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_WRAP_KEYBOX failed to wrap Keybox
|
||
* OEMCrypto_ERROR_SHORT_BUFFER if keybox is provided as NULL, to determine the
|
||
* size of the wrapped keybox
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED
|
||
*
|
||
* Version:
|
||
* This method is supported by all API versions.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t *keybox,
|
||
size_t keyBoxLength,
|
||
uint8_t *wrappedKeybox,
|
||
size_t *wrappedKeyBoxLength,
|
||
const uint8_t *transportKey,
|
||
size_t transportKeyLength);
|
||
|
||
|
||
/*
|
||
* OEMCrypto_InstallKeybox
|
||
*
|
||
* Description:
|
||
* Decrypts a wrapped keybox and installs it in the security processor. The
|
||
* keybox 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 keybox installed. It looks for a wrapped keybox in the file
|
||
* /factory/wv.keys and if it is present, will read the file and call
|
||
* OEMCrypto_InstallKeybox() with the contents of the file.
|
||
*
|
||
* Parameters:
|
||
* keybox (in) - pointer to encrypted Keybox data as input
|
||
* keyboxLength (in) - length of the keybox data in bytes
|
||
*
|
||
* Threading:
|
||
* This function is not called simultaneously with any other functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_BAD_MAGIC
|
||
* OEMCrypto_ERROR_BAD_CRC
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_WRITE_KEYBOX failed to handle and store Keybox
|
||
*
|
||
* Version:
|
||
* This method is supported in all API versions.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t *keybox,
|
||
size_t keyBoxLength);
|
||
|
||
/*
|
||
* OEMCrypto_IsKeyboxValid
|
||
*
|
||
* Description:
|
||
* Validate the Widevine Keybox stored on the device.
|
||
*
|
||
* The API performs two verification steps on the Keybox. It first verifies
|
||
* the MAGIC field contains a valid signature (must be 'kbox'). The API then
|
||
* computes the CRC using CRC-32 (Posix 1003.2 standard) and compares the
|
||
* checksum to the CRC stored in the Keybox. The CRC is computed over the
|
||
* entire Keybox excluding the 4 CRC bytes (i.e. Keybox[0..123]).
|
||
*
|
||
* Parameters:
|
||
* none
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with any session functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS
|
||
* OEMCrypto_ERROR_BAD_MAGIC
|
||
* OEMCrypto_ERROR_BAD_CRC
|
||
*
|
||
* Version:
|
||
* This method is supported by all API versions.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_IsKeyboxValid(void);
|
||
|
||
/*
|
||
* OEMCrypto_GetDeviceID
|
||
*
|
||
* Description:
|
||
* Retrieve the device's unique identifier from the Keybox.
|
||
*
|
||
* Parameters:
|
||
* deviceId (out) - pointer to the buffer that receives the Device ID
|
||
* idLength (in/out) - on input, size of the caller's device ID buffer.
|
||
* On output, the number of bytes written into the buffer.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with any session functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_SHORT_BUFFER buffer is too small to return the device ID
|
||
* OEMCrypto_ERROR_NO_DEVICEID failed to return Device Id
|
||
*
|
||
* Version:
|
||
* This method is supported by all API versions.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
|
||
size_t *idLength);
|
||
|
||
/*
|
||
* OEMCrypto_GetKeyData
|
||
*
|
||
* Description:
|
||
* Returns the Key Data field from the Keybox. The Key Data field does not
|
||
* need to be encrypted by an OEM root key, but may be if desired.
|
||
*
|
||
* If the Key Data field was encrypted with an OEM root key when the Keybox
|
||
* was stored on the device, then this function should decrypt it and return
|
||
* the clear Key Data. If the Key Data was not encrypted, then this function
|
||
* should just access and return the clear Key data.
|
||
*
|
||
* Parameters:
|
||
* keyData (out) - pointer to a caller-managed buffer to hold the Key Data
|
||
* field from the Keybox
|
||
* dataLength (in/out) - on input, the allocated buffer size. On output,
|
||
* the number of bytes in KeyData.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with any session functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_SHORT_BUFFER the buffer is too small to return the KeyData
|
||
* OEMCrypto_ERROR_NO_KEYDATA failed to return KeyData
|
||
*
|
||
* Version:
|
||
* This method is supported by all API versions.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
|
||
size_t *keyDataLength);
|
||
|
||
/*
|
||
* OEMCrypto_GetRandom
|
||
*
|
||
* Description:
|
||
* Return a buffer filled with hardware-generated random bytes. If the
|
||
* hardware feature does not exist, return OEMCrypto_ERROR_RNG_NOT_SUPPORTED.
|
||
*
|
||
* Parameters:
|
||
* randomData (out) - Pointer to caller-manager buffer that will receive the
|
||
* random data.
|
||
* dataLength (in) - Length of the random data buffer in bytes.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with any session functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_RNG_FAILED failed to generate random number
|
||
* OEMCrypto_ERROR_RNG_NOT_SUPPORTED function not supported
|
||
*
|
||
* Version:
|
||
* This method is supported by all API versions.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
|
||
size_t dataLength);
|
||
|
||
/*
|
||
* OEMCrypto_RewrapDeviceRSAKey
|
||
*
|
||
* Description:
|
||
* Verifies an RSA provisioning response is valid and corresponds to the previous
|
||
* provisioning request by checking the nonce. The RSA private key is decrypted
|
||
* and stored in secure memory. The RSA key is then re-encrypted and signed for
|
||
* storage on the filesystem. We recommend that the OEM use an encryption key
|
||
* and signing key generated using an algorithm at least as strong as that in
|
||
* GenerateDerivedKeys.
|
||
*
|
||
* After decrypting enc_rsa_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_rsa_key are not the string “SIGN”,
|
||
* then the default value of allowed_schemes = 1 will be used.
|
||
*
|
||
* Verification:
|
||
* 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_rsa_key_length is large enough to hold the rewrapped
|
||
* key, returning OEMCRYPTO_ERROR_BUFFER_TOO_SMALL otherwise.
|
||
* 3. Verify that the nonce matches one generated by a previous call to
|
||
* OEMCrypto_GenerateNonce(). The matching nonce shall be removed from the nonce
|
||
* table. If there is no matching nonce, return OEMCRYPTO_ERROR_INVALID_NONCE.
|
||
* 4. Verify the message signature, using the derived signing key
|
||
* (mac_key[server]).
|
||
* 5. Decrypt enc_rsa_key using the derived encryption key (enc_key), and
|
||
* enc_rsa_key_iv.
|
||
* 6. Validate the decrypted RSA device key by verifying that it can be loaded by
|
||
* the RSA implementation.
|
||
* 7. Generate a random initialization vector and store it in
|
||
* wrapped_rsa_key_iv.
|
||
* 8. Re-encrypt the device RSA key with an internal key (such as the OEM key or
|
||
* Widevine Keybox key) and the generated IV using AES-128-CBC with PKCS#5
|
||
* padding.
|
||
* 9. Copy the rewrapped key to the buffer specified by wrapped_rsa_key and the
|
||
* size of the wrapped key to wrapped_rsa_key_length.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* message (in) - pointer to memory containing message to be
|
||
* - verified.
|
||
* message_length (in) - length of the message, in bytes.
|
||
* signature (in) - pointer to memory containing the HMAC-SHA256
|
||
* - signature for message, received from the
|
||
* - provisioning server.
|
||
* signature_length (in) - length of the signature, in bytes.
|
||
* nonce (in) - The nonce provided in the provisioning response.
|
||
* enc_rsa_key (in) - Encrypted device private RSA key received from
|
||
* - the provisioning server. Format is PKCS#8
|
||
* - binary DER encoded, encrypted with the derived
|
||
* - encryption key, using AES-128-CBC with PKCS#5
|
||
* - padding.
|
||
* enc_rsa_key_length (in) - length of the encrypted RSA key, in bytes.
|
||
* enc_rsa_key_iv (in) - IV for decrypting RSA key. Size is 128 bits.
|
||
* wrapped_rsa_key (out) - pointer to buffer in which encrypted RSA key
|
||
* - should be stored. May be null on the first call
|
||
* - in order to find required buffer size.
|
||
* wrapped_rsa_key_length (in/out) - length of the encrypted RSA key, in bytes.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INVALID_RSA_KEY
|
||
* OEMCrypto_ERROR_SIGNATURE_FAILURE
|
||
* OEMCrypto_ERROR_INVALID_NONCE
|
||
* OEMCrypto_ERROR_SHORT_BUFFER
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
|
||
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 *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_LoadDeviceRSAKey
|
||
*
|
||
* Description:
|
||
* Loads a wrapped RSA private key to secure memory for use by this session in
|
||
* future calls to OEMCrypto_GenerateRSASignature. The wrapped RSA key will be
|
||
* the one verified and wrapped by OEMCrypto_RewrapDeviceRSAKey. The RSA 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. If there was not bit field
|
||
* wrapped with the RSA key, the key will use a default value of 1 = RSASSA-PSS
|
||
* with SHA1.
|
||
*
|
||
* 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 RewrapDeviceRSAKey.
|
||
* 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.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* wrapped_rsa_key (in) - wrapped device RSA key stored on the device.
|
||
* - Format is PKCS#8, binary DER encoded, and
|
||
* - encrypted with a key internal to the OEMCrypto
|
||
* - instance, using AES-128-CBC with PKCS#5
|
||
* - padding. This is the wrapped key generated
|
||
* - by OEMCrypto_RewrapDeviceRSAKey.
|
||
* wrapped_rsa_key_length (in) - length of the wrapped key buffer, in bytes.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INVALID_RSA_KEY
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
|
||
const uint8_t* wrapped_rsa_key,
|
||
size_t wrapped_rsa_key_length);
|
||
|
||
/*
|
||
* OEMCrypto_GenerateRSASignature
|
||
*
|
||
* Description:
|
||
* The OEMCrypto_GenerateRSASignature method is used to sign messages using the
|
||
* device private RSA key, specifically, it is used to sign the initial license
|
||
* request. Refer to the License Request Signed by RSA Certificate section above
|
||
* for more details.
|
||
*
|
||
* For devices that wish to be CAST receivers, there is a new RSA padding scheme.
|
||
* The padding_scheme parameter indicates which hashing and padding is to be
|
||
* applied to the message so as to generate the encoded message (the
|
||
* modulus-sized block to which the integer conversion and RSA decryption is
|
||
* applied). The following values are defined:
|
||
* 0x1 - RSASSA-PSS with SHA1.
|
||
* 0x2 - PKCS1 with block type 1 padding (only).
|
||
*
|
||
* In the first case, a hash algorithm (SHA1) is first applied to the message,
|
||
* whose length is not otherwise restricted. In the 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 the second scheme and can return
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
|
||
*
|
||
* Verification:
|
||
* The bitwise AND of the parameter padding_scheme and the RSA key’s
|
||
* allowed_schemes is computed. If this value is 0, then the signature is not
|
||
* computed and the error OEMCrypto_ERROR_INVALID_RSA_KEY is returned.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* message (in) - pointer to memory containing message to be
|
||
* - signed.
|
||
* message_length (in) - length of the message, in bytes.
|
||
* signature (out) - buffer to hold the message signature. On
|
||
* - return, it will contain the message signature
|
||
* - generated with the device private RSA key using
|
||
* - RSASSA-PSS.
|
||
* signature_length (in/out) - (in) length of the signature buffer, in bytes.
|
||
* - (out) actual length of the signature
|
||
* padding_scheme (in) - specify which scheme to use for the signature.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_SHORT_BUFFER if the signature buffer is too small.
|
||
* OEMCrypto_ERROR_INVALID_RSA_KEY
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED - if algorithm > 0, and the device does not
|
||
* support that algorithm.
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
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_DeriveKeysFromSessionKey
|
||
*
|
||
* Description:
|
||
* Generates three secondary keys -- mac_key_server, mac_key_client, and
|
||
* encrypt_key -- for handling signing and content key decryption under the
|
||
* license server protocol for AES CTR mode.
|
||
*
|
||
* This function is similar to OEMCrypto_GenerateDerivedKeys, except that it
|
||
* uses a session key to generate the secondary keys instead of the Widevine
|
||
* Keybox device key. These two keys will be stored in secure memory until
|
||
* the next call to LoadKeys. The session key is passed in encrypted by the
|
||
* device RSA public key, and must be decrypted with the RSA private key
|
||
* before use. Once the enc_key and mac_keys have been generated, all calls
|
||
* to LoadKeys and RefreshKeys proceed in the same manner for license
|
||
* requests using RSA or using a Widevine keybox token.
|
||
*
|
||
* Verification:
|
||
* If the RSA key’s allowed_schemes is not kSign_RSASSA_PSS, then no keys are
|
||
* derived and the error OEMCrypto_ERROR_INVALID_RSA_KEY is returned. An RSA key
|
||
* cannot be used for both deriving session keys and also for PKCS1 signatures.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* enc_session_key (in) - session key, encrypted with the device RSA key
|
||
* - (from the device certifcate) using RSA-OAEP.
|
||
* enc_session_key_length (in) - length of session_key, in bytes.
|
||
* mac_key_context (in) - pointer to memory containing context data for
|
||
* - computing the HMAC generation key.
|
||
* mac_key_context_length (in) - length of the HMAC key context data, in bytes.
|
||
* enc_key_context (in) - pointer to memory containing context data for
|
||
* - computing the encryption key.
|
||
* enc_key_context_length (in) - length of the encryption key context data, in
|
||
* - bytes.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(OEMCrypto_SESSION session,
|
||
const uint8_t* enc_session_key,
|
||
size_t enc_session_key_length,
|
||
const uint8_t *mac_key_context,
|
||
size_t mac_key_context_length,
|
||
const uint8_t *enc_key_context,
|
||
size_t enc_key_context_length);
|
||
|
||
|
||
/*
|
||
* OEMCrypto_APIVersion()
|
||
*
|
||
* Description:
|
||
* This function returns the current API version number. Because this
|
||
* API is part of a shared library, the version number allows the calling
|
||
* application to avoid version mis-match errors.
|
||
*
|
||
* 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 9. Any OEM that returns this
|
||
* version number guarantees it passes all unit tests associated this version.
|
||
*
|
||
* Parameters:
|
||
* none
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with any other functions.
|
||
*
|
||
* Returns:
|
||
* The supported API, as specified in the header file OEMCryptoCENC.h.
|
||
*
|
||
* Version:
|
||
* This method should change in all API versions.
|
||
*/
|
||
uint32_t OEMCrypto_APIVersion();
|
||
|
||
/*
|
||
* OEMCrypto_SecurityLevel()
|
||
*
|
||
* Description:
|
||
* This function returns the security level of the OEMCrypto library.
|
||
*
|
||
* Since this function is spoofable, it is not relied on for security
|
||
* purposes. It is for information only.
|
||
*
|
||
* Returns:
|
||
* A null terminated string. Useful values are "L1", "L2" or "L3".
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with any other functions.
|
||
*
|
||
* Version:
|
||
* This method changed in API version 6.
|
||
*/
|
||
const char* OEMCrypto_SecurityLevel();
|
||
|
||
/*
|
||
* OEMCrypto_GetHDCPCapability()
|
||
*
|
||
* Description:
|
||
* 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:
|
||
* 0x0 - No HDCP supported, no secure data path.
|
||
* 0x1 - HDCP version 1.0
|
||
* 0x2 - HDCP version 2.0
|
||
* 0x3 - HDCP version 2.1
|
||
* 0x4 - HDCP version 2.2
|
||
* 0xFF - No HDCP device attached/using local display with secure path.
|
||
*
|
||
* Parameters:
|
||
* current (out) - this is the current HDCP version, based on the device itself,
|
||
* and the display to which it is connected.
|
||
* maximum (out) - this is the maximum supported HDCP version for the device,
|
||
* ignoring any attached device.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with any other functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
typedef uint8_t OEMCrypto_HDCP_Capability;
|
||
OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability *current,
|
||
OEMCrypto_HDCP_Capability *maximum);
|
||
|
||
/*
|
||
* OEMCrypto_SupportsUsageTable()
|
||
*
|
||
* Description:
|
||
* 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.
|
||
*
|
||
* Parameters:
|
||
* none
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with any other functions.
|
||
*
|
||
* Returns:
|
||
* Returns true if the device can maintain a usage table. Returns false otherwise.
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
bool OEMCrypto_SupportsUsageTable();
|
||
|
||
/*
|
||
* OEMCryptoResult OEMCrypto_Generic_Encrypt
|
||
*
|
||
* Description:
|
||
* This function encrypts a generic buffer of data using the current key.
|
||
*
|
||
* If the session has an entry in the Usage Table, then OEMCrypto will update the
|
||
* time_of_last_decrypt. If the status of the entry is “unused”, then change the
|
||
* status to “active” and set the time_of_first_decrypt.
|
||
*
|
||
* 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 current key shall have the Allow_Encrypt set. If
|
||
* not, return OEMCrypto_ERROR_UNKNOWN_FAILURE.
|
||
* 2. If the current key’s control block has a nonzero Duration field, then the
|
||
* API shall verify that the duration is greater than the session’s elapsed time
|
||
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED.
|
||
* 3. If the current session has an entry in the Usage Table, and the status of
|
||
* that entry is “inactive”, then return OEMCrypto_ERROR_INVALID_SESSION.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* in_buffer (in) - pointer to memory containing data to be encrypted.
|
||
* buffer_length (in) - length of the buffer, in bytes.
|
||
* iv (in) - IV for encrypting data. Size is specified by the algorithm.
|
||
* algorithm (in) - Specifies which encryption algorithm to use. See
|
||
* OEMCrypto_Algorithm for valid values.
|
||
* out_buffer (out) - pointer to buffer in which encrypted data should be stored.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_KEY_EXPIRED
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session,
|
||
const uint8_t* in_buffer,
|
||
size_t buffer_length,
|
||
const uint8_t* iv,
|
||
OEMCrypto_Algorithm algorithm,
|
||
uint8_t* out_buffer);
|
||
|
||
/*
|
||
* OEMCrypto_Generic_Decrypt
|
||
*
|
||
* Description:
|
||
* This function decrypts a generic buffer of data using the current key.
|
||
*
|
||
* If the session has an entry in the Usage Table, then OEMCrypto will update the
|
||
* time_of_last_decrypt. If the status of the entry is “unused”, then change the
|
||
* status to “active” and set the time_of_first_decrypt.
|
||
*
|
||
* 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 current key shall have the Allow_Decrypt set. If
|
||
* not, return OEMCrypto_ERROR_DECRYPT_FAILED.
|
||
* 2. If the current key’s control block has the Data_Path_Type bit set, then
|
||
* return OEMCrypto_ERROR_DECRYPT_FAILED.
|
||
* 3. If the current key’s control block has a nonzero Duration field, then the
|
||
* API shall verify that the duration is greater than the session’s elapsed time
|
||
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED.
|
||
* 4. If the current session has an entry in the Usage Table, and the status of
|
||
* that entry is “inactive”, then return OEMCrypto_ERROR_INVALID_SESSION.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* in_buffer (in) - pointer to memory containing data to be encrypted.
|
||
* buffer_length (in) - length of the buffer, in bytes. The algorithm may
|
||
* restrict buffer_length to be a multiple of block size.
|
||
* iv (in) - IV for encrypting data. Size is 128 bits.
|
||
* algorithm (in) - Specifies which encryption algorithm to use.
|
||
* out_buffer (out) - pointer to buffer in which decrypted data should be stored.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_KEY_EXPIRED
|
||
* OEMCrypto_ERROR_DECRYPT_FAILED
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session,
|
||
const uint8_t* in_buffer,
|
||
size_t buffer_length,
|
||
const uint8_t* iv,
|
||
OEMCrypto_Algorithm algorithm,
|
||
uint8_t* out_buffer);
|
||
|
||
/*
|
||
* OEMCrypto_Generic_Sign
|
||
*
|
||
* Description:
|
||
* This function signs a generic buffer of data using the current key.
|
||
*
|
||
* If the session has an entry in the Usage Table, then OEMCrypto will update the
|
||
* time_of_last_decrypt. If the status of the entry is “unused”, then change the
|
||
* status to “active” and set the time_of_first_decrypt.
|
||
*
|
||
* 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 current key shall have the Allow_Sign set.
|
||
* 2. If the current key’s control block has a nonzero Duration field, then the
|
||
* API shall verify that the duration is greater than the session’s elapsed time
|
||
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED.
|
||
* 3. If the current session has an entry in the Usage Table, and the status of
|
||
* that entry is “inactive”, then return OEMCrypto_ERROR_INVALID_SESSION.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* in_buffer (in) - pointer to memory containing data to be encrypted.
|
||
* buffer_length (in) - length of the buffer, in bytes.
|
||
* algorithm (in) - Specifies which algorithm to use.
|
||
* signature (out) - pointer to buffer in which signature should be stored. May
|
||
* be null on the first call in order to find required buffer size.
|
||
* signature_length (in/out) - (in) length of the signature buffer, in bytes.
|
||
* (out) actual length of the signature
|
||
*
|
||
*
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_KEY_EXPIRED
|
||
* OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough to hold
|
||
* the output signature.
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session,
|
||
const uint8_t* in_buffer,
|
||
size_t buffer_length,
|
||
OEMCrypto_Algorithm algorithm,
|
||
uint8_t* signature,
|
||
size_t* signature_length);
|
||
|
||
/*
|
||
* OEMCrypto_Generic_Verify
|
||
*
|
||
* Description:
|
||
* This function verifies the signature of a generic buffer of data using the
|
||
* current key.
|
||
*
|
||
* If the session has an entry in the Usage Table, then OEMCrypto will update the
|
||
* time_of_last_decrypt. If the status of the entry is “unused”, then change the
|
||
* status to “active” and set the time_of_first_decrypt.
|
||
*
|
||
* Verification:
|
||
* The following checks should be performed. If any check fails, an error is
|
||
* returned.
|
||
* 1. The control bit for the current 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 current key’s control block has a nonzero Duration field, then the
|
||
* API shall verify that the duration is greater than the session’s elapsed time
|
||
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED.
|
||
* 5. If the current session has an entry in the Usage Table, and the status of
|
||
* that entry is “inactive”, then return OEMCrypto_ERROR_INVALID_SESSION.
|
||
*
|
||
* Parameters:
|
||
* session (in) - crypto session identifier.
|
||
* in_buffer (in) - pointer to memory containing data to be encrypted.
|
||
* buffer_length (in) - length of the buffer, in bytes.
|
||
* algorithm (in) - Specifies which algorithm to use.
|
||
* signature (in) - pointer to buffer in which signature resides.
|
||
* signature_length (in) - length of the signature buffer, in bytes.
|
||
*
|
||
* Threading:
|
||
* This function may be called simultaneously with functions on other sessions,
|
||
* but not with other functions on this session.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_KEY_EXPIRED
|
||
* OEMCrypto_ERROR_SIGNATURE_FAILURE
|
||
* OEMCrypto_ERROR_NO_DEVICE_KEY
|
||
* OEMCrypto_ERROR_INVALID_SESSION
|
||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session,
|
||
const uint8_t* in_buffer,
|
||
size_t buffer_length,
|
||
OEMCrypto_Algorithm algorithm,
|
||
const uint8_t* signature,
|
||
size_t signature_length);
|
||
|
||
|
||
/*
|
||
* OEMCrypto_UpdateUsageTable
|
||
*
|
||
* Description:
|
||
* OEMCrypto should propagate values from all open sessions to the Session Usage
|
||
* Table. If any values have changed, increment the generation number, sign, and
|
||
* save the table. During playback, this function will be called approximately
|
||
* once per minute.
|
||
*
|
||
* Devices that do not implement a Session Usage Table may return
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
|
||
*
|
||
* Parameters:
|
||
* none
|
||
*
|
||
* Threading:
|
||
* This function will not be called simultaneously with any session functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_UpdateUsageTable();
|
||
|
||
/*
|
||
* OEMCrypto_DeactivateUsageEntry
|
||
*
|
||
* Description:
|
||
* Find the entry in the Usage Table with a matching PST. Mark the status of
|
||
* that entry as “inactive”. If it corresponds to an open session, the status of
|
||
* that session will also be marked as “inactive”. Then OEMCrypto will increment
|
||
* Usage Table’s generation number, sign, encrypt, and save the Usage Table.
|
||
*
|
||
* If no entry in the Usage Table has a matching PST, return the error
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT.
|
||
*
|
||
* Devices that do not implement a Session Usage Table may return
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
|
||
*
|
||
* Parameters:
|
||
* pst (in) - pointer to memory containing Provider Session Token.
|
||
* pst_length (in) - length of the pst, in bytes.
|
||
*
|
||
* Threading:
|
||
* This function will not be called simultaneously with any session functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT - no entry has matching PST.
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst,
|
||
size_t pst_length);
|
||
|
||
/*
|
||
* OEMCrypto_ReportUsage
|
||
*
|
||
* Description:
|
||
* If the buffer_length is not sufficient to hold a report structure, set
|
||
* buffer_length and return OEMCrypto_ERROR_SHORT_BUFFER.
|
||
*
|
||
* If no entry in the Usage Table has a matching PST, return the error
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT.
|
||
*
|
||
* OEMCrypto will increment Usage Table’s generation number, sign, encrypt, and
|
||
* save the Usage Table. This is done, even though the table has not changed, so
|
||
* that a single rollback cannot undo a call to DeactivateUsageEntry and still
|
||
* report that license as inactive.
|
||
*
|
||
* The pst_report is filled out by subtracting the times un the Usage Table from
|
||
* the current time on the secure clock. This is done in case the secure clock
|
||
* is not using UTC time, but is instead using something like seconds since clock
|
||
* installed.
|
||
*
|
||
* 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 -- the keys have been marked inactive.
|
||
*
|
||
* The clock_security_level is reported as follows:
|
||
* 0 = Insecure Clock - clock just uses system time.
|
||
* 1 = Secure Timer - clock uses secure timer, which cannot be modified by user
|
||
* software, when OEMCrypto is active and the system time when OEMCrypto is
|
||
* inactive.
|
||
* 2 = Software Secure Clock - clock cannot be modified by user software when
|
||
* OEMCrypto is active or inactive.
|
||
* 3 = Hardware Secure Clock - clock 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.
|
||
*
|
||
* 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 client_mac_key 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.
|
||
*
|
||
* This function also copies the client_mac_key and server_mac_key from the Usage
|
||
* Table entry to the session. They will be used to verify a signature in
|
||
* OEMCrypto_DeleteUsageEntry below. This session will be associated with the
|
||
* entry in the Usage Table.
|
||
*
|
||
* Devices that do not implement a Session Usage Table may return
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
|
||
*
|
||
* Parameters:
|
||
* session (in) - handle for the session to be used.
|
||
* pst (in) - pointer to memory containing Provider Session Token.
|
||
* pst_length (in) - length of the pst, in bytes.
|
||
* buffer (out) - pointer to buffer in which usage report should be stored. May
|
||
* be null on the first call in order to find required buffer size.
|
||
* buffer_length (in/out) - (in) length of the report buffer, in bytes.
|
||
* (out) actual length of the report
|
||
*
|
||
* Threading:
|
||
* This function will not be called simultaneously with any session functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_SHORT_BUFFER if report buffer is not large enough to hold the
|
||
* output signature.
|
||
* OEMCrypto_ERROR_INVALID_SESSION no open session with that id.
|
||
* OEMCrypto_ERROR_INVALID_CONTEXT - no entry has matching PST.
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
|
||
const uint8_t *pst,
|
||
size_t pst_length,
|
||
OEMCrypto_PST_Report *buffer,
|
||
size_t *buffer_length);
|
||
|
||
/*
|
||
* OEMCrypto_DeleteUsageEntry
|
||
*
|
||
* Description:
|
||
* This function verifies the signature of the given message using the sessions
|
||
* mac_key[server] and the algorithm HMAC-SHA256, and then deletes an entry from
|
||
* the session table. The session should already be associated with the given
|
||
* entry, from a previous call to OEMCrypto_ReportUsage.
|
||
*
|
||
* After performing all verification listed below, and deleting the entry from
|
||
* the Usage Table, OEMCrypto will increment Usage Table’s generation number, and
|
||
* then sign, encrypt, and save the Usage Table.
|
||
*
|
||
* The signature verification shall use a constant-time algorithm (a signature
|
||
* mismatch will always take the same time as a successful comparison).
|
||
*
|
||
* Devices that do not implement a Session Usage Table may return
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
|
||
*
|
||
* Verification:
|
||
* The following checks should be performed. If any check fails, an error is
|
||
* returned.
|
||
* 1. The pointer pst is not null, and points inside the message. If not, return
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE.
|
||
* 2. The signature of the message shall be computed, and the API shall verify
|
||
* the computed signature matches the signature passed in. The signature will be
|
||
* computed using HMAC-SHA256 and the mac_key_server. If they do not match,
|
||
* return OEMCrypto_ERROR_SIGNATURE_FAILURE.
|
||
* 3. If the session is not associated with an entry in the Usage Table, return
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE.
|
||
* 4. If the pst passed in as a parameter does not match that in the Usage Table,
|
||
* return OEMCrypto_ERROR_UNKNOWN_FAILURE.
|
||
*
|
||
* Parameters:
|
||
* session (in) - handle for the session to be used.
|
||
* pst (in) - pointer to memory containing Provider Session Token.
|
||
* pst_length (in) - length of the pst, in bytes.
|
||
* message (in) - pointer to memory containing message to be verified.
|
||
* message_length (in) - length of the message, in bytes.
|
||
* signature (in) - pointer to memory containing the signature.
|
||
* signature_length (in) - length of the signature, in bytes.
|
||
*
|
||
* Threading:
|
||
* This function will not be called simultaneously with any session functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_INVALID_SESSION no open session with that id.
|
||
* OEMCrypto_ERROR_SIGNATURE_FAILURE
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
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_DeleteUsageTable
|
||
*
|
||
* Description:
|
||
* This is called when the CDM system believes there are major problems or
|
||
* resource issues. The entire table should be cleaned and a new table should be
|
||
* created.
|
||
*
|
||
* Parameters:
|
||
* none
|
||
*
|
||
* Threading:
|
||
* This function will not be called simultaneously with any session functions.
|
||
*
|
||
* Returns:
|
||
* OEMCrypto_SUCCESS success
|
||
* OEMCrypto_ERROR_NOT_IMPLEMENTED
|
||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||
*
|
||
* Version:
|
||
* This method changed in API version 9.
|
||
*/
|
||
OEMCryptoResult OEMCrypto_DeleteUsageTable();
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif // OEMCRYPTO_CENC_H_
|