Address review comments

Merge from Widevine repo of http://go/wvgerrit/96163

This CL just addresses some review comments from the big merge to
master. The header OEMCryptoCENC.h is now synced with the
document http://go/oemcrypto.

Test: unit tests
Bug: 148907684
Change-Id: Ic825126e0dd3d7e86eefab2c51b4abb5d57fb568
This commit is contained in:
Fred Gylys-Colwell
2020-03-19 17:58:49 -07:00
parent 88934aa322
commit 80b0005d44
2 changed files with 82 additions and 64 deletions

View File

@@ -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);

View File

@@ -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<uint8_t>& encrypted_response_buffer() {
return encrypted_response_;
}