OEMCrypto v16.2
Merge from Widevine repo of http://go/wvgerrit/93404 This is the unit tests, reference code, and documentation for OEMCrypto v16.2. Backwards compatibility should work for a v15 OEMCrypto. Some review comments will be addressed in future CLs. Bug: 141247171 Test: Unit tests Test: Media GTS tests on bonito Change-Id: I9d427c07580e180c0a4cfdc4a68f538d351c0ddd
This commit is contained in:
@@ -147,13 +147,22 @@ typedef struct {
|
||||
* OEMCrypto_SubSampleDescription Structure
|
||||
*
|
||||
* Description:
|
||||
* This structure is used as parameters in the OEMCrypto_DecryptCENC function.
|
||||
* This structure is used as parameters in the OEMCrypto_DecryptCENC
|
||||
* function. In the DASH specification, a sample is composed of multiple
|
||||
* samples, and each subsample is composed of two regions. The first region
|
||||
* is clear unprotected data. We also call this clear data or unencrypted
|
||||
* data. Immediately following the clear region is the protected region. The
|
||||
* protected region is encrypted or encrypted with a pattern. The pattern and
|
||||
* number of bytes that are encrypted in the protected region is discussed in
|
||||
* this document when we talk about the function OEMCryptoDecryptCENC. For
|
||||
* historic reasons, this document also calls the protected region the
|
||||
* encrypted region.
|
||||
*
|
||||
* Fields:
|
||||
* [in] num_bytes_clear: The number of clear bytes in this subsample. The
|
||||
* clear bytes come before the encrypted bytes.
|
||||
* [in] num_bytes_encrypted: The number of encrypted bytes in this subsample.
|
||||
* The encrypted bytes come after the clear bytes.
|
||||
* [in] num_bytes_clear: The number of unprotected bytes in this subsample.
|
||||
* The clear bytes come before the encrypted bytes.
|
||||
* [in] num_bytes_encrypted: The number of protected bytes in this subsample.
|
||||
* The protected bytes come after the clear bytes.
|
||||
* [in] subsample_flags: bitwise flags indicating if this is the first,
|
||||
* middle, or last subsample in a sample. 1 = first subsample, 2 = last
|
||||
* subsample, 3 = both first and last subsample, 0 = neither first nor last
|
||||
@@ -231,14 +240,6 @@ typedef enum OEMCryptoCipherMode {
|
||||
OEMCrypto_CipherMode_CBC,
|
||||
} OEMCryptoCipherMode;
|
||||
|
||||
/** OEMCrypto_LicenseType is used in LoadKeys to indicate if the key objects
|
||||
* are for content keys, or for entitlement keys.
|
||||
*/
|
||||
typedef enum OEMCrypto_LicenseType {
|
||||
OEMCrypto_ContentLicense = 0,
|
||||
OEMCrypto_EntitlementLicense = 1
|
||||
} OEMCrypto_LicenseType;
|
||||
|
||||
/*
|
||||
* OEMCrypto_EntitledContentKeyObject
|
||||
* Contains encrypted content key data for loading into the sessions keytable.
|
||||
@@ -358,12 +359,6 @@ typedef enum OEMCrypto_ProvisioningMethod {
|
||||
OEMCrypto_OEMCertificate = 3 // Device has factory installed OEM certificate.
|
||||
} OEMCrypto_ProvisioningMethod;
|
||||
|
||||
/* Private key type used in OEMCrypto_LoadDRMPrivateKey. */
|
||||
typedef enum OEMCrypto_PrivateKeyType {
|
||||
OEMCrypto_RSA_Private_Key,
|
||||
OEMCrypto_ECC_Private_Key,
|
||||
} OEMCrypto_PrivateKeyType;
|
||||
|
||||
/*
|
||||
* Flags indicating public/private key types supported.
|
||||
*/
|
||||
@@ -833,6 +828,11 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
|
||||
* 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
|
||||
* request. If an attempt is made to generate a nonce while in the wrong
|
||||
* state, an error of OEMCrypto_ERROR_INVALID_CONTEXT is returned.
|
||||
*
|
||||
* Parameters:
|
||||
* [in] session: handle for the session to be used.
|
||||
* [out] nonce: pointer to memory to receive the computed nonce.
|
||||
@@ -957,10 +957,12 @@ OEMCryptoResult OEMCrypto_PrepAndSignLicenseRequest(
|
||||
* key. The entire message is the buffer starting at message with length
|
||||
* message_length.
|
||||
*
|
||||
* If nonce_values.api_level is 15, then OEMCrypto shall compute the
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
* This function generates a HMAC-SHA256 signature using the mac_key[client]
|
||||
* for license request signing under the license server protocol for CENC.
|
||||
@@ -1162,7 +1164,8 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length);
|
||||
* The mac_key and encrypt_key were generated and stored by the previous call
|
||||
* to OEMCrypto_GenerateDerivedKeys() or
|
||||
* OEMCrypto_DeriveKeysFromSessionKey(). The nonce was generated and stored
|
||||
* by the previous call to OEMCrypto_GenerateNonce().
|
||||
* in the session's nonce_values by the previous call to
|
||||
* OEMCrypto_GenerateNonce().
|
||||
*
|
||||
* This session's elapsed time clock is started at 0. The clock will be used
|
||||
* in OEMCrypto_DecryptCENC().
|
||||
@@ -1492,10 +1495,13 @@ OEMCryptoResult OEMCrypto_LoadKeys(
|
||||
* OEMCrypto_ERROR_LICENSE_INACTIVE is returned.
|
||||
* 24. The data in enc_mac_keys_iv is not identical to the 16 bytes before
|
||||
* enc_mac_keys. If it is, return OEMCrypto_ERROR_INVALID_CONTEXT.
|
||||
*
|
||||
* Usage Table and Provider Session Token (pst)
|
||||
* The function ODK_ParseLicense takes several parameters that may need more
|
||||
* explanation.
|
||||
* The parameter usage_entry_present shall be set to true if a usage entry
|
||||
* was created or loaded for this session. This parameter is passed into
|
||||
* ODK_ParseLicense and used for usage entry verification.
|
||||
* was created or loaded for this session. This parameter is used by
|
||||
* ODK_ParseLicense for usage entry verification.
|
||||
* The parameter initial_license_load shall be false if the usage entry was
|
||||
* loaded. If there is no usage entry or if the usage entry was created with
|
||||
* OEMCrypto_CreateNewUsageEntry, then initial_license_load shall be true.
|
||||
@@ -1712,6 +1718,29 @@ OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
|
||||
* signature verification shall use a constant-time algorithm (a signature
|
||||
* mismatch will always take the same time as a successful comparison).
|
||||
*
|
||||
* The key control from the first OEMCrypto_KeyRefreshObject in the key_array
|
||||
* shall be extracted. If it is encrypted, as described below, it shall be
|
||||
* decrypted. The duration from the key control shall be extracted and
|
||||
* converted to host byte order. This duration shall be passed to the
|
||||
* function ODK_RefreshV15Values as the parameter new_key_duration.
|
||||
*
|
||||
* If the KeyRefreshObject's key_control_iv has zero length, then the
|
||||
* key_control is not encrypted. If the key_control_iv is specified, then
|
||||
* key_control is encrypted with the first 128 bits of the corresponding
|
||||
* content key.
|
||||
*
|
||||
* If the KeyRefreshObject's key_id has zero length, then it is an error for
|
||||
* the key_control_iv to have nonzero length. OEMCrypto shall return an error
|
||||
* of OEMCrypto_ERROR_INVALID_CONTEXT.
|
||||
*
|
||||
* If the session's license_type is OEMCrypto_ContentLicense, and the
|
||||
* KeyRefreshObject's key_id is not null, then the entry in the keytable with
|
||||
* the matching content_key_id is used.
|
||||
*
|
||||
* If the session's license_type is OEMCrypto_EntitlementLicense, and the
|
||||
* KeyRefreshObject's key_id is not null, then the entry in the keytable with
|
||||
* the matching entitlment_key_id is used.
|
||||
*
|
||||
* The function ODK_RefreshV15Values shall be called to update the clock
|
||||
* values. See the document "Widevine Core Message Serialization" for the
|
||||
* documentation of the ODK library functions.
|
||||
@@ -1782,19 +1811,14 @@ OEMCryptoResult OEMCrypto_RefreshKeys(
|
||||
* Updates the clock values and resets the renewal timer for the current
|
||||
* session.
|
||||
*
|
||||
* OEMCrypto shall verify the signature of the message using the session's
|
||||
* renewal mac key for the server. If the signature does not match, OEMCrypto
|
||||
* returns OEMCrypto_ERROR_SIGNATURE_FAILURE.
|
||||
* OEMCrypto shall verify the signature of the entire message using the
|
||||
* session's renewal mac key for the server. The entire message is the buffer
|
||||
* starting at message with length message_length. If the signature does not
|
||||
* match, OEMCrypto returns OEMCrypto_ERROR_SIGNATURE_FAILURE.
|
||||
*
|
||||
* If nonce_values.api_level is 16, then OEMCrypto shall verify the signature
|
||||
* of the entire message using the session's server renewal mac key. The
|
||||
* entire message is the buffer starting at message with length
|
||||
* message_length.
|
||||
*
|
||||
* If nonce_values.api_level is 15, then OEMCrypto shall compute the
|
||||
* signature of the message body using the session's server renewal mac key.
|
||||
* The entire message is the buffer starting at message+core_message_size
|
||||
* with length message_length-core_message_size.
|
||||
* OEMCrypto shall verify that nonce_values.api_major_version is 16. If not,
|
||||
* return the error OEMCrypto_ERROR_INVALID_CONTEXT. Legacy licenses will use
|
||||
* the function OEMCrypto_RefreshKeys instead of OEMCrypto_LoadRenewal.
|
||||
*
|
||||
* If the signature passes, OEMCrypto shall use the function
|
||||
* ODK_ParseRenewal, as described in the document "Widevine Core Message
|
||||
@@ -2178,51 +2202,34 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
|
||||
* The 'cbcs' scheme is OEMCrypto_CipherMode_CBC with an encryption pattern.
|
||||
* Only some of the bytes in the encrypted portion of each subsample are
|
||||
* encrypted. In the pattern parameter, the encrypt and skip fields will
|
||||
* usually be non-zero. This mode allows devices to decrypt FMP4 HLS content
|
||||
* and SAMPLE-AES HLS content.
|
||||
* usually be non-zero. This mode allows devices to decrypt FMP4 HLS content,
|
||||
* SAMPLE-AES HLS content, as well as content using the DASH 'cbcs' scheme.
|
||||
*
|
||||
* The skip field of OEMCrypto_CENCEncryptPatternDesc may also be zero. If
|
||||
* the skip field is zero, then patterns are not in use and all crypto blocks
|
||||
* in the encrypted subsample are encrypted. It is not valid for the encrypt
|
||||
* field to be zero.
|
||||
* in the encrypted part of the subsample are encrypted. It is not valid for
|
||||
* the encrypt field to be zero.
|
||||
*
|
||||
* The length of a crypto block in AES-128 is 16 bytes. In the 'cbcs' scheme,
|
||||
* if an encrypted subsample has a length that is not a multiple of 16 bytes,
|
||||
* then the final bytes that do not make up a full crypto block should be
|
||||
* treated as clear and should not be decrypted. The following diagram
|
||||
* provides an example:
|
||||
* if the encrypted part of a subsample has a length that is not a multiple
|
||||
* of 16 bytes, then the final bytes that do not make up a full crypto block
|
||||
* are clear and should never be decrypted. The following diagram provides an
|
||||
* example:
|
||||
*
|
||||
* (See drawing in "Widevine Modular DRM Security Integration Guide")
|
||||
*
|
||||
* Whether any given protected block is actually encrypted also depends on
|
||||
* the pattern. But the bytes at the end that do not make up a full crypto
|
||||
* block will never be encrypted, regardless of what the pattern is. Even if
|
||||
* the pattern says to decrypt every protected block, these bytes are clear
|
||||
* and should not be decrypted.
|
||||
*
|
||||
* Of course, if the encrypted subsample has a length that is a multiple of
|
||||
* 16 bytes, the final bytes should be decrypted. The following diagram
|
||||
* provides an example:
|
||||
* 16 bytes, all the bytes in it are protected, and they may need to be
|
||||
* decrypted following the pattern. The following diagram provides an example:
|
||||
*
|
||||
* (See drawing in "Widevine Modular DRM Security Integration Guide")
|
||||
*
|
||||
* If the encrypted subsample has a length that is not an even multiple of
|
||||
* the pattern length, then there may also be extra clear blocks at the end.
|
||||
*
|
||||
* If there are not enough bytes at the end of the encrypted subsample to
|
||||
* complete an iteration of the encrypted part of the pattern, even if there
|
||||
* are enough bytes to make a full crypto block, then the final bytes that do
|
||||
* not fill the encrypted part of the pattern should be treated as clear and
|
||||
* should not be decrypted. The following diagram provides an example:
|
||||
*
|
||||
* (See drawing in "Widevine Modular DRM Security Integration Guide")
|
||||
*
|
||||
* If there are enough bytes at the end of the encrypted subsample to
|
||||
* complete an iteration of the encrypted part of the pattern, even if there
|
||||
* are not enough bytes to complete the clear part of the pattern, then the
|
||||
* bytes that fill the encrypted part of the pattern should be treated as
|
||||
* encrypted. The following diagram provides an example:
|
||||
*
|
||||
* (See drawing in "Widevine Modular DRM Security Integration Guide")
|
||||
*
|
||||
* This behavior is specified by the ISO-CENC standard. Refer to the ISO-CENC
|
||||
* standard, section 9.6, for full details of how patterns are to be applied
|
||||
* to content.
|
||||
*
|
||||
* INITIALIZATION VECTOR BETWEEN SUBSAMPLES:
|
||||
*
|
||||
* The IV is specified for the initial subsample in a sample in the iv field
|
||||
@@ -2491,7 +2498,6 @@ OEMCryptoResult OEMCrypto_DecryptCENC(
|
||||
* OEMCrypto_ERROR_SYSTEM_INVALIDATED
|
||||
*
|
||||
* Buffer Sizes:
|
||||
|
||||
* OEMCrypto shall support subsample sizes and total input buffer sizes as
|
||||
* specified by its resource rating tier.
|
||||
* OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is
|
||||
@@ -3235,7 +3241,7 @@ uint32_t OEMCrypto_APIVersion(void);
|
||||
* number allows the calling application to avoid version mis-match errors,
|
||||
* because this API is part of a shared library.
|
||||
*
|
||||
* The minor version specified in this document is 1. Any OEM that returns
|
||||
* The minor version specified in this document is 2. Any OEM that returns
|
||||
* this version number guarantees it passes all unit tests associated with
|
||||
* this version.
|
||||
*
|
||||
@@ -3762,13 +3768,6 @@ uint32_t OEMCrypto_GetAnalogOutputFlags(void);
|
||||
* sessions with 4 keys each (80 total), but it does not need to support 20
|
||||
* sessions with 20 keys each.
|
||||
*
|
||||
* Living room devices refer to devices such as TVs, set top boxes, game
|
||||
* consoles, blu-ray players etc. These devices tend to have reduced UI and
|
||||
* frequently are dedicated to playing video. For these devices, we expect
|
||||
* there to be more memory dedicated to video playback and video
|
||||
* applications. The number of sessions required for living room devices is
|
||||
* larger than for mobile devices.
|
||||
*
|
||||
* The message size that is needed for a license with a large number of keys
|
||||
* is larger than in previous versions. The message size limit applies to all
|
||||
* functions that sign or verify messages. It also applies to the size of
|
||||
@@ -3780,11 +3779,14 @@ uint32_t OEMCrypto_GetAnalogOutputFlags(void);
|
||||
* should also support a higher frame rate. Platforms may enforce these
|
||||
* values. For example Android will enforce a frame rate via a GTS test.
|
||||
*
|
||||
* Note on units: We will use KiB to mean 1024 bytes and MiB to mean 1024 KiB,
|
||||
* as described at https://en.wikipedia.org/wiki/Kibibyte.
|
||||
*
|
||||
* +--------------------------------+---------+----------+---------+---------+
|
||||
* |Resource Rating Tier |1 - Low |2 - Medium|3 - High |4 - Very |
|
||||
* | | | | | High |
|
||||
* +--------------------------------+---------+----------+---------+---------+
|
||||
* |Minimum Sample size |1 MB |2 MB |4 MB |16 MB |
|
||||
* |Minimum Sample size |1 MiB |2 MiB |4 MiB |16 MiB |
|
||||
* +--------------------------------+---------+----------+---------+---------+
|
||||
* |Minimum Number of Subsamples |10 |16 |32 |64 |
|
||||
* | (H264 or HEVC) | | | | |
|
||||
@@ -3795,16 +3797,12 @@ uint32_t OEMCrypto_GetAnalogOutputFlags(void);
|
||||
* |Minimum Number of Subsamples |72 |144 |288 |576 |
|
||||
* |(AV1) | | | | |
|
||||
* +--------------------------------+---------+----------+---------+---------+
|
||||
* |Minimum subsample buffer size |100 KB |500 KB |1 MB |4 MB |
|
||||
* |Minimum subsample buffer size |100 KiB |500 KiB |1 MiB |4 MiB |
|
||||
* +--------------------------------+---------+----------+---------+---------+
|
||||
* |Minimum Generic crypto buffer |10 KB |100 KB |500 KB |1 MB |
|
||||
* |Minimum Generic crypto buffer |10 KiB |100 KiB |500 KiB |1 MiB |
|
||||
* |size | | | | |
|
||||
* +--------------------------------+---------+----------+---------+---------+
|
||||
* |Minimum number of open sessions |10 |20 |20 |30 |
|
||||
* |(mobile devices) | | | | |
|
||||
* +--------------------------------+---------+----------+---------+---------+
|
||||
* |Minimum number of open sessions |10 |100 |100 |100 |
|
||||
* |(living room devices) | | | | |
|
||||
* |Minimum number of open sessions |10 |20 |30 |40 |
|
||||
* +--------------------------------+---------+----------+---------+---------+
|
||||
* |Minimum number of keys per |4 |20 |20 |30 |
|
||||
* |session | | | | |
|
||||
@@ -4304,6 +4302,11 @@ OEMCryptoResult OEMCrypto_CreateNewUsageEntry(OEMCrypto_SESSION session,
|
||||
* usage entry associated with it, the error
|
||||
* OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES is returned.
|
||||
*
|
||||
* Before version API 16, the usage entry stored the time that the license
|
||||
* was loaded. This value is now interpreted as the time that the licence
|
||||
* request was signed. This can be achieved by simply renaming the field and
|
||||
* using the same value when reloading an older entry.
|
||||
*
|
||||
* Parameters:
|
||||
* [in] session: handle for the session to be used.
|
||||
* [in] usage_entry_number: index of existing usage entry.
|
||||
@@ -4522,6 +4525,10 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session,
|
||||
* HMAC SHA1 signature is used to prevent a rogue application from using
|
||||
* OMECrypto_GenerateSignature to forge a Usage Report.
|
||||
*
|
||||
* Before version 16 of this API, seconds_since_license_received was reported
|
||||
* instead of seconds_since_license_signed. For any practical bookkeeping
|
||||
* purposes, these events are essentially at the same time.
|
||||
*
|
||||
* Devices that do not implement a Session Usage Table may return
|
||||
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
|
||||
*
|
||||
@@ -4985,7 +4992,6 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user