diff --git a/libwvdrmengine/oemcrypto/include/OEMCrypto.h b/libwvdrmengine/oemcrypto/include/OEMCrypto.h index 44190995..d448cbfb 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCrypto.h +++ b/libwvdrmengine/oemcrypto/include/OEMCrypto.h @@ -19,82 +19,152 @@ static const char oec_version[] = OEMCRYPTO_VERSION; typedef unsigned char OEMCrypto_UINT8; typedef char OEMCrypto_INT8; typedef unsigned long OEMCrypto_UINT32; -typedef unsigned long OEMCrypto_SECURE_BUFFER; typedef unsigned long OEMCrypto_SESSION; typedef enum OEMCryptoResult { - OEMCrypto_SUCCESS = 0, - OEMCrypto_ERROR_INIT_FAILED, - OEMCrypto_ERROR_TERMINATE_FAILED, - OEMCrypto_ERROR_OPEN_FAILURE, - OEMCrypto_ERROR_CLOSE_FAILURE, - OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED, - OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED, - OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_ERROR_NO_DEVICE_KEY, - OEMCrypto_ERROR_NO_ASSET_KEY, - OEMCrypto_ERROR_KEYBOX_INVALID, - OEMCrypto_ERROR_NO_KEYDATA, - OEMCrypto_ERROR_NO_CW, - OEMCrypto_ERROR_DECRYPT_FAILED, - OEMCrypto_ERROR_WRITE_KEYBOX, - OEMCrypto_ERROR_WRAP_KEYBOX, - OEMCrypto_ERROR_BAD_MAGIC, - OEMCrypto_ERROR_BAD_CRC, - OEMCrypto_ERROR_NO_DEVICEID, - OEMCrypto_ERROR_RNG_FAILED, - OEMCrypto_ERROR_RNG_NOT_SUPPORTED, - OEMCrypto_ERROR_SETUP, - OEMCrypto_ERROR_OPEN_SESSION_FAILED, - OEMCrypto_ERROR_CLOSE_SESSION_FAILED, - OEMCrypto_ERROR_INVALID_SESSION, - OEMCrypto_ERROR_NOT_IMPLEMENTED, - OEMCrypto_ERROR_NO_CONTENT_KEY, - OEMCrypto_ERROR_CONTROL_INVALID, - OEMCrypto_ERROR_UNKNOWN_FAILURE, - OEMCrypto_ERROR_INVALID_CONTEXT - + OEMCrypto_SUCCESS = 0, + OEMCrypto_ERROR_INIT_FAILED, + OEMCrypto_ERROR_TERMINATE_FAILED, + OEMCrypto_ERROR_OPEN_FAILURE, + OEMCrypto_ERROR_CLOSE_FAILURE, + OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED, + OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED, + OEMCrypto_ERROR_SHORT_BUFFER, + OEMCrypto_ERROR_NO_DEVICE_KEY, + OEMCrypto_ERROR_NO_ASSET_KEY, + OEMCrypto_ERROR_KEYBOX_INVALID, + OEMCrypto_ERROR_NO_KEYDATA, + OEMCrypto_ERROR_NO_CW, + OEMCrypto_ERROR_DECRYPT_FAILED, + OEMCrypto_ERROR_WRITE_KEYBOX, + OEMCrypto_ERROR_WRAP_KEYBOX, + OEMCrypto_ERROR_BAD_MAGIC, + OEMCrypto_ERROR_BAD_CRC, + OEMCrypto_ERROR_NO_DEVICEID, + OEMCrypto_ERROR_RNG_FAILED, + OEMCrypto_ERROR_RNG_NOT_SUPPORTED, + OEMCrypto_ERROR_SETUP, + OEMCrypto_ERROR_OPEN_SESSION_FAILED, + OEMCrypto_ERROR_CLOSE_SESSION_FAILED, + OEMCrypto_ERROR_INVALID_SESSION, + OEMCrypto_ERROR_NOT_IMPLEMENTED, + OEMCrypto_ERROR_NO_CONTENT_KEY, + OEMCrypto_ERROR_CONTROL_INVALID, + OEMCrypto_ERROR_UNKNOWN_FAILURE, + OEMCrypto_ERROR_INVALID_CONTEXT, + OEMCrypto_ERROR_SIGNATURE_FAILURE } OEMCryptoResult; -#define OEMCrypto_DESC_FLAG_IS_ENCRYPTED 0x01 +/* + * OEMCrypto_DestBufferDesc + * Describes the type and access information for the memory to receive + * decrypted data. + * + * The OEMCrypto API supports a range of client device architectures. + * Different architectures have different methods for acquiring and securing + * buffers that will hold portions of the audio or video stream after + * decryption. Three basic strategies are recognized for handling decrypted + * stream data: + * 1. Return the decrypted data in the clear into normal user memory + * (ClearBuffer). The caller uses normal memory allocation methods to + * acquire a buffer, and supplies the memory address of the buffer in the + * descriptor. + * 2. Place the decrypted data into protected memory (SecureBuffer). The + * caller uses a platform-specific method to acquire the protected buffer + * and a user-memory handle that references it. The handle is supplied + * to the decrypt call in the descriptor. + * 3. Place the decrypted data directly into the audio or video decoder fifo + * (Direct). The caller will use platform-specific methods to initialize + * the fifo and the decoders. The decrypted stream data is not accessible + * to the caller. + * + * Specific fields are as follows: + * + * (type == OEMCrypto_BufferType_Clear) + * address - Address of start of user memory buffer. + * max_length - Size of user memory buffer. + * (type == OEMCrypto_BufferType_Secure) + * buffer - handle to a platform-specific secure buffer. + * max_length - Size of platform-specific secure buffer. + * (type == OEMCrypto_BufferType_Direct) + * is_video - If true, decrypted bytes are routed to the video + * decoder. If false, decrypted bytes are routed to the + * audio decoder. + */ +typedef enum OEMCryptoBufferType { + OEMCrypto_BufferType_Clear, + OEMCrypto_BufferType_Secure, + OEMCrypto_BufferType_Direct +} OEMCrytoBufferType; -typedef struct -{ - OEMCrypto_UINT8 flags; /* See OEMCrypto_DESC_FLAG_* */ - OEMCrypto_UINT32 len; -} OEMCrypto_Descriptor; +typedef struct { + OEMCryptoBufferType type; + union { + struct { // type == OEMCrypto_BufferType_Clear + bool is_protected; + OEMCrypto_UINT8* address; + OEMCrypto_UINT32 max_length; + } memory; + struct { // type == OEMCrypto_BufferType_Secure + void* handle; + OEMCrypto_UINT32 max_length; + } secure; + struct { // type == OEMCrypto_BufferType_Direct + bool is_video; + } direct; + } buffer; +} OEMCrypto_DestBufferDesc; /* * OEMCrypto_KeyObject - * Points to relevant fields for this key within the License Response - * message offered to OEMCrypto_LoadKeys(). Each offset field contains - * an offset into the License Response where the field begins. + * 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. All fields are 128 bits + * (16 bytes): + * key_id - the unique id of this key. + * 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. * - * Each field is the length of an AES-128 block (16 bytes). + * The memory for the OEMCrypto_KeyObject fields is allocated and freed + * by the caller of OEMCrypto_LoadKeys(). */ -typedef struct -{ - OEMCrypto_UINT32 key_id_offset; - OEMCrypto_UINT32 key_data_iv_offset; - OEMCrypto_UINT32 key_data_offset; - OEMCrypto_UINT32 key_control_iv_offset; - OEMCrypto_UINT32 key_control_offset; +typedef struct { + const OEMCrypto_UINT8* key_id; + const OEMCrypto_UINT8* key_data_iv; + const OEMCrypto_UINT8* key_data; + const OEMCrypto_UINT8* key_control_iv; + const OEMCrypto_UINT8* key_control; } OEMCrypto_KeyObject; /* * OEMCrypto_KeyRefreshObject - * Points to relevant fields for this key within the License Renewal - * Response message offered to OEMCrypto_RefreshKeys(). Each offset - * field contains an offset into the License Renewal Response where - * the field begins. + * 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. All fields are 128 bits (16 bytes): + * key_id - the unique id of this key. + * 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. * - * Each field is the length of an AES-128 block (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_UINT32 key_id_offset; - OEMCrypto_UINT32 key_control_iv_offset; - OEMCrypto_UINT32 key_control_offset; +typedef struct { + const OEMCrypto_UINT8* key_id; + const OEMCrypto_UINT8* key_control_iv; + const OEMCrypto_UINT8* key_control; } OEMCrypto_KeyRefreshObject; #define OEMCrypto_Initialize _oec01 @@ -118,8 +188,10 @@ typedef struct #define OEMCrypto_DecryptCTS _oec19 #define OEMCrypto_GenerateDerivedKeys _oec20 #define OEMCrypto_GenerateSignature _oec21 -#define OEMCrypto_LoadKeys _oec22 -#define OEMCrypto_RefreshKeys _oec23 +#define OEMCrypto_GenerateNonce _oec22 +#define OEMCrypto_LoadKeys _oec23 +#define OEMCrypto_RefreshKeys _oec24 +#define OEMCrypto_SelectKey _oec25 /* * OEMCrypto_Initialize @@ -192,10 +264,10 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); * * Description: * Generates a pair of secondary keys, mac_key and encrypt_key, for handling - * signing and content key decryption under the V2 license server protocol + * signing and content key decryption under the license server protocol * for AES CTR mode. * - * Refer to document OEMCrypto Changes for V2 License Protocol for details + * Refer to document "OEMCrypto Changes for V2 License Protocol" for details * * Parameters: * session (in) - crypto session identifier. @@ -207,41 +279,73 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION - * OEMCrypto_UNKNOWN_FAILURE - * OEMCrypto_INVALID_CONTEXT + * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_INVALID_CONTEXT */ OEMCryptoResult OEMCrypto_GenerateDerivedKeys( OEMCrypto_SESSION session, const OEMCrypto_UINT8 *context, OEMCrypto_UINT32 context_length); + +/* + * OEMCrypto_GenerateNonce + * + * AES CTR Mode only, Levels 1 and 2 only + * + * Description: + * Generates a 32-bit nonce to detect possible replay attack on the key + * control block. + * + * Refer to documents "OEMCrypto Changes for V2 License Protocol" and "Key + * Control Block Definition" for details. + * + * Parameters: + * session (in) - crypto session identifier. + * message (in) - pointer to memory containing message to be signed. + * message_length (in) - length of the message. + * signature (out) - pointer to memory to received the computed signature. + * signature_length (in/out) - (in) length of the signature buffer. + * (out) actual length of the signature + * + * Returns: + * OEMCrypto_SUCCESS success + * OEMCrypto_ERROR_NO_DEVICE_KEY + * OEMCrypto_ERROR_INVALID_SESSION + * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_INVALID_CONTEXT + */ +OEMCryptoResult OEMCrypto_GenerateNonce( + OEMCrypto_SESSION session, + OEMCrypto_UINT32* nonce); + /* * OEMCrypto_GenerateSignature * * AES CTR Mode only, Levels 1 and 2 only * * Description: - * Generates a HMAC-SHA256 signature for license request signing under the V2 + * Generates a HMAC-SHA256 signature for license request signing under the * license server protocol for AES CTR mode. * * NOTE: OEMCrypto_GenerateDerivedKeys() must be called first to establish the * mac_key * - * Refer to document OEMCrypto Changes for V2 License Protocol for details. + * Refer to document "OEMCrypto Changes for V2 License Protocol" for details. * * Parameters: * session (in) - crypto session identifier. * message (in) - pointer to memory containing message to be signed. - * secondary keys. * message_length (in) - length of the message. * signature (out) - pointer to memory to received the computed signature. - * signature_length (in/out) - length of the message. + * signature_length (in/out) - (in) length of the signature buffer. + * (out) actual length of the signature * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION - * OEMCrypto_UNKNOWN_FAILURE - * OEMCrypto_INVALID_CONTEXT + * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_INVALID_CONTEXT */ OEMCryptoResult OEMCrypto_GenerateSignature( OEMCrypto_SESSION session, @@ -258,40 +362,50 @@ OEMCryptoResult OEMCrypto_GenerateSignature( * 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). + * If the signature verification fails, ignore all other arguments and return + * OEMCrypto_ERROR_SIGNATURE_FAILURE. Otherwise, add the keys to the session + * context. + * + * The mac_key is encrypted with the current encrypt_key and the offered IV. + * It replaces the mac_key created by OEMCrypto_GenerateDerivedkeys(). + * * NOTE: OEMCrypto_GenerateDerivedKeys() must be called first to establish the * mac_key * - * Refer to document OEMCrypto Changes for V2 License Protocol for details. + * Refer to document "OEMCrypto Changes for V2 License Protocol" for details. * * Parameters: * session (in) - crypto session identifier. - * message (in) - pointer to memory containing message to be signed. - * secondary keys. + * message (in) - pointer to memory containing message to be verified. * message_length (in) - length of the message. - * signature (in) - pointer to memory to received the computed signature. - * signature_length (in) - length of the message. - * enc_mac_key_iv_offset - IV for decrypting new mac_key. - * enc_mac_key_offset - encrypted mac_key for generating new mac_key. - * num_keys - number of keys present. - * key_array - set of keys to be installed. + * signature (in) - pointer to memory containing the signature. + * signature_length (in) - length of the signature. + * enc_mac_key_iv (in) - IV for decrypting new mac_key. Size is 128 bits. + * enc_mac_key (in) - encrypted mac_key for generating new mac_key. Size is + * 128 bits. + * num_keys (in) - number of keys present. + * key_array (in) - set of keys to be installed. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION - * OEMCrypto_UNKNOWN_FAILURE - * OEMCrypto_INVALID_CONTEXT + * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_INVALID_CONTEXT + * OEMCrypto_ERROR_SIGNATURE_FAILURE */ -OEMCryptoResult OEMCrypto_LoadKeys( - OEMCrypto_SESSION session, - const OEMCrypto_UINT8* message, - OEMCrypto_UINT32 message_length, - const OEMCrypto_UINT8* signature, - OEMCrypto_UINT32 signature_length, - OEMCrypto_UINT32 enc_mac_key_iv_offset, - OEMCrypto_UINT32 enc_mac_key_offset, - OEMCrypto_UINT32 num_keys, - const OEMCrypto_KeyObject* key_array); +OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, + const OEMCrypto_UINT8* message, + OEMCrypto_UINT32 message_length, + const OEMCrypto_UINT8* signature, + OEMCrypto_UINT32 signature_length, + const OEMCrypto_UINT8* enc_mac_key_iv, + const OEMCrypto_UINT8* enc_mac_key, + OEMCrypto_UINT32 num_keys, + const OEMCrypto_KeyObject* key_array); /* * OEMCrypto_RefreshKeys @@ -302,6 +416,13 @@ OEMCryptoResult OEMCrypto_LoadKeys( * 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). + * If the signature verification fails, ignore all other arguments and return + * OEMCrypto_ERROR_SIGNATURE_FAILURE. Otherwise, add the keys to the session + * context. + * * NOTE: OEMCrypto_GenerateDerivedKeys() must be called first to establish * the mac_key * @@ -309,29 +430,29 @@ OEMCryptoResult OEMCrypto_LoadKeys( * * Parameters: * session (in) - crypto session identifier. - * message (in) - pointer to memory containing message to be signed. - * secondary keys. + * message (in) - pointer to memory containing message to be verified. * message_length (in) - length of the message. - * signature (out) - pointer to memory to received the computed signature. - * signature_length (in/out) - length of the signature. - * num_keys - number of keys present. - * key_array - set of keys to be installed. + * signature (in) - pointer to memory containing the signature. + * signature_length (in) - length of the signature. + * num_keys (in) - number of keys present. + * key_array (in) - set of keys to be installed. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION - * OEMCrypto_UNKNOWN_FAILURE - * OEMCrypto_INVALID_CONTEXT + * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_INVALID_CONTEXT + * OEMCrypto_ERROR_SIGNATURE_FAILURE */ -OEMCryptoResult OEMCrypto_RefreshKeys( - OEMCrypto_SESSION session, - const OEMCrypto_UINT8* message, - OEMCrypto_UINT32 message_length, - const OEMCrypto_UINT8* signature, - OEMCrypto_UINT32 signature_length, - OEMCrypto_UINT32 num_keys, - const OEMCrypto_KeyRefreshObject* key_array); +OEMCryptoResult +OEMCrypto_RefreshKeys(OEMCrypto_SESSION session, + const OEMCrypto_UINT8* message, + OEMCrypto_UINT32 message_length, + const OEMCrypto_UINT8* signature, + OEMCrypto_UINT32 signature_length, + OEMCrypto_UINT32 num_keys, + const OEMCrypto_KeyRefreshObject* key_array); /* * OEMCrypto_EnterSecurePlayback @@ -361,7 +482,7 @@ OEMCryptoResult OEMCrypto_EnterSecurePlayback(void); * * Description: * Exit the secure playback mode. This may involve releasing the firewall - * regions. It is called when the decrypt session for an asset is closed. + * regions. It is called when the decrypt session for an asset is closed. * * For Non-Level1 API, return OEMCrypto_ERROR_NOT_IMPLEMENTED * @@ -410,10 +531,11 @@ OEMCryptoResult OEMCrypto_SetEntitlementKey(const OEMCrypto_UINT8* emmKey, * AES CTS Mode only, Levels 1 and 2 only * * Description: - * Using the active key ladder key from OEMCrypto_SetEntitlementKey(), decrypts - * (AES-128-CBC, iv=0) the 32-byte ECM referenced by the *ecm parameter; returns in - * *flags the first clear 4 bytes data. Latch the clear bytes [4..20] as the - * clear control word for subsequent payload decryption operation. + * Using the active key ladder key from OEMCrypto_SetEntitlementKey(), + * decrypt (AES-128-CBC, iv=0) the 32-byte ECM referenced by the *ecm + * parameter; returns in *flags the first clear 4 bytes data. Latch the + * clear bytes [4..20] as the clear control word for subsequent payload + * decryption operation. * * Parameters: * ecm (in) - points to encrypted ECM data @@ -433,8 +555,8 @@ OEMCryptoResult OEMCrypto_DeriveControlWord(const OEMCrypto_UINT8* ecm, * * AES CTR Mode only, Levels 1 and 2 only * - * For CDM implementations, this call is replaced by OEMCrypto_Loadkeys() - * and OEMCrypto_RefreshKeys() + * For CDM implementations, this call is replaced by OEMCrypto_Loadkeys(), + * and OEMCrypto_RefreshKeys(), and OEMCrypto_SelectKey() * * Description: * Place a new content key in the hardware key ladder for subsequent @@ -473,7 +595,7 @@ OEMCryptoResult OEMCrypto_DeriveControlWord(const OEMCrypto_UINT8* ecm, * * Returns: * OEMCrypto_SUCCESS success - * OEMCrypto_ERROR_INVALID_SESSION crypto session ID invalid or session not open + * 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 @@ -485,6 +607,59 @@ OEMCryptoResult OEMCrypto_SetContentKey(const OEMCrypto_SESSION session, const OEMCrypto_UINT8* control, const OEMCrypto_UINT32 controlLength); +/* + * OEMCrypto_SelectKey + * + * AES CTR Mode only, Levels 1 and 2 only (for CDM implementations) + * + * Description: + * Select a content key and install it in the hardware key ladder for + * subsequent decryption operations (OEMCrypto_DecryptCTR()). + * + * This operation is supported only while performing CTR mode decryption + * (see OEMCrypto_DecryptCTR). 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, the content key IV, the key control + * block, and the key control block IV. + * + * Step 2: Lookup the encrypt_key (derived key). Latch the result in the + * hardware key ladder. + * + * Step 3: use the encrypt_key to decrypt (AES-128-CBC) the content key data, + * using the content key IV. Latch result in the hardware key ladder. + * + * Step 4: use the latched content key to decrypt (AES-128-CBC) the key + * control block using the key control block IV. Verify the key + * control block and apply it to the current session. + * + * Step 5: use the latched content key to decrypt (AES-128-CTR) + * to decrypt buffers passed in via OEMCrypto_DecryptCTR(). Continue + * to use this key until OEMCrypto_SelectKey() is called again, or + * until OEMCrypto_CloseSession() is called. + * + * Parameters: + * session (in) - crypto session identifier + * key_id (in) - pointer to the Key ID + * key_id_length (in) - length of the Key ID in bytes + * + * Returns: + * OEMCrypto_SUCCESS success + * OEMCrypto_ERROR_INVALID_SESSION crypto session ID invalid or not open + * OEMCrypto_ERROR_NO_DEVICE_KEY failed to decrypt device key + * OEMCrypto_ERROR_NO_CONTENT_KEY failed to decrypt content key + * OEMCrypto_ERROR_CONTROL_INVALID invalid or unsupported control input + * OEMCrypto_ERROR_KEYBOX_INVALID cannot decrypt and read from Keybox + */ +OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session, + const OEMCrypto_UINT8* key_id, + const OEMCrypto_UINT32 key_id_length); + /* * OEMCrypto_DecryptVideo * @@ -501,13 +676,15 @@ OEMCryptoResult OEMCrypto_SetContentKey(const OEMCrypto_SESSION session, * For Non-Level1 API, return OEMCrypto_ERROR_NOT_IMPLEMENTED * * Parameters: - * iv (in/out) - If iv is NULL, then no decryption is required, i.e. the packets are - * already clear. Otherwise, iv references the AES initialization - * vector. Note that the updated IV after processing the final crypto - * block must be passed back out in *iv. + * iv (in/out) - If iv is NULL, then no decryption is required, i.e. the + * packets are already clear. Otherwise, iv references the + * AES initialization vector. Note that the updated IV after + * processing the final crypto block must be passed back out in + * *iv. * input (in) - buffer containing the encrypted data * inputLength (in) - number of bytes in the input payload. - * output (in) - reference to the secure buffer which will receive the decrypted data + * output (in) - reference to the secure buffer which will receive the + * decrypted data * outputLength (out) - number of bytes written into the secure buffer * * @@ -528,27 +705,28 @@ OEMCryptoResult OEMCrypto_DecryptVideo(const OEMCrypto_UINT8* iv, * AES CTS Mode only, Levels 1 and 2 only * * Description: - * The API decrypts (AES-128-CBC) the audio payload in the buffer referenced by - * the *input parameter into the non-secure buffer referenced by the output + * The API decrypts (AES-128-CBC) the audio payload in the buffer referenced + * by the *input parameter into the non-secure buffer referenced by the output * parameter, using the control word latched in the active hardware key * ladder. If inputLength is not a multiple of the crypto block size (16 bytes), * the API handles the residual bytes using CipherText Stealing (CTS). * - * OEMCrypto_DecryptAudio must make sure that it cannot be used to decrypt a video - * stream into non-firewalled buffers, by verifying that no video packets are - * processed. + * OEMCrypto_DecryptAudio must make sure that it cannot be used to decrypt a + * video stream into non-firewalled buffers, by verifying that no video + * packets are processed. * * For Non-Level1 API, return OEMCrypto_ERROR_NOT_IMPLEMENTED * * Parameters: - * iv (in/out) - If iv is NULL, then no decryption is required, i.e. the packets are - * already clear. Otherwise, iv references the AES initialization - * vector. Note that the updated IV after processing the final crypto - * block must be passed back out in *iv. + * iv (in/out) - If iv is NULL, then no decryption is required, i.e. the + * packets are already clear. Otherwise, iv references the + * AES initialization vector. Note that the updated IV after + * processing the final crypto block must be passed back out + * in *iv. * input (in) - buffer containing the encrypted data * inputLength (in) - number of bytes in the input payload. - * output (in) - reference to the non-secure buffer which will receive the decrypted - * data + * output (in) - reference to the non-secure buffer which will receive the + * decrypted data * outputLength (out) - number of bytes written into the non-secure buffer * * Returns: @@ -574,25 +752,41 @@ OEMCryptoResult OEMCrypto_DecryptAudio(const OEMCrypto_UINT8* iv, * * Parameters: * session (in) - crypto session identifier. - * is_video (in) - true if buffer contains video data. - * buffer_addr (in) - An unaligned pointer to this segment of the stream. - * buffer_length (in) - The length of this segment of the stream. If - * encrypted==true, buffer_length must be a multiple of 16 unless this - * segment holds the final block of an encrypted sequence. - * is_encrypted (in) - True if the buffer described by buf_addr, buf_len is - * encrypted. If not encrypted, only the buf_addr and buf_len - * parameters are used. If is_encrypted is false, the remaining arguments - * should be ignored. - * key_id (in) - The key ID of the content key to be used for decryption. - * key_id_length (in) - Length of the key ID. + * data_addr (in) - An unaligned pointer to this segment of the stream. + * data_length (in) - The length of this segment of the stream. + * is_encrypted (in) - True if the buffer described by data_addr, + * data_length is encrypted. If is_encrypted is false, only the + * data_addr and data_length parameters are used. The iv and offset + * arguments are ignored. * iv (in) - The initial value block to be used for content decryption. * This is discussed further below. - * offset, data_length (in) - After decrypting the entire buffer, send - * data_length bytes starting at address buffer_addr[offset] to the - * decoder. This has the effect of dropping offset bytes from the - * beginning of the buffer and dropping - * (buffer_length - (data_length + offset)) bytes from the end of - * the buffer. + * offset (in) - If non-zero, the decryption block boundary is different + * from the start of the data. 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. + * out_buffer (in) - A caller-owned descriptor that specifies the + * handling of the decrypted byte stream. See OEMCrypto_DestbufferDesc + * for details. + * + * AES CTR is a stream cipher. The stream may be composed of arbitrary- + * length clear and encrypted segments. The encrypted portions of a sample + * are collectively treated as a continuous sequence of decryption + * block-sized blocks even though the sequence is interrupted by clear blocks. + * This means a given encrypted segment may not start or end on a decryption + * block boundary. + * + * If data_addr is not aligned with a decryption block boundary (offset != 0), + * the additional offset bytes before data_addr (pre-padding) are included in + * the decrypt operation, and they are dropped after decryption. If + * data_length + offset is not a multiple of the decryption block size, the + * extra bytes in the final decryption block (post-padding) are also dropped + * after decryption. The caller is responsible for guaranteeing that all + * memory addresses from (data-addr - pre-padding) to (data-addr + + * data-length + post-padding) are valid memory addresses. + * + * After decrypting the entire buffer including any pre-padding and + * post-padding, send data_length bytes starting at data_addr to the decoder. * * NOTES: * IV points to the counter value to be used for the initial @@ -603,58 +797,33 @@ OEMCryptoResult OEMCrypto_DecryptAudio(const OEMCrypto_UINT8* iv, * zero when it reaches its maximum value (0xFFFFFFFFFFFFFFFF). * The upper 64 bits (byte 0-7) of the IV do not change. * - * Since AES CTR is a stream cipher, the cumulative length of all - * the encrypted chunks in the buffer is not necessarily a - * multiple of the AES block size. In this case any unused bytes - * in the final AES block decryption are discarded. - * A special case exists when an individual encrypted chunk is - * not a multiple of the AES block size. In this case the - * encrypted block is split by an intervening clear chunk. Bytes - * from the next encrypted block in the current buffer must be - * used to complete the current block. - * Consider an input buffer with four chunks as follows: - * chunk 1: clear, 14 bytes, - * chunk 2: encrypted, 20 bytes, - * chunk 3: clear, 19 bytes, - * chunk 4: encrypted, 16 bytes. - * There are three AES blocks that must be decrypted as follows: - * block 1 from chunk 2, bytes 0-15. - * block 2 from chunk 2, bytes 16-19 - * + chunk 4, bytes 0-11. - * block 3 from chunk 4, bytes 12-15 - * + 12 bytes of padding (zeroes). - * The relative positions of each decrypted and clear chunk in the - * output buffer must be preserved. - * * Returns: - * OEMCrypto_SUCCESS success + * OEMCrypto_SUCCESS * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION - * OEMCrypto_UNKNOWN_FAILURE - * OEMCrypto_INVALID_CONTEXT - * OEMCrypto_ERROR_DECRYPT_FAILED failed decryption + * OEMCrypto_ERROR_UNKNOWN_FAILURE + * OEMCrypto_ERROR_INVALID_CONTEXT + * OEMCrypto_ERROR_DECRYPT_FAILED */ -OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session_id, - bool is_video, - const OEMCrypto_UINT8 *buffer_addr, - OEMCrypto_UINT32 buffer_length, - bool is_encrypted, - const OEMCrypto_UINT8 *key_id, - OEMCrypto_UINT32 key_id_length, - const OEMCrypto_UINT8 *iv, - OEMCrypto_UINT32 offset, - OEMCrypto_UINT32 data_length); +OEMCryptoResult +OEMCrypto_DecryptCTR(OEMCrypto_SESSION session_id, + const OEMCrypto_UINT8 *data_addr, + OEMCrypto_UINT32 data_length, + bool is_encrypted, + const OEMCrypto_UINT8 *iv, + OEMCrypto_UINT32 offset, + const OEMCrypto_DestBufferDesc* out_buffer); /* * OEMCrypto_InstallKeybox * * Description: * Unwrap and store the keybox to persistent memory. - * The device key must be stored securely. The device key will be decrypted and - * latched into hardware key ladder by OEMCrypto_SetEntitlementKey. + * The device key must be stored securely. The device key will be decrypted + * and latched into hardware key ladder by OEMCrypto_SetEntitlementKey. * - * This function is used once to load the keybox onto the device at provisioning - * time. + * This function is used once to load the keybox onto the device at + * provisioning time. * * Parameters: * keybox (in) - Pointer to clear keybox data. Must have been originally @@ -703,7 +872,7 @@ OEMCryptoResult OEMCrypto_IsKeyboxValid(void); * * Returns: * OEMCrypto_SUCCESS success - * OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return the device ID + * OEMCrypto_ERROR_SHORT_BUFFER buffer is too small to return the device ID * OEMCrypto_ERROR_NO_DEVICEID failed to return Device Id */ OEMCryptoResult OEMCrypto_GetDeviceID(OEMCrypto_UINT8* deviceID, @@ -713,8 +882,8 @@ OEMCryptoResult OEMCrypto_GetDeviceID(OEMCrypto_UINT8* deviceID, * OEMCrypto_GetKeyData * * Description: - * Returns the Key Data field from the Keybox. The Key Data field does not need to be - * encrypted by an OEM root key, but may be if desired. + * Returns the Key Data field from the Keybox. The Key Data field does not + * need to be encrypted by an OEM root key, but may be if desired. * * If the Key Data field was encrypted with an OEM root key when the Keybox * was stored on the device, then this function should decrypt it and return @@ -722,13 +891,14 @@ OEMCryptoResult OEMCrypto_GetDeviceID(OEMCrypto_UINT8* deviceID, * should just access and return the clear Key data. * * Parameters: - * keyData (out) - pointer to the buffer to hold the Key Data field from the Keybox - * dataLength (in/out) - on input, the allocated buffer size. On output, the number - * of bytes in KeyData. + * keyData (out) - pointer to a caller-managed buffer to hold the Key Data + * field from the Keybox + * dataLength (in/out) - on input, the allocated buffer size. On output, + * the number of bytes in KeyData. * * Returns: * OEMCrypto_SUCCESS success - * OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return the KeyData + * OEMCrypto_ERROR_SHORT_BUFFER the buffer is too small to return the KeyData * OEMCrypto_ERROR_NO_KEYDATA failed to return KeyData */ OEMCryptoResult OEMCrypto_GetKeyData(OEMCrypto_UINT8* keyData, @@ -738,11 +908,12 @@ OEMCryptoResult OEMCrypto_GetKeyData(OEMCrypto_UINT8* keyData, * OEMCrypto_GetRandom * * Description: - * Returns a buffer filled with hardware-generated random bytes. If the hardware - * feature does not exist, returns OEMCrypto_ERROR_RNG_NOT_SUPPORTED. + * Return a buffer filled with hardware-generated random bytes. If the + * hardware feature does not exist, return OEMCrypto_ERROR_RNG_NOT_SUPPORTED. * * Parameters: - * randomData (out) - Points to the buffer that should recieve the random data. + * randomData (out) - Pointer to caller-manager buffer that will receive the + * random data. * dataLength (in) - Length of the random data buffer in bytes. * * Returns: @@ -766,7 +937,8 @@ OEMCryptoResult OEMCrypto_GetRandom(OEMCrypto_UINT8* randomData, * keybox (in) - Pointer to keybox data. * keyboxLength - Length of the Keybox data in bytes * wrappedKeybox (out) - Pointer to wrapped keybox - * wrappedKeyboxLength (out) - Pointer to the length of the wrapped keybox in bytes + * wrappedKeyboxLength (out) - Pointer to the length of the wrapped keybox in + * bytes * transportKey (in) - An optional AES transport key. If provided, the input * keybox is encrypted with this transport key with AES-CBC * and a null IV.