diff --git a/docs/WidevineModularDRMSecurityIntegrationGuideforCENC_v15.pdf b/docs/WidevineModularDRMSecurityIntegrationGuideforCENC_v15.pdf index dff1514..7ed497d 100644 Binary files a/docs/WidevineModularDRMSecurityIntegrationGuideforCENC_v15.pdf and b/docs/WidevineModularDRMSecurityIntegrationGuideforCENC_v15.pdf differ diff --git a/docs/Widevine_Modular_DRM_Version_15_Delta.pdf b/docs/Widevine_Modular_DRM_Version_15_Delta.pdf index 06bd96f..038ad2c 100644 Binary files a/docs/Widevine_Modular_DRM_Version_15_Delta.pdf and b/docs/Widevine_Modular_DRM_Version_15_Delta.pdf differ diff --git a/oemcrypto/include/OEMCryptoCENC.h b/oemcrypto/include/OEMCryptoCENC.h index 2440bea..f7a560c 100644 --- a/oemcrypto/include/OEMCryptoCENC.h +++ b/oemcrypto/include/OEMCryptoCENC.h @@ -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. * - * - * | 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 | - * + * +-----------------------------------+-----------+------------+-----------+ + * |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. diff --git a/oemcrypto/include/level3.h b/oemcrypto/include/level3.h index 499d2ca..49031fb 100644 --- a/oemcrypto/include/level3.h +++ b/oemcrypto/include/level3.h @@ -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. diff --git a/oemcrypto/ref/src/oemcrypto_auth_ref.h b/oemcrypto/ref/src/oemcrypto_auth_ref.h index 6bdeb84..61b85aa 100644 --- a/oemcrypto/ref/src/oemcrypto_auth_ref.h +++ b/oemcrypto/ref/src/oemcrypto_auth_ref.h @@ -8,6 +8,7 @@ #define OEMCRYPTO_AUTH_REF_H_ #include +#include #include #include @@ -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 { diff --git a/oemcrypto/ref/src/oemcrypto_engine_device_properties.cpp b/oemcrypto/ref/src/oemcrypto_engine_device_properties.cpp index 20d8f02..a3bdf4e 100644 --- a/oemcrypto/ref/src/oemcrypto_engine_device_properties.cpp +++ b/oemcrypto/ref/src/oemcrypto_engine_device_properties.cpp @@ -7,11 +7,13 @@ #include "oemcrypto_engine_ref.h" +#include + namespace wvoec_ref { CryptoEngine* CryptoEngine::MakeCryptoEngine( - scoped_ptr file_system) { - return new CryptoEngine(file_system); + std::unique_ptr&& file_system) { + return new CryptoEngine(std::move(file_system)); } } // namespace wvoec_ref diff --git a/oemcrypto/ref/src/oemcrypto_engine_device_properties_L1.cpp b/oemcrypto/ref/src/oemcrypto_engine_device_properties_L1.cpp index 749e2e6..5e92a88 100644 --- a/oemcrypto/ref/src/oemcrypto_engine_device_properties_L1.cpp +++ b/oemcrypto/ref/src/oemcrypto_engine_device_properties_L1.cpp @@ -8,12 +8,14 @@ // level 1 device. #include "oemcrypto_engine_ref.h" +#include + namespace wvoec_ref { class L1CryptoEngine : public CryptoEngine { public: - explicit L1CryptoEngine(scoped_ptr file_system) - : CryptoEngine(file_system) {} + explicit L1CryptoEngine(std::unique_ptr&& 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 file_system) { - return new L1CryptoEngine(file_system); + std::unique_ptr&& file_system) { + return new L1CryptoEngine(std::move(file_system)); } } // namespace wvoec_ref diff --git a/oemcrypto/ref/src/oemcrypto_engine_device_properties_cert.cpp b/oemcrypto/ref/src/oemcrypto_engine_device_properties_cert.cpp index 73809f5..df17c88 100644 --- a/oemcrypto/ref/src/oemcrypto_engine_device_properties_cert.cpp +++ b/oemcrypto/ref/src/oemcrypto_engine_device_properties_cert.cpp @@ -15,7 +15,7 @@ namespace wvoec_ref { class CertOnlyCryptoEngine : public CryptoEngine { public: - explicit CertOnlyCryptoEngine(scoped_ptr file_system) + explicit CertOnlyCryptoEngine(std::unique_ptr 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 file_system) { + std::unique_ptr file_system) { return new CertOnlyCryptoEngine(file_system); } diff --git a/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp b/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp index dacd979..fe78fe6 100644 --- a/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp +++ b/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp @@ -12,6 +12,8 @@ #include +#include + #include "log.h" #include "oem_cert.h" @@ -19,8 +21,8 @@ namespace wvoec_ref { class Prov30CryptoEngine : public CryptoEngine { public: - explicit Prov30CryptoEngine(scoped_ptr file_system) - : CryptoEngine(file_system) {} + explicit Prov30CryptoEngine(std::unique_ptr&& 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 file_system) { - return new Prov30CryptoEngine(file_system); + std::unique_ptr&& file_system) { + return new Prov30CryptoEngine(std::move(file_system)); } } // namespace wvoec_ref diff --git a/oemcrypto/ref/src/oemcrypto_engine_ref.cpp b/oemcrypto/ref/src/oemcrypto_engine_ref.cpp index 66319ff..843d966 100644 --- a/oemcrypto/ref/src/oemcrypto_engine_ref.cpp +++ b/oemcrypto/ref/src/oemcrypto_engine_ref.cpp @@ -8,9 +8,11 @@ #include #include +#include #include #include #include +#include #include #include @@ -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 file_system) +CryptoEngine::CryptoEngine(std::unique_ptr&& 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 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 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 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 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, ¤t_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& key = DeviceRootKey(); - wvcdm::File* file; + std::unique_ptr 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(&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(&encrypted_buffer[0]), sizeof(TimeInfo)); - file->Close(); // Return time with offset. return current_time; diff --git a/oemcrypto/ref/src/oemcrypto_engine_ref.h b/oemcrypto/ref/src/oemcrypto_engine_ref.h index c965edf..5000f78 100644 --- a/oemcrypto/ref/src/oemcrypto_engine_ref.h +++ b/oemcrypto/ref/src/oemcrypto_engine_ref.h @@ -11,17 +11,16 @@ #include #include #include +#include #include #include #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 file_system); + std::unique_ptr&& file_system); virtual ~CryptoEngine(); @@ -196,15 +195,15 @@ class CryptoEngine { } protected: - explicit CryptoEngine(scoped_ptr file_system); + explicit CryptoEngine(std::unique_ptr&& 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 file_system_; - scoped_ptr usage_table_; + std::mutex session_table_lock_; + std::unique_ptr file_system_; + std::unique_ptr usage_table_; CORE_DISALLOW_COPY_AND_ASSIGN(CryptoEngine); }; diff --git a/oemcrypto/ref/src/oemcrypto_key_ref.h b/oemcrypto/ref/src/oemcrypto_key_ref.h index 4aa38ca..c6c7441 100644 --- a/oemcrypto/ref/src/oemcrypto_key_ref.h +++ b/oemcrypto/ref/src/oemcrypto_key_ref.h @@ -47,7 +47,7 @@ class Key { Key(const std::vector& 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& 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& value() const { return content_key_; } + ~EntitlementKey() override {} + const std::vector& value() const override { return content_key_; } const std::vector& content_key() { return content_key_; } const std::vector& content_key_id() { return content_key_id_; } const std::vector& entitlement_key() { return Key::value(); } diff --git a/oemcrypto/ref/src/oemcrypto_old_usage_table_ref.cpp b/oemcrypto/ref/src/oemcrypto_old_usage_table_ref.cpp index 93438eb..5e9e9a7 100644 --- a/oemcrypto/ref/src/oemcrypto_old_usage_table_ref.cpp +++ b/oemcrypto/ref/src/oemcrypto_old_usage_table_ref.cpp @@ -64,7 +64,7 @@ OldUsageTable::OldUsageTable(CryptoEngine *ce) { // Load saved table. wvcdm::FileSystem *file_system = ce->file_system(); - wvcdm::File *file; + std::unique_ptr 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(&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(&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 &pst) { - wvcdm::AutoLock lock(lock_); + std::unique_lock 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 lock(lock_); table_[pst_hash] = entry; return entry; } void OldUsageTable::Clear() { - wvcdm::AutoLock lock(lock_); + std::unique_lock lock(lock_); for (EntryMap::iterator i = table_.begin(); i != table_.end(); ++i) { if (i->second) delete i->second; } diff --git a/oemcrypto/ref/src/oemcrypto_old_usage_table_ref.h b/oemcrypto/ref/src/oemcrypto_old_usage_table_ref.h index 1072d9e..452d504 100644 --- a/oemcrypto/ref/src/oemcrypto_old_usage_table_ref.h +++ b/oemcrypto/ref/src/oemcrypto_old_usage_table_ref.h @@ -12,11 +12,11 @@ #include #include +#include #include #include #include "OEMCryptoCENC.h" -#include "lock.h" #include "oemcrypto_types.h" #include "openssl/sha.h" @@ -89,7 +89,7 @@ class OldUsageTable { typedef std::map, OldUsageTableEntry *> EntryMap; EntryMap table_; - wvcdm::Lock lock_; + std::mutex lock_; int64_t generation_; CryptoEngine *ce_; diff --git a/oemcrypto/ref/src/oemcrypto_ref.cpp b/oemcrypto/ref/src/oemcrypto_ref.cpp index 7675308..bb5ca17 100644 --- a/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -15,10 +15,10 @@ #include #include #include -#include -#include +#include #include #include +#include #include #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 fs(new wvcdm::FileSystem()); - crypto_engine = CryptoEngine::MakeCryptoEngine(fs); + std::unique_ptr 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."); diff --git a/oemcrypto/ref/src/oemcrypto_session.cpp b/oemcrypto/ref/src/oemcrypto_session.cpp index 7b1fb66..5653abf 100644 --- a/oemcrypto/ref/src/oemcrypto_session.cpp +++ b/oemcrypto/ref/src/oemcrypto_session.cpp @@ -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& content_key); - virtual bool GetEntitlementKey(const KeyId& entitlement_id, - const std::vector** entitlement_key); + bool SetContentKey(const KeyId& entitlement_id, + const KeyId& content_key_id, + const std::vector& content_key) override; + bool GetEntitlementKey(const KeyId& entitlement_id, + const std::vector** 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& content_key); - virtual bool GetEntitlementKey(const KeyId& entitlement_id, - const std::vector** 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& content_key) override; + bool GetEntitlementKey(const KeyId& entitlement_id, + const std::vector** 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(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(hash); return OEMCrypto_SUCCESS; } diff --git a/oemcrypto/ref/src/oemcrypto_session.h b/oemcrypto/ref/src/oemcrypto_session.h index 9d65c4f..3522abe 100644 --- a/oemcrypto/ref/src/oemcrypto_session.h +++ b/oemcrypto/ref/src/oemcrypto_session.h @@ -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); diff --git a/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp b/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp index 21eb7e0..c24275d 100644 --- a/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp +++ b/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp @@ -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(&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(&master_generation_number_), @@ -709,7 +708,6 @@ bool UsageTable::LoadGenerationNumber(bool or_make_new_one) { } file->Read(reinterpret_cast(&master_generation_number_), sizeof(int64_t)); - file->Close(); return true; } diff --git a/oemcrypto/ref/src/wvcrc.cpp b/oemcrypto/ref/src/wvcrc.cpp index 1e88ea6..e9f9783 100644 --- a/oemcrypto/ref/src/wvcrc.cpp +++ b/oemcrypto/ref/src/wvcrc.cpp @@ -7,6 +7,8 @@ #include #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 diff --git a/oemcrypto/ref/src/wvcrc32.h b/oemcrypto/ref/src/wvcrc32.h index b1fde53..99677ec 100644 --- a/oemcrypto/ref/src/wvcrc32.h +++ b/oemcrypto/ref/src/wvcrc32.h @@ -9,6 +9,8 @@ #include +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_ diff --git a/oemcrypto/test/oec_device_features.cpp b/oemcrypto/test/oec_device_features.cpp index 35c27e0..fdc5164 100644 --- a/oemcrypto/test/oec_device_features.cpp +++ b/oemcrypto/test/oec_device_features.cpp @@ -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); diff --git a/oemcrypto/test/oec_session_util.cpp b/oemcrypto/test/oec_session_util.cpp index 0cc739d..cb6e884 100644 --- a/oemcrypto/test/oec_session_util.cpp +++ b/oemcrypto/test/oec_session_util.cpp @@ -212,7 +212,7 @@ void Session::DeriveKey(const uint8_t* key, const vector& 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 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 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 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(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(&padded_message_), message_size_, &signature_); - OEMCrypto_KeyRefreshObject key_array[key_count]; - FillRefreshArray(key_array, key_count); + std::vector 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& data, std::vector* 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(32), gen_signature_length); vector 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 expected_signature; ClientSignMessage(data, &expected_signature); @@ -809,12 +811,12 @@ void Session::TestDecryptCTR(bool select_key_first, vector 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 encryptionIv(KEY_IV_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], KEY_IV_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), KEY_IV_SIZE)); vector encryptedData(unencryptedData.size()); EncryptCTR(unencryptedData, license_.keys[key_index].key_data, - &encryptionIv[0], &encryptedData); + encryptionIv.data(), &encryptedData); // Describe the output vector 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 store(X509_STORE_new()); ASSERT_TRUE(store.NotNull()); boringssl_ptr store_ctx( @@ -979,16 +981,17 @@ void Session::RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted, const uint8_t* message_ptr = reinterpret_cast(&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& message, boringssl_ptr 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 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* session_key, void Session::InstallRSASessionTestKey(const vector& 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* 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& 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(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(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 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 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(report.pst.c_str()), report.pst.length()); if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) return; diff --git a/oemcrypto/test/oec_test_data.h b/oemcrypto/test/oec_test_data.h index 390e81a..144c4d3 100644 --- a/oemcrypto/test/oec_test_data.h +++ b/oemcrypto/test/oec_test_data.h @@ -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 { diff --git a/oemcrypto/test/oemcrypto_session_tests_helper.cpp b/oemcrypto/test/oemcrypto_session_tests_helper.cpp index ffc67fb..cb040e3 100644 --- a/oemcrypto/test/oemcrypto_session_tests_helper.cpp +++ b/oemcrypto/test/oemcrypto_session_tests_helper.cpp @@ -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(&keybox_), diff --git a/oemcrypto/test/oemcrypto_test.cpp b/oemcrypto/test/oemcrypto_test.cpp index e3fdb12..409ec18 100644 --- a/oemcrypto/test/oemcrypto_test.cpp +++ b/oemcrypto/test/oemcrypto_test.cpp @@ -16,11 +16,11 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -90,7 +90,7 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil { protected: OEMCryptoClientTest() {} - virtual void SetUp() { + void SetUp() override { ::testing::Test::SetUp(); wvcdm::g_cutoff = wvcdm::LOG_INFO; const ::testing::TestInfo* const test_info = @@ -100,7 +100,7 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); } - virtual void TearDown() { + void TearDown() override { OEMCrypto_Terminate(); ::testing::Test::TearDown(); } @@ -204,8 +204,9 @@ TEST_F(OEMCryptoClientTest, CheckSRMCapabilityV13) { EXPECT_EQ(OEMCrypto_ERROR_NOT_IMPLEMENTED, current_result); } vector bad_srm(42); - GetRandBytes(&bad_srm[0], bad_srm.size()); - EXPECT_NE(OEMCrypto_SUCCESS, OEMCrypto_LoadSRM(&bad_srm[0], bad_srm.size())); + GetRandBytes(bad_srm.data(), bad_srm.size()); + EXPECT_NE(OEMCrypto_SUCCESS, + OEMCrypto_LoadSRM(bad_srm.data(), bad_srm.size())); } TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) { @@ -432,15 +433,15 @@ TEST_F(OEMCryptoClientTest, ClearCopyTestAPI10) { ASSERT_NO_FATAL_FAILURE(s.open()); const int kDataSize = 256; vector input_buffer(kDataSize); - GetRandBytes(&input_buffer[0], input_buffer.size()); + GetRandBytes(input_buffer.data(), input_buffer.size()); vector output_buffer(kDataSize); OEMCrypto_DestBufferDesc dest_buffer; dest_buffer.type = OEMCrypto_BufferType_Clear; - dest_buffer.buffer.clear.address = &output_buffer[0]; + dest_buffer.buffer.clear.address = output_buffer.data(); dest_buffer.buffer.clear.max_length = output_buffer.size(); ASSERT_EQ( OEMCrypto_SUCCESS, - OEMCrypto_CopyBuffer(s.session_id(), &input_buffer[0], + OEMCrypto_CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), &dest_buffer, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); ASSERT_EQ(input_buffer, output_buffer); @@ -450,19 +451,19 @@ TEST_F(OEMCryptoClientTest, ClearCopyTestAPI10) { OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, OEMCrypto_CopyBuffer( - s.session_id(), &input_buffer[0], input_buffer.size(), NULL, + s.session_id(), input_buffer.data(), input_buffer.size(), NULL, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); dest_buffer.buffer.clear.address = NULL; ASSERT_EQ( OEMCrypto_ERROR_INVALID_CONTEXT, - OEMCrypto_CopyBuffer(s.session_id(), &input_buffer[0], + OEMCrypto_CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), &dest_buffer, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); - dest_buffer.buffer.clear.address = &output_buffer[0]; + dest_buffer.buffer.clear.address = output_buffer.data(); dest_buffer.buffer.clear.max_length = output_buffer.size() - 1; ASSERT_EQ( OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_CopyBuffer(s.session_id(), &input_buffer[0], + OEMCrypto_CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), &dest_buffer, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); } @@ -472,15 +473,15 @@ TEST_F(OEMCryptoClientTest, ClearCopyTestLargeSubsample) { ASSERT_NO_FATAL_FAILURE(s.open()); size_t max_size = GetResourceValue(kMaxSubsampleSize); vector input_buffer(max_size); - GetRandBytes(&input_buffer[0], input_buffer.size()); + GetRandBytes(input_buffer.data(), input_buffer.size()); vector output_buffer(max_size); OEMCrypto_DestBufferDesc dest_buffer; dest_buffer.type = OEMCrypto_BufferType_Clear; - dest_buffer.buffer.clear.address = &output_buffer[0]; + dest_buffer.buffer.clear.address = output_buffer.data(); dest_buffer.buffer.clear.max_length = output_buffer.size(); ASSERT_EQ( OEMCrypto_SUCCESS, - OEMCrypto_CopyBuffer(s.session_id(), &input_buffer[0], + OEMCrypto_CopyBuffer(s.session_id(), input_buffer.data(), input_buffer.size(), &dest_buffer, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); ASSERT_EQ(input_buffer, output_buffer); @@ -492,7 +493,7 @@ TEST_F(OEMCryptoClientTest, CanLoadTestKeys) { } class OEMCryptoKeyboxTest : public OEMCryptoClientTest { - virtual void SetUp() { + void SetUp() override { OEMCryptoClientTest::SetUp(); OEMCryptoResult sts = OEMCrypto_IsKeyboxValid(); // If the production keybox is valid, use it for these tests. Most of the @@ -557,6 +558,8 @@ TEST_F(OEMCryptoKeyboxTest, GetKeyDataNullPointer) { ASSERT_NE(OEMCrypto_SUCCESS, sts); } +// This test makes sure the installed keybox is valid. It doesn't really check +// that it is a production keybox. That must be done by an integration test. TEST_F(OEMCryptoKeyboxTest, ProductionKeyboxValid) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid()); } @@ -573,9 +576,9 @@ TEST_F(OEMCryptoKeyboxTest, GenerateDerivedKeysFromKeyboxLargeBuffer) { enc_context[i] = (3 * i) % 0x100; } ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GenerateDerivedKeys(s.session_id(), &mac_context[0], - mac_context.size(), &enc_context[0], - enc_context.size())); + OEMCrypto_GenerateDerivedKeys( + s.session_id(), mac_context.data(), mac_context.size(), + enc_context.data(),enc_context.size())); } class OEMCryptoProv30Test : public OEMCryptoClientTest {}; @@ -584,6 +587,23 @@ TEST_F(OEMCryptoProv30Test, DeviceClaimsOEMCertificate) { ASSERT_EQ(OEMCrypto_OEMCertificate, OEMCrypto_GetProvisioningMethod()); } +TEST_F(OEMCryptoProv30Test, GetDeviceId) { + OEMCryptoResult sts; + std::vector dev_id(128, 0); + size_t dev_id_len = dev_id.size(); + sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); + if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) return; + if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { + ASSERT_GT(dev_id_len, 0u); + dev_id.resize(dev_id_len); + sts = OEMCrypto_GetDeviceID(dev_id.data(), &dev_id_len); + } + cout << " NormalGetDeviceId: dev_id = " << dev_id.data() + << " len = " << dev_id_len << endl; + ASSERT_EQ(OEMCrypto_SUCCESS, sts); +} + + // The OEM certificate must be valid. TEST_F(OEMCryptoProv30Test, CertValidAPI15) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxOrOEMCertValid()); @@ -603,25 +623,25 @@ TEST_F(OEMCryptoProv30Test, OEMCertSignature) { OEMCryptoResult sts; // Sign a Message vector data(500); - GetRandBytes(&data[0], data.size()); + GetRandBytes(data.data(), data.size()); size_t signature_length = 0; vector signature(1); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &data[0], data.size(), - &signature[0], &signature_length, + sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), data.size(), + signature.data(), &signature_length, kSign_RSASSA_PSS); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_NE(static_cast(0), signature_length); signature.resize(signature_length, 0); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &data[0], data.size(), - &signature[0], &signature_length, + sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), data.size(), + signature.data(), &signature_length, kSign_RSASSA_PSS); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature( - data, &signature[0], signature_length, kSign_RSASSA_PSS)); + data, signature.data(), signature_length, kSign_RSASSA_PSS)); } TEST_F(OEMCryptoProv30Test, OEMCertForbiddenPaddingScheme) { @@ -631,23 +651,23 @@ TEST_F(OEMCryptoProv30Test, OEMCertForbiddenPaddingScheme) { OEMCryptoResult sts; // Sign a Message vector data(500); - GetRandBytes(&data[0], data.size()); + GetRandBytes(data.data(), data.size()); size_t signature_length = 0; // We need a size one vector to pass as a pointer. vector signature(1, 0); vector zero(1, 0); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &data[0], data.size(), - &signature[0], &signature_length, + sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), data.size(), + signature.data(), &signature_length, kSign_PKCS1_Block1); if (OEMCrypto_ERROR_SHORT_BUFFER == sts) { // The OEMCrypto could complain about buffer length first, so let's // resize and check if it's writing to the signature again. signature.resize(signature_length, 0); zero.resize(signature_length, 0); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &data[0], data.size(), - &signature[0], &signature_length, - kSign_PKCS1_Block1); + sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), + data.size(), signature.data(), + &signature_length, kSign_PKCS1_Block1); } EXPECT_NE(OEMCrypto_SUCCESS, sts) << "OEM Cert Signed with forbidden kSign_PKCS1_Block1."; @@ -661,25 +681,25 @@ TEST_F(OEMCryptoProv30Test, OEMCertSignatureLargeBuffer) { OEMCryptoResult sts; // Sign a Message vector data(kMaxMessageSize); - GetRandBytes(&data[0], data.size()); + GetRandBytes(data.data(), data.size()); size_t signature_length = 0; vector signature(1); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &data[0], data.size(), - &signature[0], &signature_length, + sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), data.size(), + signature.data(), &signature_length, kSign_RSASSA_PSS); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_NE(static_cast(0), signature_length); signature.resize(signature_length); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &data[0], data.size(), - &signature[0], &signature_length, + sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), data.size(), + signature.data(), &signature_length, kSign_RSASSA_PSS); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature( - data, &signature[0], signature_length, kSign_RSASSA_PSS)); + data, signature.data(), signature_length, kSign_RSASSA_PSS)); } // @@ -691,7 +711,7 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest { protected: OEMCryptoSessionTests() {} - virtual void SetUp() { + void SetUp() override { OEMCryptoClientTest::SetUp(); EnsureTestKeys(); if (global_features.usage_table) { @@ -710,7 +730,7 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest { if (sts != OEMCrypto_ERROR_SHORT_BUFFER) return; } encrypted_usage_header_.resize(header_buffer_length); - sts = OEMCrypto_CreateUsageTableHeader(&encrypted_usage_header_[0], + sts = OEMCrypto_CreateUsageTableHeader(encrypted_usage_header_.data(), &header_buffer_length); if (expect_success) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); @@ -719,7 +739,7 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest { } } - virtual void TearDown() { + void TearDown() override { // If we installed a bad keybox, end with a good one installed. if (global_features.derive_key_method == DeviceFeatures::FORCE_TEST_KEYBOX) InstallKeybox(kTestKeybox, true); @@ -800,8 +820,9 @@ TEST_F(OEMCryptoSessionTestKeyboxTest, GenerateSignature) { size_t signature_length = signature.size(); OEMCryptoResult sts; - sts = OEMCrypto_GenerateSignature(s.session_id(), &context[0], context.size(), - &signature[0], &signature_length); + sts = OEMCrypto_GenerateSignature(s.session_id(), context.data(), + context.size(), signature.data(), + &signature_length); ASSERT_EQ(OEMCrypto_SUCCESS, sts); static const uint32_t SignatureExpectedLength = 32; @@ -869,8 +890,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithNoMAC) { size_t signature_length = signature.size(); OEMCryptoResult sts; - sts = OEMCrypto_GenerateSignature(s.session_id(), &context[0], context.size(), - &signature[0], &signature_length); + sts = OEMCrypto_GenerateSignature(s.session_id(), context.data(), + context.size(), signature.data(), + &signature_length); ASSERT_EQ(OEMCrypto_SUCCESS, sts); @@ -941,8 +963,9 @@ TEST_F(OEMCryptoSessionTests, ClientSignatureLargeBuffer) { size_t signature_length = signature.size(); OEMCryptoResult sts; - sts = OEMCrypto_GenerateSignature(s.session_id(), &context[0], context.size(), - &signature[0], &signature_length); + sts = OEMCrypto_GenerateSignature(s.session_id(), context.data(), + context.size(), signature.data(), + &signature_length); ASSERT_EQ(OEMCrypto_SUCCESS, sts); static const uint32_t SignatureExpectedLength = 32; @@ -989,7 +1012,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange1) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), reinterpret_cast(double_message.data()), - s.message_size(), &s.signature()[0], s.signature().size(), + s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), wrong_mac_keys, // Not within range of one message. s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), @@ -1009,7 +1032,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange2) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), reinterpret_cast(double_message.data()), - s.message_size(), &s.signature()[0], s.signature().size(), + s.message_size(), s.signature().data(), s.signature().size(), wrong_mac_keys_iv, // bad. s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1027,7 +1050,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange3) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), reinterpret_cast(double_message.data()), - s.message_size(), &s.signature()[0], s.signature().size(), + s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); @@ -1045,7 +1068,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange4) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), reinterpret_cast(double_message.data()), - s.message_size(), &s.signature()[0], s.signature().size(), + s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); @@ -1061,7 +1084,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange5) { s.key_array()[1].key_data_iv.offset += s.message_size(); OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), reinterpret_cast(double_message.data()), - s.message_size(), &s.signature()[0], s.signature().size(), + s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); @@ -1079,7 +1102,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange6) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), reinterpret_cast(double_message.data()), - s.message_size(), &s.signature()[0], s.signature().size(), + s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); @@ -1096,7 +1119,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange7) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), reinterpret_cast(double_message.data()), - s.message_size(), &s.signature()[0], s.signature().size(), + s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); @@ -1112,7 +1135,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithNullKeyControl) { s.key_array()[2].key_control.length = 0; OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1129,7 +1152,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithNullKeyControlIv) { s.key_array()[2].key_control_iv.length = 0; OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1144,7 +1167,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadNonce) { 42)); // bad nonce. ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1169,7 +1192,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) { nonce)); // same old nonce. ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1195,7 +1218,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNonceReopenSession) { nonce)); // same old nonce ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1220,8 +1243,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNonceWrongSession) { nonce)); // nonce from session s1 ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s2.session_id(), s2.message_ptr(), s2.message_size(), &s2.signature()[0], - s2.signature().size(), s2.enc_mac_keys_iv_substr(), + s2.session_id(), s2.message_ptr(), s2.message_size(), + s2.signature().data(), s2.signature().size(), s2.enc_mac_keys_iv_substr(), s2.enc_mac_keys_substr(), s2.num_keys(), s2.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1236,7 +1259,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadVerification) { s.license().keys[1].control.verification[2] = 'Z'; ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1244,11 +1267,38 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadVerification) { ASSERT_NE(OEMCrypto_SUCCESS, sts); } +// This test verifies that LoadKeys still works when the message is not aligned +// in memory on a word (2 or 4 byte) boundary. +TEST_F(OEMCryptoSessionTests, LoadKeyUnalignedMessage) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); + ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage( + kDuration, wvoec::kControlNonceEnabled, s.get_nonce())); + ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); + std::vector buffer(1, '0'); // A string of 1 byte long. + size_t offset = buffer.size(); + ASSERT_EQ(1u, offset); + // We assume that vectors are allocated on as a small chunk of data that is + // aligned on a word boundary. I.e. we assume buffer is word aligned. Next, + // we append the message to buffer after the single padding byte. + buffer.insert(buffer.end(), s.message_ptr(), + s.message_ptr() + s.message_size()); + // Thus, buffer[offset] is NOT word aligned. + const uint8_t* unaligned_message = &buffer[offset]; + OEMCryptoResult sts = OEMCrypto_LoadKeys( + s.session_id(), unaligned_message, s.message_size(), s.signature().data(), + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); +} + // This tests each key control block verification string in the range kc09-kc1?. class SessionTestAlternateVerification : public OEMCryptoSessionTests, public WithParamInterface { public: - virtual void SetUp() { + void SetUp() override { OEMCryptoSessionTests::SetUp(); target_api_ = static_cast(GetParam()); } @@ -1272,7 +1322,7 @@ TEST_P(SessionTestAlternateVerification, LoadKeys) { } ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1300,7 +1350,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeysBadSignature) { ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); s.signature()[0] ^= 42; // Bad signature. OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1314,7 +1364,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeysWithNoDerivedKeys) { ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1333,7 +1383,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeys) { ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), GetSubstring(), + s.signature().data(), s.signature().size(), GetSubstring(), GetSubstring(), kNoKeys, s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense)); } @@ -1349,7 +1399,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeyWithNonce) { ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), GetSubstring(), + s.signature().data(), s.signature().size(), GetSubstring(), GetSubstring(), kNoKeys, s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense)); } @@ -1404,7 +1454,7 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) { 0, wvoec::kControlRequireAntiRollbackHardware, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -1428,7 +1478,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { ASSERT_EQ( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), + s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense)); @@ -1443,7 +1493,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { ASSERT_EQ( OEMCrypto_ERROR_UNKNOWN_FAILURE, OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), + s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense)); @@ -1458,7 +1508,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { ASSERT_EQ( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), + s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense)); @@ -1523,7 +1573,7 @@ class SessionTestRefreshKeyTest : public OEMCryptoSessionTests, public WithParamInterface > { public: - virtual void SetUp() { + void SetUp() override { OEMCryptoSessionTests::SetUp(); new_mac_keys_ = GetParam().first; // Whether to put new mac keys in LoadKeys. @@ -1645,7 +1695,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshWithNoSelectKey) { s.FillRefreshArray(key_array, num_keys_); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_RefreshKeys(s.session_id(), s.message_ptr(), - s.message_size(), &s.signature()[0], + s.message_size(), s.signature().data(), s.signature().size(), num_keys_, key_array)); ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR(false)); // This should still be valid key, even if the refresh failed, because this @@ -1671,21 +1721,27 @@ INSTANTIATE_TEST_CASE_P(TestRefreshEachKeys, SessionTestRefreshKeyTest, // If the license does not allow a hash, then we should not compute one. TEST_F(OEMCryptoSessionTests, HashForbiddenAPI15) { + uint32_t hash_type = OEMCrypto_SupportsDecryptHash(); + // If hash is not supported, or is vendor defined, don't try to test it. + if (hash_type != OEMCrypto_CRC_Clear_Buffer) return; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(kDuration, 0, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys()); - // Either failure, or not supported is allowed. - ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_InitializeDecryptHash(s.session_id())); - ASSERT_EQ( - OEMCrypto_SUCCESS, - OEMCrypto_SelectKey(s.session_id(), s.license().keys[0].key_id, - s.license().keys[0].key_id_length, - OEMCrypto_CipherMode_CTR)); - // Still not allowed. - ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_InitializeDecryptHash(s.session_id())); + uint32_t frame_number = 1; + uint32_t hash = 42; + // It is OK to set the hash before loading the keys + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_SetDecryptHash(s.session_id(), frame_number, + reinterpret_cast(&hash), + sizeof(hash))); + // It is OK to select the key and decrypt. + ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); + // But the error code should be bad. + ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, + OEMCrypto_GetHashErrorCode(s.session_id(), &frame_number)); } // @@ -1785,7 +1841,7 @@ class OEMCryptoSessionTestsDecryptTests public WithParamInterface > { protected: - virtual void SetUp() { + void SetUp() override { OEMCryptoSessionTests::SetUp(); pattern_ = ::testing::get<0>(GetParam()); cipher_mode_ = ::testing::get<1>(GetParam()); @@ -1805,12 +1861,12 @@ class OEMCryptoSessionTestsDecryptTests const vector& in_buffer, vector* out_buffer) { AES_KEY aes_key; - AES_set_encrypt_key(&key[0], AES_BLOCK_SIZE * 8, &aes_key); + AES_set_encrypt_key(key.data(), AES_BLOCK_SIZE * 8, &aes_key); out_buffer->resize(in_buffer.size()); uint8_t iv[AES_BLOCK_SIZE]; // Current iv. - memcpy(iv, &starting_iv[0], AES_BLOCK_SIZE); + memcpy(iv, starting_iv.data(), AES_BLOCK_SIZE); size_t buffer_index = 0; // byte index into in and out. size_t block_offset = 0; // byte index into current block. @@ -1890,18 +1946,22 @@ class OEMCryptoSessionTestsDecryptTests ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE( s.FillSimpleMessage(kDuration, kControlAllowHashVerification, 0)); - memcpy(s.license().keys[0].key_data, &key[0], key.size()); + memcpy(s.license().keys[0].key_data, key.data(), key.size()); s.license().keys[0].cipher_mode = cipher_mode_; ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys()); + if (global_features.supports_crc) { + uint32_t hash = + wvcrc32(unencryptedData.data(), unencryptedData.size()); + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_SetDecryptHash( + s.session_id(), 1, reinterpret_cast(&hash), + sizeof(hash))); + } sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[0].key_id, s.license().keys[0].key_id_length, cipher_mode_); ASSERT_EQ(OEMCrypto_SUCCESS, sts); - if (global_features.supports_crc) { - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_InitializeDecryptHash(s.session_id())); - } // We decrypt each subsample. vector output_buffer(total_size_ + 16, 0xaa); const uint8_t *input_buffer = NULL; @@ -1910,9 +1970,9 @@ class OEMCryptoSessionTestsDecryptTests // will be the same as input_buffer. Leave the 0xaa padding at the end. for(size_t i=0; i < total_size_; i++) output_buffer[i] = encryptedData[i]; // Now let input_buffer point to the same data. - input_buffer = &output_buffer[0]; + input_buffer = output_buffer.data(); } else { - input_buffer = &encryptedData[0]; + input_buffer = encryptedData.data(); } size_t buffer_offset = 0; for (size_t i = 0; i < subsample_size_.size(); i++) { @@ -1971,12 +2031,6 @@ class OEMCryptoSessionTestsDecryptTests output_buffer.resize(total_size_); EXPECT_EQ(unencryptedData, output_buffer); if (global_features.supports_crc) { - uint32_t hash = - wvcrc32(&unencryptedData[0], unencryptedData.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_SetDecryptHash( - s.session_id(), 1, reinterpret_cast(&hash), - sizeof(hash))); uint32_t frame; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetHashErrorCode(s.session_id(), &frame)); @@ -2007,8 +2061,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2025,8 +2079,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2039,8 +2093,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, OneBlock) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2058,8 +2112,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, NoOffset) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2079,7 +2133,7 @@ TEST_P(OEMCryptoSessionTestsPartialBlockTests, EvenOffset) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); // CTR Mode is self-inverse -- i.e. We can pick the encrypted data and // compute the unencrypted data. By picking the encrypted data to be all 0, // it is easier to re-encrypt the data and debug problems. Similarly, we @@ -2107,8 +2161,8 @@ TEST_P(OEMCryptoSessionTestsPartialBlockTests, OddOffset) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2131,7 +2185,7 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptWithNearWrap) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); encryptionIv = wvcdm::a2b_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); @@ -2151,8 +2205,8 @@ TEST_P(OEMCryptoSessionTestsPartialBlockTests, PartialBlock) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2176,8 +2230,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSample) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2192,8 +2246,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSubsample) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2207,8 +2261,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2221,8 +2275,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptUnencrypted) { vector encryptedData(total_size_); vector encryptionIv(AES_BLOCK_SIZE); vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(&key[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; EncryptData(key, encryptionIv, unencryptedData, &encryptedData); TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); @@ -2238,12 +2292,12 @@ TEST_F(OEMCryptoSessionTests, DecryptUnencryptedNoKey) { vector in_buffer(256); for (size_t i = 0; i < in_buffer.size(); i++) in_buffer[i] = i % 256; vector encryptionIv(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], AES_BLOCK_SIZE)); + EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); // Describe the output vector out_buffer(in_buffer.size()); OEMCrypto_DestBufferDesc destBuffer; destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = &out_buffer[0]; + destBuffer.buffer.clear.address = out_buffer.data(); destBuffer.buffer.clear.max_length = out_buffer.size(); OEMCrypto_CENCEncryptPatternDesc pattern; pattern.encrypt = 0; @@ -2252,8 +2306,9 @@ TEST_F(OEMCryptoSessionTests, DecryptUnencryptedNoKey) { // Decrypt the data sts = - OEMCrypto_DecryptCENC(s.session_id(), &in_buffer[0], in_buffer.size(), - false, &encryptionIv[0], 0, &destBuffer, &pattern, + OEMCrypto_DecryptCENC(s.session_id(), in_buffer.data(), in_buffer.size(), + false, encryptionIv.data(), 0, &destBuffer, + &pattern, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(in_buffer, out_buffer); @@ -2386,17 +2441,17 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange1KeyboxTest) { size_t wrapped_key_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + 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); uint32_t nonce = encrypted.nonce; ASSERT_NE( OEMCrypto_SUCCESS, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], + s.session_id(), message_ptr, sizeof(encrypted), signature.data(), signature.size(), &nonce, encrypted.rsa_key, encrypted.rsa_key_length, encrypted.rsa_key_iv, &(wrapped_key.front()), &wrapped_key_length)); } @@ -2416,10 +2471,10 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange2KeyboxTest) { size_t wrapped_key_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + 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); vector bad_buffer(encrypted.rsa_key, @@ -2427,10 +2482,10 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange2KeyboxTest) { ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, &bad_buffer[0], - encrypted.rsa_key_length, encrypted.rsa_key_iv, - &(wrapped_key.front()), &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + signature.data(), signature.size(), &encrypted.nonce, + bad_buffer.data(), encrypted.rsa_key_length, + encrypted.rsa_key_iv, wrapped_key.data(), &wrapped_key_length)); } TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange3KeyboxTest) { @@ -2449,10 +2504,10 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange3KeyboxTest) { size_t wrapped_key_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + 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); vector bad_buffer(encrypted.rsa_key, @@ -2460,9 +2515,9 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange3KeyboxTest) { ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, &bad_buffer[0], + s.session_id(), message_ptr, sizeof(encrypted), + signature.data(), signature.size(), &encrypted.nonce, + encrypted.rsa_key, encrypted.rsa_key_length, bad_buffer.data(), &(wrapped_key.front()), &wrapped_key_length)); } @@ -2482,19 +2537,19 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadSignatureKeyboxTest) { size_t wrapped_key_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + 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); signature[4] ^= 42; // bad signature. ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, - &(wrapped_key.front()), &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + signature.data(), signature.size(), &encrypted.nonce, + encrypted.rsa_key, encrypted.rsa_key_length, + encrypted.rsa_key_iv, wrapped_key.data(), &wrapped_key_length)); } TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonceKeyboxTest) { @@ -2513,19 +2568,19 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonceKeyboxTest) { size_t wrapped_key_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + 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); encrypted.nonce ^= 42; // Almost surely a bad nonce. ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, - &(wrapped_key.front()), &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + signature.data(), signature.size(), &encrypted.nonce, + encrypted.rsa_key, encrypted.rsa_key_length, + encrypted.rsa_key_iv, wrapped_key.data(), &wrapped_key_length)); } TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKeyKeyboxTest) { @@ -2544,19 +2599,19 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKeyKeyboxTest) { size_t wrapped_key_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + 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); encrypted.rsa_key[1] ^= 42; // Almost surely a bad key. ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_RewrapDeviceRSAKey( - s.session_id(), message_ptr, sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, - &(wrapped_key.front()), &wrapped_key_length)); + s.session_id(), message_ptr, sizeof(encrypted), + signature.data(), signature.size(), &encrypted.nonce, + encrypted.rsa_key, encrypted.rsa_key_length, + encrypted.rsa_key_iv, wrapped_key.data(), &wrapped_key_length)); } TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionLargeBufferKeyboxTest) { @@ -2596,17 +2651,17 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonceProv30Test) { size_t wrapped_key_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, OEMCrypto_RewrapDeviceRSAKey30( - s.session_id(), &bad_nonce, &encrypted_message_key[0], + s.session_id(), &bad_nonce, encrypted_message_key.data(), encrypted_message_key.size(), encrypted.rsa_key, encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, &wrapped_key_length)); vector wrapped_key(wrapped_key_length, 0); ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE, OEMCrypto_RewrapDeviceRSAKey30( - s.session_id(), &bad_nonce, &encrypted_message_key[0], + s.session_id(), &bad_nonce, encrypted_message_key.data(), encrypted_message_key.size(), encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, &wrapped_key[0], - &wrapped_key_length)); + encrypted.rsa_key_length, encrypted.rsa_key_iv, + wrapped_key.data(), &wrapped_key_length)); } TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKeyProv30Test) { @@ -2626,7 +2681,7 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKeyProv30Test) { uint32_t nonce = s.get_nonce(); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, OEMCrypto_RewrapDeviceRSAKey30( - s.session_id(), &nonce, &encrypted_message_key[0], + s.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)); @@ -2634,10 +2689,10 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKeyProv30Test) { encrypted.rsa_key[1] ^= 42; // Almost surely a bad key. ASSERT_EQ(OEMCrypto_ERROR_INVALID_RSA_KEY, OEMCrypto_RewrapDeviceRSAKey30( - s.session_id(), &nonce, &encrypted_message_key[0], + s.session_id(), &nonce, encrypted_message_key.data(), encrypted_message_key.size(), encrypted.rsa_key, - encrypted.rsa_key_length, encrypted.rsa_key_iv, &wrapped_key[0], - &wrapped_key_length)); + encrypted.rsa_key_length, encrypted.rsa_key_iv, + wrapped_key.data(), &wrapped_key_length)); } TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) { @@ -2646,7 +2701,7 @@ TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], + sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); } @@ -2672,7 +2727,7 @@ TEST_F(OEMCryptoLoadsCertificate, TestLargeRSAKey3072) { CreateWrappedRSAKey(kSign_RSASSA_PSS, true); Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(kDuration, 0, 0)); @@ -2690,7 +2745,7 @@ TEST_F(OEMCryptoLoadsCertificate, TestCarmichaelRSAKey) { CreateWrappedRSAKey(kSign_RSASSA_PSS, true); Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(kDuration, 0, 0)); @@ -2705,10 +2760,10 @@ TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) { Session s1; // Session s1 loads the default rsa key, but doesn't use it // until after s2 uses its key. ASSERT_NO_FATAL_FAILURE(s1.open()); - ASSERT_NO_FATAL_FAILURE(s1.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(s1.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadDeviceRSAKey(s1.session_id(), &wrapped_rsa_key_[0], + OEMCrypto_LoadDeviceRSAKey(s1.session_id(), wrapped_rsa_key_.data(), wrapped_rsa_key_.size())); Session s2; // Session s2 uses a different rsa key. @@ -2717,7 +2772,7 @@ TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) { sizeof(kTestRSAPKCS8PrivateKeyInfo4_2048)); CreateWrappedRSAKey(kSign_RSASSA_PSS, true); ASSERT_NO_FATAL_FAILURE(s2.open()); - ASSERT_NO_FATAL_FAILURE(s2.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(s2.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_NO_FATAL_FAILURE(s2.InstallRSASessionTestKey(wrapped_rsa_key_)); ASSERT_NO_FATAL_FAILURE(s2.FillSimpleMessage(kDuration, 0, 0)); @@ -2743,7 +2798,7 @@ TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) { class OEMCryptoUsesCertificate : public OEMCryptoLoadsCertificate { protected: - virtual void SetUp() { + void SetUp() override { OEMCryptoLoadsCertificate::SetUp(); ASSERT_NO_FATAL_FAILURE(session_.open()); if (global_features.derive_key_method != @@ -2751,12 +2806,12 @@ class OEMCryptoUsesCertificate : public OEMCryptoLoadsCertificate { CreateWrappedRSAKey(kSign_RSASSA_PSS, true); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadDeviceRSAKey(session_.session_id(), - &wrapped_rsa_key_[0], + wrapped_rsa_key_.data(), wrapped_rsa_key_.size())); } } - virtual void TearDown() { + void TearDown() override { session_.close(); OEMCryptoLoadsCertificate::TearDown(); } @@ -2767,77 +2822,64 @@ class OEMCryptoUsesCertificate : public OEMCryptoLoadsCertificate { // This test is not run by default, because it takes a long time and // is used to measure RSA performance, not test functionality. TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) { + const std::chrono::milliseconds kTestDuration(5000); OEMCryptoResult sts; + std::chrono::steady_clock clock; sleep(2); // Make sure are not nonce limited. - const uint32_t TestDuration = 5000; // milliseconds. - struct timeval start_time, end_time; - gettimeofday(&start_time, NULL); - gettimeofday(&end_time, NULL); - double mtime = 0; - long count = 0; - for (int i = 0; i < 15; i++) { // Only 20 nonce available. + auto start_time = clock.now(); + int count = 15; + for (int i = 0; i < count; i++) { // Only 20 nonce available. CreateWrappedRSAKey(kSign_RSASSA_PSS, true); - count++; - gettimeofday(&end_time, NULL); - long seconds = end_time.tv_sec - start_time.tv_sec; - long useconds = end_time.tv_usec - start_time.tv_usec; - mtime = seconds * 1e3 + useconds * 1e-3; } - double provision_time = mtime / count; + auto delta_time = clock.now() - start_time; + const double provision_time = + delta_time / std::chrono::milliseconds(1) / count; Session session; CreateWrappedRSAKey(kSign_RSASSA_PSS, true); - gettimeofday(&start_time, NULL); - gettimeofday(&end_time, NULL); - mtime = 0; + start_time = clock.now(); count = 0; - do { + while (clock.now() - start_time < kTestDuration) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], + sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); const size_t size = 50; vector licenseRequest(size); - GetRandBytes(&licenseRequest[0], licenseRequest.size()); + GetRandBytes(licenseRequest.data(), licenseRequest.size()); size_t signature_length = 0; - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &licenseRequest[0], + sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(), licenseRequest.size(), NULL, &signature_length, kSign_RSASSA_PSS); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_NE(static_cast(0), signature_length); uint8_t* signature = new uint8_t[signature_length]; - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &licenseRequest[0], + sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(), licenseRequest.size(), signature, &signature_length, kSign_RSASSA_PSS); delete[] signature; ASSERT_EQ(OEMCrypto_SUCCESS, sts); count++; - gettimeofday(&end_time, NULL); - long seconds = end_time.tv_sec - start_time.tv_sec; - long useconds = end_time.tv_usec - start_time.tv_usec; - mtime = seconds * 1e3 + useconds * 1e-3; - } while (mtime < TestDuration); - double license_request_time = mtime / count; + } + delta_time = clock.now() - start_time; + const double license_request_time = + delta_time / std::chrono::milliseconds(1) / count; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], + OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), wrapped_rsa_key_.size())); vector session_key; vector enc_session_key; - ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_TRUE(s.GenerateRSASessionKey(&session_key, &enc_session_key)); vector mac_context; vector enc_context; s.FillDefaultContext(&mac_context, &enc_context); - gettimeofday(&start_time, NULL); - gettimeofday(&end_time, NULL); - mtime = 0; - count = 0; enc_session_key = wvcdm::a2b_hex( "7789c619aa3b9fa3c0a53f57a4abc6" @@ -2857,19 +2899,19 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) { "ad2b1254f80c0c5dd3cf111b56572217" "b9f58fc1dacbf74b59d354a1e62cfa0e" "bf"); - do { + start_time = clock.now(); + while (clock.now() - start_time < kTestDuration) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_DeriveKeysFromSessionKey( - s.session_id(), &enc_session_key[0], enc_session_key.size(), - &mac_context[0], mac_context.size(), &enc_context[0], - enc_context.size())); + s.session_id(), + enc_session_key.data(), enc_session_key.size(), + mac_context.data(), mac_context.size(), + enc_context.data(), enc_context.size())); count++; - gettimeofday(&end_time, NULL); - long seconds = end_time.tv_sec - start_time.tv_sec; - long useconds = end_time.tv_usec - start_time.tv_usec; - mtime = seconds * 1e3 + useconds * 1e-3; - } while (mtime < TestDuration); - double derive_keys_time = mtime / count; + } + delta_time = clock.now() - start_time; + const double derive_keys_time = + delta_time / std::chrono::milliseconds(1) / count; const char* level = OEMCrypto_SecurityLevel(); printf("PERF:head, security, provision (ms), lic req(ms), derive keys(ms)\n"); @@ -2881,12 +2923,12 @@ TEST_F(OEMCryptoUsesCertificate, RSASignature) { OEMCryptoResult sts; // Sign a Message vector licenseRequest(500); - GetRandBytes(&licenseRequest[0], licenseRequest.size()); + GetRandBytes(licenseRequest.data(), licenseRequest.size()); size_t signature_length = 0; uint8_t signature[500]; sts = OEMCrypto_GenerateRSASignature( - session_.session_id(), &licenseRequest[0], licenseRequest.size(), + session_.session_id(), licenseRequest.data(), licenseRequest.size(), signature, &signature_length, kSign_RSASSA_PSS); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); @@ -2894,13 +2936,13 @@ TEST_F(OEMCryptoUsesCertificate, RSASignature) { ASSERT_GE(sizeof(signature), signature_length); sts = OEMCrypto_GenerateRSASignature( - session_.session_id(), &licenseRequest[0], licenseRequest.size(), + session_.session_id(), licenseRequest.data(), licenseRequest.size(), signature, &signature_length, kSign_RSASSA_PSS); ASSERT_EQ(OEMCrypto_SUCCESS, sts); // In the real world, the signature above would just have been used to contact // the license server to get this response. - ASSERT_NO_FATAL_FAILURE(session_.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(session_.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_NO_FATAL_FAILURE(session_.VerifyRSASignature( licenseRequest, signature, signature_length, kSign_RSASSA_PSS)); @@ -2910,12 +2952,12 @@ TEST_F(OEMCryptoUsesCertificate, RSASignatureLargeBuffer) { OEMCryptoResult sts; // Sign a Message vector licenseRequest(kMaxMessageSize); - GetRandBytes(&licenseRequest[0], licenseRequest.size()); + GetRandBytes(licenseRequest.data(), licenseRequest.size()); size_t signature_length = 0; uint8_t signature[500]; sts = OEMCrypto_GenerateRSASignature( - session_.session_id(), &licenseRequest[0], licenseRequest.size(), + session_.session_id(), licenseRequest.data(), licenseRequest.size(), signature, &signature_length, kSign_RSASSA_PSS); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); @@ -2923,13 +2965,13 @@ TEST_F(OEMCryptoUsesCertificate, RSASignatureLargeBuffer) { ASSERT_GE(sizeof(signature), signature_length); sts = OEMCrypto_GenerateRSASignature( - session_.session_id(), &licenseRequest[0], licenseRequest.size(), + session_.session_id(), licenseRequest.data(), licenseRequest.size(), signature, &signature_length, kSign_RSASSA_PSS); ASSERT_EQ(OEMCrypto_SUCCESS, sts); // In the real world, the signature above would just have been used to contact // the license server to get this response. - ASSERT_NO_FATAL_FAILURE(session_.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(session_.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_NO_FATAL_FAILURE(session_.VerifyRSASignature( licenseRequest, signature, signature_length, kSign_RSASSA_PSS)); @@ -2938,7 +2980,7 @@ TEST_F(OEMCryptoUsesCertificate, RSASignatureLargeBuffer) { TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) { vector session_key; vector enc_session_key; - ASSERT_NO_FATAL_FAILURE(session_.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(session_.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_TRUE(session_.GenerateRSASessionKey(&session_key, &enc_session_key)); vector mac_context(kMaxMessageSize); @@ -2950,9 +2992,10 @@ TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) { } ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_DeriveKeysFromSessionKey( - session_.session_id(), &enc_session_key[0], - enc_session_key.size(), &mac_context[0], mac_context.size(), - &enc_context[0], enc_context.size())); + session_.session_id(), + enc_session_key.data(), enc_session_key.size(), + mac_context.data(), mac_context.size(), + enc_context.data(), enc_context.size())); } // This test attempts to use alternate algorithms for loaded device certs. @@ -2962,25 +3005,28 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { OEMCryptoResult sts; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], + sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); // Sign a Message vector licenseRequest(size); - GetRandBytes(&licenseRequest[0], licenseRequest.size()); + GetRandBytes(licenseRequest.data(), licenseRequest.size()); size_t signature_length = 256; vector signature(signature_length); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &licenseRequest[0], - licenseRequest.size(), &signature[0], - &signature_length, scheme); + sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(), + licenseRequest.size(), + signature.data(), &signature_length, + scheme); // Allow OEMCrypto to request a full buffer. if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { ASSERT_NE(static_cast(0), signature_length); signature.assign(signature_length, 0); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &licenseRequest[0], - licenseRequest.size(), &signature[0], - &signature_length, scheme); + sts = OEMCrypto_GenerateRSASignature(s.session_id(), + licenseRequest.data(), + licenseRequest.size(), + signature.data(), &signature_length, + scheme); } EXPECT_NE(OEMCrypto_SUCCESS, sts) @@ -2994,28 +3040,28 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { OEMCryptoResult sts; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], + sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); vector licenseRequest(size); - GetRandBytes(&licenseRequest[0], licenseRequest.size()); + GetRandBytes(licenseRequest.data(), licenseRequest.size()); size_t signature_length = 0; - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &licenseRequest[0], + sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(), licenseRequest.size(), NULL, &signature_length, scheme); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_NE(static_cast(0), signature_length); uint8_t* signature = new uint8_t[signature_length]; - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &licenseRequest[0], + sts = OEMCrypto_GenerateRSASignature(s.session_id(), licenseRequest.data(), licenseRequest.size(), signature, &signature_length, scheme); ASSERT_EQ(OEMCrypto_SUCCESS, sts) << "Failed to sign with padding scheme=" << (int)scheme << ", size=" << (int)size; - ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature(licenseRequest, signature, signature_length, scheme)); @@ -3026,13 +3072,13 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { OEMCryptoResult sts; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], + sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); s.GenerateNonce(); vector session_key; vector enc_session_key; - ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); ASSERT_TRUE(s.GenerateRSASessionKey(&session_key, &enc_session_key)); vector mac_context; @@ -3040,9 +3086,9 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate { s.FillDefaultContext(&mac_context, &enc_context); ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_DeriveKeysFromSessionKey( - s.session_id(), &enc_session_key[0], enc_session_key.size(), - &mac_context[0], mac_context.size(), &enc_context[0], - enc_context.size())); + s.session_id(), enc_session_key.data(), + enc_session_key.size(), mac_context.data(), + mac_context.size(), enc_context.data(), enc_context.size())); } // If force is true, we assert that the key loads successfully. @@ -3267,14 +3313,14 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates { OEMCryptoResult sts; Session s; ASSERT_NO_FATAL_FAILURE(s.open()); - sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], + sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), wrapped_rsa_key_.data(), wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); // The application will compute the SHA-1 Hash of the message, so this // test must do that also. uint8_t hash[SHA_DIGEST_LENGTH]; - if (!SHA1(&message[0], message.size(), hash)) { + if (!SHA1(message.data(), message.size(), hash)) { dump_boringssl_error(); FAIL() << "boringssl error creating SHA1 hash."; } @@ -3286,21 +3332,21 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates { // OEMCrypto will apply the padding, and encrypt to generate the signature. size_t signature_length = 0; - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &digest[0], + sts = OEMCrypto_GenerateRSASignature(s.session_id(), digest.data(), digest.size(), NULL, &signature_length, scheme); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_NE(static_cast(0), signature_length); vector signature(signature_length); - sts = OEMCrypto_GenerateRSASignature(s.session_id(), &digest[0], - digest.size(), &signature[0], + sts = OEMCrypto_GenerateRSASignature(s.session_id(), digest.data(), + digest.size(), signature.data(), &signature_length, scheme); ASSERT_EQ(OEMCrypto_SUCCESS, sts) << "Failed to sign with padding scheme=" << (int)scheme << ", size=" << (int)message.size(); - ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(&encoded_rsa_key_[0], + ASSERT_NO_FATAL_FAILURE(s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size())); // Verify that the signature matches the official test vector. @@ -3310,10 +3356,10 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates { // Also verify that our verification algorithm agrees. This is not needed // to test OEMCrypto, but it does verify that this test is valid. - ASSERT_NO_FATAL_FAILURE( - s.VerifyRSASignature(digest, &signature[0], signature_length, scheme)); ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature( - digest, &correct_signature[0], correct_signature.size(), scheme)); + digest, signature.data(), signature_length, scheme)); + ASSERT_NO_FATAL_FAILURE(s.VerifyRSASignature( + digest, correct_signature.data(), correct_signature.size(), scheme)); } }; @@ -4021,14 +4067,14 @@ class GenericCryptoTest : public OEMCryptoSessionTests { // reasonable number of blocks for most of the tests. GenericCryptoTest() : buffer_size_(160) {} - virtual void SetUp() { + void SetUp() override { OEMCryptoSessionTests::SetUp(); ASSERT_NO_FATAL_FAILURE(session_.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&session_)); ASSERT_NO_FATAL_FAILURE(MakeFourKeys()); } - virtual void TearDown() { + void TearDown() override { session_.close(); OEMCryptoSessionTests::TearDown(); } @@ -4074,7 +4120,7 @@ class GenericCryptoTest : public OEMCryptoSessionTests { out_buffer->resize(in_buffer.size()); ASSERT_GT(in_buffer.size(), 0u); ASSERT_EQ(0u, in_buffer.size() % AES_BLOCK_SIZE); - AES_cbc_encrypt(&in_buffer[0], out_buffer->data(), in_buffer.size(), + AES_cbc_encrypt(in_buffer.data(), out_buffer->data(), in_buffer.size(), &aes_key, iv_buffer, AES_ENCRYPT); } @@ -4084,7 +4130,7 @@ class GenericCryptoTest : public OEMCryptoSessionTests { unsigned int md_len = SHA256_DIGEST_LENGTH; signature->resize(SHA256_DIGEST_LENGTH); HMAC(EVP_sha256(), session_.license().keys[key_index].key_data, - wvoec::MAC_KEY_SIZE, &in_buffer[0], in_buffer.size(), + wvoec::MAC_KEY_SIZE, in_buffer.data(), in_buffer.size(), signature->data(), &md_len); } @@ -4100,8 +4146,9 @@ class GenericCryptoTest : public OEMCryptoSessionTests { ASSERT_EQ(OEMCrypto_SUCCESS, sts); vector encrypted(buffer_length); sts = - OEMCrypto_Generic_Encrypt(session_.session_id(), &clear_buffer_[0], - buffer_length, iv_, algorithm, &encrypted[0]); + OEMCrypto_Generic_Encrypt(session_.session_id(), clear_buffer_.data(), + buffer_length, iv_, algorithm, + encrypted.data()); EXPECT_NE(OEMCrypto_SUCCESS, sts); expected_encrypted.resize(buffer_length); EXPECT_NE(encrypted, expected_encrypted); @@ -4119,8 +4166,9 @@ class GenericCryptoTest : public OEMCryptoSessionTests { ASSERT_EQ(OEMCrypto_SUCCESS, sts); vector resultant(encrypted.size()); sts = - OEMCrypto_Generic_Decrypt(session_.session_id(), &encrypted[0], - buffer_length, iv_, algorithm, &resultant[0]); + OEMCrypto_Generic_Decrypt(session_.session_id(), encrypted.data(), + buffer_length, iv_, algorithm, + resultant.data()); EXPECT_NE(OEMCrypto_SUCCESS, sts); EXPECT_NE(clear_buffer_, resultant); } @@ -4137,9 +4185,9 @@ class GenericCryptoTest : public OEMCryptoSessionTests { ASSERT_EQ(OEMCrypto_SUCCESS, sts); size_t signature_length = (size_t)SHA256_DIGEST_LENGTH; vector signature(SHA256_DIGEST_LENGTH); - sts = OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0], - clear_buffer_.size(), algorithm, &signature[0], - &signature_length); + sts = OEMCrypto_Generic_Sign(session_.session_id(), clear_buffer_.data(), + clear_buffer_.size(), algorithm, + signature.data(), &signature_length); EXPECT_NE(OEMCrypto_SUCCESS, sts); EXPECT_NE(signature, expected_signature); } @@ -4158,9 +4206,9 @@ class GenericCryptoTest : public OEMCryptoSessionTests { session_.license().keys[key_index].key_id_length, OEMCrypto_CipherMode_CTR); ASSERT_EQ(OEMCrypto_SUCCESS, sts); - sts = OEMCrypto_Generic_Verify(session_.session_id(), &clear_buffer_[0], + sts = OEMCrypto_Generic_Verify(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), algorithm, - &signature[0], signature_size); + signature.data(), signature_size); EXPECT_NE(OEMCrypto_SUCCESS, sts); } @@ -4188,8 +4236,9 @@ TEST_F(GenericCryptoTest, GenericKeyEncrypt) { vector encrypted(clear_buffer_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Encrypt( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, &encrypted[0])); + session_.session_id(), clear_buffer_.data(), + clear_buffer_.size(), iv_, OEMCrypto_AES_CBC_128_NO_PADDING, + encrypted.data())); ASSERT_EQ(expected_encrypted, encrypted); } @@ -4218,8 +4267,8 @@ TEST_F(GenericCryptoTest, GenericKeyEncryptSameBufferAPI12) { vector buffer = clear_buffer_; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Encrypt( - session_.session_id(), &buffer[0], buffer.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, &buffer[0])); + session_.session_id(), buffer.data(), buffer.size(), + iv_, OEMCrypto_AES_CBC_128_NO_PADDING, buffer.data())); ASSERT_EQ(expected_encrypted, buffer); } @@ -4237,8 +4286,8 @@ TEST_F(GenericCryptoTest, GenericKeyDecrypt) { vector resultant(encrypted.size()); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Decrypt( - session_.session_id(), &encrypted[0], encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &resultant[0])); + session_.session_id(), encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); ASSERT_EQ(clear_buffer_, resultant); } @@ -4256,8 +4305,8 @@ TEST_F(GenericCryptoTest, GenericKeyDecryptSameBufferAPI12) { vector buffer = encrypted; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Decrypt( - session_.session_id(), &buffer[0], buffer.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &buffer[0])); + session_.session_id(), buffer.data(), buffer.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, buffer.data())); ASSERT_EQ(clear_buffer_, buffer); } @@ -4277,8 +4326,8 @@ TEST_F(GenericCryptoTest, GenericSecureToClear) { vector resultant(encrypted.size()); ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_Generic_Decrypt( - session_.session_id(), &encrypted[0], encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &resultant[0])); + session_.session_id(), encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); ASSERT_NE(clear_buffer_, resultant); } @@ -4306,15 +4355,15 @@ TEST_F(GenericCryptoTest, GenericKeySign) { OEMCrypto_CipherMode_CTR)); size_t gen_signature_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0], + OEMCrypto_Generic_Sign(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, NULL, &gen_signature_length)); ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); vector signature(SHA256_DIGEST_LENGTH); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0], + OEMCrypto_Generic_Sign(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - &signature[0], &gen_signature_length)); + signature.data(), &gen_signature_length)); ASSERT_EQ(expected_signature, signature); } @@ -4340,8 +4389,9 @@ TEST_F(GenericCryptoTest, GenericKeyVerify) { OEMCrypto_CipherMode_CTR)); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Verify( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), - OEMCrypto_HMAC_SHA256, &signature[0], signature.size())); + session_.session_id(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, signature.data(), + signature.size())); } TEST_F(GenericCryptoTest, GenericKeyBadVerify) { @@ -4370,8 +4420,9 @@ TEST_F(GenericCryptoTest, GenericKeyEncryptLargeBuffer) { vector encrypted(clear_buffer_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Encrypt( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, &encrypted[0])); + session_.session_id(), clear_buffer_.data(), + clear_buffer_.size(), iv_, OEMCrypto_AES_CBC_128_NO_PADDING, + encrypted.data())); ASSERT_EQ(expected_encrypted, encrypted); } @@ -4391,8 +4442,8 @@ TEST_F(GenericCryptoTest, GenericKeyDecryptLargeBuffer) { vector resultant(encrypted.size()); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Decrypt( - session_.session_id(), &encrypted[0], encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &resultant[0])); + session_.session_id(), encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); ASSERT_EQ(clear_buffer_, resultant); } @@ -4411,15 +4462,15 @@ TEST_F(GenericCryptoTest, GenericKeySignLargeBuffer) { OEMCrypto_CipherMode_CTR)); size_t gen_signature_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0], + OEMCrypto_Generic_Sign(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, NULL, &gen_signature_length)); ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); vector signature(SHA256_DIGEST_LENGTH); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0], + OEMCrypto_Generic_Sign(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - &signature[0], &gen_signature_length)); + signature.data(), &gen_signature_length)); ASSERT_EQ(expected_signature, signature); } @@ -4438,8 +4489,9 @@ TEST_F(GenericCryptoTest, GenericKeyVerifyLargeBuffer) { OEMCrypto_CipherMode_CTR)); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Verify( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), - OEMCrypto_HMAC_SHA256, &signature[0], signature.size())); + session_.session_id(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, signature.data(), + signature.size())); } TEST_F(GenericCryptoTest, KeyDurationEncrypt) { @@ -4459,16 +4511,17 @@ TEST_F(GenericCryptoTest, KeyDurationEncrypt) { OEMCrypto_CipherMode_CTR)); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Encrypt( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), - iv_, OEMCrypto_AES_CBC_128_NO_PADDING, &encrypted[0])); + session_.session_id(), clear_buffer_.data(), + clear_buffer_.size(), iv_, OEMCrypto_AES_CBC_128_NO_PADDING, + encrypted.data())); ASSERT_EQ(expected_encrypted, encrypted); sleep(kLongSleep); // Should be expired key. encrypted.assign(clear_buffer_.size(), 0); OEMCryptoResult status = OEMCrypto_Generic_Encrypt( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &encrypted[0]); + session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data()); ASSERT_NO_FATAL_FAILURE( session_.TestDecryptResult(OEMCrypto_ERROR_KEY_EXPIRED, status)); ASSERT_NE(encrypted, expected_encrypted); @@ -4493,16 +4546,16 @@ TEST_F(GenericCryptoTest, KeyDurationDecrypt) { vector resultant(encrypted.size()); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Decrypt( - session_.session_id(), &encrypted[0], encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &resultant[0])); + session_.session_id(), encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); ASSERT_EQ(clear_buffer_, resultant); sleep(kLongSleep); // Should be expired key. resultant.assign(encrypted.size(), 0); OEMCryptoResult status = OEMCrypto_Generic_Decrypt( - session_.session_id(), &encrypted[0], encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &resultant[0]); + session_.session_id(), encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data()); ASSERT_NO_FATAL_FAILURE( session_.TestDecryptResult(OEMCrypto_ERROR_KEY_EXPIRED, status)); ASSERT_NE(clear_buffer_, resultant); @@ -4528,17 +4581,17 @@ TEST_F(GenericCryptoTest, KeyDurationSign) { sleep(kShortSleep); // Should still be valid key. ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0], + OEMCrypto_Generic_Sign(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - &signature[0], &signature_length)); + signature.data(), &signature_length)); ASSERT_EQ(expected_signature, signature); sleep(kLongSleep); // Should be expired key. signature.assign(SHA256_DIGEST_LENGTH, 0); OEMCryptoResult status = OEMCrypto_Generic_Sign( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), - OEMCrypto_HMAC_SHA256, &signature[0], &signature_length); + session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), + OEMCrypto_HMAC_SHA256, signature.data(), &signature_length); ASSERT_NO_FATAL_FAILURE( session_.TestDecryptResult(OEMCrypto_ERROR_KEY_EXPIRED, status)); ASSERT_NE(expected_signature, signature); @@ -4563,14 +4616,15 @@ TEST_F(GenericCryptoTest, KeyDurationVerify) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Verify( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), - OEMCrypto_HMAC_SHA256, &signature[0], signature.size())); + session_.session_id(), clear_buffer_.data(), + clear_buffer_.size(), OEMCrypto_HMAC_SHA256, signature.data(), + signature.size())); sleep(kLongSleep); // Should be expired key. OEMCryptoResult status = OEMCrypto_Generic_Verify( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), - OEMCrypto_HMAC_SHA256, &signature[0], signature.size()); + session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), + OEMCrypto_HMAC_SHA256, signature.data(), signature.size()); ASSERT_NO_FATAL_FAILURE( session_.TestDecryptResult(OEMCrypto_ERROR_KEY_EXPIRED, status)); ASSERT_NO_FATAL_FAILURE(session_.TestSelectExpired(key_index)); @@ -4580,7 +4634,7 @@ const unsigned int kLongKeyId = 2; class GenericCryptoKeyIdLengthTest : public GenericCryptoTest { protected: - virtual void SetUp() { + void SetUp() override { GenericCryptoTest::SetUp(); const uint32_t kNoNonce = 0; session_.set_num_keys(5); @@ -4628,8 +4682,8 @@ class GenericCryptoKeyIdLengthTest : public GenericCryptoTest { vector resultant(encrypted.size()); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Generic_Decrypt( - session_.session_id(), &encrypted[0], encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &resultant[0])); + session_.session_id(), encrypted.data(), encrypted.size(), + iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data())); ASSERT_EQ(clear_buffer_, resultant); } }; @@ -4656,7 +4710,7 @@ TEST_F(GenericCryptoKeyIdLengthTest, UniformLongKeyId) { class UsageTableTest : public GenericCryptoTest { public: - virtual void SetUp() { + void SetUp() override { GenericCryptoTest::SetUp(); new_mac_keys_ = true; } @@ -4712,7 +4766,7 @@ class UsageTableTest : public GenericCryptoTest { class UsageTableTestWithMAC : public UsageTableTest, public WithParamInterface { public: - virtual void SetUp() { + void SetUp() override { UsageTableTest::SetUp(); new_mac_keys_ = GetParam(); } @@ -4746,6 +4800,12 @@ TEST_P(UsageTableTestWithMAC, OnlineLicense) { // Decrypt should fail. ASSERT_NO_FATAL_FAILURE( s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); + // We could call DeactivateUsageEntry multiple times. The state should not + // change. + ASSERT_NO_FATAL_FAILURE(s.DeactivateUsageEntry(pst)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // It should report as inactive. + ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kInactiveUsed)); } TEST_P(UsageTableTestWithMAC, OnlineLicenseUnused) { @@ -4770,6 +4830,12 @@ TEST_P(UsageTableTestWithMAC, OnlineLicenseUnused) { // Decrypt should fail. ASSERT_NO_FATAL_FAILURE( s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); + // We could call DeactivateUsageEntry multiple times. The state should not + // change. + ASSERT_NO_FATAL_FAILURE(s.DeactivateUsageEntry(pst)); + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + // It should report as inactive. + ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kInactiveUnused)); } TEST_P(UsageTableTestWithMAC, ForbidReportWithNoUpdate) { @@ -4853,7 +4919,7 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) { ASSERT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), + s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(), OEMCrypto_ContentLicense)); @@ -4871,7 +4937,7 @@ TEST_F(UsageTableTest, OnlineEmptyPST) { ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -4891,7 +4957,7 @@ TEST_F(UsageTableTest, OnlineMissingEntry) { ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); // ENTRY NOT CREATED: ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(), OEMCrypto_ContentLicense); @@ -4918,8 +4984,8 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); vector encrypted(clear_buffer_.size()); sts = OEMCrypto_Generic_Encrypt( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &encrypted[0]); + session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); EXPECT_EQ(expected_encrypted, encrypted); ASSERT_NO_FATAL_FAILURE(session_.UpdateUsageEntry(&encrypted_usage_header_)); @@ -4929,8 +4995,8 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) { ASSERT_NO_FATAL_FAILURE(session_.GenerateVerifyReport(pst, kInactiveUsed)); encrypted.assign(clear_buffer_.size(), 0); sts = OEMCrypto_Generic_Encrypt( - session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &encrypted[0]); + session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, encrypted.data()); ASSERT_NE(OEMCrypto_SUCCESS, sts); EXPECT_NE(encrypted, expected_encrypted); } @@ -4955,8 +5021,8 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoDecrypt) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); vector resultant(encrypted.size()); sts = OEMCrypto_Generic_Decrypt( - session_.session_id(), &encrypted[0], encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &resultant[0]); + session_.session_id(), encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING,resultant.data()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); EXPECT_EQ(clear_buffer_, resultant); ASSERT_NO_FATAL_FAILURE(session_.UpdateUsageEntry(&encrypted_usage_header_)); @@ -4966,8 +5032,8 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoDecrypt) { ASSERT_NO_FATAL_FAILURE(session_.GenerateVerifyReport(pst, kInactiveUsed)); resultant.assign(encrypted.size(), 0); sts = OEMCrypto_Generic_Decrypt( - session_.session_id(), &encrypted[0], encrypted.size(), iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, &resultant[0]); + session_.session_id(), encrypted.data(), encrypted.size(), iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, resultant.data()); ASSERT_NE(OEMCrypto_SUCCESS, sts); EXPECT_NE(clear_buffer_, resultant); } @@ -4994,15 +5060,15 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoSign) { OEMCrypto_CipherMode_CTR); ASSERT_EQ(OEMCrypto_SUCCESS, sts); size_t gen_signature_length = 0; - sts = OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0], + sts = OEMCrypto_Generic_Sign(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, NULL, &gen_signature_length); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); vector signature(SHA256_DIGEST_LENGTH); - sts = OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0], + sts = OEMCrypto_Generic_Sign(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - &signature[0], &gen_signature_length); + signature.data(), &gen_signature_length); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(expected_signature, signature); @@ -5013,9 +5079,9 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoSign) { ASSERT_NO_FATAL_FAILURE(session_.GenerateVerifyReport(pst, kInactiveUsed)); signature.assign(SHA256_DIGEST_LENGTH, 0); gen_signature_length = SHA256_DIGEST_LENGTH; - sts = OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0], + sts = OEMCrypto_Generic_Sign(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - &signature[0], &gen_signature_length); + signature.data(), &gen_signature_length); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NE(signature, expected_signature); } @@ -5040,18 +5106,18 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoVerify) { session_.license().keys[key_index].key_id_length, OEMCrypto_CipherMode_CTR); ASSERT_EQ(OEMCrypto_SUCCESS, sts); - sts = OEMCrypto_Generic_Verify(session_.session_id(), &clear_buffer_[0], + sts = OEMCrypto_Generic_Verify(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - &signature[0], signature.size()); + signature.data(), signature.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(session_.UpdateUsageEntry(&encrypted_usage_header_)); ASSERT_NO_FATAL_FAILURE(session_.GenerateVerifyReport(pst, kActive)); ASSERT_NO_FATAL_FAILURE(session_.DeactivateUsageEntry(pst)); ASSERT_NO_FATAL_FAILURE(session_.UpdateUsageEntry(&encrypted_usage_header_)); ASSERT_NO_FATAL_FAILURE(session_.GenerateVerifyReport(pst, kInactiveUsed)); - sts = OEMCrypto_Generic_Verify(session_.session_id(), &clear_buffer_[0], + sts = OEMCrypto_Generic_Verify(session_.session_id(), clear_buffer_.data(), clear_buffer_.size(), OEMCrypto_HMAC_SHA256, - &signature[0], signature.size()); + signature.data(), signature.size()); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -5148,7 +5214,7 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineLicenseWithTerminate) { ShutDown(); Restart(); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageTableHeader(&encrypted_usage_header_[0], + OEMCrypto_LoadUsageTableHeader(encrypted_usage_header_.data(), encrypted_usage_header_.size())); ASSERT_NO_FATAL_FAILURE(s.open()); @@ -5182,7 +5248,7 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) { ASSERT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.session_id(), s2.message_ptr(), s2.message_size(), - &s2.signature()[0], s2.signature().size(), + s2.signature().data(), s2.signature().size(), s2.enc_mac_keys_iv_substr(), s2.enc_mac_keys_substr(), s.num_keys(), s2.key_array(), s2.pst_substr(), GetSubstring(), OEMCrypto_ContentLicense)); @@ -5211,7 +5277,7 @@ TEST_P(UsageTableTestWithMAC, OfflineBadNonce) { s.FillSimpleMessage(0, wvoec::kControlNonceOrEntry, 42, pst)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(), OEMCrypto_ContentLicense); @@ -5229,7 +5295,7 @@ TEST_P(UsageTableTestWithMAC, OfflineEmptyPST) { s.FillSimpleMessage(0, wvoec::kControlNonceOrEntry, s.get_nonce())); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], + s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); @@ -5251,7 +5317,7 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineWrongPST) { ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), GetSubstring(), + s.signature().data(), s.signature().size(), GetSubstring(), GetSubstring(), s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(), OEMCrypto_ContentLicense)); } @@ -5283,7 +5349,7 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) { EXPECT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), + s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(), OEMCrypto_ContentLicense)); @@ -5295,6 +5361,12 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) { ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_)); ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, OEMCrypto_SUCCESS, &s)); EXPECT_EQ(kInactiveUsed, s3.pst_report().status()); + // We could call DeactivateUsageEntry multiple times. The state should not + // change. + ASSERT_NO_FATAL_FAILURE(s3.DeactivateUsageEntry(pst)); + ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, OEMCrypto_SUCCESS, &s)); + EXPECT_EQ(kInactiveUsed, s3.pst_report().status()); } TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicenseUnused) { @@ -5324,7 +5396,7 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicenseUnused) { EXPECT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.session_id(), s1.message_ptr(), s1.message_size(), - &s1.signature()[0], s1.signature().size(), + s1.signature().data(), s1.signature().size(), s1.enc_mac_keys_iv_substr(), s1.enc_mac_keys_substr(), s1.num_keys(), s1.key_array(), s1.pst_substr(), GetSubstring(), OEMCrypto_ContentLicense)); @@ -5336,6 +5408,12 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicenseUnused) { ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_)); ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, OEMCrypto_SUCCESS, &s1)); EXPECT_EQ(kInactiveUnused, s3.pst_report().status()); + // We could call DeactivateUsageEntry multiple times. The state should not + // change. + ASSERT_NO_FATAL_FAILURE(s3.DeactivateUsageEntry(pst)); + ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_)); + ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, OEMCrypto_SUCCESS, &s1)); + EXPECT_EQ(kInactiveUnused, s3.pst_report().status()); } TEST_P(UsageTableTestWithMAC, BadRange) { @@ -5355,7 +5433,7 @@ TEST_P(UsageTableTestWithMAC, BadRange) { OEMCrypto_LoadKeys( s.session_id(), reinterpret_cast(double_message.data()), - s.message_size(), &s.signature()[0], s.signature().size(), + s.message_size(), s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), wrong_pst, GetSubstring(), OEMCrypto_ContentLicense)); } @@ -5379,10 +5457,10 @@ TEST_F(UsageTableTest, UpdateFailsWithNullPtr) { ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageEntry( s.session_id(), NULL, &header_buffer_length, - &buffer[0], &entry_buffer_length)); + buffer.data(), &entry_buffer_length)); ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageEntry( - s.session_id(), &encrypted_usage_header_[0], + s.session_id(), encrypted_usage_header_.data(), &header_buffer_length, NULL, &entry_buffer_length)); } @@ -5424,13 +5502,13 @@ class UsageTableDefragTest : public UsageTableTest { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(s)); ASSERT_EQ(expected_result, OEMCrypto_LoadUsageEntry(s->session_id(), s->usage_entry_number(), - &s->encrypted_usage_entry()[0], + s->encrypted_usage_entry().data(), s->encrypted_usage_entry().size())); ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_LoadKeys( s->session_id(), s->message_ptr(), s->message_size(), - &s->signature()[0], s->signature().size(), + s->signature().data(), s->signature().size(), s->enc_mac_keys_iv_substr(), s->enc_mac_keys_substr(), s->num_keys(), s->key_array(), s->pst_substr(), GetSubstring(), OEMCrypto_ContentLicense)); @@ -5451,7 +5529,7 @@ class UsageTableDefragTest : public UsageTableTest { ASSERT_LT(0u, header_buffer_length); encrypted_usage_header_.resize(header_buffer_length); sts = OEMCrypto_ShrinkUsageTableHeader( - new_size, &encrypted_usage_header_[0], + new_size, encrypted_usage_header_.data(), &header_buffer_length); ASSERT_EQ(expected_result, sts); } @@ -5478,7 +5556,7 @@ TEST_F(UsageTableDefragTest, MoveUsageEntries) { ShutDown(); Restart(); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageTableHeader(&encrypted_usage_header_[0], + OEMCrypto_LoadUsageTableHeader(encrypted_usage_header_.data(), encrypted_usage_header_.size())); ASSERT_NO_FATAL_FAILURE(ReloadLicense(&sessions[0], start[0])); // Now has index 1. @@ -5560,7 +5638,7 @@ TEST_F(UsageTableDefragTest, ReloadUsageEntryBadData) { // Error could be signature or verification error. ASSERT_NE(OEMCrypto_SUCCESS, OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - &data[0], data.size())); + data.data(), data.size())); } static std::string MakePST(size_t n) { @@ -5733,7 +5811,7 @@ TEST_F(UsageTableTest, ReloadUsageTableWithSkew) { ASSERT_EQ( OEMCrypto_ERROR_UNKNOWN_FAILURE, OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - &s.encrypted_usage_entry()[0], + s.encrypted_usage_entry().data(), s.encrypted_usage_entry().size())); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.close()); @@ -5742,42 +5820,42 @@ TEST_F(UsageTableTest, ReloadUsageTableWithSkew) { vector bad_header = encrypted_usage_header_; bad_header[3] ^= 42; ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageTableHeader(&bad_header[0], + OEMCrypto_LoadUsageTableHeader(bad_header.data(), bad_header.size())); ASSERT_NO_FATAL_FAILURE(s.open()); // Cannot load an entry with if header didn't load. ASSERT_EQ( OEMCrypto_ERROR_UNKNOWN_FAILURE, OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - &s.encrypted_usage_entry()[0], + s.encrypted_usage_entry().data(), s.encrypted_usage_entry().size())); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.close()); // Old by 2 generation numbers is error. ASSERT_EQ(OEMCrypto_ERROR_GENERATION_SKEW, - OEMCrypto_LoadUsageTableHeader(&old_usage_header_2_[0], + OEMCrypto_LoadUsageTableHeader(old_usage_header_2_.data(), old_usage_header_2_.size())); ASSERT_NO_FATAL_FAILURE(s.open()); // Cannot load an entry with if header didn't load. ASSERT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - &s.encrypted_usage_entry()[0], + s.encrypted_usage_entry().data(), s.encrypted_usage_entry().size())); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.close()); // Old by 1 generation numbers is just warning. ASSERT_EQ(OEMCrypto_WARNING_GENERATION_SKEW, - OEMCrypto_LoadUsageTableHeader(&old_usage_header_1_[0], + OEMCrypto_LoadUsageTableHeader(old_usage_header_1_.data(), old_usage_header_1_.size())); // Everything else should still work. Skew by 1 is just a warning. ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_EQ( OEMCrypto_WARNING_GENERATION_SKEW, OEMCrypto_LoadUsageEntry(s.session_id(), s.usage_entry_number(), - &s.encrypted_usage_entry()[0], + s.encrypted_usage_entry().data(), s.encrypted_usage_entry().size())); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); @@ -5847,7 +5925,7 @@ TEST_F(UsageTableTest, TimingTest) { sleep(kShortSleep); Restart(); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadUsageTableHeader(&encrypted_usage_header_[0], + OEMCrypto_LoadUsageTableHeader(encrypted_usage_header_.data(), encrypted_usage_header_.size())); // After a reboot, we should be able to reload keys, and generate reports. @@ -6113,7 +6191,7 @@ TEST_F(UsageTableTest, LoadSharedLicenseWithNoMaster) { ASSERT_EQ( OEMCrypto_ERROR_MISSING_MASTER, OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), + s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(), OEMCrypto_ContentLicense)); @@ -6147,7 +6225,7 @@ TEST_F(UsageTableTest, PSTLargeBuffer) { EXPECT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), + s.signature().data(), s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(), OEMCrypto_ContentLicense)); diff --git a/oemcrypto/test/oemcrypto_test_android.cpp b/oemcrypto/test/oemcrypto_test_android.cpp index 77a12ff..79211a3 100644 --- a/oemcrypto/test/oemcrypto_test_android.cpp +++ b/oemcrypto/test/oemcrypto_test_android.cpp @@ -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. diff --git a/oemcrypto/test/oemcrypto_unittests.gyp b/oemcrypto/test/oemcrypto_unittests.gyp index 67257c3..c02d055 100644 --- a/oemcrypto/test/oemcrypto_unittests.gyp +++ b/oemcrypto/test/oemcrypto_unittests.gyp @@ -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', ], diff --git a/oemcrypto/test/oemcrypto_unittests.gypi b/oemcrypto/test/oemcrypto_unittests.gypi index 3f22334..b7a6717 100644 --- a/oemcrypto/test/oemcrypto_unittests.gypi +++ b/oemcrypto/test/oemcrypto_unittests.gypi @@ -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', diff --git a/oemcrypto/test/wvcrc.cpp b/oemcrypto/test/wvcrc.cpp new file mode 100644 index 0000000..2c178f6 --- /dev/null +++ b/oemcrypto/test/wvcrc.cpp @@ -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 +#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 diff --git a/oemcrypto/test/wvcrc32.h b/oemcrypto/test/wvcrc32.h new file mode 100644 index 0000000..2436211 --- /dev/null +++ b/oemcrypto/test/wvcrc32.h @@ -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 + +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_ diff --git a/util/include/file_store.h b/util/include/file_store.h index 6787229..75ad36c 100644 --- a/util/include/file_store.h +++ b/util/include/file_store.h @@ -8,35 +8,33 @@ #define WVCDM_UTIL_FILE_STORE_H_ #include +#include #include #include #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 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* 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 impl_; std::string origin_; std::string identifier_; diff --git a/util/include/log.h b/util/include/log.h index 624e0a3..ce390a0 100644 --- a/util/include/log.h +++ b/util/include/log.h @@ -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 diff --git a/util/include/string_conversions.h b/util/include/string_conversions.h index 3a6a354..3bb73dc 100644 --- a/util/include/string_conversions.h +++ b/util/include/string_conversions.h @@ -10,23 +10,31 @@ #include #include +#include "util_common.h" + namespace wvcdm { -std::vector a2b_hex(const std::string& b); -std::vector 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& b); -std::string b2a_hex(const std::string& b); -std::string Base64Encode(const std::vector& bin_input); -std::vector Base64Decode(const std::string& bin_input); -std::string Base64SafeEncode(const std::vector& bin_input); -std::string Base64SafeEncodeNoPad(const std::vector& bin_input); -std::vector 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 a2b_hex(const std::string& b); +CORE_UTIL_EXPORT std::vector 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& b); +CORE_UTIL_EXPORT std::string b2a_hex(const std::string& b); +CORE_UTIL_EXPORT std::string Base64Encode( + const std::vector& bin_input); +CORE_UTIL_EXPORT std::vector Base64Decode( + const std::string& bin_input); +CORE_UTIL_EXPORT std::string Base64SafeEncode( + const std::vector& bin_input); +CORE_UTIL_EXPORT std::string Base64SafeEncodeNoPad( + const std::vector& bin_input); +CORE_UTIL_EXPORT std::vector 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 diff --git a/util/include/util_common.h b/util/include/util_common.h new file mode 100644 index 0000000..9a1f309 --- /dev/null +++ b/util/include/util_common.h @@ -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_