From ef80dcf790be78aff540bfa07b3ccb23b8c247e8 Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Sat, 4 Dec 2021 00:50:57 +0000 Subject: [PATCH] Update documentation and update some tests Some changes were made to align the source code with the new devsite, https://developers.devsite.corp.google.com/widevine. Updates to documentation: 6cd6438a5 Update doc string for return values 8705af128 Move documentation of Resource Rating to devsite f0394da46 Documentation: specify usage entry may not be reloaded f7e1dd729 Documentation: clarify buffers sizes for DeriveKeys 305d98f4a Documentation: Entitled content keys are not wrapped 11174fd01 Documentation: Add figures to OEMCrypto API e1fdbbfc2 Document buffer size for OEMCrypto_CopyBuffer 06dd39c46 Update return code docs for OEMCrypto_ReportUsage b67a0c688 Documentation: Add parentheses so Doxygen creates links 369fcde53 Documentation: Add links from OEMCrypto API a7489aa25 Remove extra blank line Some unit tests were not compiling on some platforms. Some platforms were not passing usage table duration tests even though they correctly implemented the spec. Update to tests: 0268104c1 Add curly braces in oemcrypto_test.cpp 8dce14f2d Update usage entry before sleeping 0c164a2c4 Use size_t for length in wvcrc32 --- oemcrypto/include/OEMCryptoCENC.h | 841 ++++++++++++++++++------------ oemcrypto/ref/src/wvcrc.cpp | 120 ++--- oemcrypto/ref/src/wvcrc32.h | 6 +- oemcrypto/test/oemcrypto_test.cpp | 23 +- oemcrypto/test/wvcrc.cpp | 120 ++--- oemcrypto/test/wvcrc32.h | 6 +- 6 files changed, 638 insertions(+), 478 deletions(-) diff --git a/oemcrypto/include/OEMCryptoCENC.h b/oemcrypto/include/OEMCryptoCENC.h index b268321..36ccaae 100644 --- a/oemcrypto/include/OEMCryptoCENC.h +++ b/oemcrypto/include/OEMCryptoCENC.h @@ -12,7 +12,7 @@ * * For an overview of OEMCrypto functionality, please see * [Widevine Modular DRM Security Integration Guide for Common - * Encryption](../oemcrypto) + * Encryption](../index) * * The OEMCrypto API is divided into several sections. * @@ -48,6 +48,13 @@ * securely delivered from the server to the client device using the same * factory installed root of trust as a media content keys. * + * + * ![Generic Encrypt and Decrypt flow](fig2.svg) + * + * ![Generic Sign flow](fig3.svg) + * + * ![Generic Verify flow](fig4.svg) + * * @defgroup factory_provision Factory Provisioning API * Functions that are used to install the root of trust. This could be either a * keybox or an OEM Certificate. @@ -59,14 +66,14 @@ * section describes the API that installs the Widevine Keybox and the * recommended methods for the OEM's factory provisioning procedure. * - * Starting with API version 10, devices should have two keyboxes. One is the - * production keybox which may be installed in the factory, or using - * OEMCrypto_WrapKeyboxOrOEMCert and OEMCrypto_InstallKeyboxOrOEMCert as - * described below. The second keybox is a test keybox. The test keybox is the - * same for all devices and is used for a suite of unit tests. The test keybox - * will only be used temporarily while the unit tests are running, and will not - * be used by the general public. After the unit tests have been run, and - * OEMCrypto_Terminate has been called, the production keybox should be active + * Devices should support both a production keybox and a temporary test + * keybox. The production keybox is usually installed in the factory, or using + * OEMCrypto_WrapKeyboxOrOEMCert() and OEMCrypto_InstallKeyboxOrOEMCert(). The + * temporary keybox is a test keybox, and is loaded via + * OEMCrypto_LoadTestKeybox() by the unit tests. The test keybox will only be + * used temporarily while the unit tests are running, and will not be used by + * the general public. After the unit tests have been run, and + * OEMCrypto_Terminate() has been called, the production keybox should be active * again. * * API functions marked as optional may be used by the OEM's factory @@ -77,7 +84,8 @@ * Functions that are needed to for a device with a keybox. * * The OEMCrypto API allows for a device to be initially provisioned with a - * keybox or with an OEM certificate. See the section Provisioning above. In a + * keybox or with an OEM certificate. See the section + * [Provisioning](../../index#provisioning) in the integration guide. In a * Level 1 or Level 2 implementation, only the security processor may access the * keys in the keybox. The following functions are for devices that are * provisioned with a keybox, i.e. Provisioning 2.0. @@ -86,9 +94,10 @@ * Functions that are needed to for a device with an OEM Certificate. * * The OEMCrypto API allows for a device to be initially provisioned with a - * keybox or with an OEM certificate. See the Provisioning above. The - * functions in this section are for devices that are provisioned with an OEM - * Certificate, i.e. Provisioning 3.0. + * keybox or with an OEM certificate. See the section + * Provisioning in the integration guide. + * The functions in this section are for devices that are provisioned with an + * OEM Certificate, i.e. Provisioning 3.0. * * API functions marked as optional may be used by the OEM's factory * provisioning procedure and implemented in the library, but are not called @@ -117,7 +126,7 @@ * * @defgroup test_verify Test and Verification API * Functions that are designed to help test OEMCrypto and the device. They are - * not used during normal operation. Some functions, like OEMCrypto_RemoveSRM + * not used during normal operation. Some functions, like OEMCrypto_RemoveSRM() * should only be implemented on test devices. Other functions, like those that * test the full decrypt data path may be supported on a production device with * no added risk of security loss. @@ -172,8 +181,8 @@ typedef enum OEMCryptoBufferType { } OEMCryptoBufferType; /** - * This structure is used as parameters in the OEMCrypto_DecryptCENC and - * OEMCrypto_CopyBuffer functions. This describes the type and access + * This structure is used as parameters in the OEMCrypto_DecryptCENC() and + * OEMCrypto_CopyBuffer() functions. This describes the type and access * information for the memory to receive decrypted data. * * The OEMCrypto API supports a range of client device architectures. Different @@ -242,7 +251,7 @@ typedef struct { } OEMCrypto_DestBufferDesc; /** - * This structure is used as parameters in the OEMCrypto_DecryptCENC function. + * This structure is used as parameters in the OEMCrypto_DecryptCENC() function. * * @param[in] input_data: An unaligned pointer to this sample from the stream. * @param[in] input_data_length: The length of this sample in the stream, in @@ -261,7 +270,7 @@ typedef struct { } OEMCrypto_InputOutputPair; /** - * This structure is used as parameters in the OEMCrypto_DecryptCENC + * This structure is used as parameters in the OEMCrypto_DecryptCENC() * function. In the DASH specification, a sample is composed of multiple * samples, and each subsample is composed of two regions. The first region is * clear unprotected data. We also call this clear data or unencrypted @@ -302,7 +311,7 @@ typedef struct { #define OEMCrypto_LastSubsample 2 /** - * This structure is used as parameters in the OEMCrypto_DecryptCENC function. + * This structure is used as parameters in the OEMCrypto_DecryptCENC() function. * * @param[in] buffers: A structure containing information about the input and * output buffers. @@ -325,7 +334,7 @@ typedef struct { } OEMCrypto_SampleDescription; /** - * This structure is used as parameters in the OEMCrypto_DecryptCENC function. + * This structure is used as parameters in the OEMCrypto_DecryptCENC() function. * * Fields: * @param[in] encrypt: The number of 16-byte crypto blocks to encrypt. @@ -481,8 +490,8 @@ typedef enum OEMCrypto_ProvisioningMethod { OEMCrypto_ProvisioningError = 0, // Device cannot be provisioned. OEMCrypto_DrmCertificate = 1, // Device has baked in DRM certificate // (level 3 only) - OEMCrypto_Keybox = 2, // Device has factory installed unique keybox. - OEMCrypto_OEMCertificate = 3 // Device has factory installed OEM certificate. + OEMCrypto_Keybox = 2, // Device has factory installed unique keybox. + OEMCrypto_OEMCertificate = 3 // Device has factory installed OEM certificate. } OEMCrypto_ProvisioningMethod; /** @@ -490,7 +499,7 @@ typedef enum OEMCrypto_ProvisioningMethod { */ #define OEMCrypto_Supports_RSA_2048bit 0x1 #define OEMCrypto_Supports_RSA_3072bit 0x2 -#define OEMCrypto_Supports_RSA_CAST 0x10 +#define OEMCrypto_Supports_RSA_CAST 0x10 #define OEMCrypto_Supports_ECC_secp256r1 0x100 #define OEMCrypto_Supports_ECC_secp384r1 0x200 #define OEMCrypto_Supports_ECC_secp521r1 0x400 @@ -505,12 +514,12 @@ typedef enum OEMCrypto_ProvisioningMethod { /** * Return values from OEMCrypto_GetAnalogOutputFlags. */ -#define OEMCrypto_No_Analog_Output 0x0 -#define OEMCrypto_Supports_Analog_Output 0x1 -#define OEMCrypto_Can_Disable_Analog_Ouptput 0x2 -#define OEMCrypto_Supports_CGMS_A 0x4 +#define OEMCrypto_No_Analog_Output 0x0 +#define OEMCrypto_Supports_Analog_Output 0x1 +#define OEMCrypto_Can_Disable_Analog_Ouptput 0x2 +#define OEMCrypto_Supports_CGMS_A 0x4 // Unknown_Analog_Output is used only for backwards compatibility. -#define OEMCrypto_Unknown_Analog_Output (1<<31) +#define OEMCrypto_Unknown_Analog_Output (1 << 31) /// @} @@ -623,6 +632,19 @@ typedef enum OEMCrypto_ProvisioningMethod { #define OEMCrypto_DecryptCENC _oecc105 #define OEMCrypto_LoadDRMPrivateKey _oecc107 #define OEMCrypto_MinorAPIVersion _oecc108 +#define OEMCrypto_AllocateSecureBuffer _oecc109 +#define OEMCrypto_FreeSecureBuffer _oecc110 +#define OEMCrypto_CreateEntitledKeySession _oecc111 +#define OEMCrypto_RemoveEntitledKeySession _oecc112 +#define OEMCrypto_GenerateOTARequest _oecc113 +#define OEMCrypto_ProcessOTAKeybox _oecc114 +#define OEMCrypto_OPK_SerializationVersion _oecc115 +#define OEMCrypto_GetBootCertificateChain _oecc116 +#define OEMCrypto_GenerateCertificateKeyPair _oecc117 +#define OEMCrypto_InstallOemPrivateKey _oecc118 +#define OEMCrypto_ReassociateEntitledKeySession _oecc119 +#define OEMCrypto_LoadCasECMKeys _oecc120 +#define OEMCrypto_LoadEntitledContentKeys_v17 _oecc121 // place holder for v17. // clang-format on /// @addtogroup initcontrol @@ -632,8 +654,8 @@ typedef enum OEMCrypto_ProvisioningMethod { * This tells OEMCrypto which sandbox the current process belongs to. Any * persistent memory used to store the generation number should be associated * with this sandbox id. OEMCrypto can assume that this sandbox will be tied - * to the current process or VM until OEMCrypto_Terminate is called. See the - * section "VM and Sandbox Support" above for more details. + * to the current process or VM until OEMCrypto_Terminate() is called. See the + * section [VM and Sandbox Support](../../index#sandbox) for more details. * * If OEMCrypto does not support sandboxes, it will return * OEMCrypto_ERROR_NOT_IMPLEMENTED. On most platforms, this function will @@ -641,10 +663,10 @@ typedef enum OEMCrypto_ProvisioningMethod { * sandboxes, this function returns OEMCrypto_SUCCESS on success, and * OEMCrypto_ERROR_UNKNOWN_FAILURE on failure. * - * The CDM layer will call OEMCrypto_SetSandbox once before - * OEMCrypto_Initialize. After this function is called and returns success, + * The CDM layer will call OEMCrypto_SetSandbox() once before + * OEMCrypto_Initialize(). After this function is called and returns success, * it will be OEMCrypto's responsibility to keep calls to usage table - * functions separate, and to accept a call to OEMCrypto_Terminate for each + * functions separate, and to accept a call to OEMCrypto_Terminate() for each * sandbox. * * @param[in] sandbox_id: a short string unique to the current sandbox. @@ -658,7 +680,7 @@ typedef enum OEMCrypto_ProvisioningMethod { * This is an "Initialization and Termination Function" and will not be * called simultaneously with any other function, as if the CDM holds a write * lock on the OEMCrypto system. It is called once before - * OEMCrypto_Initialize. + * OEMCrypto_Initialize(). * * @version * This method is new in version 15 of the API. @@ -739,7 +761,7 @@ OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session); * Closes the crypto security engine session and frees any associated * resources. If this session is associated with a Usage Entry, all resident * memory associated with it will be freed. It is the CDM layer's - * responsibility to call OEMCrypto_UpdateUsageEntry before closing the + * responsibility to call OEMCrypto_UpdateUsageEntry() before closing the * session. * * @param[in] session: handle for the session to be closed. @@ -804,7 +826,8 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); * * @buffer_size * OEMCrypto shall support mac_key_context and enc_key_context sizes as - * described in the section OEMCrypto_ResourceRatingTier. + * described in the section OEMCrypto_ResourceRatingTier() for messages. The + * key derivation context is about 25 bytes prepended to the request message. * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffers are * too large. * @@ -829,7 +852,7 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys( * encrypt_key, for handling signing and content key decryption under the * license server protocol for CENC. * - * This function is similar to OEMCrypto_GenerateDerivedKeys, except that it + * This function is similar to OEMCrypto_GenerateDerivedKeys(), except that it * uses a session key to generate the secondary keys instead of the Widevine * Keybox device key. These three keys will be stored in secure memory until * the next call to LoadLicense or LoadProvisioning. @@ -886,7 +909,8 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys( * * @buffer_size * OEMCrypto shall support mac_key_context and enc_key_context sizes as - * described in the section OEMCrypto_ResourceRatingTier. + * described in the section OEMCrypto_ResourceRatingTier() for messages. The + * key derivation context is about 25 bytes prepended to the request message. * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffers are * too large. * @@ -957,7 +981,7 @@ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, /** * OEMCrypto will use ODK_PrepareCoreLicenseRequest to prepare the core * message. If it returns OEMCrypto_SUCCESS, then OEMCrypto shall sign the - * the message body using the DRM certificate's private key. If it returns an + * message body using the DRM certificate's private key. If it returns an * error, the error should be returned by OEMCrypto to the CDM layer. * ODK_PrepareCoreLicenseRequest is described in the document "Widevine Core * Message Serialization". @@ -1011,7 +1035,7 @@ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, * * @buffer_size * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier. + * OEMCrypto_ResourceRatingTier(). * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * @@ -1055,14 +1079,14 @@ OEMCryptoResult OEMCrypto_PrepAndSignLicenseRequest( * for license request signing under the license server protocol for CENC. * * The key used for signing should be the mac_key[client] that was generated - * for this session or loaded for this session by OEMCrypto_LoadKeys, - * OEMCrypto_LoadLicense, or OEMCrypto_LoadUsageEntry. + * for this session or loaded for this session by OEMCrypto_LoadKeys(), + * OEMCrypto_LoadLicense(), or OEMCrypto_LoadUsageEntry(). * * Refer to the Signing Messages Sent to a Server section above for more * details. * * If a usage entry has been loaded, but keys have not been loaded through - * OEMCrypto_LoadKeys, then the derived mac keys and the keys in the usage + * OEMCrypto_LoadKeys(), then the derived mac keys and the keys in the usage * entry may be different. In this case, the mac keys specified in the usage * entry should be used. * @@ -1093,7 +1117,7 @@ OEMCryptoResult OEMCrypto_PrepAndSignLicenseRequest( * * @buffer_size * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier. + * OEMCrypto_ResourceRatingTier(). * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * @@ -1112,7 +1136,7 @@ OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest( size_t* core_message_size, uint8_t* signature, size_t* signature_length); /** - * OEMCrypto will use OEMCrypto_PrepAndSignProvisioningRequest, as described + * OEMCrypto will use OEMCrypto_PrepAndSignProvisioningRequest(), as described * in the document "Widevine Core Message Serialization", to prepare the core * message. If it returns an error, the error should be returned by OEMCrypto * to the CDM layer. If it returns OEMCrypto_SUCCESS, then OEMCrypto shall @@ -1121,12 +1145,12 @@ OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest( * * For a device that has a keybox, i.e. Provisioning 2.0, OEMCrypto will sign * the request with the session's derived client mac key from the previous - * call to OEMCrypto_GenerateDerivedKeys. + * call to OEMCrypto_GenerateDerivedKeys(). * * For a device that has an OEM Certificate, i.e. Provisioning 3.0, OEMCrypto * will sign the request with the private key associated with the OEM * Certificate. The key shall have been loaded by a previous call to - * OEMCrypto_LoadDRMPrivateKey. + * OEMCrypto_LoadDRMPrivateKey(). * * Refer to the Signing Messages Sent to a Server section above for more * details. @@ -1158,7 +1182,7 @@ OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest( * * @buffer_size * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier. + * OEMCrypto_ResourceRatingTier(). * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * @@ -1177,15 +1201,15 @@ OEMCryptoResult OEMCrypto_PrepAndSignProvisioningRequest( size_t* core_message_size, uint8_t* signature, size_t* signature_length); /** - * Verify and install a new SRM file. The device shall install the new file - * only if verification passes. If verification fails, the existing SRM will - * be left in place. Verification is defined by DCP, and includes - * verification of the SRM's signature and verification that the SRM version - * number will not be decreased. See the section HDCP SRM Update above for + * Verify and install a new SRM file. The device shall install the new file only + * if verification passes. If verification fails, the existing SRM will be left + * in place. Verification is defined by DCP, and includes verification of the + * SRM's signature and verification that the SRM version number will not be + * decreased. See the section [HDCP SRM Update](../../index#hdcp_srm_update) for * more details about the SRM. This function is for devices that support HDCP * v2.2 or higher and wish to receive 4k content. * - * @param[in] bufer: buffer containing the SRM + * @param[in] buffer: buffer containing the SRM * @param[in] buffer_length: length of the SRM, in bytes. * * @retval OEMCrypto_SUCCESS if the file was valid and was installed. @@ -1228,12 +1252,14 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length); * and the IV given in the KeyObject. * * If its length is not zero, enc_mac_keys will be used to create new - * mac_keys. After all keys have been decrypted and validated, the new - * mac_keys are decrypted with the current encrypt_key and the offered IV. - * The new mac_keys replaces the current mac_keys for future calls to + * mac_keys. After all keys have been decrypted and validated, the new mac_keys + * are decrypted with the current encrypt_key and the offered IV. The new + * mac_keys replaces the current mac_keys for future calls to * OEMCrypto_RefreshKeys(). The first 256 bits of the mac_keys become the * mac_key[server] and the following 256 bits of the mac_keys become the - * mac_key[client]. + * mac_key[client]. Some servers will pad the encrypted mac keys to 80 bytes. If + * there are more than 64 bytes in the enc_mac_keys string, the remaining bytes + * shall be ignored by OEMCrypto. * * The mac_key and encrypt_key were generated and stored by the previous call * to OEMCrypto_GenerateDerivedKeys() or @@ -1269,7 +1295,7 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length); * current interval, next interval) times 4 content keys (audio, SD, HD, UHD) * plus up to 8 keys for watermarks. * - * After a call to OEMCrypto_LoadKeys, oemcrypto should clear the encrypt_key + * After a call to OEMCrypto_LoadKeys(), oemcrypto should clear the encrypt_key * for the session. * * @verification @@ -1328,11 +1354,11 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length); * check described above. If not, return * OEMCrypto_ERROR_INVALID_CONTEXT. * - The session must be associated with a usage table entry, either - * created via OEMCrypto_CreateNewUsageEntry or loaded via - * OEMCrypto_LoadUsageEntry. + * created via OEMCrypto_CreateNewUsageEntry() or loaded via + * OEMCrypto_LoadUsageEntry(). * - If Replay_Control is 1 = Nonce_Required, then OEMCrypto will perform a * nonce check as described above. OEMCrypto will verify that the - * usage entry is newly created with OEMCrypto_CreateNewUsageEntry. If + * usage entry is newly created with OEMCrypto_CreateNewUsageEntry(). If * an existing entry was reloaded, an error * OEMCrypto_ERROR_INVALID_CONTEXT is returned and no keys are loaded. * OEMCrypto will then copy the pst and the mac keys to the usage entry, @@ -1342,12 +1368,12 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length); * - If Replay_Control is 2 = "Require existing Session Usage table entry * or Nonce", then OEMCrypto will behave slightly differently on the * first call to LoadKeys for this license. - * * If the usage entry was created with OEMCrypto_CreateNewUsageEntry + * * If the usage entry was created with OEMCrypto_CreateNewUsageEntry() * for this session, then OEMCrypto will verify the nonce for each * key. OEMCrypto will copy the pst and mac keys to the usage * entry. The license received time of the entry will be updated * to the current time, and the status will be set to Unused. - * * If the usage entry was loaded with OEMCrypto_LoadUsageEntry for + * * If the usage entry was loaded with OEMCrypto_LoadUsageEntry() for * this session, then OEMCrypto will NOT verify the nonce for each * key. Instead, it will verify that the pst passed in matches * that in the entry. Also, the entry's mac keys will be verified @@ -1433,7 +1459,7 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length); * * @buffer_size * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier. + * OEMCrypto_ResourceRatingTier(). * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * @@ -1493,7 +1519,7 @@ OEMCryptoResult OEMCrypto_LoadKeys( * requests and loading renewal responses. The first 256 bits of the mac_keys * become the mac_key[server] and the following 256 bits of the mac_keys * become the mac_key[client]. If enc_mac_keys is null, then there will not - * be a call to OEMCrypto_LoadRenewal for this session and the current + * be a call to OEMCrypto_LoadRenewal() for this session and the current * mac_keys may be deleted. * * If the field license_type is OEMCrypto_ContentLicense, then the fields @@ -1510,10 +1536,10 @@ OEMCryptoResult OEMCrypto_LoadKeys( * OEMCrypto may assume that the key_id_length is at most 16. However, * OEMCrypto shall correctly handle key id lengths from 1 to 16 bytes. * - * OEMCrypto shall handle multiple keys, as described in the section on - * Resource Rating Tiers in this document. + * OEMCrypto shall handle multiple keys, as described in the document + * [Resource Rating Tiers](/widevine/drm/feature/resource-rating). * - * After a call to OEMCrypto_LoadLicense, oemcrypto should clear the + * After a call to OEMCrypto_LoadLicense(), oemcrypto should clear the * encrypt_key for the session. * * @verification @@ -1573,7 +1599,7 @@ OEMCryptoResult OEMCrypto_LoadKeys( * ODK_ParseLicense for usage entry verification. * The parameter initial_license_load shall be false if the usage entry was * loaded. If there is no usage entry or if the usage entry was created with - * OEMCrypto_CreateNewUsageEntry, then initial_license_load shall be true. + * OEMCrypto_CreateNewUsageEntry(), then initial_license_load shall be true. * If a usage entry is present, then it shall be verified after the call to * ODK_ParseLicense. * If initial_license_load is true: @@ -1597,11 +1623,11 @@ OEMCryptoResult OEMCrypto_LoadKeys( * check described above. If not, return * OEMCrypto_ERROR_INVALID_CONTEXT. * - The session must be associated with a usage table entry, either - * created via OEMCrypto_CreateNewUsageEntry or loaded via - * OEMCrypto_LoadUsageEntry. + * created via OEMCrypto_CreateNewUsageEntry() or loaded via + * OEMCrypto_LoadUsageEntry(). * - If Replay_Control is 1 = Nonce_Required, then OEMCrypto will perform a * nonce check as described above. OEMCrypto will verify that the - * usage entry is newly created with OEMCrypto_CreateNewUsageEntry. If + * usage entry is newly created with OEMCrypto_CreateNewUsageEntry(). If * an existing entry was reloaded, an error * OEMCrypto_ERROR_INVALID_CONTEXT is returned and no keys are loaded. * OEMCrypto will then copy the pst and the mac keys to the usage entry, @@ -1612,12 +1638,12 @@ OEMCryptoResult OEMCrypto_LoadKeys( * - If Replay_Control is 2 = "Require existing Session Usage table entry * or Nonce", then OEMCrypto will behave slightly differently on the * first call to LoadKeys for this license. - * * If the usage entry was created with OEMCrypto_CreateNewUsageEntry + * * If the usage entry was created with OEMCrypto_CreateNewUsageEntry() * for this session, then OEMCrypto will verify the nonce for each * key. OEMCrypto will copy the pst and mac keys to the usage * entry. The license received time of the entry will be updated * to the current time, and the status will be set to Unused. - * * If the usage entry was loaded with OEMCrypto_LoadUsageEntry for + * * If the usage entry was loaded with OEMCrypto_LoadUsageEntry() for * this session, then OEMCrypto will NOT verify the nonce for each * key. Instead, it will verify that the pst passed in matches * that in the entry. Also, the entry's mac keys will be verified @@ -1685,7 +1711,7 @@ OEMCryptoResult OEMCrypto_LoadKeys( * * @buffer_size * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier. + * OEMCrypto_ResourceRatingTier(). * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * @@ -1709,7 +1735,7 @@ OEMCryptoResult OEMCrypto_LoadLicense(OEMCrypto_SESSION session, /** * Load content keys into a session which already has entitlement keys * loaded. This function will only be called for a session after a call to - * OEMCrypto_LoadKeys with the parameter type license_type equal to + * OEMCrypto_LoadKeys() with the parameter type license_type equal to * OEMCrypto_EntitlementLicense. This function may be called multiple times * for the same session. * @@ -1726,10 +1752,9 @@ OEMCryptoResult OEMCrypto_LoadLicense(OEMCrypto_SESSION session, * 3. The content_key_id from the key_array is copied to the entry's * content_key_id. * 4. The content_key_data decrypted using the entitlement_key_data as a - * key for AES-256-CBC with an IV of content_key_data_iv. Wrapped - * content is padded using PKCS#7 padding. Notice that the entitlement - * key will be an AES 256 bit key. The clear content key data will be - * stored in the entry's content_key_data. + * key for AES-256-CBC with an IV of content_key_data_iv. Notice that + * the entitlement key will be an AES 256 bit key. The clear content key + * data will be stored in the entry's content_key_data. * Entries in the key table that do not correspond to anything in the * key_array are not modified or removed. * @@ -1803,7 +1828,7 @@ OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( * the matching entitlment_key_id is used. * * The function ODK_RefreshV15Values shall be called to update the clock - * values. See the document "Widevine Core Message Serialization" for the + * values. See [Widevine Core Message Serialization](../../odk) for the * documentation of the ODK library functions. * * If ODK_RefreshV15Values returns @@ -1816,7 +1841,7 @@ OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( * - ODK_STALE_RENEWAL: This renewal is not the most recently signed. It is * rejected. Return this error * - Any other error - OEMCrypto shall pass any other error up to the - * caller of OEMCrypto_RefreshKeys. + * caller of OEMCrypto_RefreshKeys(). * * NOTE: OEMCrypto_LoadKeys() must be called first to load the keys into the * session. @@ -1844,7 +1869,7 @@ OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( * * @buffer_size * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier. + * OEMCrypto_ResourceRatingTier(). * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * @@ -1874,7 +1899,7 @@ OEMCryptoResult OEMCrypto_RefreshKeys( * * OEMCrypto shall verify that nonce_values.api_major_version is 16. If not, * return the error OEMCrypto_ERROR_INVALID_CONTEXT. Legacy licenses will use - * the function OEMCrypto_RefreshKeys instead of OEMCrypto_LoadRenewal. + * the function OEMCrypto_RefreshKeys() instead of OEMCrypto_LoadRenewal(). * * If the signature passes, OEMCrypto shall use the function * ODK_ParseRenewal, as described in the document "Widevine Core Message @@ -1918,7 +1943,7 @@ OEMCryptoResult OEMCrypto_RefreshKeys( * * @buffer_size * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier. + * OEMCrypto_ResourceRatingTier(). * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * @@ -2004,7 +2029,7 @@ OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, * Select a content key and install it in the hardware key ladder for * subsequent decryption operations (OEMCrypto_DecryptCENC()) for this * session. The specified key must have been previously "installed" via - * OEMCrypto_LoadKeys(), OEMCrypto_LoadLicense, or + * OEMCrypto_LoadKeys(), OEMCrypto_LoadLicense(), or * OEMCrypto_LoadEntitledContentKeys(). * * A key control block is associated with the key and the session, and is @@ -2019,9 +2044,9 @@ OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, * * Step 3: use the latched content key to decrypt (AES-128-CTR or * AES-128-CBC) buffers passed in via OEMCrypto_DecryptCENC(). If the key is - * 256 bits it will be used for OEMCrypto_Generic_Sign or - * OEMCrypto_Generic_Verify as specified in the key control block. If the key - * will be used for OEMCrypto_Generic_Encrypt or OEMCrypto_Generic_Decrypt + * 256 bits it will be used for OEMCrypto_Generic_Sign() or + * OEMCrypto_Generic_Verify() as specified in the key control block. If the key + * will be used for OEMCrypto_Generic_Encrypt() or OEMCrypto_Generic_Decrypt() * then the cipher mode will always be OEMCrypto_CipherMode_CBC. Continue to * use this key for this session until OEMCrypto_SelectKey() is called again, * or until OEMCrypto_CloseSession() is called. @@ -2035,12 +2060,12 @@ OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, * analog video output that cannot be disabled, then the key is not * selected, and OEMCrypto_ERROR_ANALOG_OUTPUT is returned. This step is * optional -- SelectKey may return OEMCrypto_SUCCESS and delay the - * error until a call to OEMCrypto_DecryptCENC. + * error until a call to OEMCrypto_DecryptCENC(). * 3. If the key control block has HDCP required, and the device cannot * enforce HDCP, then the key is not selected, and * OEMCrypto_ERROR_INSUFFICIENT_HDCP is returned. This step is optional * -- SelectKey may return OEMCrypto_SUCCESS and delay the error until a - * call to OEMCrypto_DecryptCENC. + * call to OEMCrypto_DecryptCENC(). * 4. If the key control block has a nonzero value for HDCP_Version, and * the device cannot enforce at least that version of HDCP, then the key * is not selected, and OEMCrypto_ERROR_INSUFFICIENT_HDCP is returned. @@ -2100,7 +2125,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * ISO-CENC standard. * * Decryption mode is AES-128-CTR or AES-128-CBC depending on the value of - * cipher_mode previously passed in to OEMCrypto_SelectKey. For the encrypted + * cipher_mode previously passed in to OEMCrypto_SelectKey(). For the encrypted * portion of subsamples, the content key associated with the session is * latched in the active hardware key ladder and is used for the decryption * operation. For the clear portion of subsamples, the data is simply copied. @@ -2132,12 +2157,12 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * * If the OEMCrypto implementation cannot handle multiple samples at once, it * may return OEMCrypto_ERROR_BUFFER_TOO_LARGE any time it receives more than - * one sample in a single call to OEMCrypto_DecryptCENC. + * one sample in a single call to OEMCrypto_DecryptCENC(). * * Similarly, if the OEMCrypto implementation cannot handle multiple * subsamples at once, it may return OEMCrypto_ERROR_BUFFER_TOO_LARGE any * time it receives more than one subsample in a single call to - * OEMCrypto_DecryptCENC. + * OEMCrypto_DecryptCENC(). * * The exact way that the CDM code breaks up the samples array is not * guaranteed by this specification. The CDM may break down the array of @@ -2147,8 +2172,8 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * subsamples into smaller subsamples, just like in OEMCrypto v15. * * If OEMCrypto requests that the CDM break samples into subsamples, the - * "samples" passed into OEMCrypto_DecryptCENC will no longer be full - * samples. When a full sample is passed into OEMCrypto_DecryptCENC, the + * "samples" passed into OEMCrypto_DecryptCENC() will no longer be full + * samples. When a full sample is passed into OEMCrypto_DecryptCENC(), the * first subsample in the subsample array will have the * OEMCrypto_FirstSubsample flag set in its subsample_flags field and the * last subsample array will have the OEMCrypto_LastSubsample flag set in its @@ -2156,33 +2181,33 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * accumulate more subsamples from successive calls to OEMCrypto_DecryptCENC * to receive the full sample. * - * The first subsample in the sample will always have - * OEMCrypto_FirstSubsample set and the last subsample will always have the - * OEMCrypto_LastSubsample flag set, even if those subsamples are passed in - * separate calls to OEMCrypto_DecryptCENC. This is the same as in OEMCrypto - * v15. The decrypted data will not be used until after the subsample with - * the flag OEMCrypto_LastSubsample has been sent to OEMCrypto. This can be - * relied on by OEMCrypto for optimization by not doing decrypt until the - * last subsample has been received. However, a device that can do decrypt of - * more than one subsample at a time will always have better performance if - * it can receive those subsamples in one OEMCrypto_Decrypt call rather than - * as individual subsamples. + * The first subsample in the sample will always have OEMCrypto_FirstSubsample + * set and the last subsample will always have the OEMCrypto_LastSubsample flag + * set, even if those subsamples are passed in separate calls to + * OEMCrypto_DecryptCENC(). This is the same as in OEMCrypto v15. The decrypted + * data will not be used until after the subsample with the flag + * OEMCrypto_LastSubsample has been sent to OEMCrypto. This can be relied on by + * OEMCrypto for optimization by not doing decrypt until the last subsample has + * been received. However, a device that can do decrypt of more than one + * subsample at a time will always have better performance if it can receive + * those subsamples in one OEMCrypto_DecryptCENC() call rather than as + * individual subsamples. * * Although the exact way that the CDM code breaks up the samples array when * it receives OEMCrypto_ERROR_BUFFER_TOO_LARGE is not guaranteed by this * specification, here is a sample way it might work: * - * 1. It tries to pass the array of samples to OEMCrypto_DecryptCENC. + * 1. It tries to pass the array of samples to OEMCrypto_DecryptCENC(). * 2. If OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE, it tries to - * pass each sample individually into OEMCrypto_DecryptCENC. + * pass each sample individually into OEMCrypto_DecryptCENC(). * 3. If OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE, it tries to * pass the clear and encrypted parts of each subsample individually - * into OEMCrypto_DecryptCENC. At this point, (and in the subsequent + * into OEMCrypto_DecryptCENC(). At this point, (and in the subsequent * steps) it is replicating the behavior of OEMCrypto v15 and lower. * 4. If OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE, it breaks each * piece of a subsample into smaller pieces, down to the minimum * subsample size required by the device's resource rating tier. It - * passes these pieces into OEMCrypto_DecryptCENC. + * passes these pieces into OEMCrypto_DecryptCENC(). * 5. If OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE, the device has * failed to meet its resource rating tier requirements. It returns an * error. @@ -2199,7 +2224,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * * The decryption mode, either OEMCrypto_CipherMode_CTR or * OEMCrypto_CipherMode_CBC, was already specified in the call to - * OEMCrypto_SelectKey. The encryption pattern is specified by the fields in + * OEMCrypto_SelectKey(). The encryption pattern is specified by the fields in * the parameter pattern. A description of partial encryption patterns for * 'cbcs' can be found in the ISO-CENC standard, section 10.4. * @@ -2217,7 +2242,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * block from the previous encrypted subsample. The following diagram * provides an example: * - * (See drawing in "Widevine Modular DRM Security Integration Guide") + * ![Drawing of block offset](fig5.svg) * * To help with this, the block_offset field of each subsample will contain * the number of bytes the initial crypto block of that subsample should be @@ -2245,7 +2270,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * are clear and should never be decrypted. The following diagram provides an * example: * - * (See drawing in "Widevine Modular DRM Security Integration Guide") + * ![CBCS Scheme](fig6.svg) * * Whether any given protected block is actually encrypted also depends on * the pattern. But the bytes at the end that do not make up a full crypto @@ -2257,7 +2282,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * 16 bytes, all the bytes in it are protected, and they may need to be * decrypted following the pattern. The following diagram provides an example: * - * (See drawing in "Widevine Modular DRM Security Integration Guide") + * ![CBCS Scheme - final partial block](fig7.svg) * * INITIALIZATION VECTOR BETWEEN SUBSAMPLES: * @@ -2278,7 +2303,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * * For 'cbcs', the IV is reset at the beginning of each subsample. Each * subsample should start with the IV that was passed into - * OEMCrypto_DecryptCENC. + * OEMCrypto_DecryptCENC(). * * To phrase it another way: In 'cenc', the encrypted portions of the * subsamples can be concatenated to form one continuous ciphertext. In @@ -2310,7 +2335,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * NOTES: * * If the destination buffer is secure, an offset may be specified. - * OEMCrypto_DecryptCENC begins storing data buffers.output.secure.offset + * OEMCrypto_DecryptCENC() begins storing data buffers.output.secure.offset * bytes after the beginning of the secure buffer. * * If the session has an entry in the Usage Table, then OEMCrypto must update @@ -2327,13 +2352,13 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * The ISO-CENC spec implicitly limits both the skip and encrypt values to be * 4 bits, so they are at most 15. * - * (See drawing in "Widevine Modular DRM Security Integration Guide") + * ![CTR Mode - no skip pattern](fig8.svg) * * If OEMCrypto assembles all of the encrypted subsample portions into a * single buffer and then decrypts it in one pass, it can assume that the * block offset is 0. * - * (See drawing in "Widevine Modular DRM Security Integration Guide") + * ![CTR Mode - with skip pattern](fig9.svg) * * @verification * The total size of all the subsamples cannot exceed the total size of the @@ -2346,8 +2371,8 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * If this is the first use of a key for this session, then OEMCrypto shall * call ODK_AttemptFirstPlayback to update the session's clock values and * verify playback is allowed. If this is not the first use of a key for this - * session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See the - * document "License Duration and Renewal" for handling the return value of + * session, then OEMCrypto shall call ODK_UpdateLastPlaybackTime. See + * [ODK Clocks and Timers](../../odk-timers) for handling the return value of * these ODK functions. * The following checks should be performed if any subsamples contain any * encrypted bytes. If any check fails, an error is returned, and no @@ -2378,36 +2403,36 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * 5. 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. - * 6. If a Decrypt Hash has been initialized via OEMCrypto_SetDecryptHash, + * 6. If a 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. * - * Delayed Error Conditions + * #### Delayed Error Conditions * * On some devices, the HDCP subsystem is not directly connected to the * OEMCrypto TA. This means that returning the error * OEMCrypto_ERROR_INSUFFICIENT_HDCP at the time of the decrypt call is a * performance hit. However, some devices have the ability to tag output * buffers with security requirements, such as the required HDCP level. - * For those devices, when a call to OEMCrypto_DecryptCENC is made using a + * For those devices, when a call to OEMCrypto_DecryptCENC() is made using a * key that requires HDCP output, and if the HDCP level on the output does * not meet the required level. * - OEMCrypto may tag the output buffer as requiring HDCP at the required * level and return OEMCrypto_SUCCESS. * - Output shall not be sent to the display. - * - On the second or third call to OEMCrypto_DecryptCENC with the same + * - On the second or third call to OEMCrypto_DecryptCENC() with the same * key, OEMCrypto shall return OEMCrypto_ERROR_INSUFFICIENT_HDCP. - * For those devices, when a call to OEMCrypto_DecryptCENC is made using a + * For those devices, when a call to OEMCrypto_DecryptCENC() is made using a * key that requires HDCP output, and if the HDCP level on some of the * displays does not meet the required level. * - OEMCrypto may tag the output buffer as requiring HDCP at the required * level and return OEMCrypto_SUCCESS. * - Output shall only be sent to the display with sufficient output * control, e.g. the local display. - * - On the second or third call to OEMCrypto_DecryptCENC with the same + * - On the second or third call to OEMCrypto_DecryptCENC() with the same * key, OEMCrypto shall return OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION. - * In either case, a call to OEMCrypto_GetHDCPCapability shall return the + * In either case, a call to OEMCrypto_GetHDCPCapability() shall return the * current HDCP level. * * @param[in] session: Crypto session identifier. The crypto session in which @@ -2470,7 +2495,7 @@ OEMCryptoResult OEMCrypto_DecryptCENC( * Copies the payload in the buffer referenced by the *data parameter into * the buffer referenced by the out_buffer parameter. The data is simply * copied. The definition of OEMCrypto_DestBufferDesc and subsample_flags are - * the same as in OEMCrypto_DecryptCENC, above. + * the same as in OEMCrypto_DecryptCENC(), above. * * The main difference between this and DecryptCENC is that this function may be * used before a license is loaded into a session. In particular, an application @@ -2501,7 +2526,7 @@ OEMCryptoResult OEMCrypto_DecryptCENC( * @param[in] data_addr: An unaligned pointer to the buffer to be copied. * @param[in] data_addr_length: The length of the buffer, in bytes. * @param[in] out_buffer_descriptor: A caller-owned descriptor that specifies - * the handling of the byte stream. See OEMCrypto_DestbufferDesc for details. + * the handling of the byte stream. See OEMCrypto_DestBufferDesc for details. * @param[in] subsample_flags: bitwise flags indicating if this is the first, * middle, or last subsample in a chunk of data. 1 = first subsample, 2 = * last subsample, 3 = both first and last subsample, 0 = neither first nor @@ -2517,16 +2542,16 @@ OEMCryptoResult OEMCrypto_DecryptCENC( * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED * * @buffer_size - * OEMCrypto shall support subsample sizes and total input buffer sizes as - * specified by its resource rating tier. - * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is - * larger than the supported size. If OEMCrypto returns + * OEMCrypto shall support subsample sizes and sample sizes as specified in + * OEMCrypto_ResourceRatingTier(). This function will only be given a single + * sample. OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the + * buffer is larger than the supported size. If OEMCrypto returns * OEMCrypto_ERROR_BUFFER_TOO_LARGE, the calling function must break the * buffer into smaller chunks. For high performance devices, OEMCrypto should * handle larger buffers. We encourage OEMCrypto implementers not to - * artificially restrict the maximum buffer size. - * If OEMCrypto detects that the output data is too large, and breaking the - * buffer into smaller subsamples will not work, then it returns + * artificially restrict the maximum buffer size. If OEMCrypto detects that + * the output data is too large, and breaking the buffer into smaller + * subsamples will not work, then it returns * OEMCrypto_ERROR_OUTPUT_TOO_LARGE. This error will bubble up to the * application, which can decide to skip the current frame of video or to * switch to a lower resolution. @@ -2565,8 +2590,9 @@ OEMCryptoResult OEMCrypto_CopyBuffer( * shall call ODK_AttemptFirstPlayback to update the session's clock * values and verify playback is allowed. If this is not the first use * of a key for this session, then OEMCrypto shall call - * ODK_UpdateLastPlaybackTime. See the document "License Duration and - * Renewal" for handling the return value of these ODK functions. + * ODK_UpdateLastPlaybackTime. + * See [ODK Clocks and Timers](../../odk-timers) for handling the return + * value of these ODK functions. * 3. 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. @@ -2633,8 +2659,9 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt( * shall call ODK_AttemptFirstPlayback to update the session's clock * values and verify playback is allowed. If this is not the first use * of a key for this session, then OEMCrypto shall call - * ODK_UpdateLastPlaybackTime. See the document "License Duration and - * Renewal" for handling the return value of these ODK functions. + * ODK_UpdateLastPlaybackTime. + * See [ODK Clocks and Timers](../../odk-timers) for handling the return + * value of these ODK functions. * 4. 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. @@ -2697,8 +2724,9 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt( * shall call ODK_AttemptFirstPlayback to update the session's clock * values and verify playback is allowed. If this is not the first use * of a key for this session, then OEMCrypto shall call - * ODK_UpdateLastPlaybackTime. See the document "License Duration and - * Renewal" for handling the return value of these ODK functions. + * ODK_UpdateLastPlaybackTime. + * See [ODK Clocks and Timers](../../odk-timers) for handling the return + * value of these ODK functions. * 3. 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. @@ -2771,8 +2799,9 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, * shall call ODK_AttemptFirstPlayback to update the session's clock * values and verify playback is allowed. If this is not the first use * of a key for this session, then OEMCrypto shall call - * ODK_UpdateLastPlaybackTime. See the document "License Duration and - * Renewal" for handling the return value of these ODK functions. + * ODK_UpdateLastPlaybackTime. + * See [ODK Clocks and Timers](../../odk-timers) for handling the return + * value of these ODK functions. * 5. 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. @@ -2828,12 +2857,12 @@ OEMCryptoResult OEMCrypto_Generic_Verify( * manufacturing, the root of trust should be encrypted with the OEM root key * and stored on the file system in a region that will not be erased during * factory reset. This function may be used by legacy systems that use the - * two-step WrapKeyboxOrOEMCert/InstallKeyboxOrOEMCert approach. When the + * two-step WrapKeyboxOrOEMCert()/InstallKeyboxOrOEMCert() approach. When the * Widevine DRM plugin initializes, it will look for a wrapped root of trust * in the file /factory/wv.keys and install it into the security processor by * calling OEMCrypto_InstallKeyboxOrOEMCert(). * - * Figure 10. OEMCrypto_WrapKeyboxOrOEMCert Operation + * ![OEMCrypto_WrapKeyboxOrOEMCert Operation](fig1.svg) * * OEMCrypto_WrapKeyboxOrOEMCert() is used to generate an OEM-encrypted root * of trust that may be passed to OEMCrypto_InstallKeyboxOrOEMCert() for @@ -2891,6 +2920,8 @@ OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert( * provisioning method involves saving the keybox or OEM Certificate to the * file system. * + * ![InstallKeyboxOrOEMCert](fig10.svg) + * * @param[in] keybox_or_cert: pointer to encrypted data as input * @param[in] keybox_or_cert_length: length of the data in bytes * @@ -2950,17 +2981,23 @@ OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod(void); * checksum to the CRC stored in the Keybox. * The CRC is computed over the entire Keybox excluding the 4 bytes of the * CRC (for example, Keybox[0..123]). For a description of the fields stored - * in the keybox, see Keybox Definition. + * in the keybox, see Keybox Definition in the + * [Provisioning 2.0](../../index#prov20) section of the integration guide. * * If the device has an OEM Certificate, this validates the certificate * private key. * + * On devices that support OEMCrypto_GenerateOTARequest() and + * OEMCrypto_ProcessOTAKeybox(), this function may return + * OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING when a valid keybox is not present. + * * @retval OEMCrypto_SUCCESS * @retval OEMCrypto_ERROR_BAD_MAGIC * @retval OEMCrypto_ERROR_BAD_CRC * @retval OEMCrypto_ERROR_KEYBOX_INVALID * @retval OEMCrypto_ERROR_INVALID_RSA_KEY * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED + * @retval OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING * * @threading * This is a "Property Function" and may be called simultaneously with any @@ -3040,7 +3077,7 @@ OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* key_data, /** * Temporarily use the specified test keybox until the next call to - * OEMCrypto_Terminate. This allows a standard suite of unit tests to be run + * OEMCrypto_Terminate(). This allows a standard suite of unit tests to be run * on a production device without permanently changing the keybox. Using the * test keybox is not persistent. OEMCrypto cannot assume that this keybox is * the same as previous keyboxes used for testing. @@ -3061,8 +3098,8 @@ OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* key_data, * @threading * This is an "Initialization and Termination Function" and will not be * called simultaneously with any other function, as if the CDM holds a write - * lock on the OEMCrypto system. It is called after OEMCrypto_Initialize and - * after OEMCrypto_GetProvisioningMethod and only if the provisoining method + * lock on the OEMCrypto system. It is called after OEMCrypto_Initialize() and + * after OEMCrypto_GetProvisioningMethod() and only if the provisoining method * is OEMCrypto_Keybox, * * @version @@ -3077,8 +3114,9 @@ OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer, /// @{ /** * After a call to this function, all session functions using an RSA key - * should use the OEM certificate's private RSA key. See the section above - * discussing Provisioning 3.0. + * should use the OEM certificate's private RSA key. See the section + * discussing [Provisioning 3.0](../../index#prov30) section of the integration + * guide. * * @param[in] session: this function affects the specified session only. * @@ -3101,7 +3139,8 @@ OEMCryptoResult OEMCrypto_LoadOEMPrivateKey(OEMCrypto_SESSION session); /** * This function should place the OEM public certificate in the buffer - * public_cert. See the section above discussing Provisioning 3.0. + * public_cert. See the section discussing + * [Provisioning 3.0](../../index#prov30) section of the integration guide. * * If the buffer is not large enough, OEMCrypto should update * public_cert_length and return OEMCrypto_ERROR_SHORT_BUFFER. @@ -3181,7 +3220,8 @@ OEMCryptoResult OEMCrypto_GetRandom(uint8_t* random_data, * version number guarantees it passes all unit tests associated with this * version. * - * @retval The supported API, as specified in the header file OEMCryptoCENC.h. + * @return + * The supported API, as specified in the header file OEMCryptoCENC.h. * * @threading * This is a "Property Function" and may be called simultaneously with any @@ -3203,7 +3243,8 @@ uint32_t OEMCrypto_APIVersion(void); * this version number guarantees it passes all unit tests associated with * this version. * - * @retval The supported API, as specified in the header file OEMCryptoCENC.h. + * @return + * The supported API, as specified in the header file OEMCryptoCENC.h. * * @threading * This is a "Property Function" and may be called simultaneously with any @@ -3234,8 +3275,9 @@ uint32_t OEMCrypto_MinorAPIVersion(void); * number in this string, e.g. "15.1" or "15.2" if those minor versions are * released. * - * @retval A printable null terminated C string, suitable for a single line in a - * log. + * @return + * A printable null terminated C string, suitable for a single line in a + * log. * * @threading * This is a "Property Function" and may be called simultaneously with any @@ -3253,9 +3295,11 @@ const char* OEMCrypto_BuildInformation(void); * the trusted environment. The patch level is defined by the OEM, and is * only incremented when a security update has been added. * - * See the section Security Patch Level above for more details. + * See the section [Security Patch Level](../../index#security_patch_level) + * for more details. * - * @retval The OEM defined version number. + * @return + * The OEM defined version number. * * @threading * This is a "Property Function" and may be called simultaneously with any @@ -3274,7 +3318,8 @@ uint8_t OEMCrypto_Security_Patch_Level(void); * Since this function is spoofable, it is not relied on for security * purposes. It is for information only. * - * @retval A null terminated string. Useful value are "L1", "L2" and "L3". + * @return + * A null terminated string. Useful value are "L1", "L2" and "L3". * * @threading * This is a "Property Function" and may be called simultaneously with any @@ -3363,8 +3408,9 @@ OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability* current, * this function is spoofable, it is not relied on for security purposes. It * is for information only. The usage table is described in the section above. * - * @retval Returns true if the device can maintain a usage table. Returns false - * otherwise. + * @return + * Returns true if the device can maintain a usage table. Returns false + * otherwise. * * @threading * This is a "Property Function" and may be called simultaneously with any @@ -3384,7 +3430,8 @@ bool OEMCrypto_SupportsUsageTable(void); * * Widevine requires the size to be at least 300 entries. * - * @retval Returns an estimate for the maximum size of the usage table header. + * @return + * Returns an estimate for the maximum size of the usage table header. * * @threading * This is a "Property Function" and may be called simultaneously with any @@ -3404,7 +3451,7 @@ size_t OEMCrypto_MaximumUsageTableHeaderSize(void); * to. Another example is if the usage table has a generation number and the * generation number is stored in secure memory that is not user accessible. * - * @retval Returns true if oemcrypto uses anti-rollback hardware. Returns false + * @return Returns true if oemcrypto uses anti-rollback hardware. Returns false * otherwise. * * @threading @@ -3489,7 +3536,7 @@ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* max); * certificate with a 3072 bit RSA key. * - 0x10 = OEMCrypto_Supports_RSA_CAST - the device can load a CAST * certificate. These certificates are used with - * OEMCrypto_GenerateRSASignature with padding type set to 0x2, PKCS1 + * OEMCrypto_GenerateRSASignature() with padding type set to 0x2, PKCS1 * with block type 1 padding. * - 0x100 = OEMCrypto_Supports_ECC_secp256r1 - Elliptic Curve secp256r1 * - 0x200 = OEMCrypto_Supports_ECC_secp384r1 - Elliptic Curve secp384r1 @@ -3508,7 +3555,7 @@ uint32_t OEMCrypto_SupportedCertificates(void); /** * Returns true if the device supports SRM files and the file can be updated - * via the function OEMCrypto_LoadSRM. This also returns false for devices + * via the function OEMCrypto_LoadSRM(). This also returns false for devices * that do not support an SRM file, devices that do not support HDCP, and * devices that have no external display support. * @@ -3533,7 +3580,7 @@ bool OEMCrypto_IsSRMUpdateSupported(void); * OEMCrypto_LOCAL_DISPLAY_ONLY. If the device has an SRM, but cannot use * OEMCrypto to update the SRM, then this function would set version to be * the current version number, and return OEMCrypto_SUCCESS, but it would - * return false from OEMCrypto_IsSRMUpdateSupported. + * return false from OEMCrypto_IsSRMUpdateSupported(). * * @param[out] version: current SRM version number. * @@ -3593,101 +3640,39 @@ uint32_t OEMCrypto_GetAnalogOutputFlags(void); * claimed by the device. If a device claims to be a low end device, the * OEMCrypto unit tests will only verify the low end performance values. * - * OEMCrypto implementers should consider the numbers below to be minimum + * OEMCrypto implementers should consider the numbers in the table to be minimum * values. * * These performance parameters are for OEMCrypto only. In particular, * bandwidth and codec resolution are determined by the platform. * - * Some parameters need more explanation. The Sample size is typically the - * size of one encoded frame, but might be several frames for AV1. Converting - * this to resolution depends on the Codec, which is not specified by - * OEMCrypto. Some content has the sample broken into several subsamples. The - * "number of subsamples" restriction requires that any content can be broken - * into at least that many subsamples. However, this number may be larger if - * DecryptCENC returns OEMCrypto_ERROR_BUFFER_TOO_LARGE. In that case, the - * layer above OEMCrypto 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. + * See the document [Resource Rating] + * (https://developers.google.com/widevine/drm/feature/resource-rating) + * for more information and for the table of parameters. * - * The minimum subsample buffer size is the smallest buffer that the CDM - * layer above OEMCrypto will use when breaking a sample into subsamples. As - * mentioned above, the CDM layer will only break a sample into smaller - * subsamples if OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE. Because - * this might be a performance problem, OEMCrypto implementers are encouraged - * to process larger subsamples and to process multiple subsamples in a - * single call to DecryptCENC. * - * 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 - * have several keys corresponding to audio and video at different - * resolutions. If the content uses key rotation, there could be three keys - * -- previous interval, current interval, and next interval -- for each - * resolution. + * Here is an additional note on the number of subsamples: * - * Concurrent playback sessions versus concurrent sessions: some applications - * will preload multiple licenses before the user picks which content to - * play. Each of these licenses corresponds to an open session. Once playback - * starts, some platforms support picture-in-picture or multiple displays. - * Each of these pictures would correspond to a separate playback session - * with active decryption. + * The table specifies the number of subsamples that partition the content when + * it is encrypted. However, if OEMCrypto_DecryptCENC() returns + * OEMCrypto_ERROR_BUFFER_TOO_LARGE, the layer above OEMCrypto will break the + * sample into more subsamples. * - * The total number of keys for all sessions indicates that the device may - * share key memory over multiple sessions. For example, on a Tier 3 device, - * the device must support four sessions with 20 keys each (80 total), or 20 - * sessions with 4 keys each (80 total), but it does not need to support 20 - * sessions with 20 keys each. + * The minimum subsample buffer size is the smallest buffer that the CDM layer + * above OEMCrypto will use when breaking a sample into subsamples. As mentioned + * above, the CDM layer will only break a sample into smaller subsamples if + * OEMCrypto returns OEMCrypto_ERROR_BUFFER_TOO_LARGE. Because this might be a + * performance problem, OEMCrypto implementers are encouraged to process larger + * subsamples and to process multiple subsamples in a single call to + * DecryptCENC. * - * The message size that is needed for a license with a large number of keys - * is larger than in previous versions. The message size limit applies to all - * functions that sign or verify messages. It also applies to the size of - * context buffers in the derive key functions. + * The message size limit applies to all functions that sign or verify a + * message: OEMCrypto_PrepAndSignLicenseRequest(), + * OEMCrypto_PrepAndSignRenewalRequest(), + * OEMCrypto_PrepAndSignProvisioningRequest(), and OEMCrypto_LoadKeys(). A + * request message is also used as the context buffer in + * OEMCrypto_DeriveKeysFromSessionKey() and OEMCrypto_GenerateDerivedKeys(). * - * Decrypted frames per second -- strictly speaking, OEMCrypto only controls - * the decryption part of playback and cannot control the decoding and - * display part. However, devices that support the higher resource tiers - * should also support a higher frame rate. Platforms may enforce these - * values. For example Android will enforce a frame rate via a GTS test. - * - * Note on units: We will use KiB to mean 1024 bytes and MiB to mean 1024 - * KiB, as described at https://en.wikipedia.org/wiki/Kibibyte. - * - *
- * +--------------------------------+---------+----------+---------+---------+
- * |Resource Rating Tier            |1 - Low  |2 - Medium|3 - High |4 - Very |
- * |                                |         |          |         |    High |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum Sample size             |1 MiB    |2 MiB     |4 MiB    |16 MiB   |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum Number of Subsamples    |10       |16        |32       |64       |
- * | (H264 or HEVC)                 |         |          |         |         |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum Number of Subsamples    |9        |9         |9        |9        |
- * |(VP9)                           |         |          |         |         |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum Number of Subsamples    |72       |144       |288      |576      |
- * |(AV1)                           |         |          |         |         |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum subsample buffer size   |100 KiB  |500 KiB   |1 MiB    |4 MiB    |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum Generic crypto buffer   |10 KiB   |100 KiB   |500 KiB  |1 MiB    |
- * |size                            |         |          |         |         |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum number of concurrent    |10       |20        |30       |40       |
- * |sessions                        |         |          |         |         |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum number of keys per      |4        |20        |20       |30       |
- * |session                         |         |          |         |         |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum total number of keys    |16       |40        |80       |90       |
- * | (all sessions)                 |         |          |         |         |
- * +--------------------------------+---------+----------+---------+---------+
- * |Minimum Message Size            |8 KiB    |8 KiB     |16 KiB   |32 KiB   |
- * +--------------------------------+---------+----------+---------+---------+
- * |Decrypted Frames per Second     |30 fps SD|30 fps HD |60 fps HD|60 fps 8k|
- * +--------------------------------+---------+----------+---------+---------+
- * 
* * @return * Returns an integer indicating which resource tier the device supports. @@ -3723,8 +3708,8 @@ uint32_t OEMCrypto_ResourceRatingTier(void); * OEMCrypto_ERROR_SIGNATURE_FAILURE. * * NOTE: The calling software must have previously established the mac_keys - * and encrypt_key with a call to OEMCrypto_DeriveKeysFromSessionKey or - * OEMCrypto_GenerateDerivedKeys. + * and encrypt_key with a call to OEMCrypto_DeriveKeysFromSessionKey() or + * OEMCrypto_GenerateDerivedKeys(). * * The function ODK_ParseProvisioning is called to parse the message. If it * returns an error, OEMCrypto shall return that error to the CDM layer. The @@ -3738,7 +3723,7 @@ uint32_t OEMCrypto_ResourceRatingTier(void); * of the buffer are the string "SIGN", then the actual RSA key begins on the * 9th byte of the buffer. The second four bytes of the buffer is the 32 bit * field "allowed_schemes" of type RSA_Padding_Scheme, which is used in - * OEMCrypto_GenerateRSASignature. The value of allowed_schemes must also be + * OEMCrypto_GenerateRSASignature(). The value of allowed_schemes must also be * wrapped with RSA key. We recommend storing the magic string "SIGN" with * the key to distinguish keys that have a value for allowed_schemes from * those that should use the default allowed_schemes. Devices that do not @@ -3749,7 +3734,7 @@ uint32_t OEMCrypto_ResourceRatingTier(void); * This is not needed for devices that wish to send data to a ChromeCast. * * If the first four bytes of the buffer `enc_private_key` are not the string - * "SIGN", then this key may not be used with OEMCrypto_GenerateRSASignature. + * "SIGN", then this key may not be used with OEMCrypto_GenerateRSASignature(). * * Verification and Algorithm: * The following checks should be performed. If any check fails, an error is @@ -3760,7 +3745,7 @@ uint32_t OEMCrypto_ResourceRatingTier(void); * the rewrapped key, returning OEMCrypto_ERROR_SHORT_BUFFER otherwise. * 3. Verify the message signature, using the derived signing key * (mac_key[server]) from a previous call to - * OEMCrypto_GenerateDerivedKeys or OEMCrypto_DeriveKeysFromSessionKey. + * OEMCrypto_GenerateDerivedKeys() or OEMCrypto_DeriveKeysFromSessionKey(). * 4. The function ODK_ParseProvisioning is called to parse the message. * 5. Decrypt enc_private_key in the buffer private_key using the session's * derived encryption key (enc_key). Use enc_private_key_iv as the initial @@ -3770,7 +3755,7 @@ uint32_t OEMCrypto_ResourceRatingTier(void); * then the actual RSA key begins on the 9th byte of the buffer. The * second four bytes of the buffer is the 32 bit field * "allowed_schemes", of type RSA_Padding_Scheme, which is used in - * OEMCrypto_GenerateRSASignature. The value of allowed_schemes must + * OEMCrypto_GenerateRSASignature(). The value of allowed_schemes must * also be wrapped with RSA key. We recommend storing the magic string * "SIGN" with the key to distinguish keys that have a value for * allowed_schemes from those that should use the default @@ -3781,15 +3766,18 @@ uint32_t OEMCrypto_ResourceRatingTier(void); * certificates for authentication when acting as a ChromeCast receiver. * This is not needed for devices that wish to send data to a ChromeCast. * 7. If the first four bytes of the buffer private_key are not the string - * "SIGN", this key may not be used with OEMCrypto_GenerateRSASignature. + * "SIGN", this key may not be used with OEMCrypto_GenerateRSASignature(). * 8. After possibly skipping past the first 8 bytes signifying the allowed * signing algorithm, the rest of the buffer private_key contains an ECC * private key or an RSA private key in PKCS#8 binary DER encoded * format. The OEMCrypto library shall verify that this private key is * valid. - * 9. Re-encrypt the device private key with an internal key (such as the OEM - * key or Widevine Keybox key) and the generated IV using AES-128-CBC - * with PKCS#5 padding. + * 9. Re-encrypt the device private key with an internal key (such as one + * derived by the OEM key or Widevine Keybox key) and the generated IV + * using AES-128-CBC with PKCS#5 padding. The data should also be + * signed. This algorithm is just a suggestion. The implementer may use any + * suitable encrypting and validation algorithm with a key that ties it to + * the device. * 10. Copy the rewrapped key to the buffer specified by wrapped_private_key * and the size of the wrapped key to wrapped_private_key_length. * @@ -3820,7 +3808,7 @@ uint32_t OEMCrypto_ResourceRatingTier(void); * * @buffer_size * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier. + * OEMCrypto_ResourceRatingTier(). * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * @@ -3842,22 +3830,22 @@ OEMCryptoResult OEMCrypto_LoadProvisioning( /** * Loads a wrapped RSA or ECC private key to secure memory for use by this - * session in future calls to OEMCrypto_PrepAndSignLicenseRequest or - * OEMCrypto_DeriveKeysFromSessionKey. The wrapped private key will be the - * one verified and wrapped by OEMCrypto_LoadProvisioning. The private key + * session in future calls to OEMCrypto_PrepAndSignLicenseRequest() or + * OEMCrypto_DeriveKeysFromSessionKey(). The wrapped private key will be the + * one verified and wrapped by OEMCrypto_LoadProvisioning(). The private key * should be stored in secure memory. * * If the bit field "allowed_schemes" was wrapped with this RSA key, its * value will be loaded and stored with the RSA key, and the key may be used - * with calls to OEMCrypto_GenerateRSASignature. If there was not a bit field + * with calls to OEMCrypto_GenerateRSASignature(). If there was not a bit field * wrapped with the RSA key, the key will be used for - * OEMCrypto_PrepAndSignLicenseRequest or OEMCrypto_DeriveKeysFromSessionKey + * OEMCrypto_PrepAndSignLicenseRequest() or OEMCrypto_DeriveKeysFromSessionKey() * * @verification * The following checks should be performed. If any check fails, an error is * returned, and the RSA key is not loaded. * 1. The wrapped key has a valid signature, as described in - * RewrapDeviceRSAKey. + * OEMCrypto_LoadProvisioning(). * 2. The decrypted key is a valid private RSA key. * 3. If a value for allowed_schemes is included with the key, it is a * valid value. @@ -3866,7 +3854,7 @@ OEMCryptoResult OEMCrypto_LoadProvisioning( * @param[in] key_type: indicates either an RSA or ECC key for devices that * support both. * @param[in] wrapped_private_key: wrapped device private key (RSA or ECC). - * This is the wrapped key generated by OEMCrypto_LoadProvisioning. + * This is the wrapped key generated by OEMCrypto_LoadProvisioning(). * @param[in] wrapped_private_key_length: length of the wrapped key buffer, in * bytes. * @@ -3902,7 +3890,7 @@ OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(OEMCrypto_SESSION session, * certificate. * * Temporarily use the standard test RSA key until the next call to - * OEMCrypto_Terminate. This allows a standard suite of unit tests to be run + * OEMCrypto_Terminate(). This allows a standard suite of unit tests to be run * on a production device without permanently changing the key. Using the * test key is not persistent. * @@ -3926,9 +3914,9 @@ OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(OEMCrypto_SESSION session, OEMCryptoResult OEMCrypto_LoadTestRSAKey(void); /** - * The OEMCrypto_GenerateRSASignature method is only used for devices that - * are CAST receivers. This function is called after - * OEMCrypto_LoadDRMPrivateKey for the same session. + * The OEMCrypto_GenerateRSASignature() method is only used for devices that are + * CAST receivers. This function is called after OEMCrypto_LoadDRMPrivateKey() + * for the same session. * * The parameter padding_scheme has two possible legacy values: * @@ -3980,7 +3968,7 @@ OEMCryptoResult OEMCrypto_LoadTestRSAKey(void); * * @buffer_size * OEMCrypto shall support message sizes as described in the section - * OEMCrypto_ResourceRatingTier. + * OEMCrypto_ResourceRatingTier(). * OEMCrypto shall return OEMCrypto_ERROR_BUFFER_TOO_LARGE if the buffer is * larger than the supported size. * @@ -4024,9 +4012,10 @@ OEMCryptoResult OEMCrypto_GenerateRSASignature( * bytes. (out) actual length of the header_buffer * * @retval OEMCrypto_SUCCESS success - * @retval OEMCrypto_ERROR_SHORT_BUFFER if header_buffer_length is too small. + * @retval OEMCrypto_ERROR_SHORT_BUFFER if header_buffer_length is too small * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED - * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE + * @retval OEMCrypto_ERROR_UNKNOWN_FAILURE if any active entries are currently + * loaded * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED * * @threading @@ -4092,7 +4081,9 @@ OEMCryptoResult OEMCrypto_LoadUsageTableHeader(const uint8_t* buffer, * of it. * * If the session already has a usage entry associated with it, the error - * OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES is returned. + * OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES is returned. It is an error to attempt + * to create or load a second usage entry into a session that already has a + * usage entry. * * @param[in] session: handle for the session to be used. * @param[out] usage_entry_number: index of new usage entry. @@ -4135,10 +4126,11 @@ OEMCryptoResult OEMCrypto_CreateNewUsageEntry(OEMCrypto_SESSION session, * OEMCrypto shall call ODK_ReloadClockValues, as described in "License * Duration and Renewal" to set the session's clock values. * - * If the entry is already loaded into another open session, then this fails - * and returns OEMCrypto_ERROR_INVALID_SESSION. If the session already has a - * usage entry associated with it, the error - * OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES is returned. + * If the entry is already loaded into another open session, then this fails and + * returns OEMCrypto_ERROR_INVALID_SESSION. If the session already has a usage + * entry associated with it, the error OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES is + * returned. It is also an error to try to reload the same usage entry into the + * same open session twice. * * Before version API 16, the usage entry stored the time that the license * was loaded. This value is now interpreted as the time that the licence @@ -4204,10 +4196,10 @@ OEMCryptoResult OEMCrypto_LoadUsageEntry(OEMCrypto_SESSION session, * "first decrypt". * * If the usage entry has the flag ForbidReport set, then the flag is - * cleared. It is the responsibility of the CDM layer to call this function - * and save the usage table before the next call to ReportUsage and before - * the CDM is terminated. Failure to do so will result in generation number - * skew, which will invalidate all of the usage table. + * cleared. It is the responsibility of the CDM layer to call this function and + * save the usage table before the next call to OEMCrypto_ReportUsage() and + * before the CDM is terminated. Failure to do so will result in generation + * number skew, which will invalidate all of the usage table. * * If either entry_buffer_length or header_buffer_length is not large enough, * they are set to the needed size, and return OEMCrypto_ERROR_SHORT_BUFFER. @@ -4299,22 +4291,23 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session, * If the buffer_length is not sufficient to hold a report structure, set * buffer_length and return OEMCrypto_ERROR_SHORT_BUFFER. * - * If an entry was not loaded or created with OEMCrypto_CreateNewUsageEntry - * or OEMCrypto_LoadUsageEntry, or if the pst does not match that in the - * entry, return the error OEMCrypto_ERROR_INVALID_CONTEXT. + * If an entry was not loaded or created with OEMCrypto_CreateNewUsageEntry() or + * OEMCrypto_LoadUsageEntry() return the error + * OEMCrypto_ERROR_INVALID_CONTEXT. If the pst does not match that in the entry, + * return OEMCrypto_ERROR_WRONG_PST. * * If the usage entry's flag ForbidReport is set, indicating the entry has * not been saved since the entry was deactivated, then the error * OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE is returned and a report is not * generated. Similarly, if any key in the session has been used since the - * last call to OEMCrypto_UpdateUsageEntry, then the report is not generated, + * last call to OEMCrypto_UpdateUsageEntry(), then the report is not generated, * and OEMCrypto returns the error OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE. * * The pst_report is filled out by subtracting the times in the Usage Entry * from the current time on the secure clock. This design was chosen to avoid * a requirement to sync the device's secure clock with any external clock. * - * (See drawing in "Widevine Modular DRM Security Integration Guide") + * ![Usage Report Timeline](fig11.svg) * * Valid values for status are: * @@ -4340,7 +4333,8 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session, * that cannot be modified by user software and there are security * features that prevent the user from modifying the clock in hardware, * such as a tamper proof battery. - * (See drawing in "Widevine Modular DRM Security Integration Guide") + * + * ![Secure Clock versus Secure Timer versus Insecure Clock](fig12.svg) * * After pst_report has been filled in, the HMAC SHA1 signature is computed * for the buffer from bytes 20 to the end of the pst field. The signature is @@ -4437,19 +4431,19 @@ OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session, uint32_t new_index); /** - * This shrinks the usage table and the header. This function is used by the - * CDM layer after it has defragmented the usage table and can delete unused - * entries. It is an error if any open session is associated with an entry - * that will be erased - the error OEMCrypto_ERROR_ENTRY_IN_USE shall be - * returned in this case, and the header shall not be modified. If - * new_entry_count is larger than the current size, then the header is not - * changed and the error OEMCrypto_ERROR_UNKNOWN_FAILURE is returned. If the - * header has not been previously loaded, then an error is returned. - * OEMCrypto will increment the master generation number in the header and - * store the new value in secure persistent storage. Then, OEMCrypto will - * encrypt and sign the header into the provided buffer. The generation - * numbers of all remaining entries will remain unchanged. The next time - * OEMCrypto_CreateNewUsageEntry is called, the new entry will have an index + * This shrinks the usage table and the header. This function is used by the CDM + * layer after it has defragmented the usage table and can delete unused + * entries. It is an error if any open session is associated with an entry that + * will be erased - the error OEMCrypto_ERROR_ENTRY_IN_USE shall be returned in + * this case, and the header shall not be modified. If new_entry_count is larger + * than the current size, then the header is not changed and the error + * OEMCrypto_ERROR_UNKNOWN_FAILURE is returned. If the header has not been + * previously loaded, then OEMCrypto_ERROR_UNKNOWN_FAILURE is returned. + * OEMCrypto will increment the master generation number in the header and store + * the new value in secure persistent storage. Then, OEMCrypto will encrypt and + * sign the header into the provided buffer. The generation numbers of all + * remaining entries will remain unchanged. The next time + * OEMCrypto_CreateNewUsageEntry() is called, the new entry will have an index * of new_entry_count. * * Devices that do not implement a Session Usage Table may return @@ -4462,7 +4456,7 @@ OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session, * If the header has not been loaded or created, return the error * OEMCrypto_ERROR_UNKNOWN_FAILURE. * - * @param[in] new_entry_count: number of entries in the to be in the header. + * @param[in] new_entry_count: number of entries to be in the new header. * @param[out] header_buffer: pointer to memory where encrypted usage table * header is written. * @param[in,out] header_buffer_length: (in) length of the header_buffer, in @@ -4494,7 +4488,7 @@ OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(uint32_t new_entry_count, /** * Delete the current SRM. Any valid SRM, regardless of its version number, - * will be installable after this via OEMCrypto_LoadSRM. + * will be installable after this via OEMCrypto_LoadSRM(). * * This function should not be implemented on production devices, and will * only be used to verify unit tests on a test device. @@ -4519,7 +4513,7 @@ OEMCryptoResult OEMCrypto_RemoveSRM(void); * 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 CRC 32 checksum of the decrypted content in the secure buffer after a - * call to OEMCrypto_DecryptCENC. Google intends to provide test applications + * 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. * @@ -4549,7 +4543,7 @@ uint32_t OEMCrypto_SupportsDecryptHash(void); /** * 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 + * called before the first subsample is passed to OEMCrypto_DecryptCENC(), when * the subsample_flag has the bit OEMCrypto_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 @@ -4566,7 +4560,7 @@ uint32_t OEMCrypto_SupportsDecryptHash(void); * 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_GetHashErrorCode() should return the error * OEMCrypto_ERROR_UNKNOWN_FAILURE. * * OEMCrypto should compute the hash of the frame and then compare it with @@ -4576,7 +4570,7 @@ uint32_t OEMCrypto_SupportsDecryptHash(void); * displayed. This might happen if the actual decryption operation is carried * out by a later step in the video pipeline, or if you are using a partner * specified hash of the decoded frame. For this reason, an error state must - * be saved until the call to OEMCrypto_GetHashErrorCode is made. + * be saved until the call to OEMCrypto_GetHashErrorCode() is made. * * @param[in] session: session id for current decrypt operation * @param[in] frame_number: frame number for the recent DecryptCENC sample. @@ -4610,7 +4604,7 @@ OEMCryptoResult OEMCrypto_SetDecryptHash(OEMCrypto_SESSION session, size_t hash_length); /** - * If the hash set in OEMCrypto_SetDecryptHash did not match the computed + * 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 might not be in sync with the decrypt loop. OEMCrypto @@ -4665,9 +4659,9 @@ OEMCryptoResult OEMCrypto_GetHashErrorCode(OEMCrypto_SESSION session, * @param[in] session: session id for operation. * @param[in] buffer_size: the requested buffer size. * @param[out] output_descriptor: the buffer descriptor for the created - * buffer. This will be passed into the OEMCrypto_DecryptCENC function. + * buffer. This will be passed into the OEMCrypto_DecryptCENC() function. * @param[out] secure_fd: a pointer to platform dependent file or buffer - * descriptor. This will be passed to OEMCrypto_FreeSecureBuffer. + * descriptor. This will be passed to OEMCrypto_FreeSecureBuffer(). * * @retval OEMCrypto_SUCCESS if the buffer was created * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED @@ -4690,13 +4684,14 @@ OEMCryptoResult OEMCrypto_AllocateSecureBuffer( /** * Frees a secure buffer that had previously been created with - * OEMCrypto_AllocateSecureBuffer. Any return value except OEMCrypto_SUCCESS + * OEMCrypto_AllocateSecureBuffer(). Any return value except OEMCrypto_SUCCESS * will cause the unit test using secure buffers to fail. * * @param[in] session: session id for operation. * @param[out] output_descriptor: the buffer descriptor modified by - * OEMCrypto_AllocateSecureBuffer - * @param[in] secure_fd: The integer returned by OEMCrypto_AllocateSecureBuffer + * OEMCrypto_AllocateSecureBuffer() + * @param[in] secure_fd: The integer returned by + * OEMCrypto_AllocateSecureBuffer() * * @retval OEMCrypto_SUCCESS if the buffer was freed * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED @@ -4718,18 +4713,146 @@ OEMCryptoResult OEMCrypto_FreeSecureBuffer( /// @} +/* + * OEMCrypto_OPK_SerializationVersion + * Check the serialization protocol version used by the OEMCrypto Porting Kit + * (OPK). If the OPK is not used, this function must return + * OEMCrypto_ERROR_NOT_IMPLEMENTED. The serialization version is expressed as + * |major.minor|, where |major| and |minor| are integers. The TEE and REE + * serialization versions must match in order for OEMCrypto to communicate + * with the TEE. If the serialization versions do not match, calls to other + * OEMCrypto functions will return OPK_ERROR_INCOMPATIBLE_VERSION. A match is + * achieved if the |major| fields of the TEE and REE versions are the + * same. Differences in only the |minor| fields indicates that the protocols + * are different but are still compatible. + * + * @param[in,out] ree_major: pointer to memory to recieve the REE's |major| + * version. On input, *ree_major may be zero to request the serialization + * version of the REE. If *ree_major is non-zero, this function will test the + * TEE's compatibility using the specified REE major version. + * @param[in,out] ree_minor: pointer to memory to recieve the REE's |minor| + * version. On input, *ree_minor may be zero to request the serialization + * version of the REE. If *ree_minor is non-zero, this function will test the + * TEE's compatibility using the specified REE minor version. + * @param[out] tee_major: pointer to memory to recieve the TEE's |major| version + * @param[out] tee_minor: pointer to memory to recieve the TEE's |minor| version + * + * @retval OEMCrypto_SUCCESS success + * @retval OPK_ERROR_INCOMPATIBLE_VERSION + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + */ +OEMCryptoResult OEMCrypto_OPK_SerializationVersion(uint32_t* ree_major, + uint32_t* ree_minor, + uint32_t* tee_major, + uint32_t* tee_minor); + +/****************************************************************************/ +/****************************************************************************/ +/* The following functions are optional. They are only used if the device + * supports OTA keybox provisioning. Widevine does not allow all devices to + * support OTA provisioning. Using an OTA provisioned keybox usually lowers a + * device's security profile in the DCSL. Please work with your Widevine Partner + * Engineer before implementing these functions to make sure you understand the + * security implications of using Keybox OTA Provisioning. + */ + +/** + * Generate an OTA Keybox provisioning request. The format of the + * message is specified in the document Keybox OTA Reprovisioning. If + * use_test_key is true, then the debug model key and id should be + * used. Widevine does not allow all devices to support OTA + * provisioning. Using an OTA provisioned keybox usually lowers a device's + * security profile in the DCSL. + * + * @param[in] session: handle for the session to be used. + * @param[out] buffer: where the provisioning request is stored. + * @param[in,out] buffer_length: length of the request, in bytes. + * @param[in] use_test_key: If non-zero, use the debug model key. This is used + * for testing the workflow. + * + * @retval OEMCrypto_SUCCESS on success + * @retval OEMCrypto_ERROR_SHORT_BUFFER if buffer_length is too small. + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + * Any other error will be logged. + * + * @threading + * This is an "Initialization and Termination Function" and will not be called + * simultaneously with any other function, as if the CDM holds a write lock on + * the OEMCrypto system. It will be called only after + * OEMCrypto_IsKeyboxOrOEMCertValid() returns + * OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING immediately after initialization, + * and before any session is opened. + * + * @version + * This method is new in API version 16. + */ +OEMCryptoResult OEMCrypto_GenerateOTARequest(OEMCrypto_SESSION session, + uint8_t* buffer, + size_t* buffer_length, + uint32_t use_test_key); + +/** + * The buffer will be parsed as an OTA Keybox provisioning message, as + * described in the document OTA Keybox Reprovisioning. The + * signature will be verified. The keybox will be decrypted and verified. If + * |use_test_key| is false, the keybox will be installed permanently. + * + * If |use_test_key| is true, do not use the real model key, use the debug + * model key specified in OTA Keybox Reprovisioning. + * + * @param[in] session: handle for the session to be used. + * @param[in] buffer: pointer to provisioning response. + * @param[in] buffer_length: length of the buffer, in bytes. + * @param[in] use_test_key: If non-zero, use the debug model key. This is used + * for testing the workflow. + * + * @retval OEMCrypto_SUCCESS on success + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + * @retval OEMCrypto_ERROR_SIGNATURE_FAILURE signature of message was wrong. + * @retval OEMCrypto_ERROR_KEYBOX_INVALID if the keybox was unpacked, but is + * invalid. + * @retval OEMCrypto_ERROR_WRITE_KEYBOX could not save keybox. + * Any other error will be logged. + * + * @threading + * This is an "Initialization and Termination Function" and will not be called + * simultaneously with any other function, as if the CDM holds a write lock on + * the OEMCrypto system. It will only be called after + * OEMCrypto_GenerateOTARequest(). + * + * @version + * This method is new in API version 16. + */ +OEMCryptoResult OEMCrypto_ProcessOTAKeybox(OEMCrypto_SESSION session, + const uint8_t* buffer, + size_t buffer_length, + uint32_t use_test_key); + /****************************************************************************/ /****************************************************************************/ /* The following functions are deprecated. They are not required for the * current version of OEMCrypto. They are being declared here to help with * backwards compatibility. */ + +/* + * OEMCrypto_GenerateSignature + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_GenerateSignature(OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, uint8_t* signature, size_t* signature_length); +/* + * OEMCrypto_RewrapDeviceRSAKey30 + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( OEMCrypto_SESSION session, const uint32_t* unaligned_nonce, const uint8_t* encrypted_message_key, size_t encrypted_message_key_length, @@ -4737,6 +4860,12 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key, size_t* wrapped_rsa_key_length); +/* + * OEMCrypto_RewrapDeviceRSAKey + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, @@ -4744,26 +4873,70 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key, size_t* wrapped_rsa_key_length); +/* + * OEMCrypto_UpdateUsageTable + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_UpdateUsageTable(void); -OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION, const uint8_t*, - size_t, const uint8_t*, size_t, - const uint8_t*, size_t); +/* + * OEMCrypto_DeleteUsageEntry + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ +OEMCryptoResult OEMCrypto_DeleteUsageEntry( + OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length, + const uint8_t* message, size_t message_length, const uint8_t* signature, + size_t signature_length); -OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t*, size_t); +/* + * OEMCrypto_ForceDeleteUsageEntry + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ +OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, + size_t pst_length); +/* + * OEMCrypto_CopyOldUsageEntry + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_CopyOldUsageEntry(OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length); +/* + * OEMCrypto_DeleteOldUsageTable + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_DeleteOldUsageTable(void); +/* + * OEMCrypto_CreateOldUsageEntry + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_CreateOldUsageEntry( uint64_t time_since_license_received, uint64_t time_since_first_decrypt, uint64_t time_since_last_decrypt, OEMCrypto_Usage_Entry_Status status, uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst, size_t pst_length); +/* + * OEMCrypto_GenerateDerivedKeys_V15 + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_GenerateDerivedKeys_V15( OEMCrypto_SESSION session, const uint8_t* mac_key_context, uint32_t mac_key_context_length, const uint8_t* enc_key_context, @@ -4775,18 +4948,36 @@ typedef struct { size_t offset; // offset into the pattern in blocks for this call. } OEMCrypto_CENCEncryptPatternDesc_V15; +/* + * OEMCrypto_DecryptCENC_V15 + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_DecryptCENC_V15( - OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length, - bool is_encrypted, const uint8_t* iv, + OEMCrypto_SESSION session, const uint8_t* data_addr, + size_t data_addr_length, bool is_encrypted, const uint8_t* iv, size_t block_offset, // used for CTR "cenc" mode only. - OEMCrypto_DestBufferDesc* out_buffer_descriptor, + OEMCrypto_DestBufferDesc* out_buffer, const OEMCrypto_CENCEncryptPatternDesc_V15* pattern, uint8_t subsample_flags); +/* + * OEMCrypto_GetOEMPublicCertificate_V15 + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_GetOEMPublicCertificate_V15( OEMCrypto_SESSION session, uint8_t* public_cert, size_t* public_cert_length); +/* + * OEMCrypto_LoadDeviceRSAKey + * @deprecated + * Not required for the current version of OEMCrypto. Declared here to + * help with backward compatibility. + */ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session, const uint8_t* wrapped_rsa_key, size_t wrapped_rsa_key_length); diff --git a/oemcrypto/ref/src/wvcrc.cpp b/oemcrypto/ref/src/wvcrc.cpp index 604b5e2..f357ad8 100644 --- a/oemcrypto/ref/src/wvcrc.cpp +++ b/oemcrypto/ref/src/wvcrc.cpp @@ -11,73 +11,52 @@ namespace wvoec_ref { #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 - }; +uint32_t wvrunningcrc32(const uint8_t* p_begin, size_t i_count, + uint32_t i_crc) { + constexpr 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) { @@ -89,7 +68,7 @@ uint32_t wvrunningcrc32(const uint8_t* p_begin, int i_count, uint32_t i_crc) { return(i_crc); } -uint32_t wvcrc32(const uint8_t* p_begin, int i_count) { +uint32_t wvcrc32(const uint8_t* p_begin, size_t i_count) { return(wvrunningcrc32(p_begin, i_count, INIT_CRC32)); } @@ -97,11 +76,12 @@ uint32_t wvcrc32Init() { return INIT_CRC32; } -uint32_t wvcrc32Cont(const uint8_t* p_begin, int i_count, uint32_t prev_crc) { +uint32_t wvcrc32Cont(const uint8_t* p_begin, size_t 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) { +uint32_t wvcrc32n(const uint8_t* p_begin, size_t i_count) { return htonl(wvrunningcrc32(p_begin, i_count, INIT_CRC32)); } diff --git a/oemcrypto/ref/src/wvcrc32.h b/oemcrypto/ref/src/wvcrc32.h index b1e0ee6..56df9d3 100644 --- a/oemcrypto/ref/src/wvcrc32.h +++ b/oemcrypto/ref/src/wvcrc32.h @@ -11,12 +11,12 @@ namespace wvoec_ref { -uint32_t wvcrc32(const uint8_t* p_begin, int i_count); +uint32_t wvcrc32(const uint8_t* p_begin, size_t i_count); uint32_t wvcrc32Init(); -uint32_t wvcrc32Cont(const uint8_t* p_begin, int i_count, uint32_t prev_crc); +uint32_t wvcrc32Cont(const uint8_t* p_begin, size_t i_count, uint32_t prev_crc); // Convert to network byte order -uint32_t wvcrc32n(const uint8_t* p_begin, int i_count); +uint32_t wvcrc32n(const uint8_t* p_begin, size_t i_count); } // namespace wvoec_ref diff --git a/oemcrypto/test/oemcrypto_test.cpp b/oemcrypto/test/oemcrypto_test.cpp index 44b00f7..10d4fa0 100644 --- a/oemcrypto/test/oemcrypto_test.cpp +++ b/oemcrypto/test/oemcrypto_test.cpp @@ -240,7 +240,7 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) { */ TEST_F(OEMCryptoClientTest, VersionNumber) { const std::string log_message = - "OEMCrypto unit tests for API 16.3 or 4. Tests last updated 2021-08-05"; + "OEMCrypto unit tests for API 16.3 or 4. Tests last updated 2021-12-01"; cout << " " << log_message << "\n"; cout << " " << "These tests are part of Android S." @@ -466,7 +466,9 @@ TEST_F(OEMCryptoClientTest, CheckUsageTableSizeAPI16) { const size_t maximum = OEMCrypto_MaximumUsageTableHeaderSize(); printf(" Max Usage Table Size: %zu.\n", maximum); // A maximum of 0 means the table is constrained by dynamic memory allocation. - if (maximum > 0) ASSERT_GE(maximum, RequiredUsageSize()); + if (maximum > 0) { + ASSERT_GE(maximum, RequiredUsageSize()); + } } // @@ -3602,7 +3604,6 @@ struct TestSample { std::vector encrypted_buffer; std::vector clear_buffer; // OEMCrypto store clear output here. std::vector truth_buffer; // Truth data for clear text. - OEMCrypto_SampleDescription description; std::vector subsamples; int secure_buffer_fid; @@ -5401,7 +5402,9 @@ TEST_F(OEMCryptoLoadsCertificateAlternates, OEMCryptoResult sts; LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); // If the device is a cast receiver, then this scheme is required. - if (global_features.cast_receiver) ASSERT_TRUE(key_loaded_); + if (global_features.cast_receiver) { + ASSERT_TRUE(key_loaded_); + } if (key_loaded_) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); @@ -5435,7 +5438,9 @@ TEST_F(OEMCryptoLoadsCertificateAlternates, OEMCryptoResult sts; LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); // If the device is a cast receiver, then this scheme is required. - if (global_features.cast_receiver) ASSERT_TRUE(key_loaded_); + if (global_features.cast_receiver) { + ASSERT_TRUE(key_loaded_); + } if (key_loaded_) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); @@ -5472,7 +5477,9 @@ TEST_F(OEMCryptoLoadsCertificateAlternates, TestSignaturePKCS1) { // scheme is used by cast receivers. LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); // If the device is a cast receiver, then this scheme is required. - if (global_features.cast_receiver) ASSERT_TRUE(key_loaded_); + if (global_features.cast_receiver) { + ASSERT_TRUE(key_loaded_); + } // If the key loaded with no error, then we will verify that it is not used // for forbidden padding schemes. if (key_loaded_) { @@ -8832,6 +8839,9 @@ TEST_P(OEMCryptoUsageTableTest, VerifyUsageTimes) { s.pst_report().seconds_since_last_decrypt(), playback_time, kUsageTableTimeTolerance); + // We must update the usage entry BEFORE sleeping, not after. + ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); + cout << "Wait another " << kIdleInSeconds << " seconds " "to verify usage table time since playback ended." @@ -8844,7 +8854,6 @@ TEST_P(OEMCryptoUsageTableTest, VerifyUsageTimes) { // |<--->| = seconds_since_last_decrypt // |<----------------------------->| = seconds_since_first_decrypt // |<------------------------------------| = seconds_since_license_received - ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); ASSERT_NO_FATAL_FAILURE(entry.GenerateVerifyReport(kActive)); ASSERT_NO_FATAL_FAILURE(entry.DeactivateUsageEntry()); ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); diff --git a/oemcrypto/test/wvcrc.cpp b/oemcrypto/test/wvcrc.cpp index 1f0fbcf..ea6de41 100644 --- a/oemcrypto/test/wvcrc.cpp +++ b/oemcrypto/test/wvcrc.cpp @@ -11,73 +11,52 @@ 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 - }; +uint32_t wvrunningcrc32(const uint8_t* p_begin, size_t i_count, + uint32_t i_crc) { + constexpr 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) { @@ -89,7 +68,7 @@ uint32_t wvrunningcrc32(const uint8_t* p_begin, int i_count, uint32_t i_crc) { return(i_crc); } -uint32_t wvcrc32(const uint8_t* p_begin, int i_count) { +uint32_t wvcrc32(const uint8_t* p_begin, size_t i_count) { return(wvrunningcrc32(p_begin, i_count, INIT_CRC32)); } @@ -97,11 +76,12 @@ uint32_t wvcrc32Init() { return INIT_CRC32; } -uint32_t wvcrc32Cont(const uint8_t* p_begin, int i_count, uint32_t prev_crc) { +uint32_t wvcrc32Cont(const uint8_t* p_begin, size_t 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) { +uint32_t wvcrc32n(const uint8_t* p_begin, size_t i_count) { return htonl(wvrunningcrc32(p_begin, i_count, INIT_CRC32)); } diff --git a/oemcrypto/test/wvcrc32.h b/oemcrypto/test/wvcrc32.h index 9cf72af..bf00505 100644 --- a/oemcrypto/test/wvcrc32.h +++ b/oemcrypto/test/wvcrc32.h @@ -11,12 +11,12 @@ namespace wvoec { -uint32_t wvcrc32(const uint8_t* p_begin, int i_count); +uint32_t wvcrc32(const uint8_t* p_begin, size_t i_count); uint32_t wvcrc32Init(); -uint32_t wvcrc32Cont(const uint8_t* p_begin, int i_count, uint32_t prev_crc); +uint32_t wvcrc32Cont(const uint8_t* p_begin, size_t i_count, uint32_t prev_crc); // Convert to network byte order -uint32_t wvcrc32n(const uint8_t* p_begin, int i_count); +uint32_t wvcrc32n(const uint8_t* p_begin, size_t i_count); } // namespace wvoec