diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index 5b8e1f01..97b75909 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h @@ -131,8 +131,9 @@ typedef struct { * Fields: * [in] input_data: An unaligned pointer to this sample from the stream. * [in] input_data_length: The length of this sample in the stream, in bytes. - * [in] output: A caller-owned descriptor that specifies the handling of the - * decrypted byte stream. See OEMCrypto_DestbufferDesc for details. + * [in] output_descriptor: A caller-owned descriptor that specifies the + * handling of the decrypted byte stream. See OEMCrypto_DestbufferDesc for + * details. * * Version: * This struct changed in API version 16. @@ -599,7 +600,7 @@ OEMCryptoResult OEMCrypto_Terminate(void); * This function shall call ODK_InitializeSessionValues to initialize the * session's clock values, timer values, and nonce values. * ODK_InitializeSessionValues is described in the document "License Duration - * and Renewal", to initialize the sessions clock values. + * and Renewal", to initialize the session's clock values. * * Parameters: * [out] session: an opaque handle that the crypto firmware uses to identify @@ -824,9 +825,9 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( * waits at least one second before requesting more nonces, then OEMCrypto * will reset the error condition and generate valid nonces again. * - * The nonce should be stored in the sessions ODK_NonceValue field by calling - * the function ODK_SetNonceValue(&nonce_values, nonce). The ODK functions - * are documented in "Widevine Core Message Serialization". + * The nonce should be stored in the session's ODK_NonceValue field by + * calling the function ODK_SetNonceValue(&nonce_values, nonce). The ODK + * functions are documented in "Widevine Core Message Serialization". * * This function shall only be called at most once per open session. It shall * only be called before signing either a provisioning request or a license @@ -872,7 +873,7 @@ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, * Message Serialization". * * The message body is the buffer starting at message + core_message_size, - * and with length message_length-core_message_size. The reason OEMCrypto + * and with length message_length - core_message_size. The reason OEMCrypto * only signs the message body and not the entire message is to allow a v16 * device to request a license from a v15 license server. * @@ -882,12 +883,12 @@ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, * * OEMCrypto shall compute a hash of the core license request. The core * license request is the buffer starting at message and with length - * core_message_size. The has will be saved with the session and verified + * core_message_size. The hash will be saved with the session and verified * that it matches a hash in the license response. * * OEMCrypto shall also call the function ODK_InitializeClockValues, * described in the document "License Duration and Renewal", to initialize - * the sessions clock values. + * the session's clock values. * * Refer to the Signing Messages Sent to a Server section above for more * details about the signature algorithm. @@ -897,6 +898,7 @@ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, * signature_length to the size needed to receive the output signature. * * Parameters: + * [in] session: handle for the session to be used. * [in/out] message: Pointer to memory for the entire message. Modified by * OEMCrypto via the ODK library. * [in] message_length: length of the entire message buffer. @@ -960,7 +962,7 @@ OEMCryptoResult OEMCrypto_PrepAndSignLicenseRequest( * If nonce_values.api_major_version is 15, then OEMCrypto shall compute the * signature of the message body using the session's client renewal mac key. * The message body is the buffer starting at message+core_message_size with - * length message_length-core_message_size. If the session has not had a + * length message_length - core_message_size. If the session has not had a * license loaded, it will use the usage entries client mac key to sign the * message body. * @@ -984,6 +986,7 @@ OEMCryptoResult OEMCrypto_PrepAndSignLicenseRequest( * signature_length to the size needed to receive the output signature. * * Parameters: + * [in] session: handle for the session to be used. * [in/out] message: Pointer to memory for the entire message. Modified by * OEMCrypto via the ODK library. * [in] message_length: length of the entire message buffer. @@ -1029,19 +1032,19 @@ OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest( * OEMCrypto_PrepAndSignProvisioningRequest * * Description: - * OEMCrypto will use ODK_PrepareCoreRenewalRequest, as described in the - * document "Widevine Core Message Serialization", to prepare the core + * OEMCrypto will use OEMCrypto_PrepAndSignProvisioningRequest, as described + * in the document "Widevine Core Message Serialization", to prepare the core * message. If it returns an error, the error should be returned by OEMCrypto * to the CDM layer. If it returns OEMCrypto_SUCCESS, then OEMCrypto shall * sign compute the signature of the entire message. The entire message is * the buffer starting at message with length message_length. * * For a device that has a keybox, i.e. Provisioning 2.0, OEMCrypto will sign - * the response with the session's derived client mac key from the previous + * the request with the session's derived client mac key from the previous * call to OEMCrypto_GenerateDerivedKeys. * * For a device that has an OEM Certificate, i.e. Provisioning 3.0, OEMCrypto - * will sign the response with the private key associated with the OEM + * will sign the request with the private key associated with the OEM * Certificate. The key shall have been loaded by a previous call to * OEMCrypto_LoadDRMPrivateKey. * @@ -1053,6 +1056,7 @@ OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest( * signature_length to the size needed to receive the output signature. * * Parameters: + * [in] session: handle for the session to be used. * [in/out] message: Pointer to memory for the entire message. Modified by * OEMCrypto via the ODK library. * [in] message_length: length of the entire message buffer. @@ -1210,18 +1214,18 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length); * OEMCrypto_ERROR_LICENSE_RELOAD. * 3. 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 + * < 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. * 4. 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. + * (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. * 5. Each key's control block, after decryption, shall have a valid * verification field. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. * 6. If any key control block has the Nonce_Enabled bit set, that key's @@ -1459,18 +1463,18 @@ OEMCryptoResult OEMCrypto_LoadKeys( * OEMCrypto_ERROR_LICENSE_RELOAD. * 15. The enc_mac_keys substring must either have zero length, or satisfy * the range check. I.e. (offset < message_length) && (offset + length - * < message_length) && (offset < offset+length),and offset+length does - * not cause an integer overflow. If it does not have zero length, then - * enc_mac_keys_iv must not have zero length, and must also satisfy the - * range check. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. If the - * length is zero, then OEMCrypto may assume that the offset is also + * < message_length) && (offset < offset + length),and offset + length + * does not cause an integer overflow. If it does not have zero length, + * then enc_mac_keys_iv must not have zero length, and must also satisfy + * the range check. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. If + * the length is zero, then OEMCrypto may assume that the offset is also * zero. * 16. The API shall verify that each substring in each KeyObject points to * a location in the message. I.e. (offset < message_length) && - * (offset + length < message_length) && (offset < offset+length) and - * offset+length does not cause an integer overflow, for each of key_id, - * key_data_iv, key_data, key_control_iv, key_control. If not, return - * OEMCrypto_ERROR_INVALID_CONTEXT. + * (offset + length < message_length) && (offset < offset + length) and + * offset + length does not cause an integer overflow, for each of + * key_id, key_data_iv, key_data, key_control_iv, key_control. If not, + * return OEMCrypto_ERROR_INVALID_CONTEXT. * 17. Each key's control block, after decryption, shall have a valid * verification field. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. * 18. If any key control block has the Nonce_Enabled bit set, that key's @@ -2480,8 +2484,9 @@ OEMCryptoResult OEMCrypto_DecryptCENC( * [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_buffer: A caller-owned descriptor that specifies the handling of - * the byte stream. See OEMCrypto_DestbufferDesc for details. + * [in] out_buffer_descriptor: 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 @@ -2995,17 +3000,17 @@ 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 shall match the device id found in the core - * provisioning request message. + * Return a device unique id. For devices with a keybox, retrieve the + * DeviceID from the Keybox. For devices that have an OEM Certificate instead + * of a keybox, 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 shall match the device id found in the core provisioning + * request message. The maximum length of the device id is 64 bytes. The + * device ID field in a keybox is 32 bytes. * * Parameters: - * [out] device_id - pointer to the buffer that receives the Device ID + * [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. * @@ -3601,7 +3606,7 @@ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* max); * with block type 1 padding. * - 0x100 = OEMCrypto_Supports_ECC_secp256r1 - Elliptic Curve secp256r1 * - 0x200 = OEMCrypto_Supports_ECC_secp384r1 - Elliptic Curve secp384r1 - * - 0x200 = OEMCrypto_Supports_ECC_secp521r1 - Elliptic Curve secp521r1 + * - 0x400 = OEMCrypto_Supports_ECC_secp521r1 - Elliptic Curve secp521r1 * * Threading: * This is a "Property Function" and may be called simultaneously with any @@ -3802,7 +3807,8 @@ uint32_t OEMCrypto_GetAnalogOutputFlags(void); * |Minimum Generic crypto buffer |10 KiB |100 KiB |500 KiB |1 MiB | * |size | | | | | * +--------------------------------+---------+----------+---------+---------+ - * |Minimum number of open sessions |10 |20 |30 |40 | + * |Minimum number of concurrent |10 |20 |30 |40 | + * |sessions | | | | | * +--------------------------------+---------+----------+---------+---------+ * |Minimum number of keys per |4 |20 |20 |30 | * |session | | | | | @@ -3928,12 +3934,12 @@ uint32_t OEMCrypto_ResourceRatingTier(void); * [in] core_message_length: length of the core submessage, in bytes. * [in] signature: pointer to memory containing the signature. * [in] signature_length: length of the signature, in bytes. - * [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 + * [out] wrapped_private_key: pointer to buffer in which encrypted RSA or ECC + * private key should be stored. May be null on the first call in order + * to find required buffer size. + * [in/out] wrapped_private_key_length: (in) length of the encrypted private + * key, in bytes. + * (out) actual length of the encrypted private key * * Returns: * OEMCrypto_SUCCESS success @@ -4284,7 +4290,7 @@ OEMCryptoResult OEMCrypto_CreateNewUsageEntry(OEMCrypto_SESSION session, * OEMCrypto_LoadUsageEntry * * Description: - * This loads a usage table saved previously by UpdateUsageEntry. The + * This loads a usage entry saved previously by UpdateUsageEntry. The * signature at the beginning of the buffer is verified and the buffer will * be decrypted. Then the verification field in the entry will be verified. * The index in the entry must match the index passed in. The generation @@ -4477,7 +4483,7 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session, * buffer_length and return OEMCrypto_ERROR_SHORT_BUFFER. * * If an entry was not loaded or created with OEMCrypto_CreateNewUsageEntry - * or OEMCRypto_LoadUsageEntry, or if the pst does not match that in the + * 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 @@ -4489,7 +4495,7 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session, * * The pst_report is filled out by subtracting the times in the Usage Entry * from the current time on the secure clock. This design was chosen to avoid - * the device's secure clock with any external clock. + * a requirement to sync the device's secure clock with any external clock. * * (See drawing in "Widevine Modular DRM Security Integration Guide") * @@ -4857,11 +4863,11 @@ OEMCryptoResult OEMCrypto_GetHashErrorCode(OEMCrypto_SESSION session, * * Description: * Allocates a secure buffer and fills out the destination buffer information - * in output. The integer secure_fd may also be set to indicate the source of - * the buffer. OEMCrypto may use the secure_fd to help track the buffer if it - * wishes. The unit tests will pass a pointer to the same destination buffer - * description and the same secure_fd to OEMCrypto_FreeSecureBuffer when the - * buffer is to be freed. + * in output_descriptor. The integer secure_fd may also be set to indicate + * the source of the buffer. OEMCrypto may use the secure_fd to help track + * the buffer if it wishes. The unit tests will pass a pointer to the same + * destination buffer description and the same secure_fd to + * OEMCrypto_FreeSecureBuffer when the buffer is to be freed. * * This is especially helpful if the hash functions above are supported. This * will only be used by the OEMCrypto unit tests, so we recommend returning @@ -4872,9 +4878,9 @@ OEMCryptoResult OEMCrypto_GetHashErrorCode(OEMCrypto_SESSION session, * Parameters: * [in] session: session id for operation. * [in] buffer_size: the requested buffer size. - * [out] output: the buffer descriptor for the created buffer. This will be - * passed into the OEMCrypto_DecryptCENC function. - * [out] secure_fd: a pointer to platform dependant file or buffer + * [out] output_descriptor: the buffer descriptor for the created buffer. + * This will be passed into the OEMCrypto_DecryptCENC function. + * [out] secure_fd: a pointer to platform dependent file or buffer * descriptor. This will be passed to OEMCrypto_FreeSecureBuffer. * * Returns: @@ -4907,7 +4913,7 @@ OEMCryptoResult OEMCrypto_AllocateSecureBuffer( * * Parameters: * [in] session: session id for operation. - * [out] output: the buffer descriptor modified by + * [out] output_descriptor: the buffer descriptor modified by * OEMCrypto_AllocateSecureBuffer * [in] secure_fd: The integer returned by OEMCrypto_AllocateSecureBuffer * @@ -4941,41 +4947,52 @@ OEMCryptoResult OEMCrypto_GenerateSignature(OEMCrypto_SESSION session, size_t message_length, uint8_t* signature, size_t* signature_length); + OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( OEMCrypto_SESSION session, const uint32_t* unaligned_nonce, const uint8_t* encrypted_message_key, size_t encrypted_message_key_length, const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key, size_t* wrapped_rsa_key_length); + OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, const uint32_t* unaligned_nonce, const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key, size_t* wrapped_rsa_key_length); + OEMCryptoResult OEMCrypto_UpdateUsageTable(void); + OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION, const uint8_t*, size_t, const uint8_t*, size_t, const uint8_t*, size_t); + OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t*, size_t); + OEMCryptoResult OEMCrypto_CopyOldUsageEntry(OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length); + OEMCryptoResult OEMCrypto_DeleteOldUsageTable(void); + 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); + OEMCryptoResult OEMCrypto_GenerateDerivedKeys_V15( OEMCrypto_SESSION session, const uint8_t* mac_key_context, uint32_t mac_key_context_length, const uint8_t* enc_key_context, uint32_t enc_key_context_length); + typedef struct { size_t encrypt; // number of 16 byte blocks to decrypt. size_t skip; // number of 16 byte blocks to leave in clear. size_t offset; // offset into the pattern in blocks for this call. } OEMCrypto_CENCEncryptPatternDesc_V15; + OEMCryptoResult OEMCrypto_DecryptCENC_V15( OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length, bool is_encrypted, const uint8_t* iv, @@ -4983,9 +5000,11 @@ OEMCryptoResult OEMCrypto_DecryptCENC_V15( OEMCrypto_DestBufferDesc* out_buffer_descriptor, const OEMCrypto_CENCEncryptPatternDesc_V15* pattern, uint8_t subsample_flags); + OEMCryptoResult OEMCrypto_GetOEMPublicCertificate_V15( OEMCrypto_SESSION session, uint8_t* public_cert, size_t* public_cert_length); + OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session, const uint8_t* wrapped_rsa_key, size_t wrapped_rsa_key_length); diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.h b/libwvdrmengine/oemcrypto/test/oec_session_util.h index e092fb49..77a3f9ba 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.h +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.h @@ -177,7 +177,6 @@ class RoundTrip { CoreRequest& core_request() { return core_request_; } CoreResponse& core_response() { return core_response_; } ResponseData& response_data() { return response_data_; } - ResponseData& encrypted_response_data() { return encrypted_response_data_; } std::vector& encrypted_response_buffer() { return encrypted_response_; }