// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine Master // License Agreement. /********************************************************************* * OEMCryptoCENC.h * * Reference APIs needed to support Widevine's crypto algorithms. * * See the document "WV Modular DRM Security Integration Guide for Common * Encryption (CENC) -- version 15" for a description of this API. You * can find this document in the widevine repository as * docs/WidevineModularDRMSecurityIntegrationGuideforCENC_v15.pdf * Changes between different versions of this API are documented in the files * docs/Widevine_Modular_DRM_Version_*_Delta.pdf * *********************************************************************/ #ifndef OEMCRYPTO_CENC_H_ #define OEMCRYPTO_CENC_H_ #include #include #include #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, // deprecated OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED = 6, // deprecated OEMCrypto_ERROR_SHORT_BUFFER = 7, OEMCrypto_ERROR_NO_DEVICE_KEY = 8, // no keybox device key. 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, OEMCrypto_ERROR_BUFFER_TOO_LARGE = 39, OEMCrypto_WARNING_GENERATION_SKEW = 40, // Warning, not an error. OEMCrypto_ERROR_GENERATION_SKEW = 41, OEMCrypto_LOCAL_DISPLAY_ONLY = 42, // Info, not an error. OEMCrypto_ERROR_ANALOG_OUTPUT = 43, OEMCrypto_ERROR_WRONG_PST = 44, OEMCrypto_ERROR_WRONG_KEYS = 45, OEMCrypto_ERROR_MISSING_MASTER = 46, OEMCrypto_ERROR_LICENSE_INACTIVE = 47, OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE = 48, OEMCrypto_ERROR_ENTRY_IN_USE = 49, OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE = 50, // Reserved. Do not use. OEMCrypto_KEY_NOT_LOADED = 51, // obsolete. use error 26. OEMCrypto_KEY_NOT_ENTITLED = 52, OEMCrypto_ERROR_BAD_HASH = 53, OEMCrypto_ERROR_OUTPUT_TOO_LARGE = 54, OEMCrypto_ERROR_SESSION_LOST_STATE = 55, OEMCrypto_ERROR_SYSTEM_INVALIDATED = 56, } OEMCryptoResult; /* * The memory referenced by 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 SharedMemory; /* * 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. 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. * * 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) * handle - handle to a platform-specific secure buffer. * max_length - Size of platform-specific secure buffer. * offset - offset from beginning of buffer to which OEMCrypto should write. * (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 SharedMemory* 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; /** OEMCryptoCipherMode is used in SelectKey to prepare a key for either CTR * decryption or CBC decryption. */ typedef enum OEMCryptoCipherMode { OEMCrypto_CipherMode_CTR, OEMCrypto_CipherMode_CBC, } OEMCryptoCipherMode; /** OEMCrypto_LicenseType is used in LoadKeys to indicate if the key objects * are for content keys, or for entitlement keys. */ typedef enum OEMCrypto_LicenseType { OEMCrypto_ContentLicense = 0, OEMCrypto_EntitlementLicense = 1 } OEMCrypto_LicenseType; /* * OEMCrypto_Substring * * Used to indicate a substring of a signed message in OEMCrypto_LoadKeys and * other functions which must verify that a parameter is contained within a * signed message. */ typedef struct { size_t offset; size_t length; } OEMCrypto_Substring; /* * 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. OEMCrypto may assume this is at * most 16. However, OEMCrypto shall correctly handle key id lengths * from 1 to 16 bytes. * 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 { OEMCrypto_Substring key_id; OEMCrypto_Substring key_data_iv; OEMCrypto_Substring key_data; OEMCrypto_Substring key_control_iv; OEMCrypto_Substring key_control; } OEMCrypto_KeyObject; /* * OEMCrypto_EntitledContentKeyObject * 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. * entitlement_key_id - entitlement key id to be matched to key table. * entitlement_key_id_length - length of entitlment_key_id in bytes (1 to 16). * content_key_id - content key id to be loaded into key table. * content_key_id_length - length of content key id in bytes (1 to 16). * key_data_iv - the IV for performing AES-256-CBC decryption of the key data. * key_data - encrypted content key data. * key_data_length - length of key_data - 16 or 32 depending on intended use. */ 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; /* * 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 { OEMCrypto_Substring key_id; OEMCrypto_Substring key_control_iv; OEMCrypto_Substring 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_DecryptCENC. */ #define OEMCrypto_FirstSubsample 1 #define OEMCrypto_LastSubsample 2 /* OEMCrypto_CENCEncryptPatternDesc * This is used in OEMCrypto_DecryptCENC to indicate the encrypt/skip pattern * used, as specified in the CENC standard. */ 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; /* * OEMCrypto_Usage_Entry_Status. * Valid values for status in the usage table. */ typedef enum OEMCrypto_Usage_Entry_Status { kUnused = 0, kActive = 1, kInactive = 2, // Deprecated. Used kInactiveUsed or kInactiveUnused. kInactiveUsed = 3, kInactiveUnused = 4, } OEMCrypto_Usage_Entry_Status; /* * 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. */ #if 0 // If your compiler supports __attribute__((packed)). 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 /* * 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 uint8_t RSA_Padding_Scheme; #ifndef NO_OEMCRYPTO_VARIABLE_DEFINITIONS // RSASSA-PSS with SHA1. const RSA_Padding_Scheme kSign_RSASSA_PSS = 0x1; // PKCS1 with block type 1 padding (only). const RSA_Padding_Scheme kSign_PKCS1_Block1 = 0x2; #else #define kSign_RSASSA_PSS 0x1 #define kSign_PKCS1_Block1 0x2 #endif /* * 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.0 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. HDCP_NO_DIGITAL_OUTPUT = 0xff // No digital output. } OEMCrypto_HDCP_Capability; /* Return value for OEMCrypto_GetProvisioningMethod(). */ typedef enum OEMCrypto_ProvisioningMethod { OEMCrypto_ProvisioningError = 0, // Device cannot be provisioned. OEMCrypto_DrmCertificate = 1, // Device has baked in DRM certificate // (level 3 only) OEMCrypto_Keybox = 2, // Device has factory installed unique keybox. OEMCrypto_OEMCertificate = 3 // Device has factory installed OEM certificate. } OEMCrypto_ProvisioningMethod; /* * Flags indicating RSA keys supported. */ #define OEMCrypto_Supports_RSA_2048bit 0x1 #define OEMCrypto_Supports_RSA_3072bit 0x2 #define OEMCrypto_Supports_RSA_CAST 0x10 /* * Flags indicating full decrypt path hash supported. */ #ifndef NO_OEMCRYPTO_VARIABLE_DEFINITIONS const uint32_t OEMCrypto_Hash_Not_Supported = 0; const uint32_t OEMCrypto_CRC_Clear_Buffer = 1; const uint32_t OEMCrypto_Partner_Defined_Hash = 2; #else #define OEMCrypto_Hash_Not_Supported 0 #define OEMCrypto_CRC_Clear_Buffer 1 #define OEMCrypto_Partner_Defined_Hash 2 #endif /* * 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. */ #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 _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 _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_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 _oecc48 #define OEMCrypto_GetProvisioningMethod _oecc49 #define OEMCrypto_GetOEMPublicCertificate _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 _oecc88 #define OEMCrypto_GetHashErrorCode _oecc89 #define OEMCrypto_BuildInformation _oecc90 #define OEMCrypto_RefreshKeys _oecc91 #define OEMCrypto_LoadEntitledContentKeys _oecc92 #define OEMCrypto_CopyBuffer _oecc93 /* * OEMCrypto_SetSandbox * * Description: * 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" above 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. * * Parameters: * [in] sandbox_id: a short string unique to the current sandbox. * [in] sandbox_id_length: length of sandbox_id. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INIT_FAILED failed to initialize crypto hardware * 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); /* * OEMCrypto_Initialize * * Description: * Initialize the crypto firmware/hardware. * * Parameters: * None * * Returns: * OEMCrypto_SUCCESS success * 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); /* * OEMCrypto_Terminate * * Description: * Closes the crypto operation and releases all related resources. * * Parameters: * None * * Returns: * OEMCrypto_SUCCESS success * 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); /* * 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: * [out] session: an opaque handle that the crypto firmware uses to identify * the session. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_TOO_MANY_SESSIONS failed because too many sessions are open * OEMCrypto_ERROR_OPEN_SESSION_FAILED there is a resource issue or the * security engine is not properly initialized. * 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 5. */ OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session); /* * OEMCrypto_CloseSession * * Description: * 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. * * Parameters: * [in] session: handle for the session to be closed. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INVALID_SESSION no open session with that id. * OEMCrypto_ERROR_CLOSE_SESSION_FAILED illegal/unrecognized handle or the * security engine is not properly initialized. * 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); /* * 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 CENC. * * Refer to the Key Derivation section above for more 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 * generate the mac_key[server] and the second two cycles generate the * mac_key[client]. These two keys will be stored until the next call to * OEMCrypto_LoadKeys(). The device key from the keybox is used as the key * for the AES-128-CMAC. * * Parameters: * [in] session: handle for the session to be used. * [in] mac_key_context: pointer to memory containing context data for * computing the HMAC generation key. * [in] mac_key_context_length: length of the HMAC key context data, in bytes. * [in] enc_key_context: pointer to memory containing context data for * computing the encryption key. * [in] enc_key_context_length: 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. * * 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 * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support mac_key_context and enc_key_context sizes of at * least 8 KiB. * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffers are * too large. * * 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_GenerateDerivedKeys(OEMCrypto_SESSION session, const SharedMemory* mac_key_context, uint32_t mac_key_context_length, const SharedMemory* enc_key_context, uint32_t enc_key_context_length); /* * 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 CENC. * * 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 three 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: * [in] session: handle for the session to be used. * [in] enc_session_key: session key, encrypted with the public RSA key (from * the DRM certifcate) using RSA-OAEP. * [in] enc_session_key_length: length of session_key, in bytes. * [in] mac_key_context: pointer to memory containing context data for * computing the HMAC generation key. * [in] mac_key_context_length: length of the HMAC key context data, in bytes. * [in] enc_key_context: pointer to memory containing context data for * computing the encryption key. * [in] enc_key_context_length: 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. * * 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 * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support mac_key_context and enc_key_context sizes of at * least 8 KiB. * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffers are * too large. * * 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_DeriveKeysFromSessionKey( OEMCrypto_SESSION session, const uint8_t* enc_session_key, size_t enc_session_key_length, const SharedMemory* mac_key_context, size_t mac_key_context_length, const SharedMemory* enc_key_context, size_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: * [in] session: handle for the session to be used. * [out] nonce: pointer to memory to receive the computed nonce. * * Results: * nonce: the nonce is also stored in secure memory. At least 4 nonces should * be stored for each session. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_SESSION_LOST_STATE * 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 5. */ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, uint32_t* nonce); /* * OEMCrypto_GenerateSignature * * Description: * 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 the most recent successful * call to any one of * * - OEMCrypto_GenerateDerivedKeys, * - OEMCrypto_DeriveKeysFromSessionKey, * - OEMCrypto_LoadKeys, 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_LoadKeys, 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 set to * zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output * signature_length to the size needed to receive the output signature. * * Parameters: * [in] session: crypto session identifier. * [in] message: pointer to memory containing message to be signed. * [in] message_length: length of the message, in bytes. * [out] signature: pointer to memory to received the computed signature. May * be null (see note above). * [in/out] signature_length: (in) length of the signature buffer, in bytes. * (out) actual length of the signature, in bytes. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_ERROR_SHORT_BUFFER if signature buffer is not large enough to * hold the signature. * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support message sizes of at least 8 KiB. * 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_GenerateSignature(OEMCrypto_SESSION session, const SharedMemory* message, size_t message_length, uint8_t* signature, size_t* signature_length); /* * OEMCrypto_LoadSRM * * Description: * Verify and install a new SRM file. The device shall install the new file * only if verification passes. If verification fails, the existing SRM will * be left in place. Verification is defined by DCP, and includes * verification of the SRM's signature and verification that the SRM version * number will not be decreased. See the section HDCP SRM Update above for * more details about the SRM. This function is for devices that support HDCP * v2.2 or higher and wish to receive 4k content. * * Parameters: * [in] bufer: buffer containing the SRM * [in] buffer_length: length of the SRM, in bytes. * * Returns: * OEMCrypto_SUCCESS - if the file was valid and was installed. * OEMCrypto_ERROR_INVALID_CONTEXT - if the SRM version is too low, or the * file is corrupted. * OEMCrypto_ERROR_SIGNATURE_FAILURE - If the signature is invalid. * OEMCrypto_ERROR_BUFFER_TOO_LARGE - if the buffer is too large for the * device. * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * The size of the buffer is determined by the HDCP specification. * * 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 changed in API version 13. */ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_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 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 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() or * OEMCrypto_DeriveKeysFromSessionKey(). 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_DecryptCENC(). * * NOTE: The calling software must have previously established the mac_keys * and encrypt_key with a call to OEMCrypto_GenerateDerivedKeys(), * OEMCrypto_DeriveKeysFromSessionKey(), or a previous call to * OEMCrypto_LoadKeys(). * * Refer to the Verification of Messages from a Server section above for more * details. * * If the parameter 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 parameter 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 at least 20 keys per session. This allows a single * license to contain separate keys for 3 key rotations (previous interval, * current interval, next interval) times 4 content keys (audio, SD, HD, UHD) * plus up to 8 keys for watermarks. * * 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 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. * 3. 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. * 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 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. * 6. 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. * 7. If the key control block has a nonzero Replay_Control, then the * verification described below is also performed. * 8. 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. * 9. If key_array_length == 0, then return OEMCrypto_ERROR_INVALID_CONTEXT. * 10. If any key control block has the Shared_License bit set, and this * call to LoadKeys is not replacing keys loaded from a previous call to * LoadKeys, then the keys are not loaded, and the error * OEMCrypto_ERROR_MISSING_MASTER is returned. This feature is obsolete, * and no longer used by production license servers. OEMCrypto unit * tests for this feature have been removed. * 11. 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. * 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 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. 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 LoadKeys 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 LoadKeys 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 * LoadKeys 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. * * 1. The substring srm_restriction_data must have nonzero length and must * satisfy the range check described above. If not, return * OEMCrypto_ERROR_INVALID_CONTEXT. * 2. The first 8 bytes of srm_restriction_data must match the string * "HDCPDATA". If not, return OEMCrypto_ERROR_INVALID_CONTEXT. * 3. 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, LoadKeys 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 SelectKey for these keys while * there is an external display will return OEMCrypto_ERROR_INSUFFICIENT_HDCP * at that time. * * Parameters: * [in] session: crypto session identifier. * [in] message: pointer to memory containing message to be verified. * [in] message_length: length of the message, in bytes. * [in] signature: pointer to memory containing the signature. * [in] signature_length: length of the signature, in bytes. * [in] enc_mac_keys_iv: IV for decrypting new mac_key. Size is 128 bits. * [in] enc_mac_keys: encrypted mac_keys for generating new mac_keys. Size is * 512 bits. * [in] key_array_length: number of keys present. * [in] key_array: set of keys to be installed. * [in] pst: the Provider Session Token. * [in] srm_restriction_data: optional data specifying the minimum SRM * version. * [in] license_type: specifies if the license contains content keys or * entitlement keys. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_INVALID_CONTEXT * OEMCrypto_ERROR_SIGNATURE_FAILURE * OEMCrypto_ERROR_INVALID_NONCE * OEMCrypto_ERROR_TOO_MANY_KEYS * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support message sizes of at least 8 KiB. * 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 14. */ OEMCryptoResult OEMCrypto_LoadKeys( OEMCrypto_SESSION session, const SharedMemory* message, size_t message_length, const SharedMemory* 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); /* * OEMCrypto_LoadEntitledContentKeys * * Description: * Load content keys into a session which already has entitlement keys * loaded. This function will only be called for a session after a call to * OEMCrypto_LoadKeys with the parameter type license_type equal to * OEMCrypto_EntitlementLicense. This function may be called multiple times * for the same session. * * If the session does not have license_type equal to * OEMCrypto_EntitlementLicense, 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 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. 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 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 SelectKey is called. * * Parameters: * [in] session: handle for the session to be used. * [in] message: pointer to memory containing message to be verified. * [in] message_length: length of the message, in bytes. * [in] key_array_length: number of keys present. * [in] key_array: set of key updates. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_ERROR_INVALID_CONTEXT * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_KEY_NOT_ENTITLED * OEMCrypto_ERROR_SESSION_LOST_STATE * 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 14. */ OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( OEMCrypto_SESSION session, const SharedMemory* message, size_t message_length, size_t key_array_length, const OEMCrypto_EntitledContentKeyObject* key_array); /* * 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_LoadKeys() must be called first to load the keys into the * session. * * This session's elapsed time clock is reset to 0 when this function is * called. The elapsed time clock is used in OEMCrypto_DecryptCENC() and the * other Decryption API functions to determine if the key has expired. * * This function does not add keys to the key table. It is only used to * update a key control block license duration. 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 has zero length, 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 has zero length, 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 have zero length and the control * block will not be encrypted. * * If the session's license_type is OEMCrypto_ContentLicense, and the * KeyRefreshObject's key_id is not null, then the entry in the keytable with * the matching content_key_id is updated. * * If the session's license_type is OEMCrypto_EntitlementLicense, and the * KeyRefreshObject's key_id is not null, then the entry in the keytable with * the matching entitlment_key_id is updated. * * If the key_id is not null, and no matching entry is found in the key * table, then return OEMCrypto_ERROR_NO_CONTENT_KEY. * * Aside from the key's duration, no other values in the key control block * should be updated by this function. * * 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 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). * 2. The API shall verify that each substring in each KeyObject has zero * length or satisfies the range check described in the discussion of * OEMCrypto_LoadKeys. 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. * 5. If a key ID is specified, and that key has not been loaded into this * session, return OEMCrypto_ERROR_NO_CONTENT_KEY. * * Parameters: * [in] session: handle for the session to be used. * [in] message: pointer to memory containing message to be verified. * [in] message_length: length of the message, in bytes. * [in] signature: pointer to memory containing the signature. * [in] signature_length: length of the signature, in bytes. * [in] key_array_length: number of keys present. * [in] key_array: set of key updates. * * 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_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_NO_CONTENT_KEY * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support message sizes of at least 8 KiB. * 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_RefreshKeys( OEMCrypto_SESSION session, const SharedMemory* message, size_t message_length, const SharedMemory* signature, size_t signature_length, size_t key_array_length, const OEMCrypto_KeyRefreshObject* key_array); /* * OEMCrypto_QueryKeyControl * * Description: * 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 LoadKeys 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. * * Parameters: * [in] session: handle for the session to be used. * [in] content_key_id: The unique id of the key of interest. * [in] content_key_id_length: The length of key_id, in bytes. From 1 to 16, * inclusive. * [out] key_control_block: A caller-owned buffer. * [in/out] key_control_block_length. The length of key_control_block buffer. * * Returns: * OEMCrypto_SUCCESS * OEMCrypto_ERROR_INVALID_CONTEXT * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_SESSION_LOST_STATE * 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 10. */ 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); /* * OEMCrypto_SelectKey * * Description: * Select a content key and install it in the hardware key ladder for * subsequent decryption operations (OEMCrypto_DecryptCENC()) 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 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_CBC. Continue to * use this key for this session until OEMCrypto_SelectKey() is called again, * or until OEMCrypto_CloseSession() is called. * * 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 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 before the key is used. OEMCrypto may return * OEMCrypto_ERROR_KEY_EXPIRED from OEMCrypto_SelectKey, or SelectKey * may return success from select key and the decrypt or generic crypto * call will return OEMCrypto_ERROR_KEY_EXPIRED. * 3. 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. * 4. 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. * 5. 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. * * Parameters: * [in] session: crypto session identifier. * [in] content_key_id: pointer to the content Key ID. * [in] content_key_id_length: length of the content Key ID, in bytes. From * 1 to 16, inclusive. * [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. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_KEY_EXPIRED - if the key's timer has expired * 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_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_KEY_EXPIRED * OEMCrypto_ERROR_ANALOG_OUTPUT * OEMCrypto_ERROR_INSUFFICIENT_HDCP * OEMCrypto_ERROR_NO_CONTENT_KEY * OEMCrypto_ERROR_SESSION_LOST_STATE * 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 14. */ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, const uint8_t* content_key_id, size_t content_key_id_length, OEMCryptoCipherMode cipher_mode); /* * OEMCrypto_DecryptCENC * * Description: * Decrypts 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. Decryption mode is * AES-128-CTR or AES-128-CBC depending on the value of cipher_mode passed in * to OEMCrypto_SelectKey. 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_addr_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 renderer. * NOTES: * * For CTR mode, 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. * * For CBC mode, IV points to the initial vector for cipher block chaining. * Within each subsample, OEMCrypto is responsible for updating the IV as * prescribed by CBC mode. The calling layer above is responsible for * updating the IV from one subsample to the next if needed. * * 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. * DecryptCENC 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. * * The decryption mode, either OEMCrypto_CipherMode_CTR or * OEMCrypto_CipherMode_CBC, was specified in the call to * OEMCrypto_SelectKey. The encryption pattern is specified by the fields in * the parameter pattern. A description of partial encryption patterns can be * found in the document Draft International Standard ISO/IEC DIS 23001-7. * Search for the codes "cenc", "cbc1", "cens" or "cbcs". * * The most common mode is "cenc", which is OEMCrypto_CipherMode_CTR without * a pattern. The entire subsample is either encrypted or clear, depending on * the flag is_encrypted. In the structure pattern, both encrypt and skip * will be 0. This is the only mode that allows for a nonzero block_offset. * * A less common mode is "cens", which is OEMCrypto_CipherMode_CTR with an * encryption pattern. For this mode, OEMCrypto may assume that an encrypted * subsample will have a length that is a multiple of 16, the AES block * length. * * The mode "cbc1" is OEMCrypto_CipherMode_CBC without a pattern. In the * structure pattern, both encrypt and skip will be 0. If an encrypted * subsample has a length that is not a multiple of 16, the final partial * block will be in the clear. * * The mode "cbcs" is OEMCrypto_CipherMode_CBC with an encryption pattern. * This mode allows devices to decrypt HLS content. If an encrypted subsample * has a length that is not a multiple of 16, the final partial block will be * in the clear. In practice, the most common pattern is (1, 9), or 1 * encrypted block followed by 9 clear blocks. The ISO-CENC spec implicitly * limits both the skip and encrypt values to be 4 bits, so a value of at * most 15. * * A sample may be broken up into a mix of clear and encrypted subsamples. In * order to support the VP9 standard, the breakup of a subsample into clear * and encrypted subsamples is not always in pairs. * * If OEMCrypto assembles all of the subsamples into a single buffer and then * decrypts, it can assume that the block offset is 0. * * 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. * 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 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. * 4. 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. * 5. 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. * 6. If the current session 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. * 7. If an 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. * 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: * [in] session: crypto session identifier. * [in] data_addr: An unaligned pointer to this segment of the stream. * [in] data_addr_length: The length of this segment of the stream, in bytes. * [in] is_encrypted: True if the buffer described by data_addr, * data_addr_length is encrypted. If is_encrypted is false, only the * data_addr and data_addr_length parameters are used. The iv and offset * arguments are ignored. * [in] iv: The initial value block to be used for content decryption. * This is discussed further below. * [in] block_offset: 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. * [in/out] out_buffer: A caller-owned descriptor that specifies the handling of * the decrypted byte stream. See OEMCrypto_DestbufferDesc for details. * [in] pattern: A caller-owned structure indicating the encrypt/skip pattern * as specified in the CENC standard. * [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. * * 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_ANALOG_OUTPUT * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_OUTPUT_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support subsample sizes (i.e. data_addr_length) of at least * 100 KiB. * 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 changed in API version 15. This method changed its name in API * version 11. */ OEMCryptoResult OEMCrypto_DecryptCENC( OEMCrypto_SESSION session, const SharedMemory* 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* pattern, uint8_t subsample_flags); /* * OEMCrypto_CopyBuffer * * Description: * Copies the payload in the buffer referenced by the *data_addr 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 * does not need an open session, and it may be called concurrently with * other functions on a multithreaded system. 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_addr or out_buffer is null, return * OEMCrypto_ERROR_INVALID_CONTEXT. * * Parameters: * [in] session: crypto session identifier. * [in] data_addr: An unaligned pointer to the buffer to be copied. * [in] data_addr_length: The length of the buffer, in bytes. * [in/out] out_buffer: A caller-owned descriptor that specifies the handling of * the byte stream. See OEMCrypto_DestbufferDesc for details. * [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. * * Returns: * OEMCrypto_SUCCESS * OEMCrypto_ERROR_INVALID_CONTEXT * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_OUTPUT_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support subsample sizes (i.e. data_addr_length) up to 100 * KiB. * 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 SharedMemory* data_addr, size_t data_addr_length, OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags); /* * 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. * * OEMCrypto should be able to handle buffers at least 100 KiB long. * * 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 either kInactiveUsed or kInactiveUnused, then * return the error OEMCrypto_ERROR_LICENSE_INACTIVE. * * Parameters: * [in] session: crypto session identifier. * [in] in_buffer: pointer to memory containing data to be encrypted. * [in] in_buffer_length: length of the buffer, in bytes. The algorithm may * restrict in_buffer_length to be a multiple of block size. * [in] iv: IV for encrypting data. Size is 128 bits. * [in] algorithm: Specifies which encryption algorithm to use. Currently, * only CBC 128 mode is allowed for encryption. * [out] out_buffer: 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 * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support buffers 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 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_Generic_Encrypt( OEMCrypto_SESSION session, const SharedMemory* in_buffer, size_t in_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. * * OEMCrypto should be able to handle buffers at least 100 KiB long. * * 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 either kInactiveUsed or kInactiveUnused, then * return the error OEMCrypto_ERROR_LICENSE_INACTIVE. * * Parameters: * [in] session: crypto session identifier. * [in] in_buffer: pointer to memory containing data to be encrypted. * [in] in_buffer_length: length of the buffer, in bytes. The algorithm may * restrict in_buffer_length to be a multiple of block size. * [in] iv: IV for encrypting data. Size is 128 bits. * [in] algorithm: Specifies which encryption algorithm to use. Currently, * only CBC 128 mode is allowed for decryption. * [out] out_buffer: pointer to buffer in which decrypted data should be * stored. * * 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 * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support buffers 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 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_Generic_Decrypt( OEMCrypto_SESSION session, const SharedMemory* in_buffer, size_t in_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 either kInactiveUsed or kInactiveUnused, then * return the error OEMCrypto_ERROR_LICENSE_INACTIVE. * * Parameters: * [in] session: crypto session identifier. * [in] buffer: pointer to memory containing data to be encrypted. * [in] buffer_length: length of the buffer, in bytes. * [in] algorithm: Specifies which algorithm to use. * [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. * [in/out] signature_length: (in) length of the signature buffer, in bytes. * (out) actual length of the signature * * 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 * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support buffers 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 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 14. */ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, const SharedMemory* 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 either kInactiveUsed or kInactiveUnused, then * return the error OEMCrypto_ERROR_LICENSE_INACTIVE. * * Parameters: * [in] session: crypto session identifier. * [in] buffer: pointer to memory containing data to be encrypted. * [in] buffer_length: length of the buffer, in bytes. * [in] algorithm: Specifies which algorithm to use. * [in] signature: pointer to buffer in which signature resides. * [in] signature_length: length of the signature buffer, in bytes. * * 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 * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support buffers 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 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 14. */ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session, const SharedMemory* buffer, size_t buffer_length, OEMCrypto_Algorithm algorithm, const SharedMemory* 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(void); /* * OEMCrypto_WrapKeyboxOrOEMCert * * Description: * 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(). * * Figure 10. OEMCrypto_WrapKeyboxOrOEMCert Operation * * 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. * * Parameters: * [in] rot - 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 size of wrapped keybox. The keybox may either be clear * or previously encrypted. * [in] rotLength - length the keybox data in bytes * [out] wrappedRot – Pointer to wrapped keybox * [out] wrappedRotLength – Pointer to the length of the wrapped rot in bytes * [in] transportKey – Optional. AES transport key. If provided, the rot * parameter was previously encrypted with this key. The keybox will be * decrypted with the transport key using AES-CBC and a null IV. * [in] transportKeyLength – Optional. Number of bytes in the transportKey, * if used. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_WRITE_KEYBOX failed to encrypt the 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 * 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* rot, size_t rotLength, uint8_t* wrappedRot, size_t* wrappedRotLength, const uint8_t* transportKey, size_t transportKeyLength); /* * OEMCrypto_InstallKeyboxOrOEMCert * * Description: * 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. * * Parameters: * [in] rot - pointer to encrypted data as input * [in] rotLength - length of the data in bytes * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_BAD_MAGIC * OEMCrypto_ERROR_BAD_CRC * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_NOT_IMPLEMENTED * 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* rot, size_t rotLength); /* * OEMCrypto_GetProvisioningMethod * * Description: * This function is for OEMCrypto to tell the layer above what provisioning * method it uses: keybox or OEM certificate. * * Parameters: * none * * Returns: * - 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. * - Keybox means the device has a unique keybox. For level 1 devices this * keybox must be securely installed by the device manufacturer. * - OEMCertificate means the device has a factory installed OEM * certificate. This is also called Provisioning 3.0. * - 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); /* * OEMCrypto_IsKeyboxOrOEMCertValid * * Description: * 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. * * If the device has an OEM Certificate, this validates the certificate * private key. * * Parameters: * none * * Returns: * OEMCrypto_SUCCESS * OEMCrypto_ERROR_BAD_MAGIC * OEMCrypto_ERROR_BAD_CRC * OEMCrypto_ERROR_KEYBOX_INVALID * OEMCrypto_ERROR_INVALID_RSA_KEY * 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_IsKeyboxOrOEMCertValid(void); /* * OEMCrypto_GetDeviceID * * Description: * Retrieve DeviceID from the Keybox. For devices that have an OEM * Certificate instead of a keybox, this function may return * OEMCrypto_ERROR_NOT_IMPLEMENTED. If the function is implemented on an OEM * Certificate device, it should set the device ID to a device-unique string, * such as the device serial number. 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 function is optional but recommended for Provisioning 3.0 in API v15. * It may be required for future version of this API. * * Parameters: * [out] device_id - pointer to the buffer that receives the Device ID * [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. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return device ID * OEMCrypto_ERROR_NO_DEVICEID failed to return Device Id * OEMCrypto_ERROR_NOT_IMPLEMENTED * 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); /* * OEMCrypto_GetKeyData * * Description: * Return the Key Data field from the Keybox. * * Parameters: * [out] keyData - pointer to the buffer to hold the Key Data field from the * Keybox * [in/out] keyDataLength – on input, the allocated buffer size. On output, * the number of bytes in Key Data * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return KeyData * OEMCrypto_ERROR_NO_KEYDATA * OEMCrypto_ERROR_NOT_IMPLEMENTED - this function is for Provisioning 2.0 * only. * 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* keyData, size_t* keyDataLength); /* * OEMCrypto_LoadTestKeybox * * Description: * 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. * * Parameters: * [in] buffer: pointer to memory containing test keybox, in binary form. * [in] buffer_length: length of the buffer, in bytes. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_NOT_IMPLEMENTED - this function is for Provisioning 2.0 * only. * 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); /* * OEMCrypto_GetOEMPublicCertificate * * Description: * This function should place the OEM public certificate in the buffer * public_cert. After a call to this function, all methods using an RSA key * should use the OEM certificate's private RSA key. See the section above * discussing Provisioning 3.0. * * If the buffer is not large enough, OEMCrypto should update * public_cert_length and return OEMCrypto_ERROR_SHORT_BUFFER. * * Parameters: * - [in] session: this function affects the specified session only. * - [out] public_cert: the buffer where the public certificate is stored. * - [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. * * Returns: * OEMCrypto_SUCCESS * OEMCrypto_ERROR_NOT_IMPLEMENTED - this function is for Provisioning 3.0 * only. * OEMCrypto_ERROR_SHORT_BUFFER * 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 12. */ OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(OEMCrypto_SESSION session, uint8_t* public_cert, size_t* public_cert_length); /* * OEMCrypto_GetRandom * * Description: * Returns a buffer filled with hardware-generated random bytes, if supported * by the hardware. If the hardware feature does not exist, return * OEMCrypto_ERROR_RNG_NOT_SUPPORTED. * * Parameters: * [out] random_data - pointer to the buffer that receives random data * [in] random_data_length - length of the random data buffer in bytes * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_RNG_FAILED failed to generate random number * OEMCrypto_ERROR_RNG_NOT_SUPPORTED function not supported * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support dataLength sizes of at least 32 bytes for random * number generation. * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * * 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_GetRandom(uint8_t* random_data, size_t random_data_length); /* * OEMCrypto_APIVersion * * Description: * 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 15. Any OEM that returns this * version number guarantees it passes all unit tests associated with this * version. * * Parameters: * none * * Returns: * 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); /* * OEMCrypto_BuildInformation * * Description: * Report the build information of the OEMCrypto library as a short null * terminated C string. The string should be at most 128 characters long. * This string should be updated with each release or OEMCrypto build. * * Some SOC vendors deliver a binary OEMCrypto library to a device * manufacturer. This means the OEMCrypto version may not be exactly in sync * with the system's versions. This string can be used to help track which * version is installed on a device. * * 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. * * Since the OEMCrypto API also changes its minor version number when there * are minor corrections, it would be useful to include the API version * number in this string, e.g. "15.1" or "15.2" if those minor versions are * released. * * Parameters: * none * * Returns: * A printable null terminated C string, suitable for a single line in a log. * * 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. */ const char* OEMCrypto_BuildInformation(void); /* * OEMCrypto_Security_Patch_Level * * Description: * 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 above for more details. * * Parameters: * none * * Returns: * 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); /* * OEMCrypto_SecurityLevel * * Description: * 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. * * Parameters: * none * * Returns: * A null terminated string. Useful value are "L1", "L2" and "L3". * * 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 6. */ const char* OEMCrypto_SecurityLevel(void); /* * 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: * * 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 current HDCP should be the minimum value of any display currently * connected through any channel, either through HDMI or a supported wireless * format. The current value can be used by the application or server to * decide which license can currently be used. If the key control block * requires the current HDCP level, we expect the key to be usable. * * 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. * * 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. * * Parameters: * [out] current - this is the current HDCP version, based on the device * itself, and the display to which it is connected. * [out] maximum - this is the maximum supported HDCP version for the device, * ignoring any attached device. * * Returns: * OEMCrypto_SUCCESS * OEMCrypto_ERROR_UNKNOWN_FAILURE * 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); /* * 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 * * Returns: * 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); /* * OEMCrypto_IsAntiRollbackHwPresent * * Description: * 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. * * Parameters: * none * * Returns: * 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); /* * OEMCrypto_GetNumberOfOpenSessions * * Description: * Returns the current number of open sessions. The CDM and OEMCrypto * consumers can query this value so they can use resources more effectively. * * Parameters: * [out] count - this is the current number of opened sessions. * * Returns: * OEMCrypto_SUCCESS * OEMCrypto_ERROR_UNKNOWN_FAILURE * 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); /* * OEMCrypto_GetMaxNumberOfSessions * * Description: * 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. * * Parameters: * [out] max - this is the max number of supported sessions. * * Returns: * OEMCrypto_SUCCESS * OEMCrypto_ERROR_UNKNOWN_FAILURE * 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); /* * OEMCrypto_SupportedCertificates * * Description: * 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. * * Parameters: * none * * Returns: * 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 certificate are used with * OEMCrypto_GenerateRSASignature with padding type set to 0x2, PKCS1 * with block type 1 padding. * * 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. */ uint32_t OEMCrypto_SupportedCertificates(void); /* * OEMCrypto_IsSRMUpdateSupported * * Description: * Returns true if the device supports SRM files and the file can be updated * via the function OEMCrypto_LoadSRM. This also returns false for devices * that do not support an SRM file, devices that do not support HDCP, and * devices that have no external display support. * * Parameters: * none * * Returns: * true - if LoadSRM is supported. * 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 13. */ bool OEMCrypto_IsSRMUpdateSupported(void); /* * OEMCrypto_GetCurrentSRMVersion * * Description: * 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. * * Parameters: * [out] version: current SRM version number. * * Returns: * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_SUCCESS * OEMCrypto_LOCAL_DISPLAY_ONLY - to indicate version was not set, and is not * needed. * 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); /* * OEMCrypto_GetAnalogOutputFlags * * Description: * 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. * * Parameters: * none. * * Returns: * Returns a bitwise OR of the following flags. * - 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); /* * OEMCrypto_ResourceRatingTier * * Description: * 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 expects 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 below to be minimum * values. * * These performance parameters are for OEMCrypto only. In particular, * bandwidth and codec resolution are determined by the platform. * * Some parameters need more explanation. The Sample size is typically the * size of one encoded frame. Converting this to resolution depends on the * Codec, which is not specified by OEMCrypto. Some content has the sample * broken into several subsamples. The "number of subsamples" restriction * requires that any content can be broken into at least that many * subsamples. However, this number may be larger if DecryptCENC returns * OEMCrypto_ERROR_BUFFER_TOO_LARGE. In that case, the layer above OEMCrypto * will break the sample into subsamples of size "Decrypt Buffer Size" as * specified in the table below. The "Decrypt Buffer Size" means the size of * one subsample that may be passed into DecryptCENC or CopyBuffer without * returning error OEMCrypto_ERROR_BUFFER_TOO_LARGE. * * The number of keys per session is an indication of how many different * track types there can be for a piece of content. Typically, content will * have several keys corresponding to audio and video at different * resolutions. If the content uses key rotation, there could be three keys * -- previous interval, current interval, and next interval -- for each * resolution. * * Concurrent playback sessions versus concurrent sessions: some applications * will preload multiple licenses before the user picks which content to * play. Each of these licenses corresponds to an open session. Once playback * starts, some platforms support picture-in-picture or multiple displays. * Each of these pictures would correspond to a separate playback session * with active decryption. * * Decrypted frames per second -- strictly speaking, OEMCrypto only controls * the decryption part of playback and cannot control the decoding and * display part. However, devices that support the higher resource tiers * should also support a higher frame rate. Platforms may enforce these * values. For example Android will enforce a frame rate via a GTS test. * * +-----------------------------------+-----------+------------+-----------+ * |Resource Rating Tier |1 - Low |2 - Medium |3 - High | * +-----------------------------------+-----------+------------+-----------+ * |Sample size |1 MB |2 MB |4 MB | * +-----------------------------------+-----------+------------+-----------+ * |Number of Subsamples |8 |16 |32 | * +-----------------------------------+-----------+------------+-----------+ * |Decrypt buffer size |100 KB |500 KB |1 MB | * +-----------------------------------+-----------+------------+-----------+ * |Generic crypto buffer size |10 KB |100 KB |500 KB | * +-----------------------------------+-----------+------------+-----------+ * |Number of concurrent sessions |10 |20 |20 | * +-----------------------------------+-----------+------------+-----------+ * |Number of keys per session |4 |20 |20 | * +-----------------------------------+-----------+------------+-----------+ * |Simultaneous secure playback |1 |2 |2 | * +-----------------------------------+-----------+------------+-----------+ * |Decrypted Frames per Second |30 fps SD |30 fps HD |60 fps HD | * +-----------------------------------+-----------+------------+-----------+ * * Parameters: * none. * * Returns: * 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); /* * OEMCrypto_RewrapDeviceRSAKey30 * * Description: * This function is similar to RewrapDeviceRSAKey, except it uses the private * key from an OEM certificate to decrypt the message key instead of keys * derived from a keybox. 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 (kSign_RSASSA_PSS) * will be used. * * Verification and Algorithm: * The following checks should be performed. If any check fails, an error is * returned, and the key is not loaded. * * 1. Verify that in_wrapped_rsa_key_length is large enough to hold the * rewrapped key, returning OEMCrypto_ERROR_SHORT_BUFFER otherwise. * 2. 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. Notice that the nonce may not point * to a word aligned memory location. * 3. Decrypt encrypted_message_key with the OEM certificate's private RSA * key using RSA-OAEP into the buffer message_key. This message key is * a 128 bit AES key used only in step 4. This message_key should be * kept in secure memory and protected from the user. * 4. Decrypt enc_rsa_key into the buffer rsa_key using the message_key, * which was found in step 3. Use enc_rsa_key_iv as the initial vector * for AES_128-CBC mode, with PKCS#5 padding. The rsa_key should be kept * in secure memory and protected from the user. * 5. If the first four bytes of the buffer rsa_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. * 6. If the first four bytes of the buffer rsa_key are not the string * "SIGN", then the default value of allowed_schemes = 1 * (kSign_RSASSA_PSS) will be used. * 7. After possibly skipping past the first 8 bytes signifying the allowed * signing algorithm, the rest of the buffer rsa_key contains an RSA * device key in PKCS#8 binary DER encoded format. The OEMCrypto library * shall verify that this RSA key is valid. * 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: * [in] session: crypto session identifier. * [in] unaligned_nonce: A pointer to the nonce provided in the provisioning * response. (unaligned uint32_t) * [in] encrypted_message_key : message_key encrypted by private key from * OEM cert. * [in] encrypted_message_key_length : length of encrypted_message_key in * bytes. * [in] enc_rsa_key: Encrypted device private RSA key received from the * provisioning server. Format is PKCS#8, binary DER encoded, and * encrypted with message_key, using AES-128-CBC with PKCS#5 padding. * [in] enc_rsa_key_length: length of the encrypted RSA key, in bytes. * [in] enc_rsa_key_iv: IV for decrypting RSA key. Size is 128 bits. * [out] wrapped_rsa_key: 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. * [in/out] wrapped_rsa_key_length: (in) length of the encrypted RSA key, in * bytes. * (out) actual length of the encrypted RSA key * * 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 * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support message sizes of at least 8 KiB. * 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_RewrapDeviceRSAKey30( OEMCrypto_SESSION session, const uint32_t* unaligned_nonce, const SharedMemory* encrypted_message_key, size_t encrypted_message_key_length, const SharedMemory* 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 * * Description: * This function is similar to RewrapDeviceRSAKey30, except it uses session * keys derived from the keybox instead of the OEM certificate. 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 (kSign_RSASSA_PSS) * will be used. * * 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_rsa_key_length is large enough to hold the * rewrapped key, returning OEMCrypto_ERROR_SHORT_BUFFER 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]) from a previous call to * OEMCrypto_GenerateDerivedKeys. * 5. Decrypt enc_rsa_key in the buffer rsa_key using the derived * encryption key (enc_key) from a previous call to * OEMCrypto_GenerateDerivedKeys. Use enc_rsa_key_iv as the initial * vector for AES_128-CBC mode, with PKCS#5 padding. The rsa_key should * be kept in secure memory and protected from the user. * 6. If the first four bytes of the buffer rsa_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 rsa_key are not the string * "SIGN", then the default value of allowed_schemes = 1 * (kSign_RSASSA_PSS) will be used. * 8. After possibly skipping past the first 8 bytes signifying the allowed * signing algorithm, the rest of the buffer rsa_key contains an RSA * device key in PKCS#8 binary DER encoded format. The OEMCrypto library * shall verify that this RSA key is valid. * 9. 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. * 10. 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: * [in] session: crypto session identifier. * [in] unaligned_nonce: A pointer to the nonce provided in the provisioning * response. (unaligned uint32_t) * [in] message: pointer to memory containing message to be verified. * [in] message_length: length of the message, in bytes. * [in] signature: pointer to memory containing the HMAC-SHA256 signature for * message, received from the provisioning server. * [in] signature_length: length of the signature, in bytes. * [in] nonce: A pointer to the nonce provided in the provisioning response. * [in] enc_rsa_key: Encrypted device private RSA key received from the * provisioning server. Format is PKCS#8, binary DER encoded, and * encrypted with the derived encryption key, using AES-128-CBC with * PKCS#5 padding. * [in] enc_rsa_key_length: length of the encrypted RSA key, in bytes. * [in] enc_rsa_key_iv: IV for decrypting RSA key. Size is 128 bits. * [out] wrapped_rsa_key: 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. * [in/out] wrapped_rsa_key_length: (in) length of the encrypted RSA key, in * bytes. * (out) actual length of the encrypted RSA key * * 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 * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support message sizes of at least 8 KiB. * 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_RewrapDeviceRSAKey( OEMCrypto_SESSION session, const SharedMemory* message, size_t message_length, const SharedMemory* 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_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: * [in] session: crypto session identifier. * [in] wrapped_rsa_key: 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. * [in] wrapped_rsa_key_length: length of the wrapped key buffer, in bytes. * * 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 * OEMCrypto_ERROR_SESSION_LOST_STATE * 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 9. */ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session, const SharedMemory* wrapped_rsa_key, size_t wrapped_rsa_key_length); /* * OEMCrypto_LoadTestRSAKey * * Description: * 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 unit test code, oemcrypto_test.cpp, in * PKCS8 form as the constant kTestRSAPKCS8PrivateKeyInfo2_2048. * * Parameters: * none * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INSUFFICIENT_RESOURCES * OEMCrypto_ERROR_NOT_IMPLEMENTED - devices that use a keybox should not * implement this function * 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); /* * 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 Signing Messages Sent to a Server section above for more * details. * * If this function is called after OEMCrypto_LoadDeviceRSAKey for the same * session, then this function should use the device RSA key that was loaded. * If this function is called after a call to * OEMCrypto_GetOEMPublicCertificate for the same session, then this function * should use the RSA private key associated with the OEM certificate. The * only padding scheme that is valid for the OEM certificate is 0x1 - * RSASSA-PSS with SHA1. Any other padding scheme must generate an error. * * 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: * [in] session: crypto session identifier. * [in] message: pointer to memory containing message to be signed. * [in] message_length: length of the message, in bytes. * [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. * [in/out] signature_length: (in) length of the signature buffer, in bytes. * (out) actual length of the signature * [in] padding_scheme: specify which scheme to use for the signature. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER if the signature buffer is too small. * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_ERROR_INVALID_CONTEXT * 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. * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * OEMCrypto shall support message sizes of at least 8 KiB. * 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_GenerateRSASignature( OEMCrypto_SESSION session, const SharedMemory* message, size_t message_length, uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme padding_scheme); /* * OEMCrypto_CreateUsageTableHeader * * Description: * 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. * * Devices that do not implement a Session Usage Table may return * OEMCrypto_ERROR_NOT_IMPLEMENTED. * * Parameters: * [out] header_buffer: pointer to memory where encrypted usage table header * is written. * [in/out] header_buffer_length: (in) length of the header_buffer, in bytes. * (out) actual length of the header_buffer * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER - if header_buffer_length is too small. * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE * 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); /* * OEMCrypto_LoadUsageTableHeader * * Description: * 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. * * Parameters: * [in] buffer: pointer to memory containing encrypted usage table header. * [in] buffer_length: length of the buffer, in bytes. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER * OEMCrypto_ERROR_NOT_IMPLEMENTED - some devices do not implement usage * tables. * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_WARNING_GENERATION_SKEW - if the generation number is off by * exactly 1. * OEMCrypto_ERROR_GENERATION_SKEW - if the generation number is off by more * than 1. * OEMCrypto_ERROR_SIGNATURE_FAILURE - if the signature failed. * OEMCrypto_ERROR_BAD_MAGIC - verification string does not match. * 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_LoadUsageTableHeader(const uint8_t* buffer, size_t buffer_length); /* * OEMCrypto_CreateNewUsageEntry * * Description: * 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. * * Parameters: * [in] session: handle for the session to be used. * [out] usage_entry_number: index of new usage entry. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NOT_IMPLEMENTED - some devices do not implement usage * tables. * 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. * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_SESSION_LOST_STATE * 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_CreateNewUsageEntry(OEMCrypto_SESSION session, uint32_t* usage_entry_number); /* * OEMCrypto_LoadUsageEntry * * Description: * This loads a usage table 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 that 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. * * If the entry is already loaded into another open session, then this fails * and returns OEMCrypto_ERROR_INVALID_SESSION. * * Parameters: * [in] session: handle for the session to be used. * [in] usage_entry_number: index of existing usage entry. * [in] buffer: pointer to memory containing encrypted usage table entry. * [in] buffer_length: length of the buffer, in bytes. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER * OEMCrypto_ERROR_NOT_IMPLEMENTED - some devices do not implement usage * tables. * OEMCrypto_ERROR_UNKNOWN_FAILURE - index beyond end of table. * OEMCrypto_ERROR_INVALID_SESSION - entry associated with another session or * the index is wrong. * OEMCrypto_WARNING_GENERATION_SKEW - if the generation number is off by * exactly 1. * OEMCrypto_ERROR_GENERATION_SKEW - if the generation number is off by more * than 1. * OEMCrypto_ERROR_SIGNATURE_FAILURE - if the signature failed. * OEMCrypto_ERROR_BAD_MAGIC - verification string does not match. * OEMCrypto_ERROR_SESSION_LOST_STATE * 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_LoadUsageEntry(OEMCrypto_SESSION session, uint32_t usage_entry_number, const uint8_t* buffer, size_t buffer_length); /* * OEMCrypto_UpdateUsageEntry * * Description: * Updates the session's usage entry and fills buffers with the encrypted and * signed entry and usage table header. OEMCrypto will 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 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. As in OEMCrypto * v12, 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 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 is not large enough, they are set to the * needed size, and 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. * * Parameters: * [in] session: handle for the session to be used. * [out] header_buffer: pointer to memory where encrypted usage table header * is written. * [in/out] header_buffer_length: (in) length of the header_buffer, in bytes. * (out) actual length of the header_buffer * [out] entry_buffer: pointer to memory where encrypted usage table entry is * written. * [in/out] entry_buffer_length: (in) length of the entry_buffer, in bytes. * (out) actual length of the entry_buffer * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER * OEMCrypto_ERROR_NOT_IMPLEMENTED - some devices do not implement usage * tables. * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_SESSION_LOST_STATE * 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_UpdateUsageEntry(OEMCrypto_SESSION session, SharedMemory* header_buffer, size_t* header_buffer_length, SharedMemory* entry_buffer, size_t* entry_buffer_length); /* * OEMCrypto_DeactivateUsageEntry * * Description: * This deactivates the usage entry associated with the current session. This * means that the state 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 * 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. * * 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. * * Parameters: * [in] session: handle for the session to be used. * [in] pst: pointer to memory containing Provider Session Token. * [in] pst_length: length of the pst, in bytes. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INVALID_CONTEXT - an entry was not created or loaded, or * the pst does not match. * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * 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_DeactivateUsageEntry(OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length); /* * OEMCrypto_ReportUsage * * Description: * 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 the an entry was not loaded or created with * OEMCrypto_CreateNewUsageEntry or OEMCRypto_LoadUsageEntry, or if the pst * does not match that in the entry, return the error * OEMCrypto_ERROR_INVALID_CONTEXT. * * 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 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 - 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. * - 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. * 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. * * Devices that do not implement a Session Usage Table may return * OEMCrypto_ERROR_NOT_IMPLEMENTED. * * Parameters: * [in] session: handle for the session to be used. * [in] pst: pointer to memory containing Provider Session Token. * [in] pst_length: length of the pst, in bytes. * [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. * [in/out] buffer_length: (in) length of the report buffer, in bytes. * (out) actual length of the report * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER - if report buffer is not large enough to * hold the output report. * OEMCrypto_ERROR_INVALID_SESSION - no open session with that id. * OEMCrypto_ERROR_INVALID_CONTEXT * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE - if no call to UpdateUsageEntry since * last call to Deactivate or since key use. * OEMCrypto_ERROR_WRONG_PST - report asked for wrong pst. * OEMCrypto_ERROR_SESSION_LOST_STATE * OEMCrypto_ERROR_SYSTEM_INVALIDATED * * Buffer Sizes: * 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); /* * 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: * [in] session - handle for the session to be used. * [in] pst - pointer to memory containing Provider Session Token. * [in] pst_length - length of the pst, in bytes. * [in] message - pointer to memory containing message to be verified. * [in] message_length - length of the message, in bytes. * [in] signature - pointer to memory containing the signature. * [in] signature_length - 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_ForceDeleteUsageEntry * * Description: * This function deletes an entry from the session usage table. This will be * used for stale entries without a signed request from the server. * * After performing all verification listed below, and deleting the entry from * the Usage Table, OEMCrypto will increment the Usage Table’s generation number, * and then sign, encrypt, and save the Usage Table. * * 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. If not, return OEMCrypto_ERROR_UNKNOWN_FAILURE. * * Parameters * [in] pst - pointer to memory containing Provider Session Token. * [in] pst_length - length of the pst, in bytes. * * Returns * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE * * Threading * This function will not be called simultaneously with any session functions. * * Version * This method changed in API version 10. */ OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, size_t pst_length); /* * OEMCrypto_MoveEntry * * Description: * 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. * * Parameters: * [in] session: handle for the session to be used. * [in] new_index: new index to be used for the session's usage entry * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_BUFFER_TOO_LARGE * OEMCrypto_ERROR_ENTRY_IN_USE * OEMCrypto_ERROR_SESSION_LOST_STATE * 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); /* * OEMCrypto_ShrinkUsageTableHeader * * Description: * 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. If new_table_size is larger than the current size, * then the header is not changed and the error is returned. If the header * has not been previously loaded, then an error 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_table_size. * * 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. * * Parameters: * [in] new_entry_count: number of entries in the to be in the header. * [out] header_buffer: pointer to memory where encrypted usage table header * is written. * [in/out] header_buffer_length: (in) length of the header_buffer, in bytes. * (out) actual length of the header_buffer * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_ENTRY_IN_USE * 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); /* * OEMCrypto_CopyOldUsageEntry * * Description: * This function copies an entry from the old v12 table to the new table. The * new entry will already have been loaded by CreateNewUsageEntry. If the * device did not support pre-v13 usage tables, this may return * OEMCrypto_ERROR_NOT_IMPLEMENTED. * * This is only needed for devices that are upgrading from a version of * OEMCrypto before v13 to a recent version. Devices that have an existing * usage table with customer's offline licenses will use this method to move * entries from the old table to the new one. * * Parameters: * [in] session: handle for the session to be used. * [in] pst: pointer to memory containing Provider Session Token. * [in] pst_length: length of the pst, in bytes. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE * OEMCrypto_ERROR_SESSION_LOST_STATE * 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_CopyOldUsageEntry(OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length); /* * OEMCrypto_DeleteOldUsageTable * * Description: * This function will delete the old usage table, if possible, freeing any * nonvolatile secure memory. This may return OEMCrypto_ERROR_NOT_IMPLEMENTED * if the device did not support pre-v13 usage tables. * * This is only needed for devices that are upgrading from a version of * OEMCrypto before v13 to a recent version. Devices that have an existing * usage table with customer's offline licenses will use this method to move * entries from the old table to the new one. * * Parameters: * none * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_UNKNOWN_FAILURE * 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 13. */ OEMCryptoResult OEMCrypto_DeleteOldUsageTable(void); /* * OEMCrypto_RemoveSRM * * Description: * Delete the current SRM. Any valid SRM, regardless of version number, will * be installable after this via OEMCrypto_LoadSRM. * * This function should not be implemented on production devices, and will * only be used to verify unit tests on a test device. * * Parameters: * none * * Returns: * OEMCrypto_SUCCESS - if the SRM file was deleted. * OEMCrypto_ERROR_NOT_IMPLEMENTED - always on production devices. * * 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 13. */ OEMCryptoResult OEMCrypto_RemoveSRM(void); /* * OEMCrypto_CreateOldUsageEntry * * Description: * This forces the creation of an entry in the old usage table in order to * test OEMCrypto_CopyOldUsageTable. OEMCrypto will create a new entry, set * the status and compute the times at license receive, first decrypt and * last decrypt. The mac keys will be copied to the entry. The mac keys are * not encrypted, but will only correspond to a test license. * * Devices that do not support usage tables, or devices that will not be * field upgraded from a version of OEMCrypto before v13 to a recent version * may return OEMCrypto_ERROR_NOT_IMPLEMENTED. * * Parameters: * TODO(fredgc): add appropriate comments for parameters * [in] time_since_license_received: * [in] time_since_first_decrypt: * [in] time_since_last_decrypt: * [in] status: * [in] server_mac_key * [in] client_mac_key * [in] pst * [in] pst_length * * Returns: * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_SUCCESS * * 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 only used when running unit tests. * * Version: * This method is new in API version 13. */ 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_SupportsDecryptHash * * Description: * 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 CRC32 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. * * Returns: * OEMCrypto_Hash_Not_Supported = 0; * OEMCrypto_CRC_Clear_Buffer = 1; * 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); /* * OEMCrypto_SetDecryptHash * * Description: * 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 OEMCrytpo_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 at most 128 bytes. * * This may be called before the first call to SelectKey. 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. * * Parameters: * [in] session: session id for current decrypt operation * [in] frame_number: frame number for the recent DecryptCENC sample. * [in] hash: hash or CRC of previously decrypted frame. * [in] hash_length: length of hash, in bytes. * * Returns: * OEMCrypto_SUCCESS - if the hash was set * OEMCrypto_ERROR_NOT_IMPLEMENTED - function not implemented * OEMCrypto_ERROR_INVALID_SESSION - session not open * OEMCrypto_ERROR_SHORT_BUFFER - hash_length too short for supported hash * type * OEMCrypto_ERROR_BUFFER_TOO_LARGE - hash_length too long for supported hash * type * OEMCrypto_ERROR_UNKNOWN_FAILURE - other error * OEMCrypto_ERROR_SESSION_LOST_STATE * 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, const uint8_t* hash, size_t hash_length); /* * OEMCrypto_GetHashErrorCode * * Description: * 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. * * Parameters: * [in] session: session id for operation. * [out] failed_frame_number: frame number for sample with incorrect hash. * * Returns: * OEMCrypto_SUCCESS - if all frames have had a correct hash * OEMCrypto_ERROR_NOT_IMPLEMENTED * OEMCrypto_ERROR_BAD_HASH - if any frame had an incorrect hash * OEMCrypto_ERROR_UNKNOWN_FAILURE - if the hash could not be computed * OEMCrypto_ERROR_SESSION_LOST_STATE * 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); #ifdef __cplusplus } #endif #endif // OEMCRYPTO_CENC_H_