OEMCrypto v15.1 Updates

This CL updates documentation, reference code, and unit tests to match
the OEMCrypto v15.1 API.

1. The design for the Full Decrypt Path Testing application has
changed. Instead of reading hashes from an external file, it will use
a single key frame and modify it to match the desired size.  The test
application will then compute the hash and encrypt the frame.  For
OEMCrypto, this means that there will not be a call to
OEMCrypto_InitializeDecryptHash before the frame and
OEMCrypto_SetDecryptHash after the frame. Instead, there will be a
single call to OEMCrypto_SetDecryptHash before the frame. The function
OEMCrypto_InitializeDecryptHash will not be used.

2. The "Shared License" feature is not used by any production
server. This functionality is no longer required and OEMCrypto may
reject licenses with a nonzero bit 23 in the key control block.
This commit is contained in:
Fred Gylys-Colwell
2019-01-04 12:00:00 -08:00
parent 4b95763c6a
commit e7d6da8d24
34 changed files with 1130 additions and 898 deletions

View File

@@ -1013,7 +1013,9 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_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.
* range check. If not, return OEMCrypto_ERROR_INVALID_CONTEXT. If the
* length is zero, then OEMCrypto may assume that the offset is also
* zero.
* 3. 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
@@ -1625,6 +1627,10 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session,
* 6. If the current session has an entry in the Usage Table, and the
* status of that entry is either kInactiveUsed or kInactiveUnused, then
* return the error OEMCrypto_ERROR_LICENSE_INACTIVE.
* 7. If an Decrypt Hash has been initialized via OEMCrypto_SetDecryptHash,
* and the current key's control block does not have the
* Allow_Hash_Verification bit set, then do not compute a hash and
* return OEMCrypto_ERROR_UNKNOWN_FAILURE.
* If the flag is_encrypted is false, then no verification is performed. This
* call shall copy clear data even when there are no keys loaded, or there is
* no selected key.
@@ -2250,6 +2256,9 @@ OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void);
* should be stable -- i.e. it should not change across a device reboot or a
* system upgrade.
*
* This function is optional but recommended for Provisioning 3.0 in API v15.
* It may be required for future version of this API.
*
* Parameters:
* [out] deviceId - pointer to the buffer that receives the Device ID
* [in/out] idLength on input, size of the caller's device ID buffer. On
@@ -2259,8 +2268,7 @@ OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void);
* OEMCrypto_SUCCESS success
* OEMCrypto_ERROR_SHORT_BUFFER if the buffer is too small to return device ID
* OEMCrypto_ERROR_NO_DEVICEID failed to return Device Id
* OEMCrypto_ERROR_NOT_IMPLEMENTED - this function is required for
* Provisioning 2.0 only.
* OEMCrypto_ERROR_NOT_IMPLEMENTED
* OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* Threading:
@@ -2856,9 +2864,8 @@ uint32_t OEMCrypto_GetAnalogOutputFlags();
* Description:
* This function returns a positive number indicating which resource rating
* it supports. This value will bubble up to the application level as a
* property in much the same way security level does. This will allow
* applications to estimate what resolution and bandwidth the device expects
* to support.
* property. This will allow applications to estimate what resolution and
* bandwidth the device expects to support.
*
* OEMCrypto unit tests and Android GTS tests will verify that devices do
* support the resource values specified in the table below at the tier
@@ -2881,7 +2888,7 @@ uint32_t OEMCrypto_GetAnalogOutputFlags();
* will break the sample into subsamples of size "Decrypt Buffer Size" as
* specified in the table below. The "Decrypt Buffer Size" means the size of
* one subsample that may be passed into DecryptCENC or CopyBuffer without
* returning error OEMCrypto_ERROR_BUFFER_TOO_LARGE.
* returning error OEMCrypto_ERROR_BUFFER_TOO_LARGE.
*
* The number of keys per session is an indication of how many different
* track types there can be for a piece of content. Typically, content will
@@ -2903,17 +2910,25 @@ uint32_t OEMCrypto_GetAnalogOutputFlags();
* should also support a higher frame rate. Platforms may enforce these
* values. For example Android will enforce a frame rate via a GTS test.
*
* <see table in document>
* | Resource Rating Tier | 1 - Low | 2 - Medium | 3 - High |
* | Sample size | 1 MB | 2 MB | 4 MB |
* | Number of Subsamples| 8 | 16 | 32 |
* | Decrypt buffer size | 100 KB | 500 KB | 1 MB |
* | Generic crypto buffer size | 10 KB | 100 KB | 500 KB |
* | Number of concurrent sessions | 10 | 20 | 20 |
* | Number of keys per session | 4 | 20 | 20 |
* | Simultaneous secure playback | 1 | 2 | 2 |
* | Decrypted Frames per Second | 30 fps SD | 30 fps HD | 60 fps HD |
* <end of table>
* +-----------------------------------+-----------+------------+-----------+
* |Resource Rating Tier |1 - Low |2 - Medium |3 - High |
* +-----------------------------------+-----------+------------+-----------+
* |Sample size |1 MB |2 MB |4 MB |
* +-----------------------------------+-----------+------------+-----------+
* |Number of Subsamples |8 |16 |32 |
* +-----------------------------------+-----------+------------+-----------+
* |Decrypt buffer size |100 KB |500 KB |1 MB |
* +-----------------------------------+-----------+------------+-----------+
* |Generic crypto buffer size |10 KB |100 KB |500 KB |
* +-----------------------------------+-----------+------------+-----------+
* |Number of concurrent sessions |10 |20 |20 |
* +-----------------------------------+-----------+------------+-----------+
* |Number of keys per session |4 |20 |20 |
* +-----------------------------------+-----------+------------+-----------+
* |Simultaneous secure playback |1 |2 |2 |
* +-----------------------------------+-----------+------------+-----------+
* |Decrypted Frames per Second |30 fps SD |30 fps HD |60 fps HD |
* +-----------------------------------+-----------+------------+-----------+
*
* Parameters:
* none.
@@ -3637,6 +3652,10 @@ OEMCryptoResult OEMCrypto_UpdateUsageEntry(OEMCrypto_SESSION session,
* from generating a report of a deactivated license without first saving the
* entry.
*
* It is allowed to call this function multiple times. If the state is
* already InactiveUsed or InactiveUnused, then this function does not change
* the entry or its state.
*
* Parameters:
* [in] session: handle for the session to be used.
* [in] pst: pointer to memory containing Provider Session Token.
@@ -4004,23 +4023,23 @@ OEMCryptoResult OEMCrypto_CreateOldUsageEntry(uint64_t time_since_license_receiv
*
* Description:
* Returns the type of hash function supported for Full Decrypt Path Testing.
* A hash type of 0 means this feature is not supported. OEMCrypto is not
* required by Google to support this feature, but support will greatly
* improve automated testing. A hash type of 1 means the device will be able
* to compute the CRC32 checksum of the decrypted content in the secure
* buffer after a call to OEMCrypto_DecryptCENC. Google intends to provide
* test applications on some platforms, such as Android, that will automate
* decryption testing using the CRC 32 checksum of all frames in some test
* content.
* A hash type of OEMCrypto_Hash_Not_Supported = 0 means this feature is not
* supported. OEMCrypto is not required by Google to support this feature,
* but support will greatly improve automated testing. A hash type of
* OEMCrypto_CRC_Clear_Buffer = 1 means the device will be able to compute
* the CRC32 checksum of the decrypted content in the secure buffer after a
* call to OEMCrypto_DecryptCENC. Google intends to provide test applications
* on some platforms, such as Android, that will automate decryption testing
* using the CRC 32 checksum of all frames in some test content.
*
* If an SOC vendor cannot support CRC 32 checksums of decrypted output, but
* can support some other hash or checksum, then the function should return
* OEMCrypto_Partner_Defined_Hash and those partners should provide files
* containing hashes of test content. An application that computes the CRC 32
* hashes of test content and builds a hash file in the correct format will
* be provided by Widevine. The source of this application will be provided
* so that partners may modify it to compute their own hash format and
* generate their own hash files.
* OEMCrypto_Partner_Defined_Hash = 2 and those partners should modify the
* test application to compute the appropriate hash. An application that
* computes the CRC 32 hashes of test content and builds a hash file in the
* correct format will be provided by Widevine. The source of this
* application will be provided so that partners may modify it to compute
* their own hash format and generate their own hashes.
*
* Returns:
* OEMCrypto_Hash_Not_Supported = 0;
@@ -4038,57 +4057,29 @@ OEMCryptoResult OEMCrypto_CreateOldUsageEntry(uint64_t time_since_license_receiv
*/
uint32_t OEMCrypto_SupportsDecryptHash();
/*
* OEMCrypto_InitializeDecryptHash
*
* Description:
* This function is called before the first subsample is passed to
* OEMCrypto_DecryptCENC, when the subsample_flag has the bit
* OEMCrytpo_FirstSubsample set. OEMCrypto should expect to compute a hash
* over the whole sample.
*
* This function returns OEMCrypto_ERROR_UNKNOWN_FAILURE if the current key
* does not have the bit Allow_Hash_Verification set in its key control block.
*
* Parameters:
* [in] session: session id for current decrypt operation
*
* Returns:
* OEMCrypto_SUCCESS - if the hash was set
* OEMCrypto_ERROR_NOT_IMPLEMENTED - function not implemented
* OEMCrypto_ERROR_INVALID_SESSION - session not open
* OEMCrypto_ERROR_UNKNOWN_FAILURE - other error
* OEMCrypto_ERROR_SESSION_LOST_STATE
* OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* Threading:
* This is a "Session Function" and may be called simultaneously with session
* functions for other sessions but not simultaneously with other functions
* for this session. It will not be called simultaneously with initialization
* or usage table functions. It is as if the CDM holds a write lock for this
* session, and a read lock on the OEMCrypto system.
*
* Version:
* This method is new in API version 15.
*/
OEMCryptoResult OEMCrypto_InitializeDecryptHash(OEMCrypto_SESSION session);
/*
* OEMCrypto_SetDecryptHash
*
* Description:
* Set the hash value for the frame that was just decrypted. The hash is over
* all of the frame: encrypted and clear subsamples concatenated together. If
* hashing the output is not supported, then this will return
* Set the hash value for the next frame to be decrypted. This function is
* called before the first subsample is passed to OEMCrypto_DecryptCENC, when
* the subsample_flag has the bit OEMCrytpo_FirstSubsample set. The hash is
* over all of the frame or sample: encrypted and clear subsamples
* concatenated together, up to, and including the subsample with the
* subsample_flag having the bit OEMCrypto_LastSubsample set. If hashing the
* output is not supported, then this will return
* OEMCrypto_ERROR_NOT_IMPLEMENTED. If the hash is ill formed or there are
* other error conditions, this could return OEMCrypto_ERROR_UNKNOWN_FAILURE.
* The length of the hash will be at most 128 bytes. This function is called
* just after the last subsample in the frame, when the subsample_flag has
* the bit OEMCrypto_LastSubsample set. The hash only applies to the previous
* frame.
* other error conditions, this returns OEMCrypto_ERROR_UNKNOWN_FAILURE. The
* length of the hash will be at most 128 bytes.
*
* This function returns OEMCrypto_ERROR_UNKNOWN_FAILURE if the current key
* does not have the bit Allow_Hash_Verification set in its key control block.
* This may be called before the first call to SelectKey. In that case, this
* function cannot verify that the key control block allows hash
* verification. The function DecryptCENC should verify that the key control
* bit allows hash verification when it is called. If an attempt is made to
* compute a hash when the selected key does not have the bit
* Allow_Hash_Verification set, then a hash should not be computed, and
* OEMCrypto_GetHashErrorCode should return the error
* OEMCrypto_ERROR_UNKNOWN_FAILURE.
*
* OEMCrypto should compute the hash of the frame and then compare it with
* the correct value. If the values differ, then OEMCrypto should latch in an
@@ -4139,13 +4130,18 @@ OEMCryptoResult OEMCrypto_SetDecryptHash(OEMCrypto_SESSION session,
* If the hash set in OEMCrypto_SetDecryptHash did not match the computed
* hash, then an error code was saved internally. This function returns that
* error and the frame number of the bad hash. This will be called
* periodically, but not exactly in sync with the decrypt loop. OEMCrypto
* shall not reset the error state to "no error" once a frame has failed
* periodically, but might not be in sync with the decrypt loop. OEMCrypto
* shall not reset the error state to "no error" once any frame has failed
* verification. It should be initialized to "no error" when the session is
* first opened. If there is more than one bad frame, it is the implementer's
* choice if it is more useful to return the number of the first bad frame,
* or the most recent bad frame.
*
* If the hash could not be computed -- either because the
* Allow_Hash_Verification was not set in the key control block, or because
* there were other issues -- this function should return
* OEMCrypto_ERROR_UNKNOWN_FAILURE.
*
* Parameters:
* [in] session: session id for operation.
* [out] failed_frame_number: frame number for sample with incorrect hash.

View File

@@ -24,19 +24,18 @@ namespace wvoec3 {
#define Level3_IsInApp _lcc00
#define Level3_Initialize _lcc01
#define Level3_Terminate _lcc02
#define Level3_InstallKeybox _lcc03
#define Level3_InstallKeyboxOrOEMCert _lcc03
#define Level3_GetKeyData _lcc04
#define Level3_IsKeyboxValid _lcc05
#define Level3_IsKeyboxOrOEMCertValid _lcc05
#define Level3_GetRandom _lcc06
#define Level3_GetDeviceID _lcc07
#define Level3_WrapKeybox _lcc08
#define Level3_WrapKeyboxOrOEMCert _lcc08
#define Level3_OpenSession _lcc09
#define Level3_CloseSession _lcc10
#define Level3_DecryptCENC _lcc11
#define Level3_GenerateDerivedKeys _lcc12
#define Level3_GenerateSignature _lcc13
#define Level3_GenerateNonce _lcc14
#define Level3_RefreshKeys _lcc16
#define Level3_RewrapDeviceRSAKey _lcc18
#define Level3_LoadDeviceRSAKey _lcc19
#define Level3_GenerateRSASignature _lcc20
@@ -57,7 +56,6 @@ namespace wvoec3 {
#define Level3_GetMaxNumberOfSessions _lcc37
#define Level3_GetNumberOfOpenSessions _lcc38
#define Level3_IsAntiRollbackHwPresent _lcc39
#define Level3_CopyBuffer _lcc40
#define Level3_QueryKeyControl _lcc41
#define Level3_ForceDeleteUsageEntry _lcc43
#define Level3_LoadTestRSAKey _lcc45
@@ -81,24 +79,31 @@ namespace wvoec3 {
#define Level3_CreateOldUsageEntry _lcc70
#define Level3_GetAnalogOutputFlags _lcc71
#define Level3_LoadTestKeybox _lcc78
#define Level3_LoadEntitledContentKeys _lcc79
#define Level3_SelectKey _lcc81
#define Level3_LoadKeys _lcc82
#define Level3_LoadKeys _lcc83
#define Level3_SetSandbox _lcc84
#define Level3_ResourceRatingTier _lcc85
#define Level3_SupportsDecryptHash _lcc86
#define Level3_SetDecryptHash _lcc88
#define Level3_GetHashErrorCode _lcc89
#define Level3_BuildInformation _lcc90
#define Level3_RefreshKeys _lcc91
#define Level3_LoadEntitledContentKeys _lcc92
#define Level3_CopyBuffer _lcc93
#else
#define Level3_Initialize _oecc01
#define Level3_Terminate _oecc02
#define Level3_InstallKeybox _oecc03
#define Level3_InstallKeyboxOrOEMCert _oecc03
#define Level3_GetKeyData _oecc04
#define Level3_IsKeyboxValid _oecc05
#define Level3_IsKeyboxOrOEMCertValid _oecc05
#define Level3_GetRandom _oecc06
#define Level3_GetDeviceID _oecc07
#define Level3_WrapKeybox _oecc08
#define Level3_WrapKeyboxOrOEMCert _oecc08
#define Level3_OpenSession _oecc09
#define Level3_CloseSession _oecc10
#define Level3_GenerateDerivedKeys _oecc12
#define Level3_GenerateSignature _oecc13
#define Level3_GenerateNonce _oecc14
#define Level3_RefreshKeys _oecc16
#define Level3_RewrapDeviceRSAKey _oecc18
#define Level3_LoadDeviceRSAKey _oecc19
#define Level3_DeriveKeysFromSessionKey _oecc21
@@ -117,7 +122,6 @@ namespace wvoec3 {
#define Level3_GetMaxNumberOfSessions _oecc37
#define Level3_GetNumberOfOpenSessions _oecc38
#define Level3_IsAntiRollbackHwPresent _oecc39
#define Level3_CopyBuffer _oecc40
#define Level3_QueryKeyControl _oecc41
#define Level3_ForceDeleteUsageEntry _oecc43
#define Level3_GetHDCPCapability _oecc44
@@ -144,9 +148,17 @@ namespace wvoec3 {
#define Level3_CreateOldUsageEntry _oecc70
#define Level3_GetAnalogOutputFlags _oecc71
#define Level3_LoadTestKeybox _oecc78
#define Level3_LoadEntitledContentKeys _oecc79
#define Level3_SelectKey _oecc81
#define Level3_LoadKeys _oecc82
#define Level3_LoadKeys _oecc83
#define Level3_SetSandbox _oecc84
#define Level3_ResourceRatingTier _oecc85
#define Level3_SupportsDecryptHash _oecc86
#define Level3_SetDecryptHash _oecc88
#define Level3_GetHashErrorCode _oecc89
#define Level3_BuildInformation _oecc90
#define Level3_RefreshKeys _oecc91
#define Level3_LoadEntitledContentKeys _oecc92
#define Level3_CopyBuffer _oecc93
#endif
#define Level3_GetInitializationState _oecl3o01
@@ -170,10 +182,6 @@ OEMCryptoResult Level3_GenerateSignature(OEMCrypto_SESSION session,
size_t message_length,
uint8_t* signature,
size_t* signature_length);
OEMCryptoResult Level3_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_V14* key_array);
OEMCryptoResult Level3_QueryKeyControl(OEMCrypto_SESSION session,
const uint8_t* key_id,
size_t key_id_length,
@@ -188,23 +196,19 @@ OEMCryptoResult Level3_DecryptCENC(OEMCrypto_SESSION session,
OEMCrypto_DestBufferDesc* out_buffer,
const OEMCrypto_CENCEncryptPatternDesc* pattern,
uint8_t subsample_flags);
OEMCryptoResult Level3_CopyBuffer(const uint8_t *data_addr,
size_t data_length,
OEMCrypto_DestBufferDesc* out_buffer,
uint8_t subsample_flags);
OEMCryptoResult Level3_WrapKeybox(const uint8_t *keybox,
size_t keyBoxLength,
uint8_t *wrappedKeybox,
size_t *wrappedKeyBoxLength,
const uint8_t *transportKey,
size_t transportKeyLength);
OEMCryptoResult Level3_InstallKeybox(const uint8_t *keybox,
size_t keyBoxLength);
OEMCryptoResult Level3_InstallKeyboxOrOEMCert(const uint8_t* rot,
size_t rotLength);
OEMCryptoResult Level3_IsKeyboxOrOEMCertValid(void);
OEMCryptoResult Level3_WrapKeyboxOrOEMCert(const uint8_t* rot,
size_t rotLength,
uint8_t* wrappedRot,
size_t* wrappedRotLength,
const uint8_t* transportKey,
size_t transportKeyLength);
OEMCrypto_ProvisioningMethod Level3_GetProvisioningMethod();
OEMCryptoResult Level3_GetOEMPublicCertificate(OEMCrypto_SESSION session,
uint8_t *public_cert,
size_t *public_cert_length);
OEMCryptoResult Level3_IsKeyboxValid(void);
OEMCryptoResult Level3_GetDeviceID(uint8_t* deviceID,
size_t *idLength);
OEMCryptoResult Level3_GetKeyData(uint8_t* keyData,
@@ -306,12 +310,6 @@ OEMCryptoResult Level3_GetCurrentSRMVersion(uint16_t* version);
OEMCryptoResult Level3_LoadSRM(const uint8_t* buffer,
size_t buffer_length);
OEMCryptoResult Level3_RemoveSRM();
uint32_t Level3_SupportsDecryptHash();
OEMCryptoResult Level3_SetDecryptHash(OEMCrypto_SESSION session,
const uint8_t* hash,
size_t hash_length);
OEMCryptoResult Level3_VerifyDecryptHash(OEMCrypto_SESSION session,
uint64_t* failure_data);
OEMCryptoResult Level3_CreateUsageTableHeader(uint8_t* header_buffer,
size_t* header_buffer_length);
OEMCryptoResult Level3_LoadUsageTableHeader(const uint8_t* buffer,
@@ -345,19 +343,52 @@ OEMCryptoResult Level3_CreateOldUsageEntry(uint64_t time_since_license_received,
size_t pst_length);
uint32_t Level3_GetAnalogOutputFlags();
OEMCryptoResult Level3_LoadTestKeybox(const uint8_t* buffer, size_t length);
OEMCryptoResult Level3_LoadEntitledContentKeys(
OEMCrypto_SESSION session, size_t num_keys,
const OEMCrypto_EntitledContentKeyObject_V14* key_array);
OEMCryptoResult Level3_SelectKey(const OEMCrypto_SESSION session,
const uint8_t* key_id, size_t key_id_length,
OEMCryptoCipherMode cipher_mode);
OEMCryptoResult Level3_LoadKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject_V14* key_array, const uint8_t* pst,
size_t pst_length, const uint8_t* srm_requirement,
OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys,
size_t num_keys, const OEMCrypto_KeyObject* key_array,
OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data,
OEMCrypto_LicenseType license_type);
OEMCryptoResult Level3_SetSandbox(const uint8_t* sandbox_id,
size_t sandbox_id_length);
uint32_t Level3_ResourceRatingTier();
uint32_t Level3_SupportsDecryptHash();
OEMCryptoResult Level3_SetDecryptHash(OEMCrypto_SESSION session,
uint32_t frame_number,
const uint8_t* hash, size_t hash_length);
OEMCryptoResult Level3_GetHashErrorCode(OEMCrypto_SESSION session,
uint32_t* failed_frame_number);
const char* Level3_BuildInformation();
OEMCryptoResult Level3_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);
OEMCryptoResult Level3_LoadEntitledContentKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array);
OEMCryptoResult Level3_CopyBuffer(OEMCrypto_SESSION session,
const uint8_t *data_addr,
size_t data_length,
OEMCrypto_DestBufferDesc* out_buffer,
uint8_t subsample_flags);
// The following are specific to Google's Level 3 implementation and are not
// required.
enum Level3InitializationState {
LEVEL3_INITIALIZATION_SUCCESS = 0,
LEVEL3_INITIALIZATION_UNKNOWN_FAILURE = 1,
LEVEL3_SEED_FAILURE = 2,
LEVEL3_SAVE_DEVICE_KEYS_FAILURE = 3,
LEVEL3_READ_DEVICE_KEYS_FAILURE = 4,
LEVEL3_VERIFY_DEVICE_KEYS_FAILURE = 5,
};
/*
* Level3_GetInitializationState
*
@@ -365,7 +396,7 @@ OEMCryptoResult Level3_LoadKeys(
* Return any warning or error condition which occurred during
* initialization. On some platforms, this value will be logged and metrics
* will be gathered on production devices. This is an optional feature, and
* OEMCrypto may always return 0, even if Level3_Initialize failed. This
* OEMCrypto may always return 0, even if Level3_Initialize failed. This
* function may be called whether Level3_Initialize succeeded or not.
*
* Parameters:
@@ -375,17 +406,44 @@ OEMCryptoResult Level3_LoadKeys(
* No other function calls will be made while this function is running.
*
* Returns:
* 0 - no warnings or errors during initialization
* LEVEL3_INITIALIZATION_SUCCESS - no warnings or errors during initialization
* LEVEL3_SEED_FAILURE - error in seeding the software RNG
* LEVEL3_SAVE_DEVICE_KEYS_FAILURE - failed to save device keys to file system
* LEVEL3_READ_DEVICE_KEYS_FAILURE - failed to read device keys from file
* system
* LEVEL3_VERIFY_DEVICE_KEYS_FAILURE - failed to verify decrypted device keys
*
* Version:
* This method is new in API version 14.
*/
OEMCryptoResult Level3_GetInitializationState(void);
Level3InitializationState Level3_GetInitializationState(void);
/*
* Level3_OutputErrorLogs
*
* Description:
* Call to output any errors in the Level 3 execution if the Level 3 has
* failed. This method should only be called if the Level 3 has failed in
* an unrecoverable state, and needs to be reinitialized.
*
* Parameters:
* N/A
*
* Threading:
* No other function calls will be made while this function is running.
*
* Returns:
* N/A
*
* Version:
* This method is new in API version 15.
*/
void Level3_OutputErrorLogs();
} // extern "C"
// The following are interfaces needed for Level3 OEMCrypto specifically, which
// partners are expected to implement.
// The following are interfaces needed for Google's Level 3 OEMCrypto
// specifically, which partners are expected to implement.
// Returns a stable, unique identifier for the device. This could be a
// serial number or any other character sequence representing that device.

View File

@@ -8,6 +8,7 @@
#define OEMCRYPTO_AUTH_REF_H_
#include <stdint.h>
#include <memory>
#include <vector>
#include <openssl/rsa.h>
@@ -17,7 +18,6 @@
#include "oemcrypto_key_ref.h"
#include "oemcrypto_keybox_ref.h"
#include "oemcrypto_rsa_key_shared.h"
#include "oemcrypto_scoped_ptr.h"
#include "oemcrypto_types.h"
namespace wvoec_ref {

View File

@@ -7,11 +7,13 @@
#include "oemcrypto_engine_ref.h"
#include <utility>
namespace wvoec_ref {
CryptoEngine* CryptoEngine::MakeCryptoEngine(
scoped_ptr<wvcdm::FileSystem> file_system) {
return new CryptoEngine(file_system);
std::unique_ptr<wvcdm::FileSystem>&& file_system) {
return new CryptoEngine(std::move(file_system));
}
} // namespace wvoec_ref

View File

@@ -8,12 +8,14 @@
// level 1 device.
#include "oemcrypto_engine_ref.h"
#include <utility>
namespace wvoec_ref {
class L1CryptoEngine : public CryptoEngine {
public:
explicit L1CryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system)
: CryptoEngine(file_system) {}
explicit L1CryptoEngine(std::unique_ptr<wvcdm::FileSystem>&& file_system)
: CryptoEngine(std::move(file_system)) {}
bool config_local_display_only() { return true; }
@@ -31,8 +33,8 @@ class L1CryptoEngine : public CryptoEngine {
};
CryptoEngine* CryptoEngine::MakeCryptoEngine(
scoped_ptr<wvcdm::FileSystem> file_system) {
return new L1CryptoEngine(file_system);
std::unique_ptr<wvcdm::FileSystem>&& file_system) {
return new L1CryptoEngine(std::move(file_system));
}
} // namespace wvoec_ref

View File

@@ -15,7 +15,7 @@ namespace wvoec_ref {
class CertOnlyCryptoEngine : public CryptoEngine {
public:
explicit CertOnlyCryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system)
explicit CertOnlyCryptoEngine(std::unique_ptr<wvcdm::FileSystem> file_system)
: CryptoEngine(file_system) {}
bool config_local_display_only() { return true; }
@@ -30,7 +30,7 @@ class CertOnlyCryptoEngine : public CryptoEngine {
};
CryptoEngine* CryptoEngine::MakeCryptoEngine(
scoped_ptr<wvcdm::FileSystem> file_system) {
std::unique_ptr<wvcdm::FileSystem> file_system) {
return new CertOnlyCryptoEngine(file_system);
}

View File

@@ -12,6 +12,8 @@
#include <string.h>
#include <utility>
#include "log.h"
#include "oem_cert.h"
@@ -19,8 +21,8 @@ namespace wvoec_ref {
class Prov30CryptoEngine : public CryptoEngine {
public:
explicit Prov30CryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system)
: CryptoEngine(file_system) {}
explicit Prov30CryptoEngine(std::unique_ptr<wvcdm::FileSystem>&& file_system)
: CryptoEngine(std::move(file_system)) {}
bool config_local_display_only() { return true; }
@@ -77,8 +79,8 @@ class Prov30CryptoEngine : public CryptoEngine {
};
CryptoEngine* CryptoEngine::MakeCryptoEngine(
scoped_ptr<wvcdm::FileSystem> file_system) {
return new Prov30CryptoEngine(file_system);
std::unique_ptr<wvcdm::FileSystem>&& file_system) {
return new Prov30CryptoEngine(std::move(file_system));
}
} // namespace wvoec_ref

View File

@@ -8,9 +8,11 @@
#include <arpa/inet.h>
#include <assert.h>
#include <chrono>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
#include <openssl/aes.h>
@@ -29,15 +31,15 @@ namespace wvoec_ref {
// all configurations. See the files oemcrypto_engine_device_properties*.cpp
// for methods that are configured for specific configurations.
CryptoEngine::CryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system)
CryptoEngine::CryptoEngine(std::unique_ptr<wvcdm::FileSystem>&& file_system)
: root_of_trust_(config_provisioning_method()),
file_system_(file_system),
usage_table_(NULL) {
file_system_(std::move(file_system)),
usage_table_() {
ERR_load_crypto_strings();
}
CryptoEngine::~CryptoEngine() {
wvcdm::AutoLock lock(session_table_lock_);
std::unique_lock<std::mutex> lock(session_table_lock_);
ActiveSessions::iterator it;
for (it = sessions_.begin(); it != sessions_.end(); ++it) {
delete it->second;
@@ -52,7 +54,7 @@ bool CryptoEngine::Initialize() {
}
SessionId CryptoEngine::OpenSession() {
wvcdm::AutoLock lock(session_table_lock_);
std::unique_lock<std::mutex> lock(session_table_lock_);
static OEMCrypto_SESSION unique_id = 1;
SessionId id = ++unique_id;
sessions_[id] = MakeSession(id);
@@ -67,7 +69,7 @@ UsageTable* CryptoEngine::MakeUsageTable() { return new UsageTable(this); }
bool CryptoEngine::DestroySession(SessionId sid) {
SessionContext* sctx = FindSession(sid);
wvcdm::AutoLock lock(session_table_lock_);
std::unique_lock<std::mutex> lock(session_table_lock_);
if (sctx) {
sessions_.erase(sid);
delete sctx;
@@ -78,7 +80,7 @@ bool CryptoEngine::DestroySession(SessionId sid) {
}
SessionContext* CryptoEngine::FindSession(SessionId sid) {
wvcdm::AutoLock lock(session_table_lock_);
std::unique_lock<std::mutex> lock(session_table_lock_);
ActiveSessions::iterator it = sessions_.find(sid);
if (it != sessions_.end()) {
return it->second;
@@ -89,14 +91,8 @@ SessionContext* CryptoEngine::FindSession(SessionId sid) {
time_t CryptoEngine::OnlineTime() {
// Use the monotonic clock for times that don't have to be stable across
// device boots.
timespec current_time;
int gettime_result = clock_gettime(CLOCK_MONOTONIC, &current_time);
if (gettime_result == 0) {
return current_time.tv_sec;
} else {
// Can't use monotonic clock, use roll back time.
return RollbackCorrectedOfflineTime();
}
std::chrono::steady_clock clock;
return clock.now().time_since_epoch() / std::chrono::seconds(1);
}
time_t CryptoEngine::RollbackCorrectedOfflineTime() {
@@ -117,7 +113,7 @@ time_t CryptoEngine::RollbackCorrectedOfflineTime() {
// Use the device key for encrypt/decrypt.
const std::vector<uint8_t>& key = DeviceRootKey();
wvcdm::File* file;
std::unique_ptr<wvcdm::File> file;
std::string path;
// Note: this path is OK for a real implementation, but using security level 1
// would be better.
@@ -139,7 +135,6 @@ time_t CryptoEngine::RollbackCorrectedOfflineTime() {
return time(NULL);
}
file->Read(reinterpret_cast<char*>(&encrypted_buffer[0]), sizeof(TimeInfo));
file->Close();
// Decrypt the encrypted TimeInfo buffer.
AES_KEY aes_key;
AES_set_decrypt_key(&key[0], 128, &aes_key);
@@ -179,7 +174,6 @@ time_t CryptoEngine::RollbackCorrectedOfflineTime() {
return time(NULL);
}
file->Write(reinterpret_cast<char*>(&encrypted_buffer[0]), sizeof(TimeInfo));
file->Close();
// Return time with offset.
return current_time;

View File

@@ -11,17 +11,16 @@
#include <time.h>
#include <map>
#include <memory>
#include <mutex>
#include <vector>
#include <openssl/rsa.h>
#include "OEMCryptoCENC.h"
#include "file_store.h"
#include "lock.h"
#include "oemcrypto_auth_ref.h"
#include "oemcrypto_key_ref.h"
#include "oemcrypto_rsa_key_shared.h"
#include "oemcrypto_scoped_ptr.h"
#include "oemcrypto_session.h"
#include "oemcrypto_usage_table_ref.h"
#include "oemcrypto_types.h"
@@ -38,7 +37,7 @@ class CryptoEngine {
// NOTE: The caller must instantiate a FileSystem object - ownership
// will be transferred to the new CryptoEngine object.
static CryptoEngine* MakeCryptoEngine(
scoped_ptr<wvcdm::FileSystem> file_system);
std::unique_ptr<wvcdm::FileSystem>&& file_system);
virtual ~CryptoEngine();
@@ -196,15 +195,15 @@ class CryptoEngine {
}
protected:
explicit CryptoEngine(scoped_ptr<wvcdm::FileSystem> file_system);
explicit CryptoEngine(std::unique_ptr<wvcdm::FileSystem>&& file_system);
virtual SessionContext* MakeSession(SessionId sid);
virtual UsageTable* MakeUsageTable();
uint8_t* destination_;
ActiveSessions sessions_;
AuthenticationRoot root_of_trust_;
wvcdm::Lock session_table_lock_;
scoped_ptr<wvcdm::FileSystem> file_system_;
scoped_ptr<UsageTable> usage_table_;
std::mutex session_table_lock_;
std::unique_ptr<wvcdm::FileSystem> file_system_;
std::unique_ptr<UsageTable> usage_table_;
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoEngine);
};

View File

@@ -47,7 +47,7 @@ class Key {
Key(const std::vector<uint8_t>& key_string, const KeyControlBlock& control)
: value_(key_string), control_(control), ctr_mode_(true){};
virtual ~Key(){};
virtual ~Key() {};
void UpdateDuration(const KeyControlBlock& control);
virtual const std::vector<uint8_t>& value() const { return value_; }
const KeyControlBlock& control() const { return control_; }
@@ -65,8 +65,8 @@ class Key {
class EntitlementKey : public Key {
public:
EntitlementKey(const Key& key) : Key(key) {}
virtual ~EntitlementKey() {}
virtual const std::vector<uint8_t>& value() const { return content_key_; }
~EntitlementKey() override {}
const std::vector<uint8_t>& value() const override { return content_key_; }
const std::vector<uint8_t>& content_key() { return content_key_; }
const std::vector<uint8_t>& content_key_id() { return content_key_id_; }
const std::vector<uint8_t>& entitlement_key() { return Key::value(); }

View File

@@ -64,7 +64,7 @@ OldUsageTable::OldUsageTable(CryptoEngine *ce) {
// Load saved table.
wvcdm::FileSystem *file_system = ce->file_system();
wvcdm::File *file;
std::unique_ptr<wvcdm::File> file;
std::string path;
// Note: this path is OK for a real implementation, but using security level 1
// would be better.
@@ -93,7 +93,6 @@ OldUsageTable::OldUsageTable(CryptoEngine *ce) {
return;
}
file->Read(reinterpret_cast<char *>(&encrypted_buffer[0]), file_size);
file->Close();
// Verify the signature of the usage table file.
@@ -148,7 +147,6 @@ OldUsageTable::OldUsageTable(CryptoEngine *ce) {
return;
}
file->Read(reinterpret_cast<char *>(&generation_), sizeof(int64_t));
file->Close();
if ((stored_table->generation > generation_ + 1) ||
(stored_table->generation < generation_ - 1)) {
LOGE("OldUsageTable: Rollback detected. Clearing Usage Table. %lx -> %lx",
@@ -168,7 +166,7 @@ OldUsageTable::OldUsageTable(CryptoEngine *ce) {
}
OldUsageTableEntry *OldUsageTable::FindEntry(const std::vector<uint8_t> &pst) {
wvcdm::AutoLock lock(lock_);
std::unique_lock<std::mutex> lock(lock_);
return FindEntryLocked(pst);
}
@@ -194,13 +192,13 @@ OldUsageTableEntry *OldUsageTable::CreateEntry(
return NULL;
}
OldUsageTableEntry *entry = new OldUsageTableEntry(this, pst_hash);
wvcdm::AutoLock lock(lock_);
std::unique_lock<std::mutex> lock(lock_);
table_[pst_hash] = entry;
return entry;
}
void OldUsageTable::Clear() {
wvcdm::AutoLock lock(lock_);
std::unique_lock<std::mutex> lock(lock_);
for (EntryMap::iterator i = table_.begin(); i != table_.end(); ++i) {
if (i->second) delete i->second;
}

View File

@@ -12,11 +12,11 @@
#include <stdint.h>
#include <map>
#include <mutex>
#include <string>
#include <vector>
#include "OEMCryptoCENC.h"
#include "lock.h"
#include "oemcrypto_types.h"
#include "openssl/sha.h"
@@ -89,7 +89,7 @@ class OldUsageTable {
typedef std::map<std::vector<uint8_t>, OldUsageTableEntry *> EntryMap;
EntryMap table_;
wvcdm::Lock lock_;
std::mutex lock_;
int64_t generation_;
CryptoEngine *ce_;

View File

@@ -15,10 +15,10 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <chrono>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include "file_store.h"
#include "log.h"
@@ -27,6 +27,12 @@
#include "oemcrypto_usage_table_ref.h"
#include "string_conversions.h"
#if defined(_WIN32)
# define OEMCRYPTO_API extern "C" __declspec(dllexport)
#else // defined(_WIN32)
# define OEMCRYPTO_API extern "C" __attribute__((visibility("default")))
#endif // defined(_WIN32)
namespace {
const uint8_t kBakedInCertificateMagicBytes[] = {0xDE, 0xAD, 0xBE, 0xEF};
@@ -56,7 +62,7 @@ typedef struct {
uint8_t enc_rsa_key[];
} WrappedRSAKey;
extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_Initialize(void) {
if (crypto_engine) {
LOGE("------------------------- Calling Initialize without Terminate\n");
delete crypto_engine;
@@ -64,8 +70,8 @@ extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
}
// NOTE: This requires a compatible Filesystem implementation.
// NOTE: Ownership of the FileSystem object is transferred to CryptoEngine
scoped_ptr<wvcdm::FileSystem> fs(new wvcdm::FileSystem());
crypto_engine = CryptoEngine::MakeCryptoEngine(fs);
std::unique_ptr<wvcdm::FileSystem> fs(new wvcdm::FileSystem());
crypto_engine = CryptoEngine::MakeCryptoEngine(std::move(fs));
if (!crypto_engine || !crypto_engine->Initialize()) {
LOGE("[OEMCrypto_Initialize(): failed]");
@@ -74,12 +80,12 @@ extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_SetSandbox(const uint8_t* /*sandbox_id*/,
size_t /*sandbox_id_length*/) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_SetSandbox(
const uint8_t* /*sandbox_id*/, size_t /*sandbox_id_length*/) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_Terminate(void) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_Terminate(void) {
if (!crypto_engine) {
LOGE("[OEMCrypto_Terminate(): not initialized]");
return OEMCrypto_ERROR_TERMINATE_FAILED;
@@ -91,7 +97,8 @@ extern "C" OEMCryptoResult OEMCrypto_Terminate(void) {
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_OpenSession(
OEMCrypto_SESSION* session) {
if (!crypto_engine) {
LOGE("OEMCrypto_OpenSession: OEMCrypto not initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -106,7 +113,8 @@ extern "C" OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session) {
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_CloseSession(
OEMCrypto_SESSION session) {
if (!crypto_engine) {
LOGE("OEMCrypto_CloseSession: OEMCrypto not initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -118,7 +126,7 @@ extern "C" OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) {
}
}
extern "C" OEMCryptoResult OEMCrypto_GenerateDerivedKeys(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateDerivedKeys(
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) {
@@ -153,15 +161,9 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateDerivedKeys(
return OEMCrypto_SUCCESS;
}
static const uint64_t one_second = 1000000ull;
static uint64_t TimeStamp(void) {
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec * one_second + tv.tv_usec;
}
extern "C" OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
uint32_t* nonce) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
uint32_t* nonce) {
if (!crypto_engine) {
LOGE("OEMCrypto_GenerateNonce: OEMCrypto not initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -173,13 +175,14 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
}
// Prevent nonce flood.
uint64_t now = TimeStamp();
static uint64_t last_nonce_time = now;
static std::chrono::steady_clock clock;
const auto now = clock.now().time_since_epoch();
static auto last_nonce_time = now;
// For testing, we set nonce_flood_count to 1. Since count is initialized to
// 1, the very first nonce after initialization is counted as a flood.
static int nonce_count = 1;
if (now - last_nonce_time < one_second) {
if (now - last_nonce_time < std::chrono::seconds(1)) {
nonce_count++;
if (nonce_count > crypto_engine->nonce_flood_count()) {
LOGE("[OEMCrypto_GenerateNonce(): Nonce Flood detected]");
@@ -203,7 +206,7 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_GenerateSignature(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateSignature(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
uint8_t* signature, size_t* signature_length) {
if (!crypto_engine) {
@@ -251,7 +254,7 @@ bool RangeCheck(uint32_t message_length, const OEMCrypto_Substring& substring,
return true;
}
extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys,
@@ -307,7 +310,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
license_type);
}
extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array) {
if (num_keys == 0) {
@@ -345,7 +348,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
key_array);
}
extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
OEMCRYPTO_API 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) {
@@ -434,7 +437,7 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_QueryKeyControl(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_QueryKeyControl(
OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length,
uint8_t* key_control_block, size_t* key_control_block_length) {
if (!crypto_engine) {
@@ -469,7 +472,7 @@ extern "C" OEMCryptoResult OEMCrypto_QueryKeyControl(
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_SelectKey(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_SelectKey(
const OEMCrypto_SESSION session, const uint8_t* key_id,
size_t key_id_length, OEMCryptoCipherMode cipher_mode) {
#ifndef NDEBUG
@@ -490,7 +493,7 @@ extern "C" OEMCryptoResult OEMCrypto_SelectKey(
return session_ctx->SelectContentKey(key_id_str, cipher_mode);
}
extern "C" OEMCryptoResult OEMCrypto_DecryptCENC(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_DecryptCENC(
OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length,
bool is_encrypted, const uint8_t* iv, size_t block_offset,
OEMCrypto_DestBufferDesc* out_buffer,
@@ -532,12 +535,12 @@ extern "C" OEMCryptoResult OEMCrypto_DecryptCENC(
OEMCryptoResult result = session_ctx->DecryptCENC(
iv, block_offset, pattern, data_addr, data_length, is_encrypted,
crypto_engine->destination(), out_buffer->type);
crypto_engine->destination(), out_buffer->type, subsample_flags);
if (result != OEMCrypto_SUCCESS) return result;
return crypto_engine->PushDestination(out_buffer, subsample_flags);
}
extern "C" OEMCryptoResult OEMCrypto_CopyBuffer(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_CopyBuffer(
OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length,
OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags) {
if (!crypto_engine) {
@@ -564,7 +567,7 @@ extern "C" OEMCryptoResult OEMCrypto_CopyBuffer(
return crypto_engine->PushDestination(out_buffer, subsample_flags);
}
extern "C" OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert(
const uint8_t* keybox, size_t keyBoxLength, uint8_t* wrappedKeybox,
size_t* wrappedKeyBoxLength, const uint8_t* transportKey,
size_t transportKeyLength) {
@@ -581,7 +584,7 @@ extern "C" OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert(
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(
const uint8_t* keybox, size_t keyBoxLength) {
if (!crypto_engine) {
LOGE("OEMCrypto_InstallKeyboxOrOEMCert: OEMCrypto Not Initialized.");
@@ -596,8 +599,8 @@ extern "C" OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(
return OEMCrypto_ERROR_WRITE_KEYBOX;
}
extern "C" OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
size_t length) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
size_t length) {
if (!crypto_engine) {
LOGE("OEMCrypto_LoadTestKeybox: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -609,7 +612,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void) {
if (!crypto_engine) {
LOGE("OEMCrypto_IsKeyboxOrOEMCertValid: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -641,7 +644,7 @@ extern "C" OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void) {
}
}
extern "C" OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod() {
OEMCRYPTO_API OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod() {
if (!crypto_engine) {
LOGE("OEMCrypto_GetProvisioningMethod: OEMCrypto Not Initialized.");
return OEMCrypto_ProvisioningError;
@@ -649,7 +652,7 @@ extern "C" OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod() {
return crypto_engine->config_provisioning_method();
}
extern "C" OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(
OEMCrypto_SESSION session, uint8_t* public_cert,
size_t* public_cert_length) {
if (!crypto_engine) {
@@ -670,8 +673,8 @@ extern "C" OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(
public_cert_length);
}
extern "C" OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
size_t* idLength) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
size_t* idLength) {
if (!crypto_engine) {
LOGE("OEMCrypto_GetDeviceID: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -699,8 +702,8 @@ extern "C" OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
size_t* keyDataLength) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
size_t* keyDataLength) {
if (!crypto_engine) {
LOGE("OEMCrypto_GetKeyData: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -728,8 +731,8 @@ extern "C" OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
size_t dataLength) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
size_t dataLength) {
if (!crypto_engine) {
LOGE("OEMCrypto_GetRandom: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -743,7 +746,7 @@ extern "C" OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
OEMCRYPTO_API 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,
@@ -860,7 +863,7 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
OEMCRYPTO_API 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,
@@ -980,7 +983,7 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(
OEMCrypto_SESSION session, const uint8_t* wrapped_rsa_key,
size_t wrapped_rsa_key_length) {
if (wrapped_rsa_key == NULL) {
@@ -1049,7 +1052,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_LoadTestRSAKey() {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadTestRSAKey() {
if (!crypto_engine) {
LOGE("OEMCrypto_LoadTestRSAKey: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1058,7 +1061,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadTestRSAKey() {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
extern "C" OEMCryptoResult OEMCrypto_GenerateRSASignature(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
uint8_t* signature, size_t* signature_length,
RSA_Padding_Scheme padding_scheme) {
@@ -1095,7 +1098,7 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateRSASignature(
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
OEMCrypto_SESSION session, const uint8_t* enc_session_key,
size_t enc_session_key_length, const uint8_t* mac_key_context,
size_t mac_key_context_length, const uint8_t* enc_key_context,
@@ -1134,19 +1137,19 @@ extern "C" OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
return OEMCrypto_SUCCESS;
}
extern "C" uint32_t OEMCrypto_APIVersion() { return 15; }
OEMCRYPTO_API uint32_t OEMCrypto_APIVersion() { return 15; }
extern "C" uint8_t OEMCrypto_Security_Patch_Level() {
OEMCRYPTO_API uint8_t OEMCrypto_Security_Patch_Level() {
uint8_t security_patch_level = crypto_engine->config_security_patch_level();
return security_patch_level;
}
extern "C" const char* OEMCrypto_SecurityLevel() {
OEMCRYPTO_API const char* OEMCrypto_SecurityLevel() {
const char* security_level = crypto_engine->config_security_level();
return security_level;
}
extern "C" OEMCryptoResult OEMCrypto_GetHDCPCapability(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetHDCPCapability(
OEMCrypto_HDCP_Capability* current, OEMCrypto_HDCP_Capability* maximum) {
if (!crypto_engine) {
LOGE("OEMCrypto_GetHDCPCapability: OEMCrypto Not Initialized.");
@@ -1159,7 +1162,7 @@ extern "C" OEMCryptoResult OEMCrypto_GetHDCPCapability(
return OEMCrypto_SUCCESS;
}
extern "C" uint32_t OEMCrypto_GetAnalogOutputFlags() {
OEMCRYPTO_API uint32_t OEMCrypto_GetAnalogOutputFlags() {
if (!crypto_engine) {
LOGE("OEMCrypto_GetAnalogOutputFlags: OEMCrypto Not Initialized.");
return 0;
@@ -1167,11 +1170,11 @@ extern "C" uint32_t OEMCrypto_GetAnalogOutputFlags() {
return crypto_engine->analog_output_flags();
}
extern "C" const char* OEMCrypto_BuildInformation() {
OEMCRYPTO_API const char* OEMCrypto_BuildInformation() {
return "OEMCrypto Ref Code " __DATE__ " " __TIME__;
}
extern "C" uint32_t OEMCrypto_ResourceRatingTier(){
OEMCRYPTO_API uint32_t OEMCrypto_ResourceRatingTier() {
if (!crypto_engine) {
LOGE("OEMCrypto_ResourceRatingTier: OEMCrypto Not Initialized.");
return 0;
@@ -1179,7 +1182,7 @@ extern "C" uint32_t OEMCrypto_ResourceRatingTier(){
return crypto_engine->resource_rating();
}
extern "C" bool OEMCrypto_SupportsUsageTable() {
OEMCRYPTO_API bool OEMCrypto_SupportsUsageTable() {
if (!crypto_engine) {
LOGE("OEMCrypto_SupportsUsageTable: OEMCrypto Not Initialized.");
return 0;
@@ -1188,7 +1191,7 @@ extern "C" bool OEMCrypto_SupportsUsageTable() {
return supports_usage;
}
extern "C" OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(size_t* count) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(size_t* count) {
if (!crypto_engine) {
LOGE("OEMCrypto_GetNumberOfOpenSessions: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1198,7 +1201,8 @@ extern "C" OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(size_t* count) {
return OEMCrypto_SUCCESS;
}
extern "C" OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* maximum) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(
size_t* maximum) {
if (!crypto_engine) {
LOGE("OEMCrypto_GetMaxNumberOfSessions: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1208,14 +1212,14 @@ extern "C" OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* maximum) {
return OEMCrypto_SUCCESS;
}
extern "C" bool OEMCrypto_IsAntiRollbackHwPresent() {
OEMCRYPTO_API bool OEMCrypto_IsAntiRollbackHwPresent() {
bool anti_rollback_hw_present =
crypto_engine->config_is_anti_rollback_hw_present();
return anti_rollback_hw_present;
}
extern "C" uint32_t OEMCrypto_SupportedCertificates() {
OEMCRYPTO_API uint32_t OEMCrypto_SupportedCertificates() {
if (!crypto_engine) {
LOGE("OEMCrypto_GetProvisioningMethod: OEMCrypto Not Initialized.");
return 0;
@@ -1227,7 +1231,7 @@ extern "C" uint32_t OEMCrypto_SupportedCertificates() {
OEMCrypto_Supports_RSA_CAST;
}
extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_Generic_Encrypt(
OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length,
const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) {
if (!crypto_engine) {
@@ -1253,7 +1257,7 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt(
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_Generic_Decrypt(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_Generic_Decrypt(
OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length,
const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) {
if (!crypto_engine) {
@@ -1279,12 +1283,10 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Decrypt(
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session,
const uint8_t* in_buffer,
size_t buffer_length,
OEMCrypto_Algorithm algorithm,
uint8_t* signature,
size_t* signature_length) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_Generic_Sign(
OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length,
OEMCrypto_Algorithm algorithm, uint8_t* signature,
size_t* signature_length) {
if (!crypto_engine) {
LOGE("OEMCrypto_Generic_Sign: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1311,7 +1313,7 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session,
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_Generic_Verify(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_Generic_Verify(
OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length,
OEMCrypto_Algorithm algorithm, const uint8_t* signature,
size_t signature_length) {
@@ -1340,11 +1342,11 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Verify(
}
// TODO(fredgc): remove this.
extern "C" OEMCryptoResult OEMCrypto_UpdateUsageTable() {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_UpdateUsageTable() {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeactivateUsageEntry(
OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length) {
if (!crypto_engine) {
LOGE("OEMCrypto_DeactivateUsageEntry: OEMCrypto Not Initialized.");
@@ -1362,11 +1364,11 @@ extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(
return session_ctx->DeactivateUsageEntry(pstv);
}
extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length,
uint8_t* buffer,
size_t* buffer_length) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length,
uint8_t* buffer,
size_t* buffer_length) {
if (!crypto_engine) {
LOGE("OEMCrypto_ReportUsage: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1387,21 +1389,20 @@ extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION,
const uint8_t*, size_t,
const uint8_t*, size_t,
const uint8_t*, size_t) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeleteUsageEntry(
OEMCrypto_SESSION, const uint8_t*, size_t, const uint8_t*, size_t,
const uint8_t*, size_t) {
// TODO(fredgc): delete this.
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t*,
size_t) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t*,
size_t) {
// TODO(fredgc): delete this.
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_DeleteOldUsageTable() {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeleteOldUsageTable() {
if (!crypto_engine) {
LOGE("OEMCrypto_DeleteOldUsageTable: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1412,7 +1413,7 @@ extern "C" OEMCryptoResult OEMCrypto_DeleteOldUsageTable() {
return crypto_engine->usage_table().DeleteOldUsageTable();
}
extern "C" bool OEMCrypto_IsSRMUpdateSupported() {
OEMCRYPTO_API bool OEMCrypto_IsSRMUpdateSupported() {
if (!crypto_engine) {
LOGE("OEMCrypto_IsSRMUpdateSupported: OEMCrypto Not Initialized.");
return false;
@@ -1421,7 +1422,8 @@ extern "C" bool OEMCrypto_IsSRMUpdateSupported() {
return result;
}
extern "C" OEMCryptoResult OEMCrypto_GetCurrentSRMVersion(uint16_t* version) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetCurrentSRMVersion(
uint16_t* version) {
if (!crypto_engine) {
LOGE("OEMCrypto_GetCurrentSRMVersion: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1433,8 +1435,8 @@ extern "C" OEMCryptoResult OEMCrypto_GetCurrentSRMVersion(uint16_t* version) {
return result;
}
extern "C" OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer,
size_t buffer_length) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer,
size_t buffer_length) {
if (!crypto_engine) {
LOGE("OEMCrypto_LoadSRM: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1442,7 +1444,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer,
return crypto_engine->load_srm(buffer, buffer_length);
}
extern "C" OEMCryptoResult OEMCrypto_RemoveSRM() {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_RemoveSRM() {
if (!crypto_engine) {
LOGE("OEMCrypto_RemoveSRM: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1450,7 +1452,7 @@ extern "C" OEMCryptoResult OEMCrypto_RemoveSRM() {
return crypto_engine->remove_srm();
}
extern "C" OEMCryptoResult OEMCrypto_CreateUsageTableHeader(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_CreateUsageTableHeader(
uint8_t* header_buffer, size_t* header_buffer_length) {
if (!crypto_engine) {
LOGE("OEMCrypto_CreateUsageTableHeader: OEMCrypto Not Initialized.");
@@ -1464,7 +1466,7 @@ extern "C" OEMCryptoResult OEMCrypto_CreateUsageTableHeader(
header_buffer, header_buffer_length);
}
extern "C" OEMCryptoResult OEMCrypto_LoadUsageTableHeader(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadUsageTableHeader(
const uint8_t* buffer, size_t buffer_length) {
if (!crypto_engine) {
LOGE("OEMCrypto_LoadUsageTableHeader: OEMCrypto Not Initialized.");
@@ -1481,7 +1483,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadUsageTableHeader(
return crypto_engine->usage_table().LoadUsageTableHeader(bufferv);
}
extern "C" OEMCryptoResult OEMCrypto_CreateNewUsageEntry(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_CreateNewUsageEntry(
OEMCrypto_SESSION session, uint32_t* usage_entry_number) {
if (!crypto_engine) {
LOGE("OEMCrypto_CreateNewUsageEntry: OEMCrypto Not Initialized.");
@@ -1502,10 +1504,9 @@ extern "C" OEMCryptoResult OEMCrypto_CreateNewUsageEntry(
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_LoadUsageEntry(OEMCrypto_SESSION session,
uint32_t index,
const uint8_t* buffer,
size_t buffer_size) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadUsageEntry(
OEMCrypto_SESSION session, uint32_t index, const uint8_t* buffer,
size_t buffer_size) {
if (!crypto_engine) {
LOGE("OEMCrypto_LoadUsageEntry: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1526,7 +1527,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadUsageEntry(OEMCrypto_SESSION session,
return session_ctx->LoadUsageEntry(index, bufferv);
}
extern "C" OEMCryptoResult OEMCrypto_UpdateUsageEntry(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_UpdateUsageEntry(
OEMCrypto_SESSION session, uint8_t* header_buffer,
size_t* header_buffer_length, uint8_t* entry_buffer,
size_t* entry_buffer_length) {
@@ -1549,7 +1550,7 @@ extern "C" OEMCryptoResult OEMCrypto_UpdateUsageEntry(
entry_buffer, entry_buffer_length);
}
extern "C" OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(
uint32_t new_table_size, uint8_t* header_buffer,
size_t* header_buffer_length) {
if (!crypto_engine) {
@@ -1563,8 +1564,8 @@ extern "C" OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(
new_table_size, header_buffer, header_buffer_length);
}
extern "C" OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session,
uint32_t new_index) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session,
uint32_t new_index) {
if (!crypto_engine) {
LOGE("OEMCrypto_MoveEntry: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1580,7 +1581,7 @@ extern "C" OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session,
return session_ctx->MoveEntry(new_index);
}
extern "C" OEMCryptoResult OEMCrypto_CopyOldUsageEntry(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_CopyOldUsageEntry(
OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length) {
if (!crypto_engine) {
LOGE("OEMCrypto_CopyOldUsageEntry: OEMCrypto Not Initialized.");
@@ -1598,7 +1599,7 @@ extern "C" OEMCryptoResult OEMCrypto_CopyOldUsageEntry(
return session_ctx->CopyOldUsageEntry(pstv);
}
extern "C" OEMCryptoResult OEMCrypto_CreateOldUsageEntry(
OEMCRYPTO_API 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,
@@ -1616,28 +1617,13 @@ extern "C" OEMCryptoResult OEMCrypto_CreateOldUsageEntry(
pst_length);
}
extern "C" uint32_t OEMCrypto_SupportsDecryptHash() {
OEMCRYPTO_API uint32_t OEMCrypto_SupportsDecryptHash() {
return OEMCrypto_CRC_Clear_Buffer;
}
extern "C" OEMCryptoResult OEMCrypto_InitializeDecryptHash(
OEMCrypto_SESSION session) {
if (!crypto_engine) {
LOGE("OEMCrypto_InitializeDecryptHash: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_InitializeDecryptHash(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
return session_ctx->InitializeDecryptHash();
}
extern "C" OEMCryptoResult OEMCrypto_SetDecryptHash(OEMCrypto_SESSION session,
uint32_t frame_number,
const uint8_t* hash,
size_t hash_length) {
OEMCRYPTO_API OEMCryptoResult OEMCrypto_SetDecryptHash(
OEMCrypto_SESSION session, uint32_t frame_number, const uint8_t* hash,
size_t hash_length) {
if (!crypto_engine) {
LOGE("OEMCrypto_SetDecryptHash: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -1650,7 +1636,7 @@ extern "C" OEMCryptoResult OEMCrypto_SetDecryptHash(OEMCrypto_SESSION session,
return session_ctx->SetDecryptHash(frame_number, hash, hash_length);
}
extern "C" OEMCryptoResult OEMCrypto_GetHashErrorCode(
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetHashErrorCode(
OEMCrypto_SESSION session, uint32_t* failed_frame_number) {
if (!crypto_engine) {
LOGE("OEMCrypto_GetHashErrorCode: OEMCrypto Not Initialized.");

View File

@@ -55,20 +55,20 @@ namespace wvoec_ref {
class ContentKeysContext : public SessionContextKeys {
public:
explicit ContentKeysContext() {}
virtual ~ContentKeysContext() {}
virtual size_t size() { return session_keys_.size(); }
bool Insert(const KeyId& key_id, const Key& key_data);
virtual Key* Find(const KeyId& key_id);
virtual void Remove(const KeyId& key_id);
virtual void UpdateDuration(const KeyControlBlock& control);
~ContentKeysContext() override {}
size_t size() override { return session_keys_.size(); }
bool Insert(const KeyId& key_id, const Key& key_data) override;
Key* Find(const KeyId& key_id) override;
void Remove(const KeyId& key_id) override;
void UpdateDuration(const KeyControlBlock& control) override;
virtual OEMCrypto_LicenseType type() { return OEMCrypto_ContentLicense; }
OEMCrypto_LicenseType type() override { return OEMCrypto_ContentLicense; }
virtual bool SetContentKey(const KeyId& entitlement_id,
const KeyId& content_key_id,
const std::vector<uint8_t>& content_key);
virtual bool GetEntitlementKey(const KeyId& entitlement_id,
const std::vector<uint8_t>** entitlement_key);
bool SetContentKey(const KeyId& entitlement_id,
const KeyId& content_key_id,
const std::vector<uint8_t>& content_key) override;
bool GetEntitlementKey(const KeyId& entitlement_id,
const std::vector<uint8_t>** entitlement_key) override;
private:
SessionKeyTable session_keys_;
@@ -109,19 +109,19 @@ bool ContentKeysContext::GetEntitlementKey(const KeyId& entitlement_id,
class EntitlementKeysContext : public SessionContextKeys {
public:
EntitlementKeysContext() {}
virtual ~EntitlementKeysContext() {}
virtual size_t size() { return session_keys_.size(); }
bool Insert(const KeyId& key_id, const Key& key_data);
virtual Key* Find(const KeyId& key_id);
virtual void Remove(const KeyId& key_id);
virtual void UpdateDuration(const KeyControlBlock& control);
virtual bool SetContentKey(const KeyId& entitlement_id,
const KeyId& content_key_id,
const std::vector<uint8_t>& content_key);
virtual bool GetEntitlementKey(const KeyId& entitlement_id,
const std::vector<uint8_t>** key);
~EntitlementKeysContext() override {}
size_t size() override { return session_keys_.size(); }
bool Insert(const KeyId& key_id, const Key& key_data) override;
Key* Find(const KeyId& key_id) override;
void Remove(const KeyId& key_id) override;
void UpdateDuration(const KeyControlBlock& control) override;
bool SetContentKey(const KeyId& entitlement_id,
const KeyId& content_key_id,
const std::vector<uint8_t>& content_key) override;
bool GetEntitlementKey(const KeyId& entitlement_id,
const std::vector<uint8_t>** key) override;
virtual OEMCrypto_LicenseType type() { return OEMCrypto_EntitlementLicense; }
OEMCrypto_LicenseType type() override { return OEMCrypto_EntitlementLicense; }
private:
EntitlementKeyTable session_keys_;
@@ -405,7 +405,7 @@ bool SessionContext::ValidateMessage(const uint8_t* given_message,
uint8_t computed_signature[SHA256_DIGEST_LENGTH];
memset(computed_signature, 0, SHA256_DIGEST_LENGTH);
unsigned int md_len = SHA256_DIGEST_LENGTH;
if (!HMAC(EVP_sha256(), &mac_key_server_[0], mac_key_server_.size(),
if (!HMAC(EVP_sha256(), mac_key_server_.data(), mac_key_server_.size(),
given_message, message_length, computed_signature, &md_len)) {
LOGE("ValidateMessage: Could not compute signature.");
return false;
@@ -1168,7 +1168,6 @@ OEMCryptoResult SessionContext::SelectContentKey(
LOGE("No key matches key id");
return OEMCrypto_ERROR_NO_CONTENT_KEY;
}
compute_hash_ = false;
content_key->set_ctr_mode(cipher_mode == OEMCrypto_CipherMode_CTR);
current_content_key_ = content_key;
const KeyControlBlock& control = current_content_key()->control();
@@ -1285,7 +1284,7 @@ OEMCryptoResult SessionContext::DecryptCENC(
const uint8_t* iv, size_t block_offset,
const OEMCrypto_CENCEncryptPatternDesc* pattern, const uint8_t* cipher_data,
size_t cipher_data_length, bool is_encrypted, uint8_t* clear_data,
OEMCryptoBufferType buffer_type) {
OEMCryptoBufferType buffer_type, uint8_t subsample_flags) {
OEMCryptoResult result =
ChooseDecrypt(iv, block_offset, pattern, cipher_data, cipher_data_length,
is_encrypted, clear_data, buffer_type);
@@ -1293,13 +1292,30 @@ OEMCryptoResult SessionContext::DecryptCENC(
if (current_content_key() == NULL ||
(current_content_key()->control().control_bits() &
wvoec::kControlAllowHashVerification) == 0) {
// This should not happen: this check should already have occured in
// InitializeDecryptHash or the hash should have been discarded in
// SelectContentKey. But it doesn't hurt to double check.
LOGE("[DecryptCENC(): OEMCrypto_ERROR_UNKNOWN_FAILURE]");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
hash_error_ = OEMCrypto_ERROR_UNKNOWN_FAILURE;
compute_hash_ = false;
current_hash_ = 0;
current_frame_number_ = 0;
} else {
if (OEMCrypto_FirstSubsample & subsample_flags) {
current_hash_ = wvcrc32Init();
}
current_hash_ =
wvcrc32Cont(clear_data, cipher_data_length, current_hash_);
if (OEMCrypto_LastSubsample & subsample_flags) {
if (current_hash_ != given_hash_) {
LOGE("CRC for frame %d is %08x, should be %08x\n",
current_frame_number_, current_hash_, given_hash_);
// Update bad_frame_number_ only if this is the first bad frame.
if (hash_error_ == OEMCrypto_SUCCESS) {
bad_frame_number_ = current_frame_number_;
hash_error_ = OEMCrypto_ERROR_BAD_HASH;
}
}
compute_hash_ = false;
}
}
current_hash_ = wvcrc32Cont(clear_data, cipher_data_length, current_hash_);
}
return result;
}
@@ -1526,36 +1542,9 @@ OEMCryptoResult SessionContext::DecryptCTR(const uint8_t* key_u8,
return OEMCrypto_SUCCESS;
}
OEMCryptoResult SessionContext::InitializeDecryptHash() {
// Check there is a content key, and it is allowed.
if (current_content_key() == NULL ||
(current_content_key()->control().control_bits() &
wvoec::kControlAllowHashVerification) == 0) {
LOGE("[InitializeDecryptHash(): OEMCrypto_ERROR_UNKNOWN_FAILURE]");
compute_hash_ = false;
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
compute_hash_ = true;
current_hash_ = wvcrc32Init();
return OEMCrypto_SUCCESS;
}
OEMCryptoResult SessionContext::SetDecryptHash(uint32_t frame_number,
const uint8_t* hash,
size_t hash_length) {
// Check there is a content key, and it is allowed.
if (current_content_key() == NULL ||
(current_content_key()->control().control_bits() &
wvoec::kControlAllowHashVerification) == 0) {
LOGE("[SetDecryptHash(): OEMCrypto_ERROR_UNKNOWN_FAILURE]");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!compute_hash_) {
// This would happen if somebody computes the hash, and then changes keys.
LOGE("[SetDecryptHash(): OEMCrypto_ERROR_UNKNOWN_FAILURE]");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
compute_hash_ = false;
if (hash_length < sizeof(uint32_t)) {
LOGE("[SetDecryptHash(): short buffer]");
return OEMCrypto_ERROR_SHORT_BUFFER;
@@ -1564,15 +1553,9 @@ OEMCryptoResult SessionContext::SetDecryptHash(uint32_t frame_number,
LOGE("[SetDecryptHash(): long buffer]");
return OEMCrypto_ERROR_BUFFER_TOO_LARGE;
}
uint32_t given_hash = *reinterpret_cast<const uint32_t*>(hash);
if (current_hash_ != given_hash) {
LOGE("CRC for frame %d is %08x, should be %08x\n", frame_number,
current_hash_, given_hash);
// Update bad_frame_number_ only if this is the first bad frame.
if (hash_error_ == OEMCrypto_SUCCESS) bad_frame_number_ = frame_number;
hash_error_ = OEMCrypto_ERROR_BAD_HASH;
}
// Return success if the hash was compared, even if there was an error.
compute_hash_ = true;
current_frame_number_ = frame_number;
given_hash_ = *reinterpret_cast<const uint32_t*>(hash);
return OEMCrypto_SUCCESS;
}

View File

@@ -102,7 +102,8 @@ class SessionContext {
const uint8_t* cipher_data,
size_t cipher_data_length, bool is_encrypted,
uint8_t* clear_data,
OEMCryptoBufferType buffer_type);
OEMCryptoBufferType buffer_type,
uint8_t subsample_flags);
OEMCryptoResult Generic_Encrypt(const uint8_t* in_buffer,
size_t buffer_length, const uint8_t* iv,
@@ -152,7 +153,6 @@ class SessionContext {
virtual bool QueryKeyControlBlock(const KeyId& key_id, uint32_t* data);
virtual OEMCryptoResult SelectContentKey(const KeyId& key_id,
OEMCryptoCipherMode cipher_mode);
virtual OEMCryptoResult InitializeDecryptHash();
virtual OEMCryptoResult SetDecryptHash(uint32_t frame_number,
const uint8_t* hash,
size_t hash_length);
@@ -258,7 +258,9 @@ class SessionContext {
// These are used when doing full decrypt path testing.
bool compute_hash_; // True if the current frame needs a hash.
uint32_t current_hash_; // Running CRC hash of frame.
uint32_t bad_frame_number_; // Frame number with bad hash.
uint32_t given_hash_; // True CRC hash of frame.
uint32_t current_frame_number_; // Current frame for CRC hash.
uint32_t bad_frame_number_; // Frame number with bad hash.
OEMCryptoResult hash_error_; // Error code for first bad frame.
CORE_DISALLOW_COPY_AND_ASSIGN(SessionContext);

View File

@@ -325,7 +325,7 @@ OEMCryptoResult UsageTableEntry::CopyOldUsageEntry(
} else {
data_.pst_length = pst.size();
}
memcpy(data_.pst, &pst[0], data_.pst_length);
memcpy(data_.pst, pst.data(), data_.pst_length);
data_.pst[data_.pst_length] = '\0';
return OEMCrypto_SUCCESS;
}
@@ -669,7 +669,7 @@ bool UsageTable::SaveGenerationNumber() {
// On a real implementation, you should NOT put the generation number in
// a file in user space. It should be stored in secure memory.
std::string filename = path + "GenerationNumber.dat";
wvcdm::File* file = file_system->Open(
auto file = file_system->Open(
filename, wvcdm::FileSystem::kCreate | wvcdm::FileSystem::kTruncate);
if (!file) {
LOGE("UsageTable: File open failed: %s", path.c_str());
@@ -677,7 +677,6 @@ bool UsageTable::SaveGenerationNumber() {
}
file->Write(reinterpret_cast<char*>(&master_generation_number_),
sizeof(int64_t));
file->Close();
return true;
}
@@ -696,7 +695,7 @@ bool UsageTable::LoadGenerationNumber(bool or_make_new_one) {
// On a real implementation, you should NOT put the generation number in
// a file in user space. It should be stored in secure memory.
std::string filename = path + "GenerationNumber.dat";
wvcdm::File* file = file_system->Open(filename, wvcdm::FileSystem::kReadOnly);
auto file = file_system->Open(filename, wvcdm::FileSystem::kReadOnly);
if (!file) {
if (or_make_new_one) {
RAND_bytes(reinterpret_cast<uint8_t*>(&master_generation_number_),
@@ -709,7 +708,6 @@ bool UsageTable::LoadGenerationNumber(bool or_make_new_one) {
}
file->Read(reinterpret_cast<char*>(&master_generation_number_),
sizeof(int64_t));
file->Close();
return true;
}

View File

@@ -7,6 +7,8 @@
#include <arpa/inet.h>
#include "wvcrc32.h"
namespace wvoec_ref {
#define INIT_CRC32 0xffffffff
uint32_t wvrunningcrc32(const uint8_t* p_begin, int i_count, uint32_t i_crc) {
@@ -102,3 +104,5 @@ uint32_t wvcrc32Cont(const uint8_t* p_begin, int i_count, uint32_t prev_crc) {
uint32_t wvcrc32n(const uint8_t* p_begin, int i_count) {
return htonl(wvrunningcrc32(p_begin, i_count, INIT_CRC32));
}
} // namespace wvoec_ref

View File

@@ -9,6 +9,8 @@
#include <stdint.h>
namespace wvoec_ref {
uint32_t wvcrc32(const uint8_t* p_begin, int i_count);
uint32_t wvcrc32Init();
uint32_t wvcrc32Cont(const uint8_t* p_begin, int i_count, uint32_t prev_crc);
@@ -16,4 +18,6 @@ uint32_t wvcrc32Cont(const uint8_t* p_begin, int i_count, uint32_t prev_crc);
// Convert to network byte order
uint32_t wvcrc32n(const uint8_t* p_begin, int i_count);
} // namespace wvoec_ref
#endif // WVCRC32_H_

View File

@@ -96,7 +96,7 @@ void DeviceFeatures::Initialize(bool is_cast_receiver,
}
printf("cast_receiver = %s.\n", cast_receiver ? "true" : "false");
resource_rating = OEMCrypto_ResourceRatingTier();
printf("resource_rating = %d, security leve %s.\n", resource_rating,
printf("resource_rating = %d, security level %s.\n", resource_rating,
OEMCrypto_SecurityLevel());
uint32_t decrypt_hash_type = OEMCrypto_SupportsDecryptHash();
supports_crc = (decrypt_hash_type == OEMCrypto_CRC_Clear_Buffer);

View File

@@ -212,7 +212,7 @@ void Session::DeriveKey(const uint8_t* key, const vector<uint8_t>& context,
message.push_back(counter);
message.insert(message.end(), context.begin(), context.end());
ASSERT_EQ(1, CMAC_Update(cmac_ctx, &message[0], message.size()));
ASSERT_EQ(1, CMAC_Update(cmac_ctx, message.data(), message.size()));
size_t reslen;
uint8_t res[128];
@@ -248,9 +248,9 @@ void Session::GenerateDerivedKeysFromKeybox(
vector<uint8_t> enc_context;
FillDefaultContext(&mac_context, &enc_context);
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GenerateDerivedKeys(session_id(), &mac_context[0],
mac_context.size(), &enc_context[0],
enc_context.size()));
OEMCrypto_GenerateDerivedKeys(
session_id(), mac_context.data(), mac_context.size(),
enc_context.data(), enc_context.size()));
DeriveKeys(keybox.device_key_, mac_context, enc_context);
}
@@ -267,11 +267,11 @@ void Session::GenerateDerivedKeysFromSessionKey() {
FillDefaultContext(&mac_context, &enc_context);
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_DeriveKeysFromSessionKey(
session_id(), &enc_session_key[0], enc_session_key.size(),
&mac_context[0], mac_context.size(), &enc_context[0],
session_id(), enc_session_key.data(), enc_session_key.size(),
mac_context.data(), mac_context.size(), enc_context.data(),
enc_context.size()));
DeriveKeys(&session_key[0], mac_context, enc_context);
DeriveKeys(session_key.data(), mac_context, enc_context);
}
void Session::LoadTestKeys(const std::string& provider_session_token,
@@ -288,16 +288,17 @@ void Session::LoadTestKeys(const std::string& provider_session_token,
if (new_mac_keys) {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadKeys(
session_id(), message_ptr(), message_size_, &signature_[0],
session_id(), message_ptr(), message_size_, signature_.data(),
signature_.size(), enc_mac_keys_iv, enc_mac_keys, num_keys_,
key_array_, pst, GetSubstring(), OEMCrypto_ContentLicense));
// Update new generated keys.
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, MAC_KEY_SIZE);
memcpy(mac_key_server_.data(), license_.mac_keys, MAC_KEY_SIZE);
memcpy(mac_key_client_.data(), license_.mac_keys + MAC_KEY_SIZE,
MAC_KEY_SIZE);
} else {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadKeys(
session_id(), message_ptr(), message_size_, &signature_[0],
session_id(), message_ptr(), message_size_, signature_.data(),
signature_.size(), GetSubstring(), GetSubstring(), num_keys_,
key_array_, pst, GetSubstring(), OEMCrypto_ContentLicense));
}
@@ -320,17 +321,19 @@ void Session::LoadEntitlementTestKeys(const std::string& provider_session_token,
ASSERT_EQ(
expected_sts,
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
&signature_[0], signature_.size(), enc_mac_keys_iv,
enc_mac_keys, num_keys_, key_array_, pst,
GetSubstring(), OEMCrypto_EntitlementLicense));
signature_.data(), signature_.size(),
enc_mac_keys_iv, enc_mac_keys, num_keys_,
key_array_, pst, GetSubstring(),
OEMCrypto_EntitlementLicense));
// Update new generated keys.
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, MAC_KEY_SIZE);
memcpy(mac_key_server_.data(), license_.mac_keys, MAC_KEY_SIZE);
memcpy(mac_key_client_.data(), license_.mac_keys + MAC_KEY_SIZE,
MAC_KEY_SIZE);
} else {
ASSERT_EQ(
expected_sts,
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
&signature_[0], signature_.size(), GetSubstring(),
signature_.data(), signature_.size(), GetSubstring(),
GetSubstring(), num_keys_, key_array_, pst,
GetSubstring(), OEMCrypto_EntitlementLicense));
}
@@ -381,10 +384,8 @@ void Session::FillEntitledKeyArray() {
void Session::LoadEntitledContentKeys(OEMCryptoResult expected_sts) {
encrypted_entitled_message_ = entitled_message_;
std::vector<OEMCrypto_EntitledContentKeyObject> encrypted_entitled_key_array;
encrypted_entitled_key_array.resize(num_keys_);
memcpy(&encrypted_entitled_key_array[0], &entitled_key_array_[0],
sizeof(OEMCrypto_EntitledContentKeyObject) * num_keys_);
std::vector<OEMCrypto_EntitledContentKeyObject> encrypted_entitled_key_array(
entitled_key_array_, entitled_key_array_ + num_keys_);
for (size_t i = 0; i < num_keys_; ++i) {
// Load the entitlement key from |key_array_|.
@@ -416,7 +417,7 @@ void Session::LoadEntitledContentKeys(OEMCryptoResult expected_sts) {
session_id(),
reinterpret_cast<const uint8_t*>(encrypted_entitled_message_.data()),
encrypted_entitled_message_.size(), num_keys_,
&encrypted_entitled_key_array[0]));
encrypted_entitled_key_array.data()));
if (expected_sts != OEMCrypto_SUCCESS) {
return;
}
@@ -479,11 +480,11 @@ void Session::RefreshTestKeys(const size_t key_count, uint32_t control_bits,
FillRefreshMessage(key_count, control_bits, nonce);
ServerSignBuffer(reinterpret_cast<const uint8_t*>(&padded_message_),
message_size_, &signature_);
OEMCrypto_KeyRefreshObject key_array[key_count];
FillRefreshArray(key_array, key_count);
std::vector<OEMCrypto_KeyRefreshObject> key_array(key_count);
FillRefreshArray(key_array.data(), key_count);
OEMCryptoResult sts = OEMCrypto_RefreshKeys(
session_id(), message_ptr(), message_size_, &signature_[0],
signature_.size(), key_count, key_array);
session_id(), message_ptr(), message_size_, signature_.data(),
signature_.size(), key_count, key_array.data());
ASSERT_EQ(expected_result, sts);
ASSERT_NO_FATAL_FAILURE(TestDecryptCTR());
@@ -625,7 +626,7 @@ void Session::SetLoadKeysSubstringParams() {
load_keys_params_.resize(4);
std::string message =
wvcdm::BytesToString(message_ptr(), sizeof(MessageData));
OEMCrypto_Substring* enc_mac_keys_iv = &load_keys_params_[0];
OEMCrypto_Substring* enc_mac_keys_iv = load_keys_params_.data();
*enc_mac_keys_iv = GetSubstring(
message, wvcdm::BytesToString(encrypted_license().mac_key_iv,
sizeof(encrypted_license().mac_key_iv)));
@@ -648,7 +649,7 @@ void Session::EncryptAndSign() {
uint8_t iv_buffer[16];
memcpy(iv_buffer, &license_.mac_key_iv[0], KEY_IV_SIZE);
AES_KEY aes_key;
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_set_encrypt_key(enc_key_.data(), 128, &aes_key);
AES_cbc_encrypt(&license_.mac_keys[0], &encrypted_license().mac_keys[0],
2 * MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
@@ -661,7 +662,7 @@ void Session::EncryptAndSign() {
KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
memcpy(iv_buffer, &license_.keys[i].key_iv[0], KEY_IV_SIZE);
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_set_encrypt_key(enc_key_.data(), 128, &aes_key);
AES_cbc_encrypt(
&license_.keys[i].key_data[0], &encrypted_license().keys[i].key_data[0],
license_.keys[i].key_data_length, &aes_key, iv_buffer, AES_ENCRYPT);
@@ -695,7 +696,7 @@ void Session::ServerSignBuffer(const uint8_t* data, size_t data_length,
ASSERT_LE(data_length, kMaxMessageSize);
signature->assign(SHA256_DIGEST_LENGTH, 0);
unsigned int md_len = SHA256_DIGEST_LENGTH;
HMAC(EVP_sha256(), &mac_key_server_[0], mac_key_server_.size(), data,
HMAC(EVP_sha256(), mac_key_server_.data(), mac_key_server_.size(), data,
data_length, &(signature->front()), &md_len);
}
@@ -703,7 +704,7 @@ void Session::ClientSignMessage(const vector<uint8_t>& data,
std::vector<uint8_t>* signature) {
signature->assign(SHA256_DIGEST_LENGTH, 0);
unsigned int md_len = SHA256_DIGEST_LENGTH;
HMAC(EVP_sha256(), &mac_key_client_[0], mac_key_client_.size(),
HMAC(EVP_sha256(), mac_key_client_.data(), mac_key_client_.size(),
&(data.front()), data.size(), &(signature->front()), &md_len);
}
@@ -714,13 +715,14 @@ void Session::VerifyClientSignature(size_t data_length) {
for (size_t i = 0; i < data.size(); i++) data[i] = i % 0xFF;
OEMCryptoResult sts;
size_t gen_signature_length = 0;
sts = OEMCrypto_GenerateSignature(session_id(), &data[0], data.size(), NULL,
&gen_signature_length);
sts = OEMCrypto_GenerateSignature(session_id(), data.data(), data.size(),
NULL, &gen_signature_length);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
ASSERT_EQ(static_cast<size_t>(32), gen_signature_length);
vector<uint8_t> gen_signature(gen_signature_length);
sts = OEMCrypto_GenerateSignature(session_id(), &data[0], data.size(),
&gen_signature[0], &gen_signature_length);
sts = OEMCrypto_GenerateSignature(session_id(), data.data(), data.size(),
gen_signature.data(),
&gen_signature_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
std::vector<uint8_t> expected_signature;
ClientSignMessage(data, &expected_signature);
@@ -809,12 +811,12 @@ void Session::TestDecryptCTR(bool select_key_first,
vector<uint8_t> unencryptedData(256);
for (size_t i = 0; i < unencryptedData.size(); i++)
unencryptedData[i] = i % 256;
EXPECT_EQ(1, GetRandBytes(&unencryptedData[0], unencryptedData.size()));
EXPECT_EQ(1, GetRandBytes(unencryptedData.data(), unencryptedData.size()));
vector<uint8_t> encryptionIv(KEY_IV_SIZE);
EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], KEY_IV_SIZE));
EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), KEY_IV_SIZE));
vector<uint8_t> encryptedData(unencryptedData.size());
EncryptCTR(unencryptedData, license_.keys[key_index].key_data,
&encryptionIv[0], &encryptedData);
encryptionIv.data(), &encryptedData);
// Describe the output
vector<uint8_t> outputBuffer(256);
@@ -828,8 +830,8 @@ void Session::TestDecryptCTR(bool select_key_first,
pattern.offset = 0;
// Decrypt the data
sts = OEMCrypto_DecryptCENC(
session_id(), &encryptedData[0], encryptedData.size(), true,
&encryptionIv[0], 0, &destBuffer, &pattern,
session_id(), encryptedData.data(), encryptedData.size(), true,
encryptionIv.data(), 0, &destBuffer, &pattern,
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample);
// We only have a few errors that we test are reported.
if (expected_result == OEMCrypto_SUCCESS) { // No error.
@@ -886,7 +888,7 @@ void Session::LoadOEMCert(bool verify_cert) {
ASSERT_LT(0u, public_cert_length);
public_cert.resize(public_cert_length);
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GetOEMPublicCertificate(session_id(), &public_cert[0],
OEMCrypto_GetOEMPublicCertificate(session_id(), public_cert.data(),
&public_cert_length));
// Load the certificate chain into a BoringSSL X509 Stack
@@ -921,7 +923,7 @@ void Session::LoadOEMCert(bool verify_cert) {
X509_NAME* name = X509_get_subject_name(x509_cert);
printf(" OEM Certificate Name: %s\n",
X509_NAME_oneline(name, &buffer[0], buffer.size()));
X509_NAME_oneline(name, buffer.data(), buffer.size()));
boringssl_ptr<X509_STORE, X509_STORE_free> store(X509_STORE_new());
ASSERT_TRUE(store.NotNull());
boringssl_ptr<X509_STORE_CTX, X509_STORE_CTX_free> store_ctx(
@@ -979,16 +981,17 @@ void Session::RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
const uint8_t* message_ptr = reinterpret_cast<const uint8_t*>(&encrypted);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_RewrapDeviceRSAKey(
session_id(), message_ptr, message_size, &signature[0],
session_id(), message_ptr, message_size, signature.data(),
signature.size(), &encrypted.nonce, encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL,
&wrapped_key_length));
wrapped_key->clear();
wrapped_key->assign(wrapped_key_length, 0);
OEMCryptoResult sts = OEMCrypto_RewrapDeviceRSAKey(
session_id(), message_ptr, message_size, &signature[0], signature.size(),
&encrypted.nonce, encrypted.rsa_key, encrypted.rsa_key_length,
encrypted.rsa_key_iv, &(wrapped_key->front()), &wrapped_key_length);
session_id(), message_ptr, message_size, signature.data(),
signature.size(), &encrypted.nonce, encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, &(wrapped_key->front()),
&wrapped_key_length);
if (force) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
}
@@ -1003,14 +1006,14 @@ void Session::RewrapRSAKey30(const struct RSAPrivateKeyMessage& encrypted,
size_t wrapped_key_length = 0;
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_RewrapDeviceRSAKey30(
session_id(), &nonce_, &encrypted_message_key[0],
session_id(), &nonce_, encrypted_message_key.data(),
encrypted_message_key.size(), encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL,
&wrapped_key_length));
wrapped_key->clear();
wrapped_key->assign(wrapped_key_length, 0);
OEMCryptoResult sts = OEMCrypto_RewrapDeviceRSAKey30(
session_id(), &nonce_, &encrypted_message_key[0],
session_id(), &nonce_, encrypted_message_key.data(),
encrypted_message_key.size(), encrypted.rsa_key, encrypted.rsa_key_length,
encrypted.rsa_key_iv, &(wrapped_key->front()), &wrapped_key_length);
if (force) {
@@ -1121,16 +1124,18 @@ void Session::VerifyRSASignature(const vector<uint8_t>& message,
boringssl_ptr<EVP_PKEY, EVP_PKEY_free> pkey(EVP_PKEY_new());
ASSERT_EQ(1, EVP_PKEY_set1_RSA(pkey.get(), public_rsa_));
const bool ok = VerifyPSSSignature(pkey.get(), &message[0], message.size(),
signature, signature_length);
const bool ok = VerifyPSSSignature(
pkey.get(), message.data(), message.size(), signature,
signature_length);
EXPECT_TRUE(ok) << "PSS signature check failed.";
} else if (padding_scheme == kSign_PKCS1_Block1) {
vector<uint8_t> padded_digest(signature_length);
int size;
// RSA_public_decrypt decrypts the signature, and then verifies that
// it was padded with RSA PKCS1 padding.
size = RSA_public_decrypt(signature_length, signature, &padded_digest[0],
public_rsa_, RSA_PKCS1_PADDING);
size = RSA_public_decrypt(
signature_length, signature, padded_digest.data(), public_rsa_,
RSA_PKCS1_PADDING);
EXPECT_GT(size, 0);
padded_digest.resize(size);
EXPECT_EQ(message, padded_digest);
@@ -1161,7 +1166,7 @@ bool Session::GenerateRSASessionKey(vector<uint8_t>* session_key,
void Session::InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key) {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadDeviceRSAKey(session_id(), &wrapped_rsa_key[0],
OEMCrypto_LoadDeviceRSAKey(session_id(), wrapped_rsa_key.data(),
wrapped_rsa_key.size()));
GenerateDerivedKeysFromSessionKey();
}
@@ -1189,8 +1194,8 @@ void Session::UpdateUsageEntry(std::vector<uint8_t>* header_buffer) {
encrypted_usage_entry_.resize(entry_buffer_length);
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_UpdateUsageEntry(
session_id(), &(header_buffer->front()), &header_buffer_length,
&encrypted_usage_entry_[0], &entry_buffer_length));
session_id(), header_buffer->data(), &header_buffer_length,
encrypted_usage_entry_.data(), &entry_buffer_length));
}
void Session::DeactivateUsageEntry(const std::string& pst) {
@@ -1205,7 +1210,8 @@ void Session::LoadUsageEntry(uint32_t index, const vector<uint8_t>& buffer) {
encrypted_usage_entry_ = buffer;
ASSERT_EQ(
OEMCrypto_SUCCESS,
OEMCrypto_LoadUsageEntry(session_id(), index, &buffer[0], buffer.size()));
OEMCrypto_LoadUsageEntry(
session_id(), index, buffer.data(), buffer.size()));
}
void Session::MoveUsageEntry(uint32_t new_index,
@@ -1233,7 +1239,7 @@ void Session::GenerateReport(const std::string& pst,
size_t length = 0;
OEMCryptoResult sts = OEMCrypto_ReportUsage(
session_id(), reinterpret_cast<const uint8_t*>(pst.c_str()), pst.length(),
&pst_report_buffer_[0], &length);
pst_report_buffer_.data(), &length);
if (expected_result == OEMCrypto_SUCCESS) {
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
}
@@ -1243,7 +1249,7 @@ void Session::GenerateReport(const std::string& pst,
}
sts = OEMCrypto_ReportUsage(session_id(),
reinterpret_cast<const uint8_t*>(pst.c_str()),
pst.length(), &pst_report_buffer_[0], &length);
pst.length(), pst_report_buffer_.data(), &length);
ASSERT_EQ(expected_result, sts);
if (expected_result != OEMCrypto_SUCCESS) {
return;
@@ -1251,10 +1257,10 @@ void Session::GenerateReport(const std::string& pst,
ASSERT_EQ(pst_report_buffer_.size(), length);
vector<uint8_t> computed_signature(SHA_DIGEST_LENGTH);
unsigned int sig_len = SHA_DIGEST_LENGTH;
HMAC(EVP_sha1(), &mac_key_client_[0], mac_key_client_.size(),
HMAC(EVP_sha1(), mac_key_client_.data(), mac_key_client_.size(),
&pst_report_buffer_[SHA_DIGEST_LENGTH], length - SHA_DIGEST_LENGTH,
&computed_signature[0], &sig_len);
EXPECT_EQ(0, memcmp(&computed_signature[0], pst_report().signature(),
computed_signature.data(), &sig_len);
EXPECT_EQ(0, memcmp(computed_signature.data(), pst_report().signature(),
SHA_DIGEST_LENGTH));
EXPECT_GE(kInactiveUnused, pst_report().status());
EXPECT_GE(kHardwareSecureClock, pst_report().clock_security_level());
@@ -1287,14 +1293,14 @@ void Session::VerifyPST(const Test_PST_Report& expected) {
}
std::vector<uint8_t> signature(SHA_DIGEST_LENGTH);
unsigned int md_len = SHA_DIGEST_LENGTH;
if (!HMAC(EVP_sha1(), &mac_key_client_[0], mac_key_client_.size(),
&pst_report_buffer_[0] + SHA_DIGEST_LENGTH,
pst_report_buffer_.size() - SHA_DIGEST_LENGTH,
&signature[0], &md_len)) {
if (!HMAC(EVP_sha1(), mac_key_client_.data(), mac_key_client_.size(),
pst_report_buffer_.data() + SHA_DIGEST_LENGTH,
pst_report_buffer_.size() - SHA_DIGEST_LENGTH,
signature.data(), &md_len)) {
cout << "Error computing HMAC.\n";
dump_boringssl_error();
}
EXPECT_EQ(0, memcmp(computed.signature(), &signature[0],
EXPECT_EQ(0, memcmp(computed.signature(), signature.data(),
SHA_DIGEST_LENGTH));
}
@@ -1336,8 +1342,8 @@ void Session::CreateOldEntry(const Test_PST_Report& report) {
report.seconds_since_license_received,
report.seconds_since_first_decrypt,
report.seconds_since_last_decrypt,
report.status, &mac_key_server_[0],
&mac_key_client_[0],
report.status, mac_key_server_.data(),
mac_key_client_.data(),
reinterpret_cast<const uint8_t*>(report.pst.c_str()),
report.pst.length());
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) return;

View File

@@ -15,44 +15,9 @@
namespace wvoec {
// TODO(fredgc, b/119316243): REMOVE THIS KEYBOX!
// This test keybox is used for testing with OEMCrypto v13.
// It should be removed before release!
static const WidevineKeybox kTestKeyboxForV13 = {
// Sample keybox used for test vectors
{
// deviceID
0x54, 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x30, // TestKey01
0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
}, {
// key
0xfb, 0xda, 0x04, 0x89, 0xa1, 0x58, 0x16, 0x0e,
0xa4, 0x02, 0xe9, 0x29, 0xe3, 0xb6, 0x8f, 0x04,
}, {
// data
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x19,
0x07, 0xd9, 0xff, 0xde, 0x13, 0xaa, 0x95, 0xc1,
0x22, 0x67, 0x80, 0x53, 0x36, 0x21, 0x36, 0xbd,
0xf8, 0x40, 0x8f, 0x82, 0x76, 0xe4, 0xc2, 0xd8,
0x7e, 0xc5, 0x2b, 0x61, 0xaa, 0x1b, 0x9f, 0x64,
0x6e, 0x58, 0x73, 0x49, 0x30, 0xac, 0xeb, 0xe8,
0x99, 0xb3, 0xe4, 0x64, 0x18, 0x9a, 0x14, 0xa8,
0x72, 0x02, 0xfb, 0x02, 0x57, 0x4e, 0x70, 0x64,
0x0b, 0xd2, 0x2e, 0xf4, 0x4b, 0x2d, 0x7e, 0x39,
}, {
// magic
0x6b, 0x62, 0x6f, 0x78,
}, {
// Crc
0x0a, 0x7a, 0x2c, 0x35,
}
};
// This is a test keybox. They will not be accepted by production systems.
// By using known keyboxes for these tests, the results for a given set of
// inputs to a test are predictable and can be compared to the actual results.
// This is a test keybox. It will not be accepted by production systems. By
// using a known keybox for these tests, the results for a given set of inputs
// to a test are predictable and can be compared to the actual results.
static const WidevineKeybox kTestKeybox = {
// Sample keybox used for test vectors
{

View File

@@ -103,8 +103,6 @@ void SessionUtil::EnsureTestKeys() {
switch (global_features.derive_key_method) {
case DeviceFeatures::LOAD_TEST_KEYBOX:
keybox_ = kTestKeybox;
// TODO(fredgc, b/119316243): REMOVE FOLLOWING LINE:
if (global_features.api_version < 14) keybox_ = kTestKeyboxForV13;
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadTestKeybox(
reinterpret_cast<const uint8_t*>(&keybox_),

File diff suppressed because it is too large Load Diff

View File

@@ -23,12 +23,12 @@ namespace wvoec {
// These tests are required for LollyPop Android devices.
class OEMCryptoAndroidLMPTest : public ::testing::Test {
protected:
virtual void SetUp() {
void SetUp() override {
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
}
virtual void TearDown() { OEMCrypto_Terminate(); }
void TearDown() override { OEMCrypto_Terminate(); }
};
// Android devices must have a keybox, or use provisioning 3.0.

View File

@@ -19,7 +19,6 @@
'sources': [
'oemcrypto_test_main.cpp',
'<(platform_specific_dir)/file_store.cpp',
'<(platform_specific_dir)/lock.cpp',
'<(platform_specific_dir)/log.cpp',
'<(util_dir)/src/string_conversions.cpp',
],

View File

@@ -10,7 +10,7 @@
'oec_session_util.cpp',
'oemcrypto_session_tests_helper.cpp',
'oemcrypto_test.cpp',
'<(oemcrypto_dir)/ref/src/wvcrc.cpp',
'wvcrc.cpp',
],
'include_dirs': [
'<(util_dir)/include',

108
oemcrypto/test/wvcrc.cpp Normal file
View File

@@ -0,0 +1,108 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
//
// Compute CRC32 Checksum. Needed for verification of WV Keybox.
//
#include <arpa/inet.h>
#include "wvcrc32.h"
namespace wvoec {
#define INIT_CRC32 0xffffffff
uint32_t wvrunningcrc32(const uint8_t* p_begin, int i_count, uint32_t i_crc) {
static uint32_t CRC32[256] = {
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};
/* Calculate the CRC */
while (i_count > 0) {
i_crc = (i_crc << 8) ^ CRC32[(i_crc >> 24) ^ ((uint32_t) * p_begin)];
p_begin++;
i_count--;
}
return(i_crc);
}
uint32_t wvcrc32(const uint8_t* p_begin, int i_count) {
return(wvrunningcrc32(p_begin, i_count, INIT_CRC32));
}
uint32_t wvcrc32Init() {
return INIT_CRC32;
}
uint32_t wvcrc32Cont(const uint8_t* p_begin, int i_count, uint32_t prev_crc) {
return(wvrunningcrc32(p_begin, i_count, prev_crc));
}
uint32_t wvcrc32n(const uint8_t* p_begin, int i_count) {
return htonl(wvrunningcrc32(p_begin, i_count, INIT_CRC32));
}
} // namespace wvoec

23
oemcrypto/test/wvcrc32.h Normal file
View File

@@ -0,0 +1,23 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
//
// Compute CRC32 Checksum. Needed for verification of WV Keybox.
//
#ifndef CDM_WVCRC32_H_
#define CDM_WVCRC32_H_
#include <stdint.h>
namespace wvoec {
uint32_t wvcrc32(const uint8_t* p_begin, int i_count);
uint32_t wvcrc32Init();
uint32_t wvcrc32Cont(const uint8_t* p_begin, int i_count, uint32_t prev_crc);
// Convert to network byte order
uint32_t wvcrc32n(const uint8_t* p_begin, int i_count);
} // namespace wvoec
#endif // CDM_WVCRC32_H_

View File

@@ -8,35 +8,33 @@
#define WVCDM_UTIL_FILE_STORE_H_
#include <unistd.h>
#include <memory>
#include <string>
#include <vector>
#include "disallow_copy_and_assign.h"
#include "util_common.h"
namespace wvcdm {
// File class. The implementation is platform dependent.
class File {
class CORE_UTIL_EXPORT File {
public:
virtual ssize_t Read(char* buffer, size_t bytes);
virtual ssize_t Write(const char* buffer, size_t bytes);
virtual void Close();
protected:
class Impl;
File(Impl*);
virtual ~File();
private:
Impl* impl_;
File() {}
virtual ~File() {}
virtual ssize_t Read(char* buffer, size_t bytes) = 0;
virtual ssize_t Write(const char* buffer, size_t bytes) = 0;
friend class FileSystem;
CORE_DISALLOW_COPY_AND_ASSIGN(File);
};
class FileSystem {
class CORE_UTIL_EXPORT FileSystem {
public:
FileSystem();
FileSystem(const std::string& origin, void* extra_data);
virtual ~FileSystem();
class Impl;
// defines as bit flag
@@ -47,11 +45,7 @@ class FileSystem {
kTruncate = 4
};
FileSystem();
FileSystem(const std::string& origin, void* extra_data);
virtual ~FileSystem();
virtual File* Open(const std::string& file_path, int flags);
virtual std::unique_ptr<File> Open(const std::string& file_path, int flags);
virtual bool Exists(const std::string& file_path);
virtual bool Remove(const std::string& file_path);
@@ -63,14 +57,14 @@ class FileSystem {
std::vector<std::string>* names);
const std::string& origin() const { return origin_; }
void SetOrigin(const std::string& origin);
void set_origin(const std::string& origin);
const std::string& identifier() const { return identifier_; }
void SetIdentifier(const std::string& identifier);
void set_identifier(const std::string& identifier);
bool IsGlobal() const { return identifier_.empty(); }
private:
Impl* impl_;
std::unique_ptr<FileSystem::Impl> impl_;
std::string origin_;
std::string identifier_;

View File

@@ -7,6 +7,8 @@
#ifndef WVCDM_UTIL_LOG_H_
#define WVCDM_UTIL_LOG_H_
#include "util_common.h"
namespace wvcdm {
// Simple logging class. The implementation is platform dependent.
@@ -25,10 +27,11 @@ extern LogPriority g_cutoff;
// This function is supplied for cases where the system layer does not
// initialize logging. This is also needed to initialize logging in
// unit tests.
void InitLogging();
CORE_UTIL_EXPORT void InitLogging();
void Log(const char* file, const char* function, int line, LogPriority level,
const char* fmt, ...);
CORE_UTIL_EXPORT void Log(
const char* file, const char* function, int line, LogPriority level,
const char* fmt, ...);
// Log APIs
#ifndef LOGE

View File

@@ -10,23 +10,31 @@
#include <string>
#include <vector>
#include "util_common.h"
namespace wvcdm {
std::vector<uint8_t> a2b_hex(const std::string& b);
std::vector<uint8_t> a2b_hex(const std::string& label, const std::string& b);
std::string a2bs_hex(const std::string& b);
std::string b2a_hex(const std::vector<uint8_t>& b);
std::string b2a_hex(const std::string& b);
std::string Base64Encode(const std::vector<uint8_t>& bin_input);
std::vector<uint8_t> Base64Decode(const std::string& bin_input);
std::string Base64SafeEncode(const std::vector<uint8_t>& bin_input);
std::string Base64SafeEncodeNoPad(const std::vector<uint8_t>& bin_input);
std::vector<uint8_t> Base64SafeDecode(const std::string& bin_input);
std::string HexEncode(const uint8_t* bytes, unsigned size);
std::string IntToString(int value);
int64_t htonll64(int64_t x);
inline int64_t ntohll64(int64_t x) { return htonll64(x); }
std::string BytesToString(const uint8_t* bytes, unsigned size);
CORE_UTIL_EXPORT std::vector<uint8_t> a2b_hex(const std::string& b);
CORE_UTIL_EXPORT std::vector<uint8_t> a2b_hex(const std::string& label,
const std::string& b);
CORE_UTIL_EXPORT std::string a2bs_hex(const std::string& b);
CORE_UTIL_EXPORT std::string b2a_hex(const std::vector<uint8_t>& b);
CORE_UTIL_EXPORT std::string b2a_hex(const std::string& b);
CORE_UTIL_EXPORT std::string Base64Encode(
const std::vector<uint8_t>& bin_input);
CORE_UTIL_EXPORT std::vector<uint8_t> Base64Decode(
const std::string& bin_input);
CORE_UTIL_EXPORT std::string Base64SafeEncode(
const std::vector<uint8_t>& bin_input);
CORE_UTIL_EXPORT std::string Base64SafeEncodeNoPad(
const std::vector<uint8_t>& bin_input);
CORE_UTIL_EXPORT std::vector<uint8_t> Base64SafeDecode(
const std::string& bin_input);
CORE_UTIL_EXPORT std::string HexEncode(const uint8_t* bytes, unsigned size);
CORE_UTIL_EXPORT std::string IntToString(int value);
CORE_UTIL_EXPORT int64_t htonll64(int64_t x);
CORE_UTIL_EXPORT inline int64_t ntohll64(int64_t x) { return htonll64(x); }
CORE_UTIL_EXPORT std::string BytesToString(const uint8_t* bytes, unsigned size);
} // namespace wvcdm

View File

@@ -0,0 +1,22 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WVCDM_UTIL_UTIL_COMMON_H_
#define WVCDM_UTIL_UTIL_COMMON_H_
#ifdef _WIN32
# ifdef CORE_UTIL_IMPLEMENTATION
# define CORE_UTIL_EXPORT __declspec(dllexport)
# else
# define CORE_UTIL_EXPORT __declspec(dllimport)
# endif
#else
# ifdef CORE_UTIL_IMPLEMENTATION
# define CORE_UTIL_EXPORT __attribute__((visibility("default")))
# else
# define CORE_UTIL_EXPORT
# endif
#endif
#endif // WVCDM_UTIL_UTIL_COMMON_H_