/********************************************************************* * MockOEMCrypto.cpp * * (c) Copyright 2011-2012 Google, Inc. * * Mock implementation of OEMCryptoDASH.h used for testing. *********************************************************************/ #include #include #define LOG_TAG "WV.MockOEMCrypto" #include #include "OEMCryptoDASH.h" #include "MockOEMCrypto.h" void initializeMockOEMCrypto() { ALOGD("initializeMockOEMCrypto()\n"); } /* * OEMCrypto_Initialize * * Description: * Initialize the crypto firmware/hardware. * * Parameters: * N/A * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INIT_FAILED failed to initialize crypto hardware */ OEMCryptoResult OEMCrypto_Initialize(void) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_Terminate * * Description: * The API closes the crypto operation and releases all resources used. * * Parameters: * N/A * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_TERMINATE_FAILED failed to de-initialize crypto hardware */ OEMCryptoResult OEMCrypto_Terminate(void) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_OpenSession * * AES CTR Mode only, Levels 1 and 2 only * * Description: * The API provides for session based crypto initialization for AES CTR mode. * * Parameters: * session (out) - pointer to crypto session identifier. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_OPEN_SESSION_FAILED failed to initialize the crypto session */ OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION *session) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_CloseSession * * AES CTR Mode only, Levels 1 and 2 only * * Description: * The API provides for session based crypto termination for AES CTR mode. * * Parameters: * session (in) - crypto session identifier. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_CLOSE_SESSION_FAILED failed to terminate the crypto session */ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_GenerateDerivedKeys * * AES CTR Mode only, Levels 1 and 2 only * * 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 * for AES CTR mode. * * Refer to document OEMCrypto Changes for V2 License Protocol for details * * Parameters: * session (in) - crypto session identifier. * context (in) - pointer to memory containing context data for computing the * secondary keys. * context_length (in) - length of the context data. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_UNKNOWN_FAILURE * OEMCrypto_INVALID_CONTEXT */ OEMCryptoResult OEMCrypto_GenerateDerivedKeys( OEMCrypto_SESSION session, const uint8_t *context, size_t context_length) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_GenerateSignature * * AES CTR Mode only, Levels 1 and 2 only * * Description: * Generates a HMAC-SHA256 signature for license request signing under the V2 * 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. * * 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. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_UNKNOWN_FAILURE * OEMCrypto_INVALID_CONTEXT */ OEMCryptoResult OEMCrypto_GenerateSignature( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, uint8_t* signature, size_t* signature_length) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_LoadKeys * * AES CTR Mode only, Levels 1 and 2 only * * Description: * Installs a set of keys for performing decryption in the current session. * * NOTE: OEMCrypto_GenerateDerivedKeys() must be called first to establish the * mac_key * * 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 (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. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_UNKNOWN_FAILURE * OEMCrypto_INVALID_CONTEXT */ OEMCryptoResult OEMCrypto_LoadKeys( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, size_t enc_mac_key_iv_offset, size_t enc_mac_key_offset, size_t num_keys, const OEMCrypto_KeyObject* key_array) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_RefreshKeys * * AES CTR Mode only, Levels 1 and 2 only * * Description: * Updates an existing set of keys for continuing decryption in the * current session. * * NOTE: OEMCrypto_GenerateDerivedKeys() must be called first to establish * the mac_key * * 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 signature. * num_keys - number of keys present. * key_array - 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 */ OEMCryptoResult OEMCrypto_RefreshKeys( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, size_t num_keys, const OEMCrypto_KeyRefreshObject* key_array) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_EnterSecurePlayback * * Level 1 only * * Description: * Configures the security processor for secure decryption. This may involve * setting up firewall regions. It is called when the decrypt session for an * asset is established. * * For Non-Level1 API, return OEMCrypto_ERROR_NOT_IMPLEMENTED * * Parameters: * N/A * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED */ OEMCryptoResult OEMCrypto_EnterSecurePlayback(void) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_ExitSecurePlayback * * Level 1 only * * 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. * * For Non-Level1 API, return OEMCrypto_ERROR_NOT_IMPLEMENTED * * Parameters: * N/A * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED */ OEMCryptoResult OEMCrypto_ExitSecurePlayback(void) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_SetEntitlementKey * * AES CTS Mode only, Levels 1 and 2 only * * Description: * Decrypt the entitlement (EMM) key, also known as the asset key, * using the encrypted device key (Device Key field) in the Widevine Keybox. * * Step 1: use the OEM root key to decrypt (AES-128-ECB) the Device Key * in the Keybox; latch the result in the hardware key ladder. * * Step 2: use the latched clear device key to decrypt (AES-128-ECB) * the entitlement key passed in as the *emmKey parameter. Latch * the resulting clear entitlement key in the key ladder for the * next operation. * * Parameters: * emmKey (in) - pointer to the encrypted entitlement key * emmKeyLength (in) - length of entitlement key in bytes * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_DEVICE_KEY failed to decrypt device key * OEMCrypto_ERROR_NO_ASSET_KEY failed to decrypt asset key * OEMCrypto_ERROR_KEYBOX_INVALID cannot decrypt and read from Keybox */ OEMCryptoResult OEMCrypto_SetEntitlementKey(const uint8_t* emmKey, const size_t emmKeyLength) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_DeriveControlWord * * 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. * * Parameters: * ecm (in) - points to encrypted ECM data * length (in) - length of encrypted ECM data in bytes * flags (out) - points to buffer to receive 4 byte clear flag value * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_NO_CW cannot decrypt control word */ OEMCryptoResult OEMCrypto_DeriveControlWord(const uint8_t* ecm, const size_t length, uint32_t* flags) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_SetContentKey * * AES CTR Mode only, Levels 1 and 2 only * * For CDM implementations, this call is replaced by OEMCrypto_Loadkeys() * and OEMCrypto_RefreshKeys() * * Description: * Place a new content key in the hardware key ladder for subsequent * decryption operations. Also accept control data and apply it to * configure the session. * * This operation is supported only while performing CTR mode decryption * (see OEMCrypto_DecryptCTR). * * Control data is associated with the session and the key, and is used * to configure the session context. If no control data is required, * controlLength will be zero, and control should be ignored. * * Currently, no control data is defined. ControlLength will be zero. * If controlLength is not zero, return OEMCrypto_ERROR_CONTROL_INVALID. * * Step 1: use the OEM root key to decrypt (AES-128-ECB) the Device Key * in the Widevine Keybox; latch the result in the hardware key * ladder. * * Step 2: use the latched clear device key to decrypt (AES-128-ECB) * the control parameter data. Verify the control data and apply * it to the current session. * * Step 2: use the latched clear device key to decrypt (AES-128-ECB) * the content key passed in as the *contentKey parameter. * Latch the resulting clear content key in the key ladder for * the next operation. * * Parameters: * session (in) - crypto session identifier * contentKey (in) - pointer to the encrypted content key * contentKeyLength (in) - length of content key in bytes * control (in) - pointer to server-supplied control information * controlLength (in) - length of control memory (bytes) * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_INVALID_SESSION crypto session ID invalid or session 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_SetContentKey(const OEMCrypto_SESSION session, const uint8_t* contentKey, const size_t contentKeyLength, const uint8_t* control, const size_t controlLength) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_DecryptVideo * * AES CTS Mode only, Levels 1 and 2 only * * Description: * * The API decrypts (AES-128-CBC) the video payload in the buffer referenced by * the *input parameter into the 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). * * 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. * 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 * outputLength (out) - number of bytes written into the secure buffer * * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_DECRYPT_FAILED failed decryption */ OEMCryptoResult OEMCrypto_DecryptVideo(const uint8_t* iv, const uint8_t* input, const size_t inputLength, uint32_t output_handle, size_t output_offset, size_t *outputLength) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_DecryptAudio * * 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 * 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. * * 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. * 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 * outputLength (out) - number of bytes written into the non-secure buffer * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_DECRYPT_FAILED failed decryption */ OEMCryptoResult OEMCrypto_DecryptAudio(const uint8_t* iv, const uint8_t* input, const size_t inputLength, uint8_t *output, size_t *outputLength) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_DecryptCTR * * AES CTR Mode only, Levels 1 and 2 only * * Description: * * The API decrypts (AES-CTR) the payload in the buffer referenced by * the buffer_addr parameter into an internal buffer, using the key * identified by key_id. * * 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. * 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. * * NOTES: * IV points to the counter value to be used for the initial * encrypted block of the input buffer. The IV length is the AES * block size. For subsequent encrypted AES blocks the IV is * calculated by incrementing the lower 64 bits (byte 8-15) of the * IV value used for the previous block. The counter rolls over to * zero when it reaches its maximum value (0xFFFFFFFFFFFFFFFF). * The upper 64 bits (byte 0-7) of the IV do not change. * * 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_ERROR_NO_DEVICE_KEY * OEMCrypto_ERROR_INVALID_SESSION * OEMCrypto_UNKNOWN_FAILURE * OEMCrypto_INVALID_CONTEXT * OEMCrypto_ERROR_DECRYPT_FAILED failed decryption */ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session_id, bool is_video, const uint8_t *buffer_addr, size_t buffer_length, bool is_encrypted, const uint8_t *key_id, size_t key_id_length, const uint8_t *iv, size_t offset, size_t data_length) { return OEMCrypto_SUCCESS; } /* * 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. * * 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 * wrapped with OEMCrypto_WrapKeybox. * keyboxLength (in) - Length of the keybox data in bytes. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_WRITE_KEYBOX failed to handle and store Keybox */ OEMCryptoResult OEMCrypto_InstallKeybox(uint8_t *keybox, size_t keyBoxLength) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_IsKeyboxValid * * Description: * Validate the Widevine Keybox stored on the device. * * The API performs two verification steps on the Keybox. It first verifies * the MAGIC field contains a valid signature (must be 'kbox'). The API then * computes the CRC using CRC-32 (Posix 1003.2 standard) and compares the * checksum to the CRC stored in the Keybox. The CRC is computed over the * entire Keybox excluding the 4 CRC bytes (i.e. Keybox[0..123]). * * Parameters: * none * * Returns: * OEMCrypto_SUCCESS * OEMCrypto_ERROR_BAD_MAGIC * OEMCrypto_ERROR_BAD_CRC */ OEMCryptoResult OEMCrypto_IsKeyboxValid(void) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_GetDeviceID * * Description: * Retrieve the device's unique identifier from the Keybox. * * Parameters: * deviceId (out) - pointer to the buffer that receives the Device ID * idLength (in/out) - on input, size of the caller's device ID buffer. * On output, the number of bytes written into the buffer. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return the device ID * OEMCrypto_ERROR_NO_DEVICEID failed to return Device Id */ OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t *idLength) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_GetKeyData * * Description: * Returns the Key Data field from the Keybox. The Key Data field does not need to be * encrypted by an OEM root key, but may be if desired. * * If the Key Data field was encrypted with an OEM root key when the Keybox * was stored on the device, then this function should decrypt it and return * the clear Key Data. If the Key Data was not encrypted, then this function * should just access and return the clear Key data. * * Parameters: * keyData (out) - pointer to 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. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return the KeyData * OEMCrypto_ERROR_NO_KEYDATA failed to return KeyData */ OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t *keyDataLength) { return OEMCrypto_SUCCESS; } /* * 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. * * Parameters: * randomData (out) - Points to the buffer that should recieve the random data. * dataLength (in) - 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 */ OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, size_t dataLength) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_WrapKeybox * * Description: * Wrap the Keybox with a key derived for the device key. If transportKey * is not NULL, the input keybox is encrypted with transportKey. If so, * decrypt the input keybox before wrapping it, using transportKey in AES-CBC * mode with an IV of all zeroes. * * Parameters: * 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 * 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. * transportKeyLength - number of bytes in the transportKey * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_WRAP_KEYBOX failed to wrap Keybox */ OEMCryptoResult OEMCrypto_WrapKeybox(uint8_t *keybox, size_t keyBoxLength, uint8_t *wrappedKeybox, size_t *wrappedKeyBoxLength, uint8_t *transportKey, size_t transportKeyLength) { return OEMCrypto_SUCCESS; } /* * OEMCrypto_DecryptCTS * * AES CTS Mode only, Level 2 only * * Description: * Decrypt the contents of the supplied buffer. * * This entry point is provided for compatibility with existing Level 2 * implementations. * * Parameters: * pSrcBuf (in) - Pointer to buffer of encrypted data * pDestBuf (in) - Pointer to buffer to receive decrypted data * length (in) - Length of the input/output buffers * bInitIvFlg (in) - Set to true to indicate that a new IV (all zeroes) * should be used. If false, the IV result from the * previous decryption should be use. * * Returns: * OEMCrypto_SUCCESS success * OEMCrypto_ERROR_DECRYPT_FAILED, */ OEMCryptoResult OEMCrypto_DecryptCTS(uint8_t *pSrcBuf, uint8_t *pDestBuf, const size_t length, const uint8_t bInitIvFlg) { return OEMCrypto_SUCCESS; }