Source release 18.5.0

This commit is contained in:
Matt Feddersen
2024-03-28 19:15:22 -07:00
parent b2c35151ad
commit 28ec8548c6
109 changed files with 3623 additions and 1012 deletions

View File

@@ -3,7 +3,7 @@
// License Agreement.
/**
* @mainpage OEMCrypto API v18.2
* @mainpage OEMCrypto API v18.5
*
* OEMCrypto is the low level library implemented by the OEM to provide key and
* content protection, usually in a separate secure memory or process space. The
@@ -136,6 +136,7 @@
* license to be reloaded.
*
* @defgroup entitled Entitlement License API
* Functions that are needed for entitled and entitlement licenses.
*
* [Entitlement licensing](../../index#entitlement) is a way to provide access
* to content keys that may be stored elsewhere, such as in the content itself.
@@ -366,7 +367,8 @@ typedef struct {
} OEMCrypto_CENCEncryptPatternDesc;
/**
* OEMCryptoCipherMode is used in SelectKey to prepare a key for decryption.
* OEMCryptoCipherMode is used in OEMCrypto_GetKeyHandle() to prepare a key for
* decryption.
*/
typedef enum OEMCryptoCipherMode {
// explicit cipher modes used for modular DRM
@@ -511,7 +513,9 @@ typedef enum OEMCrypto_ProvisioningMethod {
// Device has factory installed OEM certificate.
OEMCrypto_OEMCertificate = 3,
// Device has Boot Certificate Chain (BCC).
OEMCrypto_BootCertificateChain = 4
OEMCrypto_BootCertificateChain = 4,
// Device has baked in DRM certificate with reprovisioning (level 3 only).
OEMCrypto_DrmReprovisioning = 5
} OEMCrypto_ProvisioningMethod;
/**
@@ -712,6 +716,9 @@ typedef enum OEMCrypto_SignatureHashAlgorithm {
#define OEMCrypto_GetSignatureHashAlgorithm _oecc139
#define OEMCrypto_EnterTestMode _oecc140
#define OEMCrypto_GetDeviceSignedCsrPayload _oecc141
#define OEMCrypto_FactoryInstallBCCSignature _oecc142
#define OEMCrypto_GetEmbeddedDrmCertificate _oecc143
#define OEMCrypto_UseSecondaryKey _oecc144
// clang-format on
/// @addtogroup initcontrol
@@ -1198,6 +1205,8 @@ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
* @retval OEMCrypto_ERROR_BUFFER_TOO_LARGE
* @retval OEMCrypto_ERROR_SESSION_LOST_STATE
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
* @retval OEMCrypto_ERROR_INVALID_KEY if the session's private key is not a
* DRM key.
*
* @buffer_size
* OEMCrypto shall support message sizes as described in the section
@@ -1508,9 +1517,9 @@ OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest(
* Note: if the current SRM version requirement is not met, LoadLicense will
* still succeed and the keys will be loaded. However, those keys with the
* SRMVersionRequired bit set will have their HDCP_Version increased to 0xF -
* local display only. Any future call to SelectKey for these keys while
* there is an external display will return OEMCrypto_ERROR_INSUFFICIENT_HDCP
* at that time.
* local display only. Any future call to OEMCrypto_GetKeyHandle() for these
* keys while there is an external display will return
* OEMCrypto_ERROR_INSUFFICIENT_HDCP at that time.
*
* @param[in] session: crypto session identifier.
* @param[in] message: pointer to memory containing data.
@@ -1774,7 +1783,7 @@ OEMCryptoResult OEMCrypto_RemoveEntitledKeySession(
*
* For devices that use a hardware key ladder, it may be more convenient to
* store the encrypted content key data in the key table, and decrypt it when
* the function SelectKey is called.
* the function OEMCrypto_GetKeyHandle() is called.
*
* @param[in] session: handle for the entitled key session to be used.
* @param[in] message: pointer to memory containing message to be verified.
@@ -2000,8 +2009,8 @@ OEMCryptoResult OEMCrypto_GetOEMKeyToken(OEMCrypto_SESSION key_session,
* For platforms that do not need to support Bypass Decrypt, a mode compatible
* with previous versions of OEMCrypto is available. These devices may latch the
* key to the session and continue to use this key for this session until
* OEMCrypto_SelectKey() is called again, or until OEMCrypto_CloseSession() is
* called.
* OEMCrypto_GetKeyHandle() is called again, or until OEMCrypto_CloseSession()
* is called.
*
* The "key handle" in this mode is the session ID. Platforms should request a
* 4-byte key handle buffer and copy the session ID into it.
@@ -2014,13 +2023,13 @@ OEMCryptoResult OEMCrypto_GetOEMKeyToken(OEMCrypto_SESSION key_session,
* the device should disable analog video output. If the device has
* 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().
* optional -- OEMCrypto_GetKeyHandle() may return OEMCrypto_SUCCESS and
* delay the 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().
* -- OEMCrypto_GetKeyHandle() may return OEMCrypto_SUCCESS and delay the
* error until a 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.
@@ -2090,9 +2099,9 @@ OEMCryptoResult OEMCrypto_GetKeyHandle(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
* portion of subsamples, the content key associated with the handle is
* latched in the active hardware key ladder and is used for the decryption
* cipher_mode previously passed in to OEMCrypto_GetKeyHandle(). For the
* encrypted portion of subsamples, the content key associated with the handle
* 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.
*
* After decryption, all the input_data bytes are copied to the location
@@ -2190,8 +2199,8 @@ OEMCryptoResult OEMCrypto_GetKeyHandle(OEMCrypto_SESSION session,
*
* The decryption mode, either OEMCrypto_CipherMode_CENC or
* OEMCrypto_CipherMode_CBCS, was already specified in the call to
* OEMCrypto_SelectKey(). The encryption pattern is specified by the fields in
* the parameter pattern. A description of partial encryption patterns for
* OEMCrypto_GetKeyHandle(). 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.
*
* 'cenc' SCHEME:
@@ -2996,6 +3005,41 @@ OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert(
OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(const uint8_t* keybox_or_cert,
size_t keybox_or_cert_length);
/**
* Install a factory generated signature for the BCC. This is for devices that
* use Provisioning 4.0, with the signing option in the factory. With the
* signing option, the BCC is extracted from the device in the factory. Instead
* of being uploaded to the Widevine server, the BCC is signed by a certificate
* that the manufacturer shares with Widevine. The signature is then installed
* on the device is a secure location. The signature must not be erased during
* factory reset.
*
* This signature should be returned as `addition_signature` in a call to the
* function `OEMCrypto_GetBootCertificateChain()`.
*
* Devices that do not support Provisioning 4.0, or only support Provisioning
* 4.0 Option 1 should return OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
*
* @param[in] signature: pointer to data as input
* @param[in] signature_length: length of the data in bytes
*
* @retval OEMCrypto_SUCCESS success
* @retval OEMCrypto_ERROR_INSUFFICIENT_RESOURCES
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
* @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED
*
* @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.
*
* @version
* This method is new in API version 18.3.
*/
OEMCryptoResult OEMCrypto_FactoryInstallBCCSignature(const uint8_t* signature,
size_t signature_length);
/**
* This function is for OEMCrypto to tell the layer above what provisioning
* method it uses: keybox or OEM certificate.
@@ -3319,6 +3363,8 @@ uint32_t OEMCrypto_MinorAPIVersion(void);
* different TA builds.
* - "build_timestamp" [string]: ISO 8601 formatted timestamp of the time the
* TA was compiled, eg "YYYY-MM-DDTHH:MM:SS"
* - "is_factory_mode" [bool]: Whether this was built with FACTORY_MODE_ONLY
* defined
*
* While not required, another optional top level struct can be added to the
* build information string to provide information about liboemcrypto.so:
@@ -3812,7 +3858,7 @@ OEMCryptoResult OEMCrypto_ProductionReady(void);
* the most recent license should be honored. The watermarking feature should
* be turned on or off when a license is loaded. If this conflicts with a
* license that had been loaded earlier, then keys from the earlier license may
* not be used. In this case, either OEMCrypto_SelectKey or
* not be used. In this case, either OEMCrypto_GetKeyHandle or
* OEMCrypto_DecryptCENC will return OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE to
* indicate that the watermarking status has changed and the license is no
* longer usable.
@@ -4838,6 +4884,7 @@ OEMCryptoResult OEMCrypto_GetBootCertificateChain(
* 4.4, as well as Android IRemotelyProvisionedComponent.aidl (under
* "SignedData<Data>")
*
* ~~~
* |public_key_signature|: COSE_Sign1 CBOR array
* [
* protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 /
@@ -4847,6 +4894,7 @@ OEMCryptoResult OEMCrypto_GetBootCertificateChain(
* signature: bstr ; PureEd25519(priv_key, Sig_structure) /
* ; ECDSA(priv_key, Sig_structure)
* ]
* ~~~
*
* Notes:
* 1. The payload field in the COSE_Sign1 struct is the public key generated
@@ -4861,6 +4909,7 @@ OEMCryptoResult OEMCrypto_GetBootCertificateChain(
* field in Sig_structure is the same as the payload in the above
* COSE_Sign1 CBOR array.
*
* ~~~
* Sig_structure: CBOR array
* [
* context: "Signature1",
@@ -4869,6 +4918,7 @@ OEMCryptoResult OEMCrypto_GetBootCertificateChain(
* external_aad: bstr .size 0,
* payload: bstr .cbor Data / nil,
* ]
* ~~~
*
* If an OEM private key is available, the request is assumed to be for DRM
* certificate provisioning and the public key is signed by the OEM private key.
@@ -4877,6 +4927,19 @@ OEMCryptoResult OEMCrypto_GetBootCertificateChain(
* key is an ECC key, then |public_key_signature| is the ASN.1 DER-encoded (R,S)
* signature as specified in RFC 3279 2.2.3.
*
* After this function completes successfully, the session will hold a private
* key and will be ready for a call to
* OEMCrypto_PrepAndSignProvisioningRequest(). In particular, when this
* function is used to generate a DRM Certificate key pair, the session will be
* ready to sign a provisioning request with the DRM Cert private key. When this
* function is used to generate an OEM Certificate key pair, the session will be
* ready to sign a provisioning request with the OEM Cert private key.
*
* The public key shall be an ASN.1 DER-encoded SubjectPublicKeyInfo as
* specified in RFC 5280. Widevine recommends ECC keys for Provisioning 4.0, but
* an RSA key may also be used. If the key is an RSA key, then the encoding
* should use "rsaEncryption" (OID 1.2.840.113549.1.1.1), and not RSASSA-PSS.
*
* @param[in] session: session id.
* @param[out] public_key: pointer to the buffer that receives the public key
* that is to be certified by the server. The key must be an ASN.1
@@ -4920,7 +4983,9 @@ OEMCryptoResult OEMCrypto_GenerateCertificateKeyPair(
OEMCrypto_PrivateKeyType* key_type);
/**
* Get the serialized device information in CBOR map format.
* Get the serialized device information in CBOR map format. This is for devices
* that use Provisioning 4.0, with the device key uploading option in the
* factory.
*
* The device
* information may contain, for example, device make and model, "fused" status,
@@ -4929,7 +4994,9 @@ OEMCryptoResult OEMCrypto_GenerateCertificateKeyPair(
* provisioning request is coming from the expected device in the fields, based
* on the values previously uploaded and registered.
*
* This method is used by provisioning 4 only.
* Devices that do not support Provisioning 4.0, or do not support
* Provisioning 4.0 Uploading Option should return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* @param[out] device_info: pointer to the buffer that receives the serialized
* device information in CBOR map format.
@@ -4955,24 +5022,87 @@ OEMCryptoResult OEMCrypto_GetDeviceInformation(uint8_t* device_info,
size_t* device_info_length);
/**
* Get the serialized signed Certificate Signing Request (Csr) payload in
* COSE_Sign1 format.
* Get the serialized signed Certificate Signing Request (CSR) payload in
* COSE_Sign1 format. This is for devices that use Provisioning 4.0, with the
* device key uploading option in the factory.
*
* The signed CSR payload contains challenge and device information. It is
* signed by the leaf cert of the boot certificate chain (BCC). It is only used
* in the factory, uploaded and validated during device registration.
* With the uploading option, the RKP factory extraction tool provided by Google
* makes a call to this function to collect the signed CSR payload for
* generating the CSR to be uploaded to the device database. The CSR payload is
* signed by the leaf cert of the Boot Certificate Chain.
*
* This method is used by provisioning 4 only.
* The format of a CSR payload before COSE_Sign1 is a CBOR array described in
* Android IRemotelyProvisionedComponent.aidl (under "CsrPayload"):
*
* ~~~
* CsrPayload = [ ; CBOR Array defining the payload for CSR.
* version: 3, ; The CsrPayload CDDL Schema version.
* CertificateType: "widevine" ; The type of certificate being requested.
* DeviceInfo, ; Defined in Android DeviceInfo.aidl
* KeysToSign: [] ; Empty list
* ]
* ~~~
*
* The type of CertificateType is tstr and the value should always be
* "widevine". The type of KeysToSign is CBOR array and the value is not used,
* which should be left as an empty list. Note that the DeviceInfo above is a
* CBOR map structure defined in DeviceInfo.aidl, which can be constructed from
* the input |encoded_device_info|. DeviceInfo must be canonicalized according
* to the specification in RFC 7049. The required fields from DeviceInfo.aidl
* are: brand, manufacturer, product, model, device, vb_state, bootloader_state,
* vbmeta_digest, security_level.
*
* Once CsrPayload is prepared, together with |challenge| it is signed by the
* leaf cert of BCC, in the format of:
*
* ~~~
* |signed_csr_payload| = SignedData<[
* challenge: bstr .size (0..64),
* bstr .cbor CsrPayload,
* ]>
* ~~~
*
* This function should output |signed_csr_payload| in the format of
* SignedData<Data>, which is a COSE_Sign1 CBOR and is defined in Android
* IRemotelyProvisionedComponent.aidl (under "SignedData<Data>"):
*
* ~~~
* SignedData<Data> = [
* protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 /
* AlgorithmES384 },
* unprotected: {},
* payload: bstr .cbor Data / nil,
* signature: bstr ; PureEd25519(priv_key, Sig_structure) /
* ; ECDSA(priv_key, Sig_structure)
* ]
* ~~~
*
* Also see OEMCrypto_GenerateCertificateKeyPair() for more details of
* SignedData<Data> and Sig_structure.
*
* Data in the payload field of SignedData<Data> is a CBOR array:
*
* ~~~
* Data = [
* challenge: bstr .size (0..64),
* bstr .cbor CsrPayload,
* ]
* ~~~
*
* Devices that do not support Provisioning 4.0, or do not support
* Provisioning 4.0 Uploading Option should return
* OEMCrypto_ERROR_NOT_IMPLEMENTED.
*
* @param[in] challenge: pointer to the buffer containing a byte string to be
* signed.
* signed. It is generated by the RKP factory extraction tool.
* @param[in] challenge_length: size of the challenge buffer.
* @param[in] encoded_device_info: pointer to the buffer containing the
* serialized device information in CBOR map format.
* serialized device information in CBOR map format. It should be returned as
* `device_info` in a call to the function `OEMCrypto_GetDeviceInformation()`.
* @param[in] encoded_device_info_length: size of the encoded_device_info
* buffer.
* @param[out] signed_csr_payload: pointer to the buffer that receives the
* serialized CSR payload in COSE_Sign1 format.
* serialized signed CSR payload in COSE_Sign1 format.
* @param[in,out] signed_csr_payload_length: on input, size of the caller's
* signed_csr_payload buffer. On output, the number of bytes written into the
* buffer.
@@ -5121,14 +5251,13 @@ uint32_t OEMCrypto_SupportsDecryptHash(void);
* length of the hash will be at most 128 bytes, and will be 4 bytes (32
* bits) for the default CRC32 hash.
*
* This may be called before the first call to SelectKey. In that case, this
* function cannot verify that the key control block allows hash
* verification. The function DecryptCENC should verify that the key control
* bit allows hash verification when it is called. If an attempt is made to
* compute a hash when the selected key does not have the bit
* Allow_Hash_Verification set, then a hash should not be computed, and
* OEMCrypto_GetHashErrorCode() should return the error
* OEMCrypto_ERROR_UNKNOWN_FAILURE.
* This may be called before the first call to OEMCrypto_GetKeyHandle. In that
* case, this function cannot verify that the key control block allows hash
* verification. The function DecryptCENC should verify that the key control bit
* allows hash verification when it is called. If an attempt is made to compute
* a hash when the selected key does not have the bit Allow_Hash_Verification
* set, then a hash should not be computed, and OEMCrypto_GetHashErrorCode()
* should return the error OEMCrypto_ERROR_UNKNOWN_FAILURE.
*
* OEMCrypto should compute the hash of the frame and then compare it with
* the correct value. If the values differ, then OEMCrypto should latch in an
@@ -5255,7 +5384,7 @@ OEMCryptoResult OEMCrypto_AllocateSecureBuffer(
* 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
* @param[in,out] output_descriptor: the buffer descriptor modified by
* OEMCrypto_AllocateSecureBuffer()
* @param[in] secure_fd: The integer returned by
* OEMCrypto_AllocateSecureBuffer()
@@ -5717,6 +5846,35 @@ OEMCryptoResult OEMCrypto_Generic_Verify_V17(
/****************************************************************************/
/****************************************************************************/
/* The following functions are used by internal L3 CDMs and are not required by
* other CDM implementations.
*/
/**
* Get the embedded Drm Certificate used by internal L3 CDMs.
*
* @param[out] public_cert where the certificate is stored.
* @param[in,out] public_cert_length the length, in bytes, of the certificate.
*
* @retval OEMCrypto_SUCCESS on success
* @retval OEMCrypto_ERROR_SHORT_BUFFER if public_cert_length is too small.
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
*/
OEMCryptoResult OEMCrypto_GetEmbeddedDrmCertificate(uint8_t* public_cert,
size_t* public_cert_length);
/**
* Marks the given session as using a secondary key.
*
* @param[in] session_id: handle for the session to be used.
* @param[in] dual_key: whether this session uses a secondary key.
*
* @ignore
* @retval OEMCrypto_SUCCESS on success
* @retval OEMCrypto_ERROR_NOT_IMPLEMENTED
*/
OEMCryptoResult OEMCrypto_UseSecondaryKey(OEMCrypto_SESSION session_id,
bool dual_key);
#ifdef __cplusplus
}

View File

@@ -25,6 +25,11 @@ cc_library_static {
"vendor/widevine/libwvdrmengine/oemcrypto/odk/include",
"vendor/widevine/libwvdrmengine/oemcrypto/odk/src",
],
header_libs: [
"jni_headers",
"libbase_headers",
"liblog_headers",
],
srcs: [
"src/odk.c",
@@ -38,7 +43,7 @@ cc_library_static {
proprietary: true,
owner: "widevine",
min_sdk_version: "UpsideDownCake",
min_sdk_version: "34",
}
// ----------------------------------------------------------------
@@ -51,6 +56,11 @@ cc_library_static {
"vendor/widevine/libwvdrmengine/oemcrypto/odk/include",
"vendor/widevine/libwvdrmengine/oemcrypto/odk/src",
],
header_libs: [
"jni_headers",
"libbase_headers",
"liblog_headers",
],
srcs: [
"src/core_message_deserialize.cpp",

View File

@@ -122,6 +122,7 @@ typedef enum OEMCrypto_Usage_Entry_Status {
kInactiveUnused = 4,
} OEMCrypto_Usage_Entry_Status;
/* Not used publicly. Not documented with Doxygen. */
typedef enum OEMCrypto_ProvisioningRenewalType {
OEMCrypto_NoRenewal = 0,
OEMCrypto_RenewalACert = 1,
@@ -137,7 +138,9 @@ typedef enum OEMCrypto_LicenseType {
OEMCrypto_LicenseType_MaxValue = OEMCrypto_EntitlementLicense,
} OEMCrypto_LicenseType;
/* Private key type used in the provisioning response. */
/**
* Private key type used in the provisioning response.
*/
typedef enum OEMCrypto_PrivateKeyType {
OEMCrypto_RSA_Private_Key = 0,
OEMCrypto_ECC_Private_Key = 1,

View File

@@ -26,9 +26,9 @@ struct CoreMessageFeatures {
// This is the published version of the ODK Core Message library. The default
// behavior is for the server to restrict messages to at most this version
// number. The default is 18.2.
// number. The default is 18.5.
uint32_t maximum_major_version = 18;
uint32_t maximum_minor_version = 2;
uint32_t maximum_minor_version = 5;
bool operator==(const CoreMessageFeatures &other) const;
bool operator!=(const CoreMessageFeatures &other) const {

View File

@@ -16,10 +16,10 @@ extern "C" {
/* The version of this library. */
#define ODK_MAJOR_VERSION 18
#define ODK_MINOR_VERSION 2
#define ODK_MINOR_VERSION 5
/* ODK Version string. Date changed automatically on each release. */
#define ODK_RELEASE_DATE "ODK v18.2 2023-06-14"
#define ODK_RELEASE_DATE "ODK v18.5 2024-03-21"
/* The lowest version number for an ODK message. */
#define ODK_FIRST_VERSION 16

View File

@@ -19,7 +19,9 @@ CoreMessageFeatures CoreMessageFeatures::DefaultFeatures(
uint32_t maximum_major_version) {
CoreMessageFeatures features;
features.maximum_major_version = maximum_major_version;
// The default minor version is the highest for each major version.
// The default minor version is the highest for each major version. This also
// needs to be updated with new version releases in
// ODK_InitializeSessionValues() when the minor version is being set.
switch (maximum_major_version) {
case 16:
features.maximum_minor_version = 5; // 16.5
@@ -28,7 +30,7 @@ CoreMessageFeatures CoreMessageFeatures::DefaultFeatures(
features.maximum_minor_version = 2; // 17.2
break;
case 18:
features.maximum_minor_version = 2; // 18.2
features.maximum_minor_version = 5; // 18.5
break;
default:
features.maximum_minor_version = 0;

View File

@@ -9,6 +9,7 @@
#include <stdio.h>
#include <string.h>
#include "odk_message.h"
#include "odk_overflow.h"
#include "odk_serialize.h"
#include "odk_structs.h"
@@ -45,12 +46,23 @@ static OEMCryptoResult ODK_PrepareRequest(
* message buffer has been correctly initialized by the caller. */
switch (message_type) {
case ODK_License_Request_Type: {
core_message->message_length = ODK_LICENSE_REQUEST_SIZE;
if (sizeof(ODK_PreparedLicenseRequest) > prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
if (nonce_values->api_major_version > 17) {
core_message->message_length = ODK_LICENSE_REQUEST_SIZE;
if (sizeof(ODK_PreparedLicenseRequest) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Pack_ODK_PreparedLicenseRequest(
&msg, (ODK_PreparedLicenseRequest*)prepared_request_buffer);
} else {
core_message->message_length = ODK_LICENSE_REQUEST_SIZE_V17;
if (sizeof(ODK_PreparedLicenseRequestV17) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Pack_ODK_PreparedLicenseRequestV17(
&msg, (ODK_PreparedLicenseRequestV17*)prepared_request_buffer);
}
Pack_ODK_PreparedLicenseRequest(
&msg, (ODK_PreparedLicenseRequest*)prepared_request_buffer);
break;
}
case ODK_Renewal_Request_Type: {
@@ -63,13 +75,23 @@ static OEMCryptoResult ODK_PrepareRequest(
break;
}
case ODK_Provisioning_Request_Type: {
core_message->message_length = ODK_PROVISIONING_REQUEST_SIZE;
if (sizeof(ODK_PreparedProvisioningRequest) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
if (nonce_values->api_major_version > 17) {
core_message->message_length = ODK_PROVISIONING_REQUEST_SIZE;
if (sizeof(ODK_PreparedProvisioningRequest) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Pack_ODK_PreparedProvisioningRequest(
&msg, (ODK_PreparedProvisioningRequest*)prepared_request_buffer);
} else {
core_message->message_length = ODK_PROVISIONING_REQUEST_SIZE_V17;
if (sizeof(ODK_PreparedProvisioningRequestV17) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Pack_ODK_PreparedProvisioningRequestV17(
&msg, (ODK_PreparedProvisioningRequestV17*)prepared_request_buffer);
}
Pack_ODK_PreparedProvisioningRequest(
&msg, (ODK_PreparedProvisioningRequest*)prepared_request_buffer);
break;
}
case ODK_Provisioning40_Request_Type: {
@@ -186,12 +208,19 @@ OEMCryptoResult ODK_PrepareCoreLicenseRequest(
counter_info == NULL) {
return ODK_ERROR_CORE_MESSAGE;
}
ODK_PreparedLicenseRequest license_request = {0};
memcpy(&license_request.counter_info, counter_info,
sizeof(license_request.counter_info));
return ODK_PrepareRequest(
message, message_length, core_message_size, ODK_License_Request_Type,
nonce_values, &license_request, sizeof(ODK_PreparedLicenseRequest));
if (nonce_values->api_major_version > 17) {
ODK_PreparedLicenseRequest license_request = {0};
memcpy(&license_request.counter_info, counter_info,
sizeof(license_request.counter_info));
return ODK_PrepareRequest(
message, message_length, core_message_size, ODK_License_Request_Type,
nonce_values, &license_request, sizeof(ODK_PreparedLicenseRequest));
} else {
ODK_PreparedLicenseRequestV17 license_request = {0};
return ODK_PrepareRequest(
message, message_length, core_message_size, ODK_License_Request_Type,
nonce_values, &license_request, sizeof(ODK_PreparedLicenseRequestV17));
}
}
OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
@@ -250,14 +279,22 @@ OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
counter_info == NULL) {
return ODK_ERROR_CORE_MESSAGE;
}
ODK_PreparedProvisioningRequest provisioning_request = {0};
memcpy(&provisioning_request.counter_info, counter_info,
sizeof(ODK_MessageCounterInfo));
if (nonce_values->api_major_version > 17) {
ODK_PreparedProvisioningRequest provisioning_request = {0};
memcpy(&provisioning_request.counter_info, counter_info,
sizeof(ODK_MessageCounterInfo));
return ODK_PrepareRequest(message, message_length, core_message_length,
ODK_Provisioning_Request_Type, nonce_values,
&provisioning_request,
sizeof(ODK_PreparedProvisioningRequest));
return ODK_PrepareRequest(message, message_length, core_message_length,
ODK_Provisioning_Request_Type, nonce_values,
&provisioning_request,
sizeof(ODK_PreparedProvisioningRequest));
} else {
ODK_PreparedProvisioningRequestV17 provisioning_request = {0};
return ODK_PrepareRequest(message, message_length, core_message_length,
ODK_Provisioning_Request_Type, nonce_values,
&provisioning_request,
sizeof(ODK_PreparedProvisioningRequestV17));
}
}
OEMCryptoResult ODK_PrepareCoreProvisioning40Request(
@@ -434,10 +471,14 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
*/
/* If a renewal request is lost in transit, we should throw it out and create
* a new one. We use the timestamp to make sure we have the latest request.
* We only do this if playback has already started. This allows us to reload
* an offline license and also reload a renewal before starting playback.
* We only do this if a renewal has been requested for this session. This
* allows us to reload an offline license and also reload a renewal from a
* previous session before starting playback.
* TODO: b/290249855 - This is reversed. It should be "!=" instead of "<".
* We will not fix this in the current release, because it is already in
* production code. Instead, this will be fixed in v19.
*/
if (clock_values->timer_status != ODK_CLOCK_TIMER_STATUS_LICENSE_LOADED &&
if (clock_values->time_of_renewal_request > 0 &&
clock_values->time_of_renewal_request <
renewal_response.request.playback_time) {
return ODK_STALE_RENEWAL;
@@ -489,14 +530,6 @@ OEMCryptoResult ODK_ParseProvisioning(
device_id_length) != 0) {
return ODK_ERROR_CORE_MESSAGE;
}
const uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {0};
/* check bytes beyond device_id_length are 0 */
if (crypto_memcmp(
zero, provisioning_response.request.device_id + device_id_length,
ODK_DEVICE_ID_LEN_MAX - device_id_length) != 0) {
return ODK_ERROR_CORE_MESSAGE;
}
} else {
// v18
ODK_ProvisioningResponse provisioning_response = {0};

View File

@@ -9,7 +9,7 @@
extern "C" {
#endif
#if (__STDC_VERSION__ >= 201112L)
#if defined(_MSC_VER) || (__STDC_VERSION__ >= 201112L)
#include <assert.h>
#define odk_static_assert static_assert
#else

View File

@@ -123,8 +123,10 @@ typedef struct {
// ../test/odk_test.cpp for validations of each of the defined request sizes.
#define ODK_CORE_MESSAGE_SIZE 20u
#define ODK_LICENSE_REQUEST_SIZE 90u
#define ODK_LICENSE_REQUEST_SIZE_V17 20u
#define ODK_RENEWAL_REQUEST_SIZE 28u
#define ODK_PROVISIONING_REQUEST_SIZE 94u
#define ODK_PROVISIONING_REQUEST_SIZE_V17 88u
#define ODK_PROVISIONING40_REQUEST_SIZE 862u
#define ODK_RENEWED_PROVISIONING_REQUEST_SIZE 1694u
#define ODK_MESSAGECOUNTERINFO_SIZE 70u

View File

@@ -254,11 +254,6 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits,
if (timer_limits == NULL || clock_values == NULL || nonce_values == NULL) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
/* Check that the API version passed in from OEMCrypto matches the version of
* this ODK library. */
if (api_major_version != ODK_MAJOR_VERSION) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
timer_limits->soft_enforce_rental_duration = false;
timer_limits->soft_enforce_playback_duration = false;
timer_limits->earliest_playback_start_seconds = 0;
@@ -268,8 +263,23 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits,
ODK_InitializeClockValues(clock_values, 0);
nonce_values->api_major_version = ODK_MAJOR_VERSION;
nonce_values->api_minor_version = ODK_MINOR_VERSION;
nonce_values->api_major_version = api_major_version;
// This needs to be updated with new version releases in the default features
// of core message features.
switch (nonce_values->api_major_version) {
case 16:
nonce_values->api_minor_version = 5;
break;
case 17:
nonce_values->api_minor_version = 2;
break;
case 18:
nonce_values->api_minor_version = 5;
break;
default:
nonce_values->api_minor_version = 0;
break;
}
nonce_values->nonce = 0;
nonce_values->session_id = session_id;
@@ -300,6 +310,7 @@ OEMCryptoResult ODK_InitializeClockValues(ODK_ClockValues* clock_values,
clock_values->time_of_license_request_signed = system_time_seconds;
clock_values->time_of_first_decrypt = 0;
clock_values->time_of_last_decrypt = 0;
clock_values->time_of_renewal_request = 0;
clock_values->time_when_timer_expires = 0;
clock_values->timer_status = ODK_CLOCK_TIMER_STATUS_LICENSE_NOT_LOADED;
clock_values->status = kUnused;

View File

@@ -334,12 +334,21 @@ TEST(OdkTest, NullRequestTest) {
&nonce_values, nullptr, 0uL, nullptr));
// Null device id in provisioning request is ok
uint8_t message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
core_message_length = ODK_PROVISIONING_REQUEST_SIZE;
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioningRequest(
message, ODK_PROVISIONING_REQUEST_SIZE, &core_message_length,
&nonce_values, &counter_info));
if (nonce_values.api_major_version > 17) {
uint8_t message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
core_message_length = ODK_PROVISIONING_REQUEST_SIZE;
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioningRequest(
message, ODK_PROVISIONING_REQUEST_SIZE, &core_message_length,
&nonce_values, &counter_info));
} else {
uint8_t message[ODK_PROVISIONING_REQUEST_SIZE_V17] = {0};
core_message_length = ODK_PROVISIONING_REQUEST_SIZE_V17;
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioningRequest(
message, ODK_PROVISIONING_REQUEST_SIZE_V17,
&core_message_length, &nonce_values, &counter_info));
}
// Null device info in provisioning 4.0 request is ok
uint8_t message_prov4[ODK_PROVISIONING40_REQUEST_SIZE] = {0};
@@ -885,7 +894,10 @@ TEST(OdkTest, ParseRenewalErrorTimer) {
uint32_t buf_size = 0;
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
&buf_size);
params.clock_values.time_of_renewal_request = 0;
// Set the time for the last renewal request, as seen in clock_values, to be
// after the time in the request.
// TODO: b/290249855 - This is reversed. It should be +5.
params.clock_values.time_of_renewal_request = params.playback_clock - 5;
OEMCryptoResult err = ODK_ParseRenewal(
buf, buf_size, buf_size, &(params.core_message.nonce_values),
params.system_time, &(params.timer_limits), &(params.clock_values),
@@ -1204,7 +1216,7 @@ std::vector<VersionParameters> TestCases() {
// number.
{16, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 16, 5},
{17, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 17, 2},
{18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 2},
{18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 5},
// Here are some known good versions. Make extra sure they work.
{ODK_MAJOR_VERSION, 16, 3, 16, 3},
{ODK_MAJOR_VERSION, 16, 4, 16, 4},
@@ -1213,12 +1225,16 @@ std::vector<VersionParameters> TestCases() {
{ODK_MAJOR_VERSION, 17, 2, 17, 2},
{ODK_MAJOR_VERSION, 18, 1, 18, 1},
{ODK_MAJOR_VERSION, 18, 2, 18, 2},
{ODK_MAJOR_VERSION, 18, 3, 18, 3},
{ODK_MAJOR_VERSION, 18, 4, 18, 4},
{ODK_MAJOR_VERSION, 18, 5, 18, 5},
{0, 16, 3, 16, 3},
{0, 16, 4, 16, 4},
{0, 16, 5, 16, 5},
{0, 17, 1, 17, 1},
{0, 17, 2, 17, 2},
{0, 18, 2, 18, 2}, // Change to 19 when the default version is updated.
{0, 18, 4, 18, 4},
{0, 18, 5, 18, 5},
};
return test_cases;
}
@@ -1243,7 +1259,11 @@ TEST(OdkSizeTest, LicenseRequest) {
&core_message_length, &nonce_values,
&counter_info));
// the core_message_length should be appropriately set
EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE, core_message_length);
if (nonce_values.api_major_version > 17) {
EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE, core_message_length);
} else {
EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE_V17, core_message_length);
}
}
TEST(OdkSizeTest, RenewalRequest) {
@@ -1307,7 +1327,11 @@ TEST(OdkSizeTest, ProvisioningRequest) {
&core_message_length,
&nonce_values, &counter_info));
// the core_message_length should be appropriately set
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE, core_message_length);
if (nonce_values.api_major_version > 17) {
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE, core_message_length);
} else {
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE_V17, core_message_length);
}
}
// Verify the version string contains the right version numbers.

View File

@@ -366,3 +366,12 @@ OEMCryptoResult _oecc141(const uint8_t* challenge, size_t challenge_length,
// OEMCrypto_EnterTestMode defined in v18.1
OEMCryptoResult _oecc140(void);
// OEMCrypto_FactoryInstallBCCSignature defined in v18.3
OEMCryptoResult _oecc142(const uint8_t* signature, size_t signature_length);
// OEMCrypto_GetEmbeddedDrmCertificate defined in v18.5
OEMCryptoResult _oecc143(uint8_t* public_cert, size_t* public_cert_length);
// OEMCrypto_UseSecondaryKey defined in v18.5
OEMCryptoResult _oecc144(OEMCrypto_SESSION session_id, bool dual_key);

View File

@@ -0,0 +1,136 @@
// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace {
enum class ApiMethod {
kOpenSession,
kCloseSession,
kCreateEntitledKeySession,
kReassociateEntitledKeySession,
kRemoveEntitledKeySession,
kMaxValue = kRemoveEntitledKeySession,
};
struct Session {
OEMCrypto_SESSION value;
std::vector<OEMCrypto_SESSION>::const_iterator iterator;
};
Session PickSession(FuzzedDataProvider& fuzzed_data,
const std::vector<OEMCrypto_SESSION>& sessions) {
Session session;
session.iterator =
sessions.cbegin() +
fuzzed_data.ConsumeIntegralInRange<size_t>(0, sessions.size());
if (session.iterator != sessions.cend()) {
session.value = *session.iterator;
} else {
session.value = fuzzed_data.ConsumeIntegral<OEMCrypto_SESSION>();
}
return session;
}
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
wvoec::RedirectStdoutToFile();
wvoec::SessionUtil session_util;
wvoec::InitializeFuzz(session_util);
// Contains all open and some closed OEMCrypto sessions.
std::vector<OEMCrypto_SESSION> oec_sessions;
// Contains all current and some removed key sessions.
std::vector<OEMCrypto_SESSION> key_sessions;
FuzzedDataProvider fuzzed_data(data, size);
while (fuzzed_data.remaining_bytes() > 0) {
switch (fuzzed_data.ConsumeEnum<ApiMethod>()) {
case ApiMethod::kOpenSession: {
OEMCrypto_SESSION session = 0;
const OEMCryptoResult result = OEMCrypto_OpenSession(&session);
if (result == OEMCrypto_SUCCESS) {
oec_sessions.push_back(session);
}
break;
}
case ApiMethod::kCloseSession: {
const Session session = PickSession(fuzzed_data, oec_sessions);
const OEMCryptoResult result = OEMCrypto_CloseSession(session.value);
if (result == OEMCrypto_SUCCESS &&
session.iterator != oec_sessions.cend() &&
fuzzed_data.ConsumeBool()) {
oec_sessions.erase(session.iterator);
}
break;
}
case ApiMethod::kCreateEntitledKeySession: {
const OEMCrypto_SESSION oec_session =
PickSession(fuzzed_data, oec_sessions).value;
OEMCrypto_SESSION key_session_data = 0;
OEMCrypto_SESSION* const key_session =
fuzzed_data.ConsumeBool() ? &key_session_data : nullptr;
const OEMCryptoResult result =
OEMCrypto_CreateEntitledKeySession(oec_session, key_session);
if (result == OEMCrypto_SUCCESS) {
key_sessions.push_back(*key_session);
}
break;
}
case ApiMethod::kReassociateEntitledKeySession: {
const OEMCrypto_SESSION key_session =
PickSession(fuzzed_data, key_sessions).value;
const OEMCrypto_SESSION oec_session =
PickSession(fuzzed_data, oec_sessions).value;
OEMCrypto_ReassociateEntitledKeySession(key_session, oec_session);
break;
}
case ApiMethod::kRemoveEntitledKeySession: {
const Session key_session = PickSession(fuzzed_data, key_sessions);
const OEMCryptoResult result =
OEMCrypto_RemoveEntitledKeySession(key_session.value);
if (result == OEMCrypto_SUCCESS &&
key_session.iterator != key_sessions.cend() &&
fuzzed_data.ConsumeBool()) {
key_sessions.erase(key_session.iterator);
}
break;
}
}
}
OEMCrypto_Terminate();
return 0;
}

View File

@@ -46,7 +46,6 @@ void SessionFuzz::Terminate() {
void OEMCryptoLicenseAPIFuzz::Initialize() {
session_fuzz_.Initialize();
session_fuzz_.InstallTestDrmKey();
session_fuzz_.session().GenerateNonce();
}
void OEMCryptoLicenseAPIFuzz::Terminate() {

View File

@@ -21,12 +21,6 @@
'oemcrypto_copy_buffer_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_opk_create_and_remove_entitled_key_session_fuzz',
'sources': [
'oemcrypto_create_and_remove_entitled_key_session_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_opk_deactivate_usage_entry_fuzz',
'sources': [
@@ -66,6 +60,12 @@
'<(oemcrypto_dir)/opk/ports/trusty/serialization_adapter/shared_memory.c',
],
},
{
'target_name': 'oemcrypto_opk_entitled_key_session_fuzz',
'sources': [
'oemcrypto_entitled_key_session_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_opk_generate_certificate_key_pair_first_stage_fuzz',
'sources': [

View File

@@ -19,12 +19,6 @@
'oemcrypto_copy_buffer_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_create_and_remove_entitled_key_session_fuzz',
'sources': [
'oemcrypto_create_and_remove_entitled_key_session_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_deactivate_usage_entry_fuzz',
'sources': [
@@ -43,6 +37,12 @@
'oemcrypto_decrypt_hash_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_entitled_key_session_fuzz',
'sources': [
'oemcrypto_entitled_key_session_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_generate_certificate_key_pair_first_stage_fuzz',
'sources': [

View File

@@ -148,14 +148,6 @@ void DeviceFeatures::Initialize() {
std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
std::string filter = initial_filter;
// clang-format off
if (!uses_keybox) FilterOut(&filter, "*KeyboxTest*");
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!loads_certificate ||
provisioning_method == OEMCrypto_BootCertificateChain)
FilterOut(&filter, "OEMCryptoLoadsCert*");
if (!generic_crypto) FilterOut(&filter, "*GenericCrypto*");
if (derive_key_method == NO_METHOD) FilterOut(&filter, "*SessionTest*");
if (api_version < 17) FilterOut(&filter, "*API17*");
if (api_version < 18) FilterOut(&filter, "*API18*");
// clang-format on
@@ -181,6 +173,7 @@ void DeviceFeatures::PickDerivedKey() {
derive_key_method = TEST_PROVISION_30;
return;
case OEMCrypto_DrmCertificate:
case OEMCrypto_DrmReprovisioning:
if (OEMCrypto_ERROR_NOT_IMPLEMENTED != OEMCrypto_LoadTestRSAKey()) {
derive_key_method = LOAD_TEST_RSA_KEY;
}
@@ -267,6 +260,8 @@ const char* ProvisioningMethodName(OEMCrypto_ProvisioningMethod method) {
return "OEMCrypto_OEMCertificate";
case OEMCrypto_BootCertificateChain:
return "OEMCrypto_BootCertificateChain";
case OEMCrypto_DrmReprovisioning:
return "OEMCrypto_DrmReprovisioning";
}
// Not reachable
return "";

View File

@@ -82,30 +82,6 @@ class FuzzedData {
size_t source_size_;
};
// Encrypt a block of data using CTR mode.
void EncryptCTR(const vector<uint8_t>& in_buffer, const uint8_t* key,
const uint8_t* starting_iv, vector<uint8_t>* out_buffer) {
ASSERT_NE(nullptr, key);
ASSERT_NE(nullptr, starting_iv);
ASSERT_NE(nullptr, out_buffer);
AES_KEY aes_key;
AES_set_encrypt_key(key, AES_BLOCK_SIZE * 8, &aes_key);
out_buffer->resize(in_buffer.size());
uint8_t iv[AES_BLOCK_SIZE]; // Current iv.
memcpy(iv, &starting_iv[0], AES_BLOCK_SIZE);
size_t l = 0; // byte index into encrypted subsample.
while (l < in_buffer.size()) {
uint8_t aes_output[AES_BLOCK_SIZE];
AES_encrypt(iv, aes_output, &aes_key);
for (size_t n = 0; n < AES_BLOCK_SIZE && l < in_buffer.size(); n++, l++) {
(*out_buffer)[l] = aes_output[n] ^ in_buffer[l];
}
ctr128_inc64(1, iv);
}
}
// Uses OEMCrypto to decrypt some random data in 'cenc' mode. This function
// assumes that the correct key is already selected in the session. It requires
// the plaintext of that key so that it can encrypt the test data. It resizes
@@ -138,6 +114,30 @@ OEMCryptoResult DecryptCTR(const vector<uint8_t>& key_handle,
} // namespace
// Encrypt a block of data using CTR mode.
void EncryptCTR(const vector<uint8_t>& in_buffer, const uint8_t* key,
const uint8_t* starting_iv, vector<uint8_t>* out_buffer) {
ASSERT_NE(nullptr, key);
ASSERT_NE(nullptr, starting_iv);
ASSERT_NE(nullptr, out_buffer);
AES_KEY aes_key;
AES_set_encrypt_key(key, AES_BLOCK_SIZE * 8, &aes_key);
out_buffer->resize(in_buffer.size());
uint8_t iv[AES_BLOCK_SIZE]; // Current iv.
memcpy(iv, &starting_iv[0], AES_BLOCK_SIZE);
size_t l = 0; // byte index into encrypted subsample.
while (l < in_buffer.size()) {
uint8_t aes_output[AES_BLOCK_SIZE];
AES_encrypt(iv, aes_output, &aes_key);
for (size_t n = 0; n < AES_BLOCK_SIZE && l < in_buffer.size(); n++, l++) {
(*out_buffer)[l] = aes_output[n] ^ in_buffer[l];
}
ctr128_inc64(1, iv);
}
}
int GetRandBytes(unsigned char* buf, size_t num) {
// returns 1 on success, -1 if not supported, or 0 if other failure.
return RAND_bytes(buf, static_cast<int>(num));
@@ -792,9 +792,6 @@ void LicenseRoundTrip::FillAndVerifyCoreRequest(
// for L3 release only.
EXPECT_LE(3, core_request_.api_minor_version);
EXPECT_GE(5, core_request_.api_minor_version);
} else if (global_features.api_version == ODK_MAJOR_VERSION) {
// We do not expect older tests to work with a newer OEMCrypto.
EXPECT_GE(ODK_MINOR_VERSION, core_request_.api_minor_version);
}
if (expect_request_has_correct_nonce_) {
EXPECT_EQ(session()->nonce(), core_request_.nonce);
@@ -1139,8 +1136,8 @@ OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session,
response_signature_.size());
if (verify_keys && result == OEMCrypto_SUCCESS) {
// Give the session object a copy of the license truth data so that it can
// call SelectKey, use key control information, and so that it has key data
// to verify decrypt operations.
// call GetKeyHandle, use key control information, and so that it has key
// data to verify decrypt operations.
session->set_license(response_data_);
// Also, if the license has new mac keys, then install them now.
if (core_response_.enc_mac_keys.length > 0) {
@@ -1234,6 +1231,12 @@ void EntitledMessage::MakeOneKey(size_t entitlement_key_index) {
sizeof(key_data->content_key_data_iv)));
offsets->content_key_data_iv = FindSubstring(
key_data->content_key_data_iv, sizeof(key_data->content_key_data_iv));
EXPECT_EQ(1,
GetRandBytes(key_data->content_iv, sizeof(key_data->content_iv)));
key_data->content_iv_length = sizeof(key_data->content_iv);
offsets->content_iv =
FindSubstring(key_data->content_iv, key_data->content_iv_length);
}
OEMCrypto_EntitledContentKeyObject* EntitledMessage::entitled_key_array() {
@@ -1367,8 +1370,8 @@ void EntitledMessage::LoadCasKeys(bool load_even, bool load_odd,
// Convert the OEMCrypto_EntitledContentKeyObject to
// OEMCrypto_EntitledCasKeyObject. Only the first two key object is used.
OEMCrypto_EntitledContentKeyObject even_key;
OEMCrypto_EntitledContentKeyObject odd_key;
OEMCrypto_EntitledContentKeyObject even_key = {};
OEMCrypto_EntitledContentKeyObject odd_key = {};
bool has_even = load_even && num_keys_ >= 1;
bool has_odd = load_odd && num_keys_ >= 2;
if (has_even) {
@@ -1376,14 +1379,16 @@ void EntitledMessage::LoadCasKeys(bool load_even, bool load_odd,
even_key.content_key_id = entitled_key_array_[0].content_key_id;
even_key.content_key_data_iv = entitled_key_array_[0].content_key_data_iv;
even_key.content_key_data = entitled_key_array_[0].content_key_data;
even_key.content_iv.length = 0;
even_key.content_iv = entitled_key_array_[0].content_iv;
even_key.cipher_mode = OEMCrypto_CipherMode_CBC;
}
if (has_odd) {
odd_key.entitlement_key_id = entitled_key_array_[1].entitlement_key_id;
odd_key.content_key_id = entitled_key_array_[1].content_key_id;
odd_key.content_key_data_iv = entitled_key_array_[1].content_key_data_iv;
odd_key.content_key_data = entitled_key_array_[1].content_key_data;
odd_key.content_iv.length = 0;
odd_key.content_iv = entitled_key_array_[1].content_iv;
odd_key.cipher_mode = OEMCrypto_CipherMode_CBC;
}
OEMCryptoResult sts = OEMCrypto_LoadCasECMKeys(
@@ -1464,6 +1469,7 @@ void EntitledMessage::VerifyDecrypt() {
void RenewalRoundTrip::VerifyRequestSignature(
const vector<uint8_t>& data, const vector<uint8_t>& generated_signature,
size_t core_message_length) {
(void)core_message_length;
ASSERT_EQ(HMAC_SHA256_SIGNATURE_SIZE, generated_signature.size());
std::vector<uint8_t> expected_signature;
session()->key_deriver().ClientSignBuffer(data, &expected_signature);
@@ -1770,7 +1776,7 @@ void Session::TestDecryptEntitled(OEMCryptoResult expected_result,
// We only have a few errors that we test are reported.
ASSERT_NO_FATAL_FAILURE(
TestDecryptResult(expected_result, getkeyhandle_result, decrypt_result))
<< "Either SelectKey or DecryptCENC should return " << expected_result
<< "Either GetKeyHandle or DecryptCENC should return" << expected_result
<< ", but they returned " << getkeyhandle_result << " and "
<< decrypt_result << ", respectively.";
}

View File

@@ -110,6 +110,8 @@ struct EntitledContentKeyData {
uint8_t content_key_data_iv[KEY_IV_SIZE];
uint8_t content_key_data[KEY_SIZE];
uint8_t encrypted_content_key_data[KEY_SIZE];
uint8_t content_iv[KEY_IV_SIZE];
size_t content_iv_length;
size_t key_index; // Index into the license's key array. Only for testing.
};
@@ -121,6 +123,10 @@ void GenerateSimpleSampleDescription(const std::vector<uint8_t>& in,
OEMCrypto_SampleDescription* sample,
OEMCrypto_SubSampleDescription* subsample);
// Encrypt a block of data using CTR mode.
void EncryptCTR(const vector<uint8_t>& in_buffer, const uint8_t* key,
const uint8_t* starting_iv, vector<uint8_t>* out_buffer);
// Increment counter for AES-CTR. The CENC spec specifies we increment only
// the low 64 bits of the IV counter, and leave the high 64 bits alone. This
// is different from the OpenSSL implementation, so we implement the CTR loop
@@ -334,6 +340,7 @@ class Provisioning40RoundTrip
void CreateDefaultResponse() override{};
void EncryptAndSignResponse() override{};
OEMCryptoResult LoadResponse(Session* session) override {
(void)session;
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
@@ -597,7 +604,7 @@ class RenewalRoundTrip
class EntitledMessage {
public:
EntitledMessage(LicenseRoundTrip* license_messages)
: license_messages_(license_messages), num_keys_() {}
: license_messages_(license_messages) {}
void FillKeyArray();
void MakeOneKey(size_t entitlement_key_index);
void SetEntitledKeySession(uint32_t key_session) {
@@ -631,13 +638,13 @@ class EntitledMessage {
void VerifyDecrypt();
LicenseRoundTrip* license_messages_;
uint32_t num_keys_;
uint32_t num_keys_ = 0;
// Clear Entitlement key data. This is the backing data for
// |entitled_key_array_|.
EntitledContentKeyData entitled_key_data_[kMaxNumKeys];
EntitledContentKeyData entitled_key_data_[kMaxNumKeys] = {};
// Entitled key object. Pointers are backed by |entitled_key_data_|.
OEMCrypto_EntitledContentKeyObject entitled_key_array_[kMaxNumKeys];
uint32_t entitled_key_session_;
OEMCrypto_EntitledContentKeyObject entitled_key_array_[kMaxNumKeys] = {};
uint32_t entitled_key_session_ = 0;
};
class Session {

View File

@@ -156,7 +156,7 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) {
*/
TEST_F(OEMCryptoClientTest, VersionNumber) {
const std::string log_message =
"OEMCrypto unit tests for API 18.2. Tests last updated 2023-04-12";
"OEMCrypto unit tests for API 18.5. Tests last updated 2024-03-21";
cout << " " << log_message << "\n";
cout << " "
<< "These tests are part of Android U."
@@ -165,7 +165,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
// If any of the following fail, then it is time to update the log message
// above.
EXPECT_EQ(ODK_MAJOR_VERSION, 18);
EXPECT_EQ(ODK_MINOR_VERSION, 2);
EXPECT_EQ(ODK_MINOR_VERSION, 5);
EXPECT_EQ(kCurrentAPI, static_cast<unsigned>(ODK_MAJOR_VERSION));
OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel();
EXPECT_GT(level, OEMCrypto_Level_Unknown);
@@ -200,6 +200,13 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
if (build_info.size() != buf_length) {
build_info.resize(buf_length);
}
const std::string comma = ",";
const std::string pretty_comma = ",\n ";
std::string::size_type pos = 0;
while ((pos = build_info.find(comma, pos)) != std::string::npos) {
build_info.replace(pos, comma.size(), pretty_comma);
pos += pretty_comma.size();
}
cout << " BuildInformation: " << build_info << endl;
OEMCrypto_WatermarkingSupport support = OEMCrypto_GetWatermarkingSupport();
cout << " WatermarkingSupport: " << support << endl;

View File

@@ -11,21 +11,36 @@ using ::testing::Range;
namespace wvoec {
// The alternate padding is only required for cast receivers, but all devices
// should forbid the alternate padding for regular certificates.
TEST_F(OEMCryptoLoadsCertificateAlternates, DisallowForbiddenPaddingAPI09) {
LoadWithAllowedSchemes(kSign_RSASSA_PSS,
true); // Use default padding scheme
DisallowForbiddenPadding(kSign_PKCS1_Block1, 50);
}
// The alternate padding is only required for cast receivers, but if a device
// does load an alternate certificate, it should NOT use it for generating
// a license request signature.
/** If a device can load a private key with the alternate padding schemes, it
* should support signing with the alternate scheme. */
TEST_F(OEMCryptoLoadsCertificateAlternates, TestSignaturePKCS1) {
// Try to load an RSA key with alternative padding schemes. This signing
// scheme is used by cast receivers.
LoadWithAllowedSchemes(kSign_PKCS1_Block1, false);
LoadCastCertificateKey(false);
// If the device is a cast receiver, then this scheme is required.
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_) {
if (global_features.cast_receiver) {
// A signature with a valid size should succeed.
TestSignature(kSign_PKCS1_Block1, 83);
TestSignature(kSign_PKCS1_Block1, 50);
}
// A signature with padding that is too big should fail.
DisallowForbiddenPaddingDRMKey(kSign_PKCS1_Block1, 84); // too big.
}
}
/** The alternate padding is only required for cast receivers, but if a device
* does load an alternate certificate, it should NOT be used as a DRM cert
* key. */
TEST_F(OEMCryptoLoadsCertificateAlternates, ForbidUseAsDRMCert) {
// Try to load an RSA key with alternative padding schemes. This signing
// scheme is used by cast receivers.
LoadCastCertificateKey(false);
// If the device is a cast receiver, then this scheme is required.
if (global_features.cast_receiver) {
ASSERT_TRUE(key_loaded_);
@@ -34,15 +49,44 @@ TEST_F(OEMCryptoLoadsCertificateAlternates, TestSignaturePKCS1) {
// for forbidden padding schemes.
if (key_loaded_) {
// The other padding scheme should fail.
DisallowForbiddenPadding(kSign_RSASSA_PSS, 83);
DisallowForbiddenPaddingDRMKey(kSign_RSASSA_PSS, 83);
DisallowDeriveKeys();
if (global_features.cast_receiver) {
// A signature with a valid size should succeed.
TestSignature(kSign_PKCS1_Block1, 83);
TestSignature(kSign_PKCS1_Block1, 50);
}
// A signature with padding that is too big should fail.
DisallowForbiddenPadding(kSign_PKCS1_Block1, 84); // too big.
}
}
/** A Cast receiver certificate private key cannot be used with the function
* PrepAndSignLicenseRequest.
*/
TEST_F(OEMCryptoLoadsCertificateAlternates, ForbidPrepAndSign) {
// Try to load an RSA key with alternative padding schemes. This signing
// scheme is used by cast receivers.
LoadCastCertificateKey(false);
// If the device is a cast receiver, then this scheme is required.
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_) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
s.GenerateNonce();
size_t core_message_length = 100;
std::vector<uint8_t> message(128, 0);
std::vector<uint8_t> signature(256, 0);
size_t signature_length = signature.size();
OEMCryptoResult result = OEMCrypto_PrepAndSignLicenseRequest(
s.session_id(), message.data(), message.size(), &core_message_length,
signature.data(), &signature_length);
// TODO: remove OEMCrypto_ERROR_INVALID_RSA_KEY once OEMCrypto v16 is not
// supported anymore. This error code has been deprecated since v17.
ASSERT_TRUE(result == OEMCrypto_ERROR_INVALID_KEY ||
result == OEMCrypto_ERROR_INVALID_RSA_KEY);
const vector<uint8_t> zero(signature.size(), 0);
ASSERT_EQ(signature, zero); // Signature should not have been computed.
}
}
@@ -275,7 +319,7 @@ TEST_F(OEMCryptoCastReceiverTest, SupportsCertificatesAPI13) {
// # PKCS#1 v1.5 Signature Example 15.1
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_1) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"f45d55f35551e975d6a8dc7ea9f48859"
"3940cc75694a278f27e578a163d839b3"
@@ -314,7 +358,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_1) {
// # PKCS#1 v1.5 Signature Example 15.2
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_2) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"c14b4c6075b2f9aad661def4ecfd3cb9"
"33c623f4e63bf53410d2f016d1ab98e2"
@@ -349,7 +393,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_2) {
// # PKCS#1 v1.5 Signature Example 15.3
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_3) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"d02371ad7ee48bbfdb2763de7a843b94"
"08ce5eb5abf847ca3d735986df84e906"
@@ -390,7 +434,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_3) {
// # PKCS#1 v1.5 Signature Example 15.4
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_4) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"29035584ab7e0226a9ec4b02e8dcf127"
"2dc9a41d73e2820007b0f6e21feccd5b"
@@ -419,7 +463,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_4) {
// # PKCS#1 v1.5 Signature Example 15.5
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_5) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex("bda3a1c79059eae598308d3df609");
vector<uint8_t> signature = wvutil::a2b_hex(
"a156176cb96777c7fb96105dbd913bc4"
@@ -444,7 +488,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_5) {
// # PKCS#1 v1.5 Signature Example 15.6
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_6) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"c187915e4e87da81c08ed4356a0cceac"
"1c4fb5c046b45281b387ec28f1abfd56"
@@ -476,7 +520,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_6) {
// # PKCS#1 v1.5 Signature Example 15.7
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_7) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"abfa2ecb7d29bd5bcb9931ce2bad2f74"
"383e95683cee11022f08e8e7d0b8fa05"
@@ -509,7 +553,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_7) {
// # PKCS#1 v1.5 Signature Example 15.8
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_8) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"df4044a89a83e9fcbf1262540ae3038b"
"bc90f2b2628bf2a4467ac67722d8546b"
@@ -548,7 +592,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_8) {
// # PKCS#1 v1.5 Signature Example 15.9
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_9) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"ea941ff06f86c226927fcf0e3b11b087"
"2676170c1bfc33bda8e265c77771f9d0"
@@ -585,7 +629,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_9) {
// # PKCS#1 v1.5 Signature Example 15.10
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_10) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"d8b81645c13cd7ecf5d00ed2c91b9acd"
"46c15568e5303c4a9775ede76b48403d"
@@ -615,7 +659,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_10) {
// # PKCS#1 v1.5 Signature Example 15.11
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_11) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"e5739b6c14c92d510d95b826933337ff"
"0d24ef721ac4ef64c2bad264be8b44ef"
@@ -649,7 +693,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_11) {
// # PKCS#1 v1.5 Signature Example 15.12
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_12) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"7af42835917a88d6b3c6716ba2f5b0d5"
"b20bd4e2e6e574e06af1eef7c81131be"
@@ -690,7 +734,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_12) {
// # PKCS#1 v1.5 Signature Example 15.13
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_13) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"ebaef3f9f23bdfe5fa6b8af4c208c189"
"f2251bf32f5f137b9de4406378686b3f"
@@ -719,7 +763,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_13) {
// # PKCS#1 v1.5 Signature Example 15.14
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_14) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"c5a2711278761dfcdd4f0c99e6f5619d"
"6c48b5d4c1a80982faa6b4cf1cf7a60f"
@@ -755,7 +799,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_14) {
// # PKCS#1 v1.5 Signature Example 15.15
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_15) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"9bf8aa253b872ea77a7e23476be26b23"
"29578cf6ac9ea2805b357f6fc3ad130d"
@@ -794,7 +838,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_15) {
// # PKCS#1 v1.5 Signature Example 15.16
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_16) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"32474830e2203754c8bf0681dc4f842a"
"fe360930378616c108e833656e5640c8"
@@ -835,7 +879,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_16) {
// # PKCS#1 v1.5 Signature Example 15.17
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_17) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"008e59505eafb550aae5e845584cebb0"
"0b6de1733e9f95d42c882a5bbeb5ce1c"
@@ -864,7 +908,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_17) {
// # PKCS#1 v1.5 Signature Example 15.18
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_18) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"6abc54cf8d1dff1f53b17d8160368878"
"a8788cc6d22fa5c2258c88e660b09a89"
@@ -894,7 +938,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_18) {
// # PKCS#1 v1.5 Signature Example 15.19
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_19) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"af2d78152cf10efe01d274f217b177f6"
"b01b5e749f1567715da324859cd3dd88"
@@ -931,7 +975,7 @@ TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_19) {
// # PKCS#1 v1.5 Signature Example 15.20
TEST_F(OEMCryptoCastReceiverTest, TestSignaturePKCS1_15_20) {
BuildRSAKey();
LoadWithAllowedSchemes(kSign_PKCS1_Block1, true);
LoadCastCertificateKey(true);
vector<uint8_t> message = wvutil::a2b_hex(
"40ee992458d6f61486d25676a96dd2cb"
"93a37f04b178482f2b186cf88215270d"
@@ -974,4 +1018,4 @@ TEST_P(OEMCryptoSessionTestLoadCasKeysWithHDCP, CasOnlyLoadCasKeysAPI17) {
}
INSTANTIATE_TEST_SUITE_P(TestHDCP, OEMCryptoSessionTestLoadCasKeysWithHDCP,
Range(1, 6));
} // namespace wvoec
} // namespace wvoec

View File

@@ -25,36 +25,6 @@ std::string MaybeHex(const std::vector<uint8_t>& data);
// This test attempts to use alternate algorithms for loaded device certs.
class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
protected:
void DisallowForbiddenPadding(RSA_Padding_Scheme scheme, size_t size) {
OEMCryptoResult sts;
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
// Sign a Message
vector<uint8_t> licenseRequest(size);
GetRandBytes(licenseRequest.data(), licenseRequest.size());
size_t signature_length = 256;
vector<uint8_t> signature(signature_length);
sts = OEMCrypto_GenerateRSASignature(
s.session_id(), licenseRequest.data(), licenseRequest.size(),
signature.data(), &signature_length, scheme);
// Allow OEMCrypto to request a full buffer.
if (sts == OEMCrypto_ERROR_SHORT_BUFFER) {
ASSERT_NE(static_cast<size_t>(0), signature_length);
signature.assign(signature_length, 0);
sts = OEMCrypto_GenerateRSASignature(
s.session_id(), licenseRequest.data(), licenseRequest.size(),
signature.data(), &signature_length, scheme);
}
EXPECT_NE(OEMCrypto_SUCCESS, sts)
<< "Signed with forbidden padding scheme=" << (int)scheme
<< ", size=" << (int)size;
const vector<uint8_t> zero(signature.size(), 0);
ASSERT_EQ(zero, signature); // signature should not be computed.
}
void TestSignature(RSA_Padding_Scheme scheme, size_t size) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
@@ -105,7 +75,12 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
}
// If force is true, we assert that the key loads successfully.
void LoadWithAllowedSchemes(uint32_t schemes, bool force) {
void LoadCastCertificateKey(bool force) {
if (!wvoec::global_features.cast_receiver) {
GTEST_SKIP() << "Cast not supported";
}
// Padding scheme used to sign cast data.
constexpr uint32_t schemes = kSign_PKCS1_Block1;
// prov 2 or prov 3
if (global_features.provisioning_method == OEMCrypto_Keybox ||
global_features.provisioning_method == OEMCrypto_OEMCertificate) {

View File

@@ -1,12 +1,14 @@
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine */
/* License Agreement. */
#include "oemcrypto_corpus_generator_helper.h"
#include <fstream>
#include <iostream>
namespace wvoec {
bool g_generate_corpus;
void AppendToFile(const std::string& file_name, const char* message,
@@ -32,7 +34,7 @@ void AppendSeparator(const std::string& file_name) {
std::string GetFileName(const char* directory) {
std::string file_name(PATH_TO_CORPUS);
file_name += directory;
file_name += "/";
file_name += '/';
file_name += std::to_string(rand());
return file_name;
}
@@ -40,5 +42,7 @@ std::string GetFileName(const char* directory) {
void SetGenerateCorpus(bool should_generate_corpus) {
g_generate_corpus = should_generate_corpus;
}
bool ShouldGenerateCorpus() { return g_generate_corpus; }
} // namespace wvoec

View File

@@ -1,16 +1,18 @@
/* Copyright 2020 Google LLC. All rights reserved. This file and proprietary */
/* source code may only be used and distributed under the Widevine */
/* License Agreement. */
#ifndef CDM_OEMCRYPTO_CORPUS_GENERATOR_HELPER_H_
#define CDM_OEMCRYPTO_CORPUS_GENERATOR_HELPER_H_
#define PATH_TO_CORPUS "./oemcrypto/test/fuzz_tests/corpus/"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string>
namespace wvoec {
const uint8_t kFuzzDataSeparator[] = {'-', '_', '^', '_'};
void AppendToFile(const std::string& file_name, const char* message,
@@ -22,9 +24,11 @@ void AppendSeparator(const std::string& file_name);
std::string GetFileName(const char* directory);
void SetGenerateCorpus(bool should_generate_corpus);
// Output of this function decides if binary data needs to be written
// to corpus files or not. Controlled by --generate_corpus flag.
bool ShouldGenerateCorpus();
} // namespace wvoec
#endif // CDM_OEMCRYPTO_CORPUS_GENERATOR_HELPER_H_

View File

@@ -49,10 +49,9 @@ TEST_P(OEMCryptoLicenseTest, FailDecryptWithOldKeyHandle) {
session_.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
}
// SelectKey should fail if we attempt to select a key that has not been loaded.
// Also, the error should be NO_CONTENT_KEY.
// This test should pass for v15 devices, except that the exact error code was
// not specified until v16.
// GetKeyHandle should fail if we attempt to select a key that has not been
// loaded. Also, the error should be NO_CONTENT_KEY. This test should pass for
// v15 devices, except that the exact error code was not specified until v16.
TEST_P(OEMCryptoLicenseTest, SelectKeyNotThereAPI16) {
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
@@ -540,6 +539,17 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSubsample) {
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptZeroSizeSubSample) {
ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({
{10, 10},
{0, 0},
}));
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
// There are probably no frames this small, but we should handle them anyway.
TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) {
ASSERT_NO_FATAL_FAILURE(SetSubsampleSizes({
@@ -683,4 +693,4 @@ TEST_P(OEMCryptoLicenseTest, KeyDuration) {
INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoLicenseTest,
Range<uint32_t>(kCurrentAPI - 2, kCurrentAPI + 1));
} // namespace wvoec
} // namespace wvoec

View File

@@ -98,6 +98,10 @@ class OEMCryptoSessionTestsDecryptTests
protected:
void SetUp() override {
OEMCryptoLicenseTestAPI16::SetUp();
if (wvoec::global_features.derive_key_method ==
wvoec::DeviceFeatures::NO_METHOD) {
GTEST_SKIP() << "Test for devices that can derive session keys only.";
}
pattern_ = ::testing::get<0>(GetParam());
cipher_mode_ = ::testing::get<1>(GetParam());
decrypt_inplace_ = ::testing::get<2>(GetParam()).decrypt_inplace;

View File

@@ -84,10 +84,6 @@ void TestMaxKeys(SessionUtil* util, size_t num_keys_per_session) {
}
}
TEST_F(OEMCryptoSessionTestKeyboxTest, TestKeyboxIsValid) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid());
}
TEST_F(OEMCryptoSessionTests,
OEMCryptoMemoryPrepareLicenseRequestForHugeRequestMessageLength) {
TestPrepareLicenseRequestForHugeBufferLengths(
@@ -875,7 +871,7 @@ TEST_P(OEMCryptoRefreshTest, RefreshLargeBuffer) {
}
// This situation would occur if an app only uses one key in the license. When
// that happens, SelectKey would be called before the first decrypt, and then
// that happens, GetKeyHandle would be called before the first decrypt, and then
// would not need to be called again, even if the license is refreshed.
TEST_P(OEMCryptoRefreshTest, RefreshWithNoSelectKey) {
LoadLicense();
@@ -967,4 +963,4 @@ INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoRefreshTestAPI16,
Range<uint32_t>(kCoreMessagesAPI, kCurrentAPI + 1));
/// @}
} // namespace wvoec
} // namespace wvoec

View File

@@ -39,6 +39,10 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest {
void SetUp() override {
OEMCryptoClientTest::SetUp();
if (wvoec::global_features.derive_key_method ==
wvoec::DeviceFeatures::NO_METHOD) {
GTEST_SKIP() << "Test for devices that can derive session keys only.";
}
EnsureTestROT();
if (global_features.usage_table) {
CreateUsageTableHeader();
@@ -92,8 +96,6 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest {
}
};
class OEMCryptoSessionTestKeyboxTest : public OEMCryptoSessionTests {};
// This class is for testing a single license with the default API version
// of 16.
class OEMCryptoLicenseTestAPI16 : public OEMCryptoSessionTests {
@@ -407,4 +409,4 @@ class OEMCryptoRefreshTestAPI16 : public OEMCryptoRefreshTest {};
} // namespace wvoec
#endif // CDM_OEMCRYPTO_LICENSE_TEST_
#endif // CDM_OEMCRYPTO_LICENSE_TEST_

View File

@@ -119,36 +119,24 @@ TEST_F(OEMCryptoProv30Test, OEMCertValid) {
ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert(kVerify)); // Load and verify.
}
// This verifies that the OEM Certificate cannot be used for other RSA padding
// schemes. Those schemes should only be used by cast receiver certificates.
TEST_F(OEMCryptoProv30Test, OEMCertForbiddenPaddingScheme) {
/** This verifies that the OEM Certificate cannot be used with
* GenerateRSASignature.
*/
TEST_F(OEMCryptoProv30Test, OEMCertForbidGenerateRSASignature1) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert());
OEMCryptoResult sts;
// Sign a Message
vector<uint8_t> data(500);
GetRandBytes(data.data(), data.size());
size_t signature_length = 0;
// We need a size one vector to pass as a pointer.
vector<uint8_t> signature(1, 0);
vector<uint8_t> zero(1, 0);
DisallowForbiddenPadding(s.session_id(), kSign_PKCS1_Block1, 80);
}
sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(), data.size(),
signature.data(), &signature_length,
kSign_PKCS1_Block1);
if (OEMCrypto_ERROR_SHORT_BUFFER == sts) {
// The OEMCrypto could complain about buffer length first, so let's
// resize and check if it's writing to the signature again.
signature.resize(signature_length, 0);
zero.resize(signature_length, 0);
sts = OEMCrypto_GenerateRSASignature(s.session_id(), data.data(),
data.size(), signature.data(),
&signature_length, kSign_PKCS1_Block1);
}
EXPECT_NE(OEMCrypto_SUCCESS, sts)
<< "OEM Cert Signed with forbidden kSign_PKCS1_Block1.";
ASSERT_EQ(zero, signature); // signature should not be computed.
/** This verifies that the OEM Certificate cannot be used with
* GenerateRSASignature.
*/
TEST_F(OEMCryptoProv30Test, OEMCertForbidGenerateRSASignature2) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert());
DisallowForbiddenPadding(s.session_id(), kSign_RSASSA_PSS, 80);
}
// Calling OEMCrypto_GetOEMPublicCertificate should not change the session's
@@ -186,6 +174,46 @@ TEST_F(OEMCryptoProv30Test, GetCertOnlyAPI16) {
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse());
}
/** This verifies that the OEM Certificate cannot be used with
* GenerateRSASignature.
*/
TEST_F(OEMCryptoProv40Test, OEMCertForbidGenerateRSASignature1) {
// Create an OEM Cert and save it for later.
Session s1;
ASSERT_NO_FATAL_FAILURE(s1.open());
ASSERT_NO_FATAL_FAILURE(CreateProv4OEMKey(&s1));
ASSERT_EQ(s1.IsPublicKeySet(), true);
s1.close();
Session s2;
ASSERT_NO_FATAL_FAILURE(s2.open());
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_InstallOemPrivateKey(
s2.session_id(), oem_key_type_,
reinterpret_cast<const uint8_t*>(wrapped_oem_key_.data()),
wrapped_oem_key_.size()));
DisallowForbiddenPadding(s2.session_id(), kSign_PKCS1_Block1, 80);
}
/** This verifies that the OEM Certificate cannot be used with
* GenerateRSASignature.
*/
TEST_F(OEMCryptoProv40Test, OEMCertForbidGenerateRSASignature2) {
// Create an OEM Cert and save it for later.
Session s1;
ASSERT_NO_FATAL_FAILURE(s1.open());
ASSERT_NO_FATAL_FAILURE(CreateProv4OEMKey(&s1));
ASSERT_EQ(s1.IsPublicKeySet(), true);
s1.close();
Session s2;
ASSERT_NO_FATAL_FAILURE(s2.open());
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_InstallOemPrivateKey(
s2.session_id(), oem_key_type_,
reinterpret_cast<const uint8_t*>(wrapped_oem_key_.data()),
wrapped_oem_key_.size()));
DisallowForbiddenPadding(s2.session_id(), kSign_RSASSA_PSS, 80);
}
// This verifies that the device really does claim to have BCC.
// It should be filtered out for devices that have a keybox or factory OEM
// cert.
@@ -539,7 +567,7 @@ TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeyCanBeUsed) {
* cert.
*/
TEST_F(OEMCryptoProv40Test, OEMPrivateKeyCannotBeDRMKey) {
// Create an OEM Cert and save it for alter.
// Create an OEM Cert and save it for later.
Session s1;
ASSERT_NO_FATAL_FAILURE(s1.open());
ASSERT_NO_FATAL_FAILURE(CreateProv4OEMKey(&s1));
@@ -654,7 +682,22 @@ TEST_P(OEMCryptoProv40CastTest, ProvisionCastWorks) {
INSTANTIATE_TEST_SUITE_P(Prov4CastProvisioningBasic, OEMCryptoProv40CastTest,
testing::Values(true, false));
// Verify that you cannot use GenerateRSASignature with a normal DRM Cert.
// that function needs a cast cert.
TEST_F(OEMCryptoLoadsCertificate, ForbidRSASignatureForDRMKey1) {
DisallowForbiddenPadding(session_.session_id(), kSign_RSASSA_PSS, 80);
}
TEST_F(OEMCryptoLoadsCertificate, ForbidRSASignatureForDRMKey2) {
DisallowForbiddenPadding(session_.session_id(), kSign_PKCS1_Block1, 80);
}
TEST_F(OEMCryptoLoadsCertificate, PrepAndSignLicenseRequestCounterAPI18) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
@@ -675,6 +718,11 @@ TEST_F(OEMCryptoLoadsCertificate, PrepAndSignLicenseRequestCounterAPI18) {
// This test verifies that we can create a wrapped RSA key, and then reload it.
TEST_F(OEMCryptoLoadsCertificate, LoadRSASessionKey) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
@@ -682,6 +730,11 @@ TEST_F(OEMCryptoLoadsCertificate, LoadRSASessionKey) {
}
TEST_F(OEMCryptoLoadsCertificate, SignProvisioningRequest) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
if (global_features.provisioning_method == OEMCrypto_OEMCertificate) {
@@ -696,6 +749,11 @@ TEST_F(OEMCryptoLoadsCertificate, SignProvisioningRequest) {
// This tests a large message size. The size is larger than we required in v15.
TEST_F(OEMCryptoLoadsCertificate, SignLargeProvisioningRequestAPI16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
if (global_features.provisioning_method == OEMCrypto_OEMCertificate) {
@@ -714,6 +772,11 @@ TEST_F(OEMCryptoLoadsCertificate, SignLargeProvisioningRequestAPI16) {
// unencrypted key is not found in the wrapped key. The wrapped key should be
// encrypted.
TEST_F(OEMCryptoLoadsCertificate, CertificateProvision) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
provisioning_messages.PrepareSession(keybox_);
@@ -730,6 +793,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvision) {
// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning
// message.
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange1_API16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
provisioning_messages.PrepareSession(keybox_);
@@ -747,6 +815,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange1_API16) {
// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning
// message.
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange2_API16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
provisioning_messages.PrepareSession(keybox_);
@@ -764,6 +837,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange2_API16) {
// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning
// message.
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange3_API16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
provisioning_messages.PrepareSession(keybox_);
@@ -783,6 +861,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange3_API16) {
// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning
// message.
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange4_API16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
provisioning_messages.PrepareSession(keybox_);
@@ -802,6 +885,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange4_API16) {
// Verify that RewrapDeviceRSAKey checks pointers are within the provisioning
// message.
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange5Prov30_API16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
if (global_features.provisioning_method != OEMCrypto_OEMCertificate) {
GTEST_SKIP() << "Test for Prov 3.0 devices only.";
}
@@ -825,6 +913,14 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange5Prov30_API16) {
// TODO(b/144186970): This test should also run on Prov 3.0 devices.
TEST_F(OEMCryptoLoadsCertificate,
CertificateProvisionBadSignatureKeyboxTestAPI16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
if (global_features.provisioning_method != OEMCrypto_Keybox) {
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
provisioning_messages.PrepareSession(keybox_);
@@ -839,6 +935,11 @@ TEST_F(OEMCryptoLoadsCertificate,
// Test that RewrapDeviceRSAKey verifies the nonce is current.
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonce_API16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
provisioning_messages.PrepareSession(keybox_);
@@ -853,6 +954,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonce_API16) {
// Test that RewrapDeviceRSAKey verifies the RSA key is valid.
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKey) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
provisioning_messages.PrepareSession(keybox_);
@@ -868,6 +974,14 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKey) {
// TODO(b/144186970): This test should also run on Prov 3.0 devices.
TEST_F(OEMCryptoLoadsCertificate,
CertificateProvisionBadRSAKeyKeyboxTestAPI16) {
if (global_features.provisioning_method != OEMCrypto_Keybox) {
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
}
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
provisioning_messages.PrepareSession(keybox_);
@@ -887,6 +1001,11 @@ TEST_F(OEMCryptoLoadsCertificate,
// Test that RewrapDeviceRSAKey accepts the maximum message size.
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionLargeBuffer) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
const size_t max_size = GetResourceValue(kLargeMessageSize);
@@ -904,6 +1023,11 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionLargeBuffer) {
// Test that a wrapped RSA key can be loaded.
TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
@@ -912,6 +1036,15 @@ TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) {
class OEMCryptoLoadsCertVariousKeys : public OEMCryptoLoadsCertificate {
public:
void SetUp() override {
OEMCryptoLoadsCertificate::SetUp();
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
}
void TestKey(const uint8_t* key, size_t key_length) {
encoded_rsa_key_.assign(key, key + key_length);
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
@@ -987,6 +1120,11 @@ TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerZeroNormalDer) {
// This tests that two sessions can use different RSA keys simultaneously.
TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
Session s1; // Session s1 loads the default rsa key, but doesn't use it
// until after s2 uses its key.
@@ -1023,6 +1161,11 @@ TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) {
// This tests the maximum number of DRM private keys that OEMCrypto can load
TEST_F(OEMCryptoLoadsCertificate, TestMaxDRMKeys) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
const size_t max_total_keys = GetResourceValue(kMaxTotalDRMPrivateKeys);
std::vector<std::unique_ptr<Session>> sessions;
std::vector<std::unique_ptr<LicenseRoundTrip>> licenses;
@@ -1090,6 +1233,11 @@ TEST_F(OEMCryptoLoadsCertificate, TestMaxDRMKeys) {
// Devices that load certificates, should at least support RSA 2048 keys.
TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
ASSERT_NE(0u,
OEMCrypto_Supports_RSA_2048bit & OEMCrypto_SupportedCertificates())
<< "Supported certificates is only " << OEMCrypto_SupportedCertificates();
@@ -1098,6 +1246,11 @@ TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) {
// This test is not run by default, because it takes a long time and
// is used to measure RSA performance, not test functionality.
TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
const std::chrono::milliseconds kTestDuration(5000);
OEMCryptoResult sts;
std::chrono::steady_clock clock;
@@ -1199,7 +1352,9 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
delta_time / std::chrono::milliseconds(1) / count;
OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel();
printf("PERF:head, security, provision (ms), lic req(ms), derive keys(ms)\n");
printf(
"PERF:head, security, provision (ms), lic req(ms), derive "
"keys(ms)\n");
printf("PERF:stat, %u, %8.3f, %8.3f, %8.3f\n",
static_cast<unsigned int>(level), provision_time, license_request_time,
derive_keys_time);
@@ -1225,4 +1380,4 @@ TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) {
enc_context.data(), enc_context.size()));
}
} // namespace wvoec
} // namespace wvoec

View File

@@ -17,62 +17,84 @@
namespace wvoec {
// Tests using this class are only used for devices with a keybox. They are not
// run for devices with an OEM Certificate.
class OEMCryptoKeyboxTest : public OEMCryptoClientTest {
void SetUp() override {
OEMCryptoClientTest::SetUp();
OEMCryptoResult sts = OEMCrypto_IsKeyboxValid();
// If the production keybox is valid, use it for these tests. Most of the
// other tests will use a test keybox anyway, but it's nice to check the
// device ID for the real keybox if we can.
if (sts == OEMCrypto_SUCCESS) return;
printf("Production keybox is NOT valid. All tests use test keybox.\n");
ASSERT_EQ(
OEMCrypto_SUCCESS,
OEMCrypto_LoadTestKeybox(reinterpret_cast<const uint8_t*>(&kTestKeybox),
sizeof(kTestKeybox)));
}
};
// This class is for tests that have an OEM Certificate instead of a keybox.
class OEMCryptoProv30Test : public OEMCryptoClientTest {
void SetUp() override {
OEMCryptoClientTest::SetUp();
if (global_features.provisioning_method != OEMCrypto_OEMCertificate) {
GTEST_SKIP() << "Test for Prov 3.0 devices only.";
}
}
};
// This class is for tests that have boot certificate chain instead of a keybox.
class OEMCryptoProv40Test : public OEMCryptoClientTest {
void SetUp() override {
OEMCryptoClientTest::SetUp();
if (global_features.provisioning_method != OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for Prov 4.0 devices only.";
}
}
};
class OEMCryptoProv40CastTest : public OEMCryptoClientTest,
public testing::WithParamInterface<bool> {
void SetUp() override {
OEMCryptoClientTest::SetUp();
if (!global_features.cast_receiver) {
GTEST_SKIP() << "Test for cast devices only.";
}
if (global_features.provisioning_method != OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for Prov 4.0 devices only.";
}
}
};
//
// Certificate Root of Trust Tests
//
class OEMCryptoLoadsCertificate : public OEMCryptoSessionTestKeyboxTest {
// These tests are run by all L1 devices that load and use certificates. It is
// also run by a few L3 devices that use a baked in certificate, but cannot load
// a certificate.
class OEMCryptoUsesCertificate : public OEMCryptoSessionTests {
protected:
void SetUp() override {
OEMCryptoSessionTests::SetUp();
ASSERT_NO_FATAL_FAILURE(session_.open());
if (global_features.derive_key_method ==
DeviceFeatures::LOAD_TEST_RSA_KEY) {
ASSERT_NO_FATAL_FAILURE(session_.SetRsaPublicKeyFromPrivateKeyInfo(
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
} else {
InstallTestDrmKey(&session_);
}
}
void TearDown() override {
ASSERT_NO_FATAL_FAILURE(session_.close());
OEMCryptoSessionTests::TearDown();
}
Session session_;
};
/** These tests cover all systems that can load a DRM Certificate. That includes
* Provisioning 2, 3 and 4. */
class OEMCryptoLoadsCertificate : public OEMCryptoUsesCertificate {
protected:
void SetUp() override {
OEMCryptoUsesCertificate::SetUp();
if (!global_features.loads_certificate) {
GTEST_SKIP() << "Test for devices that load a DRM certificate only.";
}
}
/** Verify that the specified padding scheme does not work with the DRM
* key and the function OEMCrypto_GenerateRSASignature. */
void DisallowForbiddenPaddingDRMKey(RSA_Padding_Scheme scheme, size_t size) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
DisallowForbiddenPadding(s.session_id(), scheme, size);
}
/** Verify that the specified padding scheme does not work with whichever key
* is currently loaded into the specified session and the function
* OEMCrypto_GenerateRSASignature. */
void DisallowForbiddenPadding(OEMCrypto_SESSION session,
RSA_Padding_Scheme scheme, size_t size) {
OEMCryptoResult sts;
// Sign a Message
vector<uint8_t> message(size);
GetRandBytes(message.data(), message.size());
size_t signature_length = 256;
vector<uint8_t> signature(signature_length);
sts = OEMCrypto_GenerateRSASignature(session, message.data(),
message.size(), signature.data(),
&signature_length, scheme);
// Allow OEMCrypto to request a full buffer.
if (sts == OEMCrypto_ERROR_SHORT_BUFFER) {
ASSERT_NE(static_cast<size_t>(0), signature_length);
signature.assign(signature_length, 0);
sts = OEMCrypto_GenerateRSASignature(session, message.data(),
message.size(), signature.data(),
&signature_length, scheme);
}
EXPECT_NE(OEMCrypto_SUCCESS, sts)
<< "Signed with forbidden padding scheme=" << (int)scheme
<< ", size=" << (int)size;
const vector<uint8_t> zero(signature.size(), 0);
ASSERT_EQ(zero, signature); // signature should not be computed.
}
void TestPrepareProvisioningRequestForHugeBufferLengths(
const std::function<void(size_t, ProvisioningRoundTrip*)> f,
bool check_status) {
@@ -139,31 +161,63 @@ class OEMCryptoLoadsCertificate : public OEMCryptoSessionTestKeyboxTest {
}
};
// These tests are run by all L1 devices that load and use certificates. It is
// also run by a few L3 devices that use a baked in certificate, but cannot load
// a certificate.
class OEMCryptoUsesCertificate : public OEMCryptoLoadsCertificate {
// Tests using this class are only used for devices with a keybox. They are not
// run for devices with an OEM Certificate.
class OEMCryptoKeyboxTest : public OEMCryptoLoadsCertificate {
protected:
void SetUp() override {
OEMCryptoLoadsCertificate::SetUp();
ASSERT_NO_FATAL_FAILURE(session_.open());
if (global_features.derive_key_method ==
DeviceFeatures::LOAD_TEST_RSA_KEY) {
ASSERT_NO_FATAL_FAILURE(session_.SetRsaPublicKeyFromPrivateKeyInfo(
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
} else {
InstallTestDrmKey(&session_);
if (global_features.provisioning_method != OEMCrypto_Keybox) {
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
}
OEMCryptoResult sts = OEMCrypto_IsKeyboxValid();
// If the production keybox is valid, use it for these tests. Most of the
// other tests will use a test keybox anyway, but it's nice to check the
// device ID for the real keybox if we can.
if (sts == OEMCrypto_SUCCESS) return;
printf("Production keybox is NOT valid. All tests use test keybox.\n");
ASSERT_EQ(
OEMCrypto_SUCCESS,
OEMCrypto_LoadTestKeybox(reinterpret_cast<const uint8_t*>(&kTestKeybox),
sizeof(kTestKeybox)));
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid())
<< "After loading Test keybox, the keybox was still not valid.";
}
};
// This class is for tests that have an OEM Certificate instead of a keybox.
class OEMCryptoProv30Test : public OEMCryptoLoadsCertificate {
protected:
void SetUp() override {
OEMCryptoLoadsCertificate::SetUp();
if (global_features.provisioning_method != OEMCrypto_OEMCertificate) {
GTEST_SKIP() << "Test for Prov 3.0 devices only.";
}
}
};
void TearDown() override {
ASSERT_NO_FATAL_FAILURE(session_.close());
OEMCryptoLoadsCertificate::TearDown();
// This class is for tests that have boot certificate chain instead of a keybox.
class OEMCryptoProv40Test : public OEMCryptoLoadsCertificate {
protected:
void SetUp() override {
OEMCryptoLoadsCertificate::SetUp();
if (global_features.provisioning_method != OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for Prov 4.0 devices only.";
}
}
};
Session session_;
class OEMCryptoProv40CastTest : public OEMCryptoProv40Test,
public testing::WithParamInterface<bool> {
protected:
void SetUp() override {
OEMCryptoProv40Test::SetUp();
if (!global_features.cast_receiver) {
GTEST_SKIP() << "Test for cast devices only.";
}
}
};
} // namespace wvoec
#endif // CDM_OEMCRYPTO_PROVISIONING_TEST_
#endif // CDM_OEMCRYPTO_PROVISIONING_TEST_

View File

@@ -39,6 +39,8 @@ namespace wvoec {
/// @addtogroup security
/// @{
/** Test that OEMCrypto_FreeSecureBuffer fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoClientTest,
OEMCryptoMemoryAllocateSecureBufferForHugeBufferSize) {
Session s;
@@ -57,6 +59,8 @@ TEST_F(OEMCryptoClientTest,
s.close();
}
/** Test that OEMCrypto_WrapKeyboxOrOEMCert fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoClientTest,
OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeKeyboxLength) {
auto oemcrypto_function = [](size_t keybox_length) {
@@ -74,6 +78,8 @@ TEST_F(OEMCryptoClientTest,
kHugeInputBufferLength, kCheckStatus);
}
/** Test that OEMCrypto_WrapKeyboxOrOEMCert fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoClientTest,
OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeWrappedKeyboxLength) {
auto oemcrypto_function = [](size_t buffer_length) {
@@ -91,6 +97,8 @@ TEST_F(OEMCryptoClientTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that OEMCrypto_WrapKeyboxOrOEMCert fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoClientTest,
OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeTransportKey) {
auto oemcrypto_function = [](size_t transport_key_length) {
@@ -105,6 +113,8 @@ TEST_F(OEMCryptoClientTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_WrapKeyboxOrOEMCert fails gracefully on a huge buffer.
*/
TEST_F(
OEMCryptoClientTest,
OEMCryptoMemoryWrapKeyboxOrOEMCertForHugeKeyboxLengthStartingFromLength1) {
@@ -124,7 +134,8 @@ TEST_F(
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
// Test that set sandbox doesn't crash for a large sandbox id leangth.
/** Test that OEMCrypto_SetSandbox fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoClientTest, OEMCryptoMemorySetSandboxForHugeSandboxIdLength) {
auto oemcrypto_function = [](size_t buffer_length) {
vector<uint8_t> buffer(buffer_length);
@@ -133,6 +144,8 @@ TEST_F(OEMCryptoClientTest, OEMCryptoMemorySetSandboxForHugeSandboxIdLength) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that OEMCrypto_CopyBuffer fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoClientTest, OEMCryptoMemoryCopyBufferForHugeBufferLengths) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
@@ -163,6 +176,9 @@ TEST_F(OEMCryptoClientTest, OEMCryptoMemoryCopyBufferForHugeBufferLengths) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** @ingroup security
* Test that OEMCrypto_CopyBuffer fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoClientTest,
OEMCryptoMemoryCopyBufferDirectForHugeBufferLengths) {
Session s;
@@ -184,6 +200,9 @@ TEST_F(OEMCryptoClientTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** @ingroup security
* Test that OEMCrypto_CopyBuffer fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoClientTest, OEMCryptoMemoryCopyBufferForOutOfRangeOffset) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
@@ -245,6 +264,9 @@ TEST_F(OEMCryptoKeyboxTest,
}
#endif
/** @ingroup security
* Test that OEMCrypto_LoadTestKeybox fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryLoadTestKeyBoxForHugeKeyboxBuffer) {
auto f = [](size_t keybox_length) {
vector<uint8_t> keybox(keybox_length);
@@ -257,6 +279,9 @@ TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryLoadTestKeyBoxForHugeKeyboxBuffer) {
kCheckStatus);
}
/** @ingroup security
* Test that OEMCrypto_LoadTestKeybox fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoKeyboxTest,
OEMCryptoMemoryLoadTestKeyBoxForHugeKeyboxBufferStartingFromLength1) {
auto f = [](size_t keybox_length) {
@@ -268,6 +293,8 @@ TEST_F(OEMCryptoKeyboxTest,
TestHugeLengthDoesNotCrashAPI(f, !kCheckStatus);
}
/** Test that OEMCrypto_GetDeviceID fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryGetDeviceIdForHugeIdLength) {
auto oemcrypto_function = [](size_t input_length) {
size_t device_id_length = input_length;
@@ -277,6 +304,8 @@ TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryGetDeviceIdForHugeIdLength) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_GetKeyData fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryGetKeyIdForHugeIdLength) {
auto oemcrypto_function = [](size_t input_length) {
size_t key_data_length = input_length;
@@ -286,6 +315,8 @@ TEST_F(OEMCryptoKeyboxTest, OEMCryptoMemoryGetKeyIdForHugeIdLength) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that OEMCrypto_GenerateDerivedKeys fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoKeyboxTest,
OEMCryptoMemoryGenerateDerivedKeysForHugeMacContextLength) {
Session s;
@@ -304,6 +335,8 @@ TEST_F(OEMCryptoKeyboxTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_GenerateDerivedKeys fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoKeyboxTest,
OEMCryptoMemoryGenerateDerivedKeysForHugeEncContextLength) {
Session s;
@@ -322,6 +355,9 @@ TEST_F(OEMCryptoKeyboxTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_GetOEMPublicCertificate fails gracefully on a huge
* buffer.
*/
TEST_F(OEMCryptoProv30Test, OEMCryptoMemoryGetOEMPublicCertForHugeCertLength) {
if (wrapped_rsa_key_.size() == 0) {
// If we don't have a wrapped key yet, create one.
@@ -343,6 +379,9 @@ TEST_F(OEMCryptoProv30Test, OEMCryptoMemoryGetOEMPublicCertForHugeCertLength) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_CreateUsageTableHeader fails gracefully on a huge
* buffer.
*/
TEST_F(OEMCryptoSessionTests,
OEMCryptoMemoryCreateUsageTableHeaderForHugeHeaderBufferLength) {
auto oemcrypto_function = [](size_t buffer_length) {
@@ -354,6 +393,9 @@ TEST_F(OEMCryptoSessionTests,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_PrepAndSignRenewalRequest fails gracefully on a huge
* buffer.
*/
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryPrepareRenewalRequestForHugeBufferLength) {
RenewalRoundTrip renewal_messages(&license_messages_);
@@ -364,6 +406,9 @@ TEST_F(OEMCryptoMemoryLicenseTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_PrepAndSignRenewalRequest fails gracefully on a huge
* buffer.
*/
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryPrepareRenewalRequestForHugeSignatureLength) {
RenewalRoundTrip renewal_messages(&license_messages_);
@@ -374,6 +419,9 @@ TEST_F(OEMCryptoMemoryLicenseTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_PrepAndSignRenewalRequest fails gracefully on a huge
* buffer.
*/
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryPrepareRenewalRequestForHugeCoreMessageLength) {
RenewalRoundTrip renewal_messages(&license_messages_);
@@ -384,8 +432,9 @@ TEST_F(OEMCryptoMemoryLicenseTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
// This verifies that entitled content keys API does not crash for unreasonable
// input message buffer lengths.
/** Test that loading entitled content keys fails gracefully on a huge
* buffer.
*/
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeBufferLength) {
auto oemcrypto_function = [&](size_t buffer_length) {
@@ -402,6 +451,8 @@ TEST_F(OEMCryptoMemoryLicenseTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that OEMCrypto_LoadLicense fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoSessionTests,
OEMCryptoMemoryLoadLicenseForHugeSignatureLength) {
auto oemcrypto_function = [&](size_t signature_size) {
@@ -424,6 +475,8 @@ TEST_F(OEMCryptoSessionTests,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that OEMCrypto_LoadRenewal fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoSessionTests, OEMCryptoMemoryLoadRenewalForHugeResponseLength) {
auto oemcrypto_function = [&](size_t message_size) {
Session s;
@@ -443,6 +496,8 @@ TEST_F(OEMCryptoSessionTests, OEMCryptoMemoryLoadRenewalForHugeResponseLength) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_LoadRenewal fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoSessionTests,
OEMCryptoMemoryLoadRenewalForHugeSignatureLength) {
auto oemcrypto_function = [&](size_t signature_size) {
@@ -467,6 +522,8 @@ TEST_F(OEMCryptoSessionTests,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that OEMCrypto_QueryKeyControl fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoSessionTests,
OEMCryptoMemoryLoadRenewalForHugeCoreMessageLength) {
auto oemcrypto_function = [&](size_t core_message_size) {
@@ -487,7 +544,8 @@ TEST_F(OEMCryptoSessionTests,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
// Test OEMCrypto_QueryKeyControl doesn't crash for huge key_id_length.
/** Test that OEMCrypto_QueryKeyControl fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoSessionTests,
OEMCryptoMemoryQueryKeyControlForHugeKeyIdLength) {
Session session;
@@ -512,8 +570,9 @@ TEST_F(OEMCryptoSessionTests,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
// Test OEMCrypto_QueryKeyControl doesn't crash for huge key_control_block
// length.
/** Test OEMCrypto_QueryKeyControl doesn't crash for huge key_control_block
* length.
*/
TEST_F(OEMCryptoSessionTests,
OEMCryptoMemoryQueryKeyControlForHugeKeyControlBlockLength) {
Session session;
@@ -534,8 +593,9 @@ TEST_F(OEMCryptoSessionTests,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
// This test verifies that OEMCrypto_SetDecryptHash doesn't crash for a very
// large hash buffer.
/** This test verifies that OEMCrypto_SetDecryptHash doesn't crash for a very
large hash buffer.
*/
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryDecryptHashForHugeHashBuffer) {
uint32_t session_id = session_.session_id();
@@ -548,6 +608,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
TestHugeLengthDoesNotCrashAPI(f, kCheckStatus);
}
/** Test Decrypt fails gracefully for huge input. */
TEST_P(OEMCryptoSessionTestsDecryptTests,
OEMCryptoMemoryDecryptCENCForHugeNumberOfSubSamples) {
auto oemcrypto_function = [&](size_t number_of_subsamples) {
@@ -575,6 +636,7 @@ TEST_P(OEMCryptoSessionTestsDecryptTests,
MakeBuffers();
}
/** Test Decrypt fails gracefully for huge input. */
TEST_P(OEMCryptoSessionTestsDecryptTests,
OEMCryptoMemoryDecryptCENCForHugeNumberOfSamples) {
auto oemcrypto_function = [&](size_t number_of_samples) {
@@ -604,8 +666,16 @@ TEST_P(OEMCryptoSessionTestsDecryptTests,
MakeBuffers();
}
/** Test that OEMCrypto_LoadProvisioning fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeSignatureLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
auto oemcrypto_function = [&](size_t signature_size) {
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
@@ -636,8 +706,16 @@ TEST_F(OEMCryptoLoadsCertificate,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that OEMCrypto_LoadProvisioning fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeWrappedRsaKeyLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
auto oemcrypto_function = [&](size_t buffer_length) {
Session s;
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
@@ -661,8 +739,16 @@ TEST_F(OEMCryptoLoadsCertificate,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_LoadDRMPrivateKey fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadDrmPrivateKeyForHugeWrappedRsaKeyLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
auto oemcrypto_function = [&](size_t wrapped_rsa_key_length) {
Session s;
@@ -682,9 +768,17 @@ TEST_F(OEMCryptoLoadsCertificate,
kHugeInputBufferLength, !kCheckStatus);
}
/** Test that OEMCrypto_LoadDRMPrivateKey fails gracefully on a huge buffer.
*/
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadDrmPrivateKeyForHugeWrappedRsaKeyLengthStartingFromLength1) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
auto oemcrypto_function = [&](size_t wrapped_rsa_key_length) {
Session s;
@@ -702,6 +796,8 @@ TEST_F(
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that OEMCrypto_LoadDRMPrivateKey fails gracefully on a huge buffer.
*/
TEST_F(OEMCryptoUsesCertificate,
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeMacContext) {
vector<uint8_t> session_key;
@@ -722,6 +818,8 @@ TEST_F(OEMCryptoUsesCertificate,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_DeriveKeysFromSessionKey fails gracefully on a huge
* buffer. */
TEST_F(OEMCryptoUsesCertificate,
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncContext) {
vector<uint8_t> session_key;
@@ -742,6 +840,8 @@ TEST_F(OEMCryptoUsesCertificate,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that OEMCrypto_DeriveKeysFromSessionKey fails gracefully on a huge
* buffer. */
TEST_F(OEMCryptoUsesCertificate,
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncSessionKey) {
vector<uint8_t> session_key;
@@ -763,10 +863,18 @@ TEST_F(OEMCryptoUsesCertificate,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that OEMCrypto_GenerateRSASignature fails gracefully on a huge
* buffer. */
TEST_F(OEMCryptoLoadsCertificateAlternates,
OEMCryptoMemoryGenerateRSASignatureForHugeBuffer) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
OEMCryptoResult sts;
LoadWithAllowedSchemes(kSign_PKCS1_Block1, false);
LoadCastCertificateKey(false);
// If the device is a cast receiver, then this scheme is required.
if (global_features.cast_receiver) {
ASSERT_TRUE(key_loaded_);
@@ -782,6 +890,7 @@ TEST_F(OEMCryptoLoadsCertificateAlternates,
sts = OEMCrypto_GenerateRSASignature(s.session_id(), message_buffer.data(),
message_buffer.size(), nullptr,
&signature_length, kSign_PKCS1_Block1);
if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) return;
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
ASSERT_NE(static_cast<size_t>(0), signature_length);
vector<uint8_t> signature(signature_length);
@@ -797,9 +906,17 @@ TEST_F(OEMCryptoLoadsCertificateAlternates,
}
}
/** Test that OEMCrypto_GenerateRSASignature fails gracefully on a huge
* buffer. */
TEST_F(OEMCryptoLoadsCertificateAlternates,
OEMCryptoMemoryGenerateRSASignatureForHugeSignatureLength) {
LoadWithAllowedSchemes(kSign_PKCS1_Block1, false);
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
LoadCastCertificateKey(false);
// If the device is a cast receiver, then this scheme is required.
if (global_features.cast_receiver) {
ASSERT_TRUE(key_loaded_);
@@ -823,6 +940,7 @@ TEST_F(OEMCryptoLoadsCertificateAlternates,
}
}
/** Test that GetKeyHandle fails gracefully on a huge buffer. */
TEST_P(OEMCryptoGenericCryptoTest, OEMCryptoMemorySelectKeyForHugeKeyIdLength) {
EncryptAndLoadKeys();
OEMCrypto_SESSION session_id = session_.session_id();
@@ -835,6 +953,7 @@ TEST_P(OEMCryptoGenericCryptoTest, OEMCryptoMemorySelectKeyForHugeKeyIdLength) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoGenericCryptoTest,
OEMCryptoMemoryGenericKeyEncryptForHugeBuffer) {
EncryptAndLoadKeys();
@@ -859,6 +978,7 @@ TEST_P(OEMCryptoGenericCryptoTest,
kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoGenericCryptoTest,
OEMCryptoMemoryGenericKeyDecryptForHugeBuffer) {
EncryptAndLoadKeys();
@@ -884,6 +1004,7 @@ TEST_P(OEMCryptoGenericCryptoTest,
kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoGenericCryptoTest, OEMCryptoMemoryGenericKeySignForHugeBuffer) {
EncryptAndLoadKeys();
unsigned int key_index = 2;
@@ -908,6 +1029,7 @@ TEST_P(OEMCryptoGenericCryptoTest, OEMCryptoMemoryGenericKeySignForHugeBuffer) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoGenericCryptoTest,
OEMCryptoMemoryGenericKeySignForHugeSignatureLength) {
EncryptAndLoadKeys();
@@ -934,6 +1056,7 @@ TEST_P(OEMCryptoGenericCryptoTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoGenericCryptoTest,
OEMCryptoMemoryGenericKeyVerifyForHugeBuffer) {
EncryptAndLoadKeys();
@@ -956,6 +1079,7 @@ TEST_P(OEMCryptoGenericCryptoTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoGenericCryptoTest,
OEMCryptoMemoryGenericKeyVerifyForHugeSignatureLength) {
EncryptAndLoadKeys();
@@ -982,6 +1106,7 @@ TEST_P(OEMCryptoGenericCryptoTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoUsageTableTest,
OEMCryptoMemoryUpdateUsageEntryForHugeHeaderBuffer) {
if (!wvoec::global_features.usage_table) {
@@ -1012,6 +1137,7 @@ TEST_P(OEMCryptoUsageTableTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoUsageTableTest,
OEMCryptoMemoryUpdateUsageEntryForHugeUsageEntryBuffer) {
if (!wvoec::global_features.usage_table) {
@@ -1039,6 +1165,7 @@ TEST_P(OEMCryptoUsageTableTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoUsageTableTest,
OEMCryptoMemoryDeactivateUsageEntryForHugePstBuffer) {
if (!wvoec::global_features.usage_table) {
@@ -1061,6 +1188,7 @@ TEST_P(OEMCryptoUsageTableTest,
kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoUsageTableTest,
OEMCryptoMemoryLoadUsageTableHeaderForHugeHeader) {
if (!wvoec::global_features.usage_table) {
@@ -1087,6 +1215,7 @@ TEST_P(OEMCryptoUsageTableTest,
kHugeInputBufferLength, !kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(
OEMCryptoUsageTableTest,
OEMCryptoMemoryLoadUsageTableHeaderForHugeHeaderStartingHeaderLengthFrom1) {
@@ -1107,6 +1236,7 @@ TEST_P(
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoUsageTableTest,
OEMCryptoMemoryLoadUsageEntryForHugeUsageEntryBuffer) {
if (!wvoec::global_features.usage_table) {
@@ -1138,6 +1268,7 @@ TEST_P(OEMCryptoUsageTableTest,
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoUsageTableTest, OEMCryptoMemoryReportUsageForHugeReportBuffer) {
if (!wvoec::global_features.usage_table) {
GTEST_SKIP() << "Usage tables are not supported.";
@@ -1167,6 +1298,7 @@ TEST_P(OEMCryptoUsageTableTest, OEMCryptoMemoryReportUsageForHugeReportBuffer) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoUsageTableTest, OEMCryptoMemoryReportUsageForHugePstBuffer) {
if (!wvoec::global_features.usage_table) {
GTEST_SKIP() << "Usage tables are not supported.";
@@ -1189,6 +1321,7 @@ TEST_P(OEMCryptoUsageTableTest, OEMCryptoMemoryReportUsageForHugePstBuffer) {
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
/** Test that API fails gracefully on a huge buffer. */
TEST_P(OEMCryptoUsageTableTest,
OEMCryptoMemoryShrinkUsageTableHeaderForHugeHeaderBufferLength) {
if (!wvoec::global_features.usage_table) {

View File

@@ -43,6 +43,11 @@
*
* @defgroup security Security Tests
* Buffer overflow tests, off-by-one tests, and other security tests.
*
* The way the huge buffer tests work is to create a large buffer and then call
* the API. The test then loops and doubles the buffer until the API returns an
* error. An error is considered a passing test. We expect OEMCrypto to fail
* gracefully on a huge buffer rather than crashing.
*/
#include <ctype.h>
@@ -443,6 +448,9 @@ TEST_P(OEMCryptoEntitlementLicenseTest,
*/
TEST_P(OEMCryptoEntitlementLicenseTest,
LoadEntitlementKeysOemcryptoSessionAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
@@ -485,6 +493,7 @@ INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoEntitlementLicenseTest,
/// @addtogroup security
/// @{
/** Test that LoadEntitledContentKeys fails gracefully on huge buffer. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyIdLength) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -495,6 +504,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
!kCheckStatus);
}
/** Test that LoadEntitledContentKeys fails gracefully on huge buffer. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyIdOffset) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -505,6 +515,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
!kCheckStatus);
}
/** Test that LoadEntitledContentKeys fails gracefully on huge buffer. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyIdLength) {
@@ -515,6 +526,7 @@ TEST_F(
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyIdOffset) {
@@ -525,6 +537,7 @@ TEST_F(
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test that LoadEntitledContentKeys fails gracefully on huge substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringEntitlementKeyIdLength) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -535,6 +548,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringEntitlementKeyIdOffset) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -545,6 +559,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringEntitlementKeyIdLength) {
@@ -555,6 +570,7 @@ TEST_F(
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringEntitlementKeyIdOffset) {
@@ -565,6 +581,7 @@ TEST_F(
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyDataIvLength) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -575,6 +592,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyDataIvOffset) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -585,6 +603,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyDataIvLength) {
@@ -595,6 +614,7 @@ TEST_F(
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyDataIvOffset) {
@@ -605,6 +625,7 @@ TEST_F(
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyDataLength) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -615,6 +636,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeSubstringContentKeyDataOffset) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -625,6 +647,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyDataLength) {
@@ -635,6 +658,7 @@ TEST_F(
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(
OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForOutOfRangeSubstringContentKeyDataOffset) {
@@ -645,6 +669,7 @@ TEST_F(
ASSERT_NE(OEMCrypto_SUCCESS, entitled_message_.LoadKeys());
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeEntitlementKeyIdLength) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -655,6 +680,7 @@ TEST_F(OEMCryptoMemoryLicenseTest,
!kCheckStatus);
}
/** Test LoadEntitledContentKeys rejects out of range substring. */
TEST_F(OEMCryptoMemoryLicenseTest,
OEMCryptoMemoryLoadEntitledKeysForHugeContentKeyIdLength) {
TestLoadEntitledKeysForHugeBufferLengths(
@@ -724,6 +750,9 @@ TEST_P(OEMCryptoLicenseTest, SelectKeyEntitledKeyNotThereAPI17) {
* id.
*/
TEST_P(OEMCryptoLicenseTest, SelectKeyEntitlementKeyAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
@@ -799,6 +828,9 @@ TEST_P(OEMCryptoLicenseTest,
// This verifies that multiple entitled key sessions can be created. They can
// load and select keys independently.
TEST_P(OEMCryptoLicenseTest, EntitledKeySessionMultipleKeySessionsAPI17) {
if (!global_features.supports_cas) {
GTEST_SKIP() << "OEMCrypto does not support CAS";
}
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
@@ -826,9 +858,7 @@ TEST_P(OEMCryptoLicenseTest, EntitledKeySessionMultipleKeySessionsAPI17) {
session_.session_id(), &key_session_id_2);
// For DRM, but not for CAS, we allow there to be only a single entitled
// session.
if (!global_features.supports_cas &&
(key_session_id_2 == key_session_id_1 ||
status == OEMCrypto_ERROR_TOO_MANY_SESSIONS)) {
if (status == OEMCrypto_ERROR_TOO_MANY_SESSIONS) {
GTEST_SKIP()
<< "Skipping test because multiple entitled sessions not supported.";
}
@@ -1018,6 +1048,7 @@ TEST_P(OEMCryptoEntitlementLicenseTest, ReassociateEntitledKeySessionAPI17) {
/// @addtogroup security
/// @{
/** Test that LoadLicense fails gracefully on huge buffer. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyIdLength) {
TestLoadLicenseForHugeBufferLengths(
@@ -1028,6 +1059,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyIdOffset) {
TestLoadLicenseForHugeBufferLengths(
@@ -1037,6 +1069,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyIdLength) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
@@ -1046,6 +1079,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyIdOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
@@ -1055,6 +1089,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyDataIvLength) {
TestLoadLicenseForHugeBufferLengths(
@@ -1065,6 +1100,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyDataIvOffset) {
TestLoadLicenseForHugeBufferLengths(
@@ -1075,6 +1111,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyDataIvLength) {
@@ -1086,6 +1123,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyDataIvOffset) {
@@ -1097,6 +1135,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyDataLength) {
TestLoadLicenseForHugeBufferLengths(
@@ -1107,6 +1146,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyDataOffset) {
TestLoadLicenseForHugeBufferLengths(
@@ -1116,6 +1156,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyDataLength) {
@@ -1127,6 +1168,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyDataOffset) {
@@ -1138,6 +1180,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyControlIvLength) {
@@ -1149,6 +1192,7 @@ TEST_P(
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyControlIvOffset) {
@@ -1160,6 +1204,7 @@ TEST_P(
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlIvLengthAPI16) {
@@ -1172,6 +1217,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlIvOffset) {
@@ -1184,6 +1230,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyControlLength) {
TestLoadLicenseForHugeBufferLengths(
@@ -1194,6 +1241,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringKeyControlOffset) {
TestLoadLicenseForHugeBufferLengths(
@@ -1204,6 +1252,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlLengthAPI16) {
@@ -1215,6 +1264,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlOffset) {
@@ -1226,6 +1276,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringEncMacKeyIvLength) {
TestLoadLicenseForHugeBufferLengths(
@@ -1235,6 +1286,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringEncMacKeyIvOffset) {
TestLoadLicenseForHugeBufferLengths(
@@ -1244,6 +1296,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringEncMacKeyIvLength) {
@@ -1256,6 +1309,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringEncMacKeyIvOffset) {
@@ -1268,6 +1322,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringEncMacKeyLength) {
TestLoadLicenseForHugeBufferLengths(
@@ -1277,6 +1332,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringEncMacKeyOffset) {
TestLoadLicenseForHugeBufferLengths(
@@ -1286,6 +1342,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringEncMacKeyLength) {
@@ -1296,6 +1353,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringEncMacKeyOffset) {
@@ -1306,6 +1364,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringPstLength) {
TestLoadLicenseForHugeBufferLengths(
@@ -1315,6 +1374,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringPstOffset) {
TestLoadLicenseForHugeBufferLengths(
@@ -1324,6 +1384,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringPstLength) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
@@ -1333,6 +1394,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringPstOffset) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
@@ -1343,6 +1405,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringSrmRestrictionDataLength) {
@@ -1353,6 +1416,7 @@ TEST_P(
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageSubstringSrmRestrictionDataOffset) {
@@ -1363,6 +1427,7 @@ TEST_P(
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringSrmRestrictionDataLength) {
@@ -1375,6 +1440,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on out of range substring. */
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringSrmRestrictionDataOffset) {
@@ -1387,6 +1453,7 @@ TEST_P(
});
}
/** Test that LoadLicense fails gracefully on huge buffer. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeResponseLength) {
TestLoadLicenseForHugeBufferLengths(
@@ -1396,6 +1463,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
!kCheckStatus, !kUpdateCoreMessageSubstringValues);
}
/** Test that LoadLicense fails gracefully on huge buffer. */
TEST_P(OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForHugeCoreMessageLength) {
TestLoadLicenseForHugeBufferLengths(
@@ -1418,8 +1486,15 @@ INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoLicenseOverflowTest,
/// @addtogroup security
/// @{
/** Test that LoadProvisioning fails gracefully on huge buffer. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeResponseLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_message_size(message_size);
@@ -1427,8 +1502,15 @@ TEST_F(OEMCryptoLoadsCertificate,
!kCheckStatus, !kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on huge buffer. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_core_message_size(message_size);
@@ -1436,8 +1518,15 @@ TEST_F(OEMCryptoLoadsCertificate,
!kCheckStatus, !kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on huge buffer. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncPrivateKeyLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t length, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().enc_private_key.length = length;
@@ -1445,8 +1534,15 @@ TEST_F(OEMCryptoLoadsCertificate,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on huge buffer. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncPrivateKeyOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t offset, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().enc_private_key.offset = offset;
@@ -1454,9 +1550,16 @@ TEST_F(OEMCryptoLoadsCertificate,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
@@ -1467,9 +1570,16 @@ TEST_F(
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
@@ -1480,8 +1590,15 @@ TEST_F(
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncPrivateKeyIvLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t length, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().enc_private_key_iv.length =
@@ -1490,8 +1607,15 @@ TEST_F(OEMCryptoLoadsCertificate,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncPrivateKeyIvOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t offset, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().enc_private_key_iv.offset =
@@ -1500,9 +1624,16 @@ TEST_F(OEMCryptoLoadsCertificate,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyIvLengthAPI16) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
@@ -1513,9 +1644,16 @@ TEST_F(
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyIvOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
@@ -1526,8 +1664,15 @@ TEST_F(
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncMessageKeyLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t length, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().encrypted_message_key.length =
@@ -1536,8 +1681,15 @@ TEST_F(OEMCryptoLoadsCertificate,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForHugeCoreMessageEncMessageKeyOffset) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestLoadProvisioningForHugeBufferLengths(
[](size_t offset, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->core_response().encrypted_message_key.offset =
@@ -1546,9 +1698,16 @@ TEST_F(OEMCryptoLoadsCertificate,
!kCheckStatus, kUpdateCoreMessageSubstringValues);
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyLengthProv30) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
if (global_features.provisioning_method != OEMCrypto_OEMCertificate) {
GTEST_SKIP() << "Test for Prov 3.0 devices only.";
}
@@ -1562,9 +1721,16 @@ TEST_F(
});
}
/** Test that LoadProvisioning fails gracefully on out of range substring. */
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyOffsetProv30) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
if (global_features.provisioning_method != OEMCrypto_OEMCertificate) {
GTEST_SKIP() << "Test for Prov 3.0 devices only.";
}
@@ -1583,8 +1749,17 @@ TEST_F(
/// @addtogroup security
/// @{
/** Test that OEMCrypto_PrepAndSignProvisioningRequest fails gracefully on a
* huge buffer.
*/
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryPrepareProvisioningRequestForHugeRequestMessageLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestPrepareProvisioningRequestForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_message_size(message_size);
@@ -1592,8 +1767,17 @@ TEST_F(OEMCryptoLoadsCertificate,
kCheckStatus);
}
/** Test that OEMCrypto_PrepAndSignProvisioningRequest fails gracefully on a
* huge buffer.
*/
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryPrepareProvisioningRequestForHugeSignatureLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestPrepareProvisioningRequestForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_request_signature_size(message_size);
@@ -1601,8 +1785,17 @@ TEST_F(OEMCryptoLoadsCertificate,
!kCheckStatus);
}
/** Test that OEMCrypto_PrepAndSignProvisioningRequest fails gracefully on a
* huge buffer.
*/
TEST_F(OEMCryptoLoadsCertificate,
OEMCryptoMemoryPrepareProvisioningRequestForHugeCoreMessageLength) {
// TODO(b/197141970): Need to revisit OEMCryptoLoadsCert* tests for
// provisioning 4. Disabled here temporarily.
if (!global_features.loads_certificate ||
global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
TestPrepareProvisioningRequestForHugeBufferLengths(
[](size_t message_size, ProvisioningRoundTrip* provisioning_messages) {
provisioning_messages->set_core_message_size(message_size);
@@ -1616,4 +1809,90 @@ TEST_F(OEMCryptoLoadsCertificate,
/// @{
/// @}
#ifdef CAS_TEST
# include "tuner_hal.h"
class OEMCryptoCasDemoTest : public OEMCryptoEntitlementLicenseTest {};
TEST_P(OEMCryptoCasDemoTest, BasicFlow) {
// License contains entitlement keys, function reused from
// OEMCryptoEntitlementLicenseTest
LoadEntitlementLicense();
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
EntitledMessage entitled_message(&license_messages_);
// Randomly generate entitled content keys
entitled_message.FillKeyArray();
if (session_.session_id() == key_session_id) {
GTEST_SKIP()
<< "Skipping test because entitled and entitlement sessions are both "
<< key_session_id << ".";
}
entitled_message.SetEntitledKeySession(key_session_id);
// Encrypt and load 0th key (even key) into OEMCrypto
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadCasKeys(
/*load_even=*/true, /*load_odd=*/false, OEMCrypto_SUCCESS));
//
// Perform DecryptCTR() but for CAS
//
vector<uint8_t> unencrypted_data(256, 0);
vector<uint8_t> encrypted_data(256, 0);
vector<uint8_t> output_buffer(256, 0);
unencrypted_data.resize(encrypted_data.size());
output_buffer.resize(encrypted_data.size());
OEMCrypto_SampleDescription sample_description;
OEMCrypto_SubSampleDescription subsample_description;
GenerateSimpleSampleDescription(encrypted_data, output_buffer,
&sample_description, &subsample_description);
// Use 0th entitled content key and IV to encrypt test data
EncryptCTR(unencrypted_data,
entitled_message.entitled_key_data()->content_key_data,
entitled_message.entitled_key_data()->content_iv, &encrypted_data);
// Assume 0,0 pattern for CTR example
OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0};
// Demo only -- copy IV into sample description so we can use
// WTPI_DecryptSample() in the Tuner decrypt impl. A real implementation would
// use the IV from the entitled content key, but the demo relies on the
// existing decrypt which uses SampleDescription IV.
memcpy(sample_description.iv,
entitled_message.entitled_key_data()->content_iv, 16);
// Get key token to send to Tuner for decrypt
std::vector<uint8_t> key_token;
size_t key_token_length = key_token.size();
OEMCryptoResult res = OEMCrypto_GetOEMKeyToken(
key_session_id, key_token.data(), &key_token_length);
if (res == OEMCrypto_ERROR_SHORT_BUFFER) {
key_token.resize(key_token_length);
res = OEMCrypto_GetOEMKeyToken(key_session_id, key_token.data(),
&key_token_length);
}
ASSERT_EQ(OEMCrypto_SUCCESS, res);
// Decrypt the data
ASSERT_EQ(TUNER_HAL_SUCCESS,
TunerHal_Decrypt(key_token.data(), key_token_length,
TunerHal_KeyParityType_EvenKey,
&sample_description, // an array of samples.
1, // the number of samples.
&pattern));
ASSERT_EQ(unencrypted_data, output_buffer);
}
INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoCasDemoTest,
Range<uint32_t>(kCoreMessagesAPI, kCurrentAPI + 1));
#endif
} // namespace wvoec

View File

@@ -27,6 +27,9 @@ class OEMCryptoAndroidLMPTest : public ::testing::Test {
void SetUp() override {
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
if (OEMCrypto_GetProvisioningMethod() == OEMCrypto_BootCertificateChain) {
GTEST_SKIP() << "Test for non Prov 4.0 devices only.";
}
OEMCrypto_SetMaxAPIVersion(kCurrentAPI);
OEMCrypto_EnterTestMode();
}
@@ -36,6 +39,10 @@ class OEMCryptoAndroidLMPTest : public ::testing::Test {
// Android devices must have a keybox, or use provisioning 3.0.
TEST_F(OEMCryptoAndroidLMPTest, GetKeyDataImplemented) {
if (global_features.provisioning_method != OEMCrypto_Keybox &&
global_features.provisioning_method != OEMCrypto_OEMCertificate) {
GTEST_SKIP() << "Test for Prov 2.0 and 3.0 devices only.";
}
uint8_t key_data[256];
size_t key_data_len = sizeof(key_data);
if (OEMCrypto_Keybox == OEMCrypto_GetProvisioningMethod()) {
@@ -59,6 +66,9 @@ TEST_F(OEMCryptoAndroidLMPTest, MinVersionNumber9) {
}
TEST_F(OEMCryptoAndroidLMPTest, ValidKeyboxTest) {
if (global_features.provisioning_method != OEMCrypto_Keybox) {
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
}
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid());
}
@@ -112,6 +122,9 @@ TEST_F(OEMCryptoAndroidMNCTest, MinVersionNumber10) {
// Android devices using Provisioning 2.0 must be able to load a test keybox.
// If they are not using Provisioning 2.0, then they must use Provisioning 3.0.
TEST_F(OEMCryptoAndroidMNCTest, LoadsTestKeyboxImplemented) {
if (global_features.provisioning_method != OEMCrypto_Keybox) {
GTEST_SKIP() << "Test for Prov 2.0 devices only.";
}
if (OEMCrypto_Keybox == OEMCrypto_GetProvisioningMethod()) {
ASSERT_EQ(
OEMCrypto_SUCCESS,

View File

@@ -175,9 +175,15 @@ TEST_F(OEMCryptoSessionTests, MasterGeneration_IncrementCounterAPI18) {
ASSERT_TRUE(prov_count2 == prov_count1);
ASSERT_TRUE(lic_count2 > lic_count1);
ASSERT_TRUE(decrypt_count2 > decrypt_count1);
ASSERT_TRUE(master_generation_number2 > master_generation_number1);
// Log if decrypt counter hasn't gone up. Not a hard requirement, so don't
// assert for it.
if (decrypt_count2 <= decrypt_count1) {
LOGE("Decrypt count did not increase.");
}
}
TEST_P(OEMCryptoUsageTableTest,
OEMCryptoMemoryLoadUsageEntryForHugeInvalidUsageEntryNumber) {
LicenseWithUsageEntry entry;
@@ -440,6 +446,9 @@ TEST_P(OEMCryptoUsageTableTest, LoadEntryInMultipleSessions) {
// Test generic encrypt when the license uses a PST.
TEST_P(OEMCryptoUsageTableTest, GenericCryptoEncrypt) {
if (!wvoec::global_features.generic_crypto) {
GTEST_SKIP() << "Test for devices with generic crypto API only";
}
LicenseWithUsageEntry entry;
entry.license_messages().set_api_version(license_api_version_);
entry.set_generic_crypto(true);
@@ -479,6 +488,9 @@ TEST_P(OEMCryptoUsageTableTest, GenericCryptoEncrypt) {
// Test generic decrypt when the license uses a PST.
TEST_P(OEMCryptoUsageTableTest, GenericCryptoDecrypt) {
if (!wvoec::global_features.generic_crypto) {
GTEST_SKIP() << "Test for devices with generic crypto API only";
}
LicenseWithUsageEntry entry;
entry.license_messages().set_api_version(license_api_version_);
entry.set_generic_crypto(true);
@@ -516,6 +528,9 @@ TEST_P(OEMCryptoUsageTableTest, GenericCryptoDecrypt) {
// Test generic sign when the license uses a PST.
TEST_P(OEMCryptoUsageTableTest, GenericCryptoSign) {
if (!wvoec::global_features.generic_crypto) {
GTEST_SKIP() << "Test for devices with generic crypto API only";
}
LicenseWithUsageEntry entry;
entry.license_messages().set_api_version(license_api_version_);
entry.set_generic_crypto(true);
@@ -565,6 +580,9 @@ TEST_P(OEMCryptoUsageTableTest, GenericCryptoSign) {
// Test generic verify when the license uses a PST.
TEST_P(OEMCryptoUsageTableTest, GenericCryptoVerify) {
if (!wvoec::global_features.generic_crypto) {
GTEST_SKIP() << "Test for devices with generic crypto API only";
}
LicenseWithUsageEntry entry;
entry.license_messages().set_api_version(license_api_version_);
entry.set_generic_crypto(true);
@@ -983,6 +1001,39 @@ TEST_P(OEMCryptoUsageTableDefragTest, MoveUsageEntries) {
FailReloadLicense(&entries[3], OEMCrypto_ERROR_UNKNOWN_FAILURE));
}
TEST_P(OEMCryptoUsageTableDefragTest, MakeAndMoveEntry) {
// 1. Make an entry then close.
LicenseWithUsageEntry entry;
ASSERT_NO_FATAL_FAILURE(entry.set_pst("pst 0"));
ASSERT_NO_FATAL_FAILURE(entry.MakeOfflineAndClose(this));
ASSERT_NO_FATAL_FAILURE(entry.OpenAndReload(this));
ASSERT_NO_FATAL_FAILURE(entry.session().close());
// 2. Make an entry then immediately move it into the previous slot.
// Not using helper functions because they shoehorn the session state into
// a limited set of possibilities. We want to create the specific case of
// immediately moving a newly created entry.
// Like LicenseWithUsageEntry::MakeAndLoad() but stop after creating the new
// usage entry.
Session session;
ASSERT_NO_FATAL_FAILURE(session.open());
ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(&session));
LicenseRoundTrip license_messages_(&session);
license_messages_.set_control(wvoec::kControlNonceOrEntry);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
OEMCryptoResult result;
ASSERT_NO_FATAL_FAILURE(session.CreateNewUsageEntry(&result));
// Not the same as Session::MoveUsageEntry, which opens and closes a session
// around the move operation. We just want to call MoveEntry on the current
// state.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_MoveEntry(session.session_id(), 0));
ASSERT_NO_FATAL_FAILURE(session.close());
}
// A usage table entry cannot be moved into an entry where an open session is
// currently using the entry.
TEST_P(OEMCryptoUsageTableDefragTest, MoveUsageEntriesToOpenSession) {
@@ -1700,4 +1751,4 @@ INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoUsageTableDefragTest,
INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoUsageTableTestWallClock,
Values<uint32_t>(kCurrentAPI));
} // namespace wvoec
} // namespace wvoec

View File

@@ -28,6 +28,9 @@ class OEMCryptoGenericCryptoTest : public OEMCryptoRefreshTest {
void SetUp() override {
OEMCryptoRefreshTest::SetUp();
if (!wvoec::global_features.generic_crypto) {
GTEST_SKIP() << "Test for devices with generic crypto API only";
}
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(
license_messages_.CreateResponseWithGenericCryptoKeys());