diff --git a/CHANGELOG.md b/CHANGELOG.md index 77c1fd1..5a9b3c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,29 @@ [TOC] +## [Version 19.6][v19.6] + +### API + +- Added new L3 API functions `OEMCrypto_LoadLicenseData()` and +`OEMCrypto_SaveLicenseData()`. + +### Tests + +- Updated `OEMCryptoClientTest.CheckBuildInformation_OutputLengthAPI17` to + accept a returned SHORT_BUFFER size that is larger than the actual required + size. +- Updated `OEMCryptoClientTest.CheckJsonBuildInformationAPI18` to treat the + JSON fields in the `ree` block as optional. + +### OPK + +- OPK_SharedBuffer_Reset optimized to zero out used memory only. +- OPK_BumpAllocator_Reset optimized to zero out used memory only. +- OPKI_ObjectTable mutable struct members separated from immutable members. +- Update reference BCC implementation to set leaf node profile name to + "widevine." + ## [Version 19.5][v19.5] This release adds new OEMCrypto APIs to support CAS PVR. It also includes test diff --git a/linux/src/log.cpp b/linux/src/log.cpp index 5b0a9e9..5faa65d 100644 --- a/linux/src/log.cpp +++ b/linux/src/log.cpp @@ -33,8 +33,8 @@ void InitLogging() { void Log(const char* file, const char* function, int line, LogPriority level, const char* fmt, ...) { const char* severities[] = {"ERROR", "WARN", "INFO", "DEBUG", "VERBOSE"}; - if (level < 0 || level >= static_cast(sizeof(severities) / - sizeof(severities[0]))) { + if (level < 0 || static_cast(level) >= + sizeof(severities) / sizeof(severities[0])) { fprintf(kOutputFile, "[FATAL:%s(%d):%s] Invalid log priority level: %d\n", file, line, function, level); return; diff --git a/oem_certificate_generator/oem_certificate_test_helper.py b/oem_certificate_generator/oem_certificate_test_helper.py deleted file mode 100644 index 75de4ae..0000000 --- a/oem_certificate_generator/oem_certificate_test_helper.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/python3 -# Copyright 2017 Google LLC. All Rights Reserved. - -"""Common test utility functions for OEM certificate generation.""" - -import datetime -import io - -from cryptography import x509 -from cryptography.hazmat import backends -from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives.asymmetric import rsa -from cryptography.x509 import oid - -import oem_certificate - -_COUNTRY_NAME = 'US' -_STATE_OR_PROVINCE_NAME = 'WA' -_LOCALITY_NAME = 'Kirkland' -_ORGANIZATION_NAME = 'CompanyXYZ' -_ORGANIZATIONAL_UNIT_NAME = 'ContentProtection' - - -_NOT_VALID_BEFORE = datetime.datetime(2001, 8, 9) -_VALID_DURATION = 100 -_LEAF_CERT_VALID_DURATION = 8000 -_SYSTEM_ID = 2001 -_ROOT_PRIVATE_KEY_PASSPHRASE = b'root_passphrase' - - -class ArgParseObject(object): - """A convenient object to allow adding arbitrary attribute to it.""" - - -def create_root_certificate_and_key(): - """Creates a root certificate and key.""" - key = rsa.generate_private_key( - public_exponent=65537, - key_size=3072, - backend=backends.default_backend()) - subject_name = x509.Name( - [x509.NameAttribute(oid.NameOID.COMMON_NAME, u'root_cert')]) - certificate = oem_certificate.build_certificate( - subject_name, subject_name, None, - datetime.datetime(2001, 8, 9), 1000, key.public_key(), key, True) - return (key, certificate) - - -def setup_csr_args(country_name=_COUNTRY_NAME, - state_or_province_name=_STATE_OR_PROVINCE_NAME, - locality_name=_LOCALITY_NAME, - organization_name=_ORGANIZATION_NAME, - organizational_unit_name=_ORGANIZATIONAL_UNIT_NAME, - key_size=4096, - output_csr_file=None, - output_private_key_file=None, - passphrase=None, - common_name=None): - """Sets up arguments to OEM Certificate generator for generating csr.""" - args = ArgParseObject() - args.key_size = key_size - args.country_name = country_name - args.state_or_province_name = state_or_province_name - args.locality_name = locality_name - args.organization_name = organization_name - args.organizational_unit_name = organizational_unit_name - args.common_name = common_name - if output_csr_file: - args.output_csr_file = output_csr_file - else: - args.output_csr_file = io.BytesIO() - if output_private_key_file: - args.output_private_key_file = output_private_key_file - else: - args.output_private_key_file = io.BytesIO() - args.passphrase = passphrase - return args - - -def setup_intermediate_cert_args( - csr_bytes, root_key, root_certificate, not_valid_before=_NOT_VALID_BEFORE, - valid_duration=_VALID_DURATION, system_id=_SYSTEM_ID, - root_private_key_passphrase=_ROOT_PRIVATE_KEY_PASSPHRASE, - output_certificate_file=None): - """Sets up args to OEM Cert generator for generating intermediate cert.""" - args = ArgParseObject() - args.not_valid_before = not_valid_before - args.valid_duration = valid_duration - args.system_id = system_id - args.csr_file = io.BytesIO(csr_bytes) - args.root_private_key_passphrase = root_private_key_passphrase - if output_certificate_file: - args.output_certificate_file = output_certificate_file - else: - args.output_certificate_file = io.BytesIO() - - serialized_private_key = root_key.private_bytes( - serialization.Encoding.DER, - format=serialization.PrivateFormat.PKCS8, - encryption_algorithm=serialization.BestAvailableEncryption( - args.root_private_key_passphrase)) - serialized_certificate = root_certificate.public_bytes( - serialization.Encoding.DER) - args.root_certificate_file = io.BytesIO(serialized_certificate) - args.root_private_key_file = io.BytesIO(serialized_private_key) - return args - - -def setup_leaf_cert_args(intermediate_key_bytes, - intermediate_certificate_bytes, - key_size=1024, - passphrase=None, - not_valid_before=_NOT_VALID_BEFORE, - valid_duration=_LEAF_CERT_VALID_DURATION, - output_certificate_file=None, - output_private_key_file=None): - """Sets up args to OEM Certificate generator for generating leaf cert.""" - args = ArgParseObject() - args.key_size = key_size - args.not_valid_before = not_valid_before - args.valid_duration = valid_duration - args.intermediate_private_key_passphrase = None - if output_certificate_file: - args.output_certificate_file = output_certificate_file - else: - args.output_certificate_file = io.BytesIO() - if output_private_key_file: - args.output_private_key_file = output_private_key_file - else: - args.output_private_key_file = io.BytesIO() - args.passphrase = passphrase - - args.intermediate_private_key_file = io.BytesIO( - intermediate_key_bytes) - args.intermediate_certificate_file = io.BytesIO( - intermediate_certificate_bytes) - return args - - -def create_intermediate_certificate_and_key_bytes(key_size=4096, - passphrase=None, - pem_format=True): - """Creates an intermediate certificate and key.""" - csr_args = setup_csr_args(key_size=key_size, passphrase=passphrase) - oem_certificate.generate_csr(csr_args) - csr_bytes = csr_args.output_csr_file.getvalue() - - root_key, root_certificate = create_root_certificate_and_key() - args = setup_intermediate_cert_args(csr_bytes, root_key, root_certificate) - - oem_certificate.generate_intermediate_certificate(args) - - cert_bytes = args.output_certificate_file.getvalue() - if pem_format: - cert = x509.load_der_x509_certificate(cert_bytes, - backends.default_backend()) - cert_bytes = cert.public_bytes(serialization.Encoding.PEM) - - return (csr_args.output_private_key_file.getvalue(), cert_bytes) diff --git a/oemcrypto/include/OEMCryptoCENC.h b/oemcrypto/include/OEMCryptoCENC.h index f2cf389..0ff0c31 100644 --- a/oemcrypto/include/OEMCryptoCENC.h +++ b/oemcrypto/include/OEMCryptoCENC.h @@ -3,7 +3,7 @@ // License Agreement. /** - * @mainpage OEMCrypto API v19.5 + * @mainpage OEMCrypto API v19.6 * * 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 @@ -766,6 +766,8 @@ typedef enum OEMCrypto_SignatureHashAlgorithm { #define OEMCrypto_GetBCCSignatureType _oecc156 #define OEMCrypto_GetPVRKey _oecc157 #define OEMCrypto_LoadPVRKey _oecc158 +#define OEMCrypto_LoadLicenseData _oecc159 +#define OEMCrypto_SaveLicenseData _oecc160 // clang-format on /// @addtogroup initcontrol @@ -1027,7 +1029,10 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); * state, an error of OEMCrypto_ERROR_INVALID_CONTEXT is returned. * * @param[in] session: handle for the session to be used. - * @param[out] nonce: pointer to memory to receive the computed nonce. + * @param[out] nonce pointer to memory to receive the computed nonce. The nonce + * will only be stored into this memory location if the function returns + * OEMCrypto_SUCCESS. If any other OEMCryptoResult is returned, the contents + * of the memory pointed to by nonce will remain unchanged. * * Results: * nonce: the nonce is also stored in secure memory. @@ -3639,7 +3644,9 @@ uint32_t OEMCrypto_MinorAPIVersion(void); * defined * * While not required, another optional top level struct can be added to the - * build information string to provide information about liboemcrypto.so: + * build information string to provide information about liboemcrypto.so. The + * fields within this struct are not required, but if they are included they + * must match the listed data type: * - "ree" { * - "liboemcrypto_ver" [string]: liboemcrypto.so version in string format * eg "2.15.0+tag". Note that this is separate from the "ta_ver" field @@ -4314,8 +4321,8 @@ OEMCryptoResult OEMCrypto_LoadProvisioning( * Receiver certificates may refuse to load these keys and return an error of * OEMCrypto_ERROR_NOT_IMPLEMENTED. The main use case for these alternative * signing algorithms is to support devices that use X509 certificates for - * authentication when acting as a ChromeCast receiver. This is not needed for - * devices that wish to send data to a ChromeCast. Keys loaded from this + * authentication when acting as a Google Cast receiver. This is not needed for + * devices that wish to send data to a Google Cast. Keys loaded from this * function may not be used with OEMCrypto_PrepAndSignLicenseRequest(). * * First, OEMCrypto should generate three secondary keys, mac_key[server], @@ -4388,8 +4395,8 @@ OEMCryptoResult OEMCrypto_LoadProvisioning( * algorithms may refuse to load these keys and return an error of * OEMCrypto_ERROR_NOT_IMPLEMENTED. The main use case for these * alternative signing algorithms is to support devices that use X.509 - * certificates for authentication when acting as a ChromeCast receiver. - * This is not needed for devices that wish to send data to a ChromeCast. + * certificates for authentication when acting as a Google Cast receiver. + * This is not needed for devices that wish to send data to a Google Cast. * 7. After possibly skipping past the first 8 bytes signifying the allowed * signing algorithm, the rest of the buffer private_key contains an ECC * private key or an RSA private key in PKCS#8 binary DER encoded @@ -4562,7 +4569,7 @@ OEMCryptoResult OEMCrypto_LoadTestRSAKey(void); * * The second padding scheme is for devices that use X509 certificates for * authentication. The main example is devices that work as a Cast receiver, - * like a ChromeCast, not for devices that wish to send to the Cast device, + * like a Google Cast, not for devices that wish to send to the Cast device, * such as almost all Android devices. OEMs that do not support X509 * certificate authentication need not implement this function and can return * OEMCrypto_ERROR_NOT_IMPLEMENTED. @@ -6398,6 +6405,44 @@ OEMCryptoResult OEMCrypto_UseSecondaryKey(OEMCrypto_SESSION session_id, */ OEMCryptoResult OEMCrypto_MarkOfflineSession(OEMCrypto_SESSION session); +/** + * Loads the license data into the given session. + * + * @param[in] session: session id for operation. + * @param[in] data: the buffer to import. + * @param[in] data_length: the number of bytes in |data|. + * + * @ignore + * @retval OEMCrypto_SUCCESS on success + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * @retval OEMCrypto_ERROR_SESSION_STATE_LOST + * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + */ +OEMCryptoResult OEMCrypto_LoadLicenseData(OEMCrypto_SESSION session, + const uint8_t* data, + size_t data_length); + +/** + * Saves the license data for the given session. + * + * @param[in] session: session id for operation. + * @param[out] data: the buffer to export into. + * @param[in,out] data_length: (in) length of the data buffer, in bytes. + * (out) actual length of the data, in bytes. + * + * @ignore + * @retval OEMCrypto_SUCCESS on success + * @retval OEMCrypto_ERROR_INVALID_SESSION + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * @retval OEMCrypto_ERROR_SESSION_STATE_LOST + * @retval OEMCrypto_ERROR_SYSTEM_INVALIDATED + * @retval OEMCrypto_ERROR_NOT_IMPLEMENTED + */ +OEMCryptoResult OEMCrypto_SaveLicenseData(OEMCrypto_SESSION session, + uint8_t* data, size_t* data_length); + #ifdef __cplusplus } #endif diff --git a/oemcrypto/include/level3.h b/oemcrypto/include/level3.h deleted file mode 100644 index 4efdb82..0000000 --- a/oemcrypto/include/level3.h +++ /dev/null @@ -1,675 +0,0 @@ -// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary -// source code may only be used and distributed under the Widevine -// License Agreement. - -/********************************************************************* - * level3.h - * - * Reference APIs needed to support Widevine's crypto algorithms. - *********************************************************************/ - -#ifndef LEVEL3_OEMCRYPTO_H_ -#define LEVEL3_OEMCRYPTO_H_ - -#include -#include - -#include "OEMCryptoCENC.h" -#include "level3_file_system.h" - -// clang-format off -#ifdef DYNAMIC_ADAPTER -#define Level3_IsInApp _lcc00 -#define Level3_Initialize _lcc01 -#define Level3_Terminate _lcc02 -#define Level3_InstallKeyboxOrOEMCert _lcc03 -#define Level3_GetKeyData _lcc04 -#define Level3_IsKeyboxOrOEMCertValid _lcc05 -#define Level3_GetDeviceID _lcc07 -#define Level3_WrapKeyboxOrOEMCert _lcc08 -#define Level3_OpenSession _lcc09 -#define Level3_CloseSession _lcc10 -#define Level3_GenerateSignature _lcc13 -#define Level3_GenerateNonce _lcc14 -#define Level3_RewrapDeviceRSAKey _lcc18 -#define Level3_LoadDeviceRSAKey _lcc19 -#define Level3_DeriveKeysFromSessionKey _lcc21 -#define Level3_APIVersion _lcc22 -#define Level3_Generic_Encrypt_V17 _lcc24 -#define Level3_Generic_Decrypt_V17 _lcc25 -#define Level3_Generic_Sign_V17 _lcc26 -#define Level3_Generic_Verify_V17 _lcc27 -#define Level3_SupportsUsageTable _lcc29 -#define Level3_ReportUsage _lcc32 -#define Level3_GetMaxNumberOfSessions _lcc37 -#define Level3_GetNumberOfOpenSessions _lcc38 -#define Level3_IsAntiRollbackHwPresent _lcc39 -#define Level3_QueryKeyControl _lcc41 -#define Level3_GetHDCPCapability _lcc44 -#define Level3_LoadTestRSAKey _lcc45 -#define Level3_SecurityPatchLevel _lcc46 -#define Level3_GetProvisioningMethod _lcc49 -#define Level3_RewrapDeviceRSAKey30 _lcc51 -#define Level3_SupportedCertificates _lcc52 -#define Level3_IsSRMUpdateSupported _lcc53 -#define Level3_GetCurrentSRMVersion _lcc54 -#define Level3_LoadSRM _lcc55 -#define Level3_RemoveSRM _lcc57 -#define Level3_CreateUsageTableHeader _lcc61 -#define Level3_LoadUsageTableHeader _lcc62 -#define Level3_CreateNewUsageEntry _lcc63 -#define Level3_LoadUsageEntry _lcc64 -#define Level3_UpdateUsageEntry _lcc65 -#define Level3_ShrinkUsageTableHeader _lcc67 -#define Level3_MoveEntry _lcc68 -#define Level3_GetAnalogOutputFlags _lcc71 -#define Level3_LoadTestKeybox _lcc78 -#define Level3_SelectKey _lcc81 -#define Level3_LoadKeys _lcc83 -#define Level3_SetSandbox _lcc84 -#define Level3_ResourceRatingTier _lcc85 -#define Level3_SupportsDecryptHash _lcc86 -#define Level3_SetDecryptHash_V18 _lcc88 -#define Level3_GetHashErrorCode _lcc89 -#define Level3_RefreshKeys _lcc91 -#define Level3_LoadEntitledContentKeys_V16 _lcc92 -#define Level3_CopyBuffer _lcc93 -#define Level3_MaximumUsageTableHeaderSize _lcc94 -#define Level3_GenerateDerivedKeys _lcc95 -#define Level3_PrepAndSignLicenseRequest _lcc96 -#define Level3_PrepAndSignRenewalRequest _lcc97 -#define Level3_PrepAndSignProvisioningRequest _lcc98 -#define Level3_LoadLicense_V18 _lcc99 -#define Level3_LoadRenewal _lcc101 -#define Level3_LoadProvisioning_V18 _lcc102 -#define Level3_LoadOEMPrivateKey _lcc103 -#define Level3_GetOEMPublicCertificate _lcc104 -#define Level3_DecryptCENC_V17 _lcc105 -#define Level3_LoadDRMPrivateKey _lcc107 -#define Level3_MinorAPIVersion _lcc108 -#define Level3_AllocateSecureBuffer _lcc109 -#define Level3_FreeSecureBuffer _lcc110 -#define Level3_CreateEntitledKeySession _lcc111 -#define Level3_RemoveEntitledKeySession _lcc112 -#define Level3_GetBootCertificateChain _lcc116 -#define Level3_GenerateCertificateKeyPair _lcc117 -#define Level3_InstallOemPrivateKey _lcc118 -#define Level3_ReassociateEntitledKeySession _lcc119 -#define Level3_LoadCasECMKeys _lcc120 -#define Level3_LoadEntitledContentKeys _lcc121 // place holder for v17. -#define Level3_ProductionReady _lcc122 -#define Level3_Idle _lcc123 -#define Level3_Wake _lcc124 -#define Level3_BuildInformation _lcc125 -#define Level3_SecurityLevel _lcc126 -#define Level3_ReuseUsageEntry _lcc127 -#define Level3_GetDTCP2Capability _lcc128 -#define Level3_GetWatermarkingSupport _lcc129 -#define Level3_GetOEMKeyToken _lcc130 -#define Level3_GetDeviceInformation _lcc131 -#define Level3_SetMaxAPIVersion _lcc132 -#define Level3_GetKeyHandle _lcc133 -#define Level3_DecryptCENC _lcc134 -#define Level3_Generic_Encrypt _lcc135 -#define Level3_Generic_Decrypt _lcc136 -#define Level3_Generic_Sign _lcc137 -#define Level3_Generic_Verify _lcc138 -#define Level3_GetSignatureHashAlgorithm _lcc139 -#define Level3_EnterTestMode _lcc140 -#define Level3_GetDeviceSignedCsrPayload _lcc141 -#define Level3_SetDecryptHash _lcc143 -#define Level3_LoadLicense _lcc144 -#define Level3_LoadProvisioning _lcc145 -#define Level3_LoadProvisioningCast _lcc146 -#define Level3_PrepAndSignReleaseRequest _lcc147 -#define Level3_GetUsageEntryInfo _lcc148 -#define Level3_GetBCCType _lcc149 -#define Level3_LoadRelease _lcc150 -#define Level3_GetEmbeddedDrmCertificate _lcc151 -#define Level3_UseSecondaryKey _lcc152 -#define Level3_MarkOfflineSession _lcc153 -#define Level3_SetSessionUsage _lcc155 -#define Level3_GetBCCSignatureType _lcc156 -#define Level3_GetPVRKey _lcc157 -#define Level3_LoadPVRKey _lcc158 -#else -#define Level3_Initialize _oecc01 -#define Level3_Terminate _oecc02 -#define Level3_InstallKeyboxOrOEMCert _oecc03 -#define Level3_GetKeyData _oecc04 -#define Level3_IsKeyboxOrOEMCertValid _oecc05 -#define Level3_GetDeviceID _oecc07 -#define Level3_WrapKeyboxOrOEMCert _oecc08 -#define Level3_OpenSession _oecc09 -#define Level3_CloseSession _oecc10 -#define Level3_GenerateSignature _oecc13 -#define Level3_GenerateNonce _oecc14 -#define Level3_RewrapDeviceRSAKey _oecc18 -#define Level3_LoadDeviceRSAKey _oecc19 -#define Level3_DeriveKeysFromSessionKey _oecc21 -#define Level3_APIVersion _oecc22 -#define Level3_Generic_Encrypt_V17 _oecc24 -#define Level3_Generic_Decrypt_V17 _oecc25 -#define Level3_Generic_Sign_V17 _oecc26 -#define Level3_Generic_Verify_V17 _oecc27 -#define Level3_SupportsUsageTable _oecc29 -#define Level3_ReportUsage _oecc32 -#define Level3_GenerateRSASignature _oecc36 -#define Level3_GetMaxNumberOfSessions _oecc37 -#define Level3_GetNumberOfOpenSessions _oecc38 -#define Level3_IsAntiRollbackHwPresent _oecc39 -#define Level3_QueryKeyControl _oecc41 -#define Level3_GetHDCPCapability _oecc44 -#define Level3_LoadTestRSAKey _oecc45 -#define Level3_SecurityPatchLevel _oecc46 -#define Level3_GetProvisioningMethod _oecc49 -#define Level3_RewrapDeviceRSAKey30 _oecc51 -#define Level3_SupportedCertificates _oecc52 -#define Level3_IsSRMUpdateSupported _oecc53 -#define Level3_GetCurrentSRMVersion _oecc54 -#define Level3_LoadSRM _oecc55 -#define Level3_RemoveSRM _oecc57 -#define Level3_CreateUsageTableHeader _oecc61 -#define Level3_LoadUsageTableHeader _oecc62 -#define Level3_CreateNewUsageEntry _oecc63 -#define Level3_LoadUsageEntry _oecc64 -#define Level3_UpdateUsageEntry _oecc65 -#define Level3_DeactivateUsageEntry _oecc66 -#define Level3_ShrinkUsageTableHeader _oecc67 -#define Level3_MoveEntry _oecc68 -#define Level3_GetAnalogOutputFlags _oecc71 -#define Level3_LoadTestKeybox _oecc78 -#define Level3_SelectKey _oecc81 -#define Level3_LoadKeys _oecc83 -#define Level3_SetSandbox _oecc84 -#define Level3_ResourceRatingTier _oecc85 -#define Level3_SupportsDecryptHash _oecc86 -#define Level3_SetDecryptHash_V18 _oecc88 -#define Level3_GetHashErrorCode _oecc89 -#define Level3_RefreshKeys _oecc91 -#define Level3_LoadEntitledContentKeys_V16 _oecc92 -#define Level3_CopyBuffer _oecc93 -#define Level3_MaximumUsageTableHeaderSize _oecc94 -#define Level3_GenerateDerivedKeys _oecc95 -#define Level3_PrepAndSignLicenseRequest _oecc96 -#define Level3_PrepAndSignRenewalRequest _oecc97 -#define Level3_PrepAndSignProvisioningRequest _oecc98 -#define Level3_LoadLicense_V18 _oecc99 -#define Level3_LoadRenewal _oecc101 -#define Level3_LoadProvisioning_V18 _oecc102 -#define Level3_LoadOEMPrivateKey _oecc103 -#define Level3_GetOEMPublicCertificate _oecc104 -#define Level3_DecryptCENC_V17 _oecc105 -#define Level3_LoadDRMPrivateKey _oecc107 -#define Level3_MinorAPIVersion _oecc108 -#define Level3_AllocateSecureBuffer _oecc109 -#define Level3_FreeSecureBuffer _oecc110 -#define Level3_CreateEntitledKeySession _oecc111 -#define Level3_RemoveEntitledKeySession _oecc112 -#define Level3_GetBootCertificateChain _oecc116 -#define Level3_GenerateCertificateKeyPair _oecc117 -#define Level3_InstallOemPrivateKey _oecc118 -#define Level3_ReassociateEntitledKeySession _oecc119 -#define Level3_LoadCasECMKeys _oecc120 -#define Level3_LoadEntitledContentKeys _oecc121 // place holder for v17. -#define Level3_ProductionReady _oecc122 -#define Level3_Idle _oecc123 -#define Level3_Wake _oecc124 -#define Level3_BuildInformation _oecc125 -#define Level3_SecurityLevel _oecc126 -#define Level3_ReuseUsageEntry _oecc127 -#define Level3_GetDTCP2Capability _oecc128 -#define Level3_GetWatermarkingSupport _oecc129 -#define Level3_GetOEMKeyToken _oecc130 -#define Level3_GetDeviceInformation _oecc131 -#define Level3_SetMaxAPIVersion _oecc132 -#define Level3_GetKeyHandle _oecc133 -#define Level3_DecryptCENC _oecc134 -#define Level3_Generic_Encrypt _oecc135 -#define Level3_Generic_Decrypt _oecc136 -#define Level3_Generic_Sign _oecc137 -#define Level3_Generic_Verify _oecc138 -#define Level3_GetSignatureHashAlgorithm _oecc139 -#define Level3_EnterTestMode _oecc140 -#define Level3_GetDeviceSignedCsrPayload _oecc141 -#define Level3_SetDecryptHash _oecc143 -#define Level3_LoadLicense _oecc144 -#define Level3_LoadProvisioning _oecc145 -#define Level3_LoadProvisioningCast _oecc146 -#define Level3_PrepAndSignReleaseRequest _oecc147 -#define Level3_GetUsageEntryInfo _oecc148 -#define Level3_GetBCCType _oecc149 -#define Level3_LoadRelease _oecc150 -// Internal-only. -#define Level3_GetEmbeddedDrmCertificate _oecc151 -#define Level3_UseSecondaryKey _oecc152 -#define Level3_MarkOfflineSession _oecc153 -#define Level3_SetSessionUsage _oecc155 -#define Level3_GetBCCSignatureType _oecc156 -#define Level3_GetPVRKey _oecc157 -#define Level3_LoadPVRKey _oecc158 -#endif - -#define Level3_GetInitializationState _oecl3o01 -// clang-format on - -extern "C" { - -bool Level3_IsInApp(); -OEMCryptoResult Level3_Initialize(void); -OEMCryptoResult Level3_Terminate(void); -OEMCryptoResult Level3_OpenSession(OEMCrypto_SESSION* session); -OEMCryptoResult Level3_CloseSession(OEMCrypto_SESSION session); -OEMCryptoResult Level3_GenerateDerivedKeys(OEMCrypto_SESSION session, - const uint8_t* mac_key_context, - size_t mac_key_context_length, - const uint8_t* enc_key_context, - size_t enc_key_context_length); -OEMCryptoResult Level3_GenerateNonce(OEMCrypto_SESSION session, - uint32_t* nonce); -OEMCryptoResult Level3_QueryKeyControl(OEMCrypto_SESSION session, - const uint8_t* key_id, - size_t key_id_length, - uint8_t* key_control_block, - size_t* key_control_block_length); -OEMCryptoResult Level3_DecryptCENC_V17( - OEMCrypto_SESSION session, const OEMCrypto_SampleDescription* samples, - size_t samples_length, const OEMCrypto_CENCEncryptPatternDesc* pattern); -OEMCryptoResult Level3_InstallKeyboxOrOEMCert(const uint8_t* rot, - size_t rotLength); -OEMCryptoResult Level3_IsKeyboxOrOEMCertValid(void); -OEMCryptoResult Level3_WrapKeyboxOrOEMCert(const uint8_t* rot, size_t rotLength, - uint8_t* wrappedRot, - size_t* wrappedRotLength, - const uint8_t* transportKey, - size_t transportKeyLength); -OEMCrypto_ProvisioningMethod Level3_GetProvisioningMethod(); -OEMCryptoResult Level3_GetOEMPublicCertificate(uint8_t* public_cert, - size_t* public_cert_length); -OEMCryptoResult Level3_GetDeviceID(uint8_t* deviceID, size_t* idLength); -OEMCryptoResult Level3_GetKeyData(uint8_t* keyData, size_t* keyDataLength); -OEMCryptoResult Level3_LoadOEMPrivateKey(OEMCrypto_SESSION session); -OEMCryptoResult Level3_LoadDRMPrivateKey(OEMCrypto_SESSION session, - OEMCrypto_PrivateKeyType key_type, - const uint8_t* wrapped_rsa_key, - size_t wrapped_rsa_key_length); -OEMCryptoResult Level3_LoadProvisioning_V18( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - size_t core_message_length, const uint8_t* signature, - size_t signature_length, uint8_t* wrapped_private_key, - size_t* wrapped_private_key_length); -OEMCryptoResult Level3_RewrapDeviceRSAKey( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const uint8_t* signature, size_t signature_length, const uint32_t* nonce, - const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, - const uint8_t* enc_rsa_key_iv, uint8_t* wrapped_rsa_key, - size_t* wrapped_rsa_key_length); -OEMCryptoResult Level3_LoadTestRSAKey(); -OEMCryptoResult Level3_GenerateRSASignature(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - uint8_t* signature, - size_t* signature_length, - RSA_Padding_Scheme padding_scheme); -OEMCryptoResult Level3_DeriveKeysFromSessionKey(OEMCrypto_SESSION session, - const uint8_t* enc_session_key, - size_t enc_session_key_length, - const uint8_t* mac_key_context, - size_t mac_key_context_length, - const uint8_t* enc_key_context, - size_t enc_key_context_length); -uint32_t Level3_APIVersion(); -uint32_t Level3_MinorAPIVersion(); -uint8_t Level3_SecurityPatchLevel(); -OEMCrypto_Security_Level Level3_SecurityLevel(); -OEMCryptoResult Level3_GetHDCPCapability(OEMCrypto_HDCP_Capability* current, - OEMCrypto_HDCP_Capability* maximum); -bool Level3_SupportsUsageTable(); -bool Level3_IsAntiRollbackHwPresent(); -OEMCryptoResult Level3_GetNumberOfOpenSessions(size_t* count); -OEMCryptoResult Level3_GetMaxNumberOfSessions(size_t* maximum); -uint32_t Level3_SupportedCertificates(); -OEMCryptoResult Level3_Generic_Encrypt_V17( - OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length, - const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer); -OEMCryptoResult Level3_Generic_Decrypt_V17( - OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length, - const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer); -OEMCryptoResult Level3_Generic_Sign_V17(OEMCrypto_SESSION session, - const uint8_t* in_buffer, - size_t buffer_length, - OEMCrypto_Algorithm algorithm, - uint8_t* signature, - size_t* signature_length); -OEMCryptoResult Level3_Generic_Verify_V17(OEMCrypto_SESSION session, - const uint8_t* in_buffer, - size_t buffer_length, - OEMCrypto_Algorithm algorithm, - const uint8_t* signature, - size_t signature_length); -OEMCryptoResult Level3_DeactivateUsageEntry(OEMCrypto_SESSION session, - const uint8_t* pst, - size_t pst_length); -OEMCryptoResult Level3_ReportUsage(OEMCrypto_SESSION session, - const uint8_t* pst, size_t pst_length, - uint8_t* buffer, size_t* buffer_length); -bool Level3_IsSRMUpdateSupported(); -OEMCryptoResult Level3_GetCurrentSRMVersion(uint16_t* version); -OEMCryptoResult Level3_LoadSRM(const uint8_t* buffer, size_t buffer_length); -OEMCryptoResult Level3_RemoveSRM(); -OEMCryptoResult Level3_CreateUsageTableHeader(uint8_t* header_buffer, - size_t* header_buffer_length); -OEMCryptoResult Level3_LoadUsageTableHeader(const uint8_t* buffer, - size_t buffer_length); -OEMCryptoResult Level3_CreateNewUsageEntry(OEMCrypto_SESSION session, - uint32_t* usage_entry_number); -OEMCryptoResult Level3_LoadUsageEntry(OEMCrypto_SESSION session, uint32_t index, - const uint8_t* buffer, - size_t buffer_size); -OEMCryptoResult Level3_UpdateUsageEntry(OEMCrypto_SESSION session, - uint8_t* header_buffer, - size_t* header_buffer_length, - uint8_t* entry_buffer, - size_t* entry_buffer_length); -OEMCryptoResult Level3_ShrinkUsageTableHeader(uint32_t new_table_size, - uint8_t* header_buffer, - size_t* header_buffer_length); -OEMCryptoResult Level3_MoveEntry(OEMCrypto_SESSION session, uint32_t new_index); -uint32_t Level3_GetAnalogOutputFlags(); -OEMCryptoResult Level3_LoadTestKeybox(const uint8_t* buffer, size_t length); -OEMCryptoResult Level3_SelectKey(const OEMCrypto_SESSION session, - const uint8_t* key_id, size_t key_id_length, - OEMCryptoCipherMode cipher_mode); -OEMCryptoResult Level3_LoadLicense_V18(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - size_t core_message_length, - const uint8_t* signature, - size_t signature_length); -OEMCryptoResult Level3_LoadKeys( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const uint8_t* signature, size_t signature_length, - OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, - size_t num_keys, const OEMCrypto_KeyObject* key_array, - OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, - OEMCrypto_LicenseType license_type); -OEMCryptoResult Level3_SetSandbox(const uint8_t* sandbox_id, - size_t sandbox_id_length); -uint32_t Level3_ResourceRatingTier(); -uint32_t Level3_SupportsDecryptHash(); - -OEMCryptoResult Level3_SetDecryptHash(OEMCrypto_SESSION session, - uint32_t frame_number, uint32_t crc32); -OEMCryptoResult Level3_SetDecryptHash_V18(OEMCrypto_SESSION session, - uint32_t frame_number, - const uint8_t* hash, - size_t hash_length); -OEMCryptoResult Level3_GetHashErrorCode(OEMCrypto_SESSION session, - uint32_t* failed_frame_number); -OEMCryptoResult Level3_BuildInformation(char* buffer, size_t* buffer_length); -OEMCryptoResult Level3_LoadRenewal(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - size_t core_message_length, - const uint8_t* signature, - size_t signature_length); -OEMCryptoResult Level3_RefreshKeys(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - const uint8_t* signature, - size_t signature_length, size_t num_keys, - const OEMCrypto_KeyRefreshObject* key_array); -OEMCryptoResult Level3_LoadEntitledContentKeys( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array); -OEMCryptoResult Level3_CopyBuffer( - OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length, - const OEMCrypto_DestBufferDesc* out_buffer_descriptor, - uint8_t subsample_flags); -OEMCryptoResult Level3_PrepAndSignProvisioningRequest( - OEMCrypto_SESSION session, uint8_t* message, size_t message_length, - size_t* core_message_length, uint8_t* signature, size_t* signature_length); -OEMCryptoResult Level3_PrepAndSignLicenseRequest( - OEMCrypto_SESSION session, uint8_t* message, size_t message_length, - size_t* core_message_length, uint8_t* signature, size_t* signature_length); -OEMCryptoResult Level3_PrepAndSignRenewalRequest( - OEMCrypto_SESSION session, uint8_t* message, size_t message_length, - size_t* core_message_length, uint8_t* signature, size_t* signature_length); -size_t Level3_MaximumUsageTableHeaderSize(); -OEMCryptoResult Level3_AllocateSecureBuffer( - OEMCrypto_SESSION session, size_t buffer_size, - OEMCrypto_DestBufferDesc* output_descriptor, int* secure_fd); -OEMCryptoResult Level3_FreeSecureBuffer( - OEMCrypto_SESSION session, OEMCrypto_DestBufferDesc* output_descriptor, - int secure_fd); -OEMCryptoResult Level3_CreateEntitledKeySession(OEMCrypto_SESSION oec_session, - OEMCrypto_SESSION* key_session); -OEMCryptoResult Level3_RemoveEntitledKeySession(OEMCrypto_SESSION key_session); -OEMCryptoResult Level3_GetBootCertificateChain( - uint8_t* bcc, size_t* bcc_size, uint8_t* additional_signature, - size_t* additional_signature_size); -OEMCryptoResult Level3_GenerateCertificateKeyPair( - OEMCrypto_SESSION session, uint8_t* public_key, size_t* public_key_size, - uint8_t* public_key_signature, size_t* public_key_signature_size, - uint8_t* wrapped_private_key, size_t* wrapped_private_key_size, - OEMCrypto_PrivateKeyType* key_type); -OEMCryptoResult Level3_InstallOemPrivateKey(OEMCrypto_SESSION session, - OEMCrypto_PrivateKeyType key_type, - const uint8_t* wrapped_private_key, - size_t wrapped_private_key_length); -OEMCryptoResult Level3_ReassociateEntitledKeySession( - OEMCrypto_SESSION key_session, OEMCrypto_SESSION oec_session); -OEMCryptoResult Level3_LoadCasECMKeys( - OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, - const OEMCrypto_EntitledContentKeyObject* even_key, - const OEMCrypto_EntitledContentKeyObject* odd_key); -OEMCryptoResult Level3_ProductionReady(); -OEMCryptoResult Level3_Idle(OEMCrypto_IdleState state, - uint32_t os_specific_code); -OEMCryptoResult Level3_Wake(); -OEMCryptoResult Level3_ReuseUsageEntry(OEMCrypto_SESSION session, - uint32_t usage_entry_number); -OEMCryptoResult Level3_GetDTCP2Capability( - OEMCrypto_DTCP2_Capability* capability); -OEMCrypto_WatermarkingSupport Level3_GetWatermarkingSupport(); -OEMCryptoResult Level3_GetOEMKeyToken(OEMCrypto_SESSION key_session, - uint8_t* key_token, - size_t* key_token_length); -OEMCryptoResult Level3_SetSessionUsage(OEMCrypto_SESSION session, - uint32_t intent, uint32_t mode); -OEMCryptoResult Level3_GetPVRKey(OEMCrypto_SESSION session, - uint8_t* wrapped_pvr_key, - size_t* wrapped_pvr_key_length); -OEMCryptoResult Level3_LoadPVRKey(OEMCrypto_SESSION session, - const uint8_t* wrapped_pvr_key, - size_t wrapped_pvr_key_length); -OEMCryptoResult Level3_GetDeviceInformation(uint8_t* device_info, - size_t* device_info_length); -OEMCryptoResult Level3_GetDeviceSignedCsrPayload( - const uint8_t* challenge, size_t challenge_length, - const uint8_t* encoded_device_info, size_t encoded_device_info_length, - uint8_t* signed_csr_payload, size_t* signed_csr_payload_length); -OEMCryptoResult Level3_SetMaxAPIVersion(uint32_t max_version); -OEMCryptoResult Level3_GetKeyHandle(OEMCrypto_SESSION session, - const uint8_t* content_key_id, - size_t content_key_id_length, - OEMCryptoCipherMode cipher_mode, - uint8_t* key_handle, - size_t* key_handle_length); -OEMCryptoResult Level3_DecryptCENC( - const uint8_t* key_handle, size_t key_handle_length, - const OEMCrypto_SampleDescription* samples, size_t samples_length, - const OEMCrypto_CENCEncryptPatternDesc* pattern); -OEMCryptoResult Level3_Generic_Encrypt(const uint8_t* key_handle, - size_t key_handle_length, - const OEMCrypto_SharedMemory* in_buffer, - size_t in_buffer_length, - const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - OEMCrypto_SharedMemory* out_buffer); -OEMCryptoResult Level3_Generic_Decrypt(const uint8_t* key_handle, - size_t key_handle_length, - const OEMCrypto_SharedMemory* in_buffer, - size_t in_buffer_length, - const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - OEMCrypto_SharedMemory* out_buffer); -OEMCryptoResult Level3_Generic_Sign(const uint8_t* key_handle, - size_t key_handle_length, - const OEMCrypto_SharedMemory* buffer, - size_t buffer_length, - OEMCrypto_Algorithm algorithm, - OEMCrypto_SharedMemory* signature, - size_t* signature_length); -OEMCryptoResult Level3_Generic_Verify(const uint8_t* key_handle, - size_t key_handle_length, - const OEMCrypto_SharedMemory* buffer, - size_t buffer_length, - OEMCrypto_Algorithm algorithm, - const OEMCrypto_SharedMemory* signature, - size_t signature_length); -OEMCryptoResult Level3_GetSignatureHashAlgorithm( - OEMCrypto_SESSION session, OEMCrypto_SignatureHashAlgorithm* algorithm); -OEMCryptoResult Level3_EnterTestMode(void); -OEMCryptoResult Level3_LoadLicense( - OEMCrypto_SESSION session, const uint8_t* context, size_t context_length, - const uint8_t* derivation_key, size_t derivation_key_length, - const uint8_t* message, size_t message_length, size_t core_message_length, - const uint8_t* signature, size_t signature_length); -OEMCryptoResult Level3_LoadProvisioning( - OEMCrypto_SESSION session, const uint8_t* provision_request, - size_t provision_request_length, const uint8_t* message, - size_t message_length, size_t core_message_length, const uint8_t* signature, - size_t signature_length, uint8_t* wrapped_private_key, - size_t* wrapped_private_key_length); -OEMCryptoResult Level3_LoadProvisioningCast( - OEMCrypto_SESSION session, const uint8_t* derivation_key, - size_t derivation_key_length, const uint8_t* provision_request, - size_t provision_request_length, const uint8_t* message, - size_t message_length, size_t core_message_length, const uint8_t* signature, - size_t signature_length, uint8_t* wrapped_private_key, - size_t* wrapped_private_key_length); -OEMCryptoResult Level3_GetBCCType(OEMCrypto_BCCType* bcc_type); -OEMCryptoResult Level3_GetEmbeddedDrmCertificate(uint8_t* public_cert, - size_t* public_cert_length); -OEMCryptoResult Level3_UseSecondaryKey(OEMCrypto_SESSION session_id, - bool dual_key); -OEMCryptoResult Level3_MarkOfflineSession(OEMCrypto_SESSION session_id); -OEMCryptoResult Level3_GetBCCSignatureType( - OEMCrypto_BCCSignatureType* bcc_signature_type); - -// The following are specific to Google's Level 3 implementation and are not -// required. - -enum Level3InitializationState { - LEVEL3_INITIALIZATION_SUCCESS = 0, - LEVEL3_INITIALIZATION_UNKNOWN_FAILURE = 1, - LEVEL3_SEED_FAILURE = 2, - LEVEL3_SAVE_DEVICE_KEYS_FAILURE = 3, - LEVEL3_READ_DEVICE_KEYS_FAILURE = 4, - LEVEL3_VERIFY_DEVICE_KEYS_FAILURE = 5, -}; - -enum Level3RunningMode { - LEVEL3_MODE_HAYSTACK_ONLY = 0, - LEVEL3_MODE_RIKERS_DEFAULT = 1, - LEVEL3_MODE_RIKERS_ONLY = 2, -}; - -/* - * Level3_GetRunningMode - * - * Description: - * Returns the current mode the Level3 is running in. This shouldn't change - * while the processes is running. - * - * Parameters: - * N/A - * - * Threading: - * No other function calls will be made while this function is running. - * - * Version: - * This method is new in API version 19. - */ -Level3RunningMode Level3_GetRunningMode(void); - -/* - * Level3_GetInitializationState - * - * Description: - * Return any warning or error condition which occurred during - * initialization. On some platforms, this value will be logged and metrics - * will be gathered on production devices. This is an optional feature, and - * OEMCrypto may always return 0, even if Level3_Initialize failed. This - * function may be called whether Level3_Initialize succeeded or not. - * - * Parameters: - * N/A - * - * Threading: - * No other function calls will be made while this function is running. - * - * Returns: - * LEVEL3_INITIALIZATION_SUCCESS - no warnings or errors during initialization - * LEVEL3_SEED_FAILURE - error in seeding the software RNG - * LEVEL3_SAVE_DEVICE_KEYS_FAILURE - failed to save device keys to file system - * LEVEL3_READ_DEVICE_KEYS_FAILURE - failed to read device keys from file - * system - * LEVEL3_VERIFY_DEVICE_KEYS_FAILURE - failed to verify decrypted device keys - * - * Version: - * This method is new in API version 14. - */ -Level3InitializationState Level3_GetInitializationState(void); - -/* - * Level3_OutputErrorLogs - * - * Description: - * Call to output any errors in the Level 3 execution if the Level 3 has - * failed. This method should only be called if the Level 3 has failed in - * an unrecoverable state, and needs to be reinitialized. - * - * Parameters: - * N/A - * - * Threading: - * No other function calls will be made while this function is running. - * - * Returns: - * N/A - * - * Version: - * This method is new in API version 15. - */ -void Level3_OutputErrorLogs(); - -} // extern "C" - -namespace wvoec3 { - -// The following are interfaces needed for Google's Level 3 OEMCrypto -// specifically, which partners are expected to implement. - -// Returns a stable, unique identifier for the device. This could be a -// serial number or any other character sequence representing that device. -// The parameter |len| needs to be changed to reflect the length of the -// unique identifier. -const char* getUniqueID(size_t* len); - -// Returns a 64-bit unsigned integer to be used as a random seed for RNG. -// If the operation is unsuccessful, this function returns 0. -// We provide a sample implementation under the name generate_entropy_linux.cpp -// which partners should use if they can. -uint64_t generate_entropy(); - -// Creates and returns an OEMCrypto_Level3FileSystem implementation. -OEMCrypto_Level3FileSystem* createLevel3FileSystem(); - -// Deletes the pointer retrieved by the function above. -void deleteLevel3FileSystem(OEMCrypto_Level3FileSystem* file_system); - -} // namespace wvoec3 - -#endif // LEVEL3_OEMCRYPTO_H_ diff --git a/oemcrypto/include/level3_file_system.h b/oemcrypto/include/level3_file_system.h deleted file mode 100644 index 8f8fbc3..0000000 --- a/oemcrypto/include/level3_file_system.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary -// source code may only be used and distributed under the Widevine -// License Agreement. - -/********************************************************************* - * level3_file_system.h - * - * File system for OEMCrypto Level3 file operations. - *********************************************************************/ - -#ifndef LEVEL3_FILE_SYSTEM_H_ -#define LEVEL3_FILE_SYSTEM_H_ - -#include -#include "platform.h" - -namespace wvoec3 { - -class OEMCrypto_Level3FileSystem { - public: - virtual ~OEMCrypto_Level3FileSystem() {} - virtual ssize_t Read(const char *filename, void *buffer, size_t size) = 0; - virtual ssize_t Write(const char *filename, const void *buffer, - size_t size) = 0; - virtual bool Exists(const char *filename) = 0; - virtual ssize_t FileSize(const char *filename) = 0; - virtual bool Remove(const char *filename) = 0; -}; - -} // namespace wvoec3 - -#endif diff --git a/oemcrypto/odk/include/core_message_features.h b/oemcrypto/odk/include/core_message_features.h index 3edfc02..1ac3c75 100644 --- a/oemcrypto/odk/include/core_message_features.h +++ b/oemcrypto/odk/include/core_message_features.h @@ -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 19.5. + // number. The default is 19.6. uint32_t maximum_major_version = 19; - uint32_t maximum_minor_version = 5; + uint32_t maximum_minor_version = 6; bool operator==(const CoreMessageFeatures &other) const; bool operator!=(const CoreMessageFeatures &other) const { diff --git a/oemcrypto/odk/include/odk.h b/oemcrypto/odk/include/odk.h index 679d4e0..f050d2a 100644 --- a/oemcrypto/odk/include/odk.h +++ b/oemcrypto/odk/include/odk.h @@ -98,6 +98,36 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits, uint32_t api_major_version, uint32_t session_id); +/* + * This function initializes the session's data structures. It shall be + * called from OEMCrypto_OpenSession. + * + * This function is an extended "Ex" version of + * ODK_InitializeSessionValues(). It is not intended for production systems; + * ODK_InitializeSessionValues() should be used instead. + * + * This function is intentionally excluded from Doxygen. + * + * @param[out] timer_limits: the session's timer limits. + * @param[out] clock_values: the session's clock values. + * @param[out] nonce_values: the session's ODK nonce values. + * @param[in] api_major_version: the API major version of OEMCrypto. + * @param[in] api_minor_version: the API minor version of OEMCrypto. + * @param[in] session_id: the session id of the newly created session. + * + * @retval OEMCrypto_SUCCESS + * @retval OEMCrypto_ERROR_INVALID_CONTEXT + * + * @version + * This method is new in version 19.6 of the API. + */ +OEMCryptoResult ODK_InitializeSessionValuesEx(ODK_TimerLimits* timer_limits, + ODK_ClockValues* clock_values, + ODK_NonceValues* nonce_values, + uint32_t api_major_version, + uint32_t api_minor_version, + uint32_t session_id); + /** * This function sets the nonce value in the session's nonce structure. It * shall be called from OEMCrypto_GenerateNonce. diff --git a/oemcrypto/odk/include/odk_structs.h b/oemcrypto/odk/include/odk_structs.h index 0b905aa..803f832 100644 --- a/oemcrypto/odk/include/odk_structs.h +++ b/oemcrypto/odk/include/odk_structs.h @@ -16,10 +16,10 @@ extern "C" { /* The version of this library. */ #define ODK_MAJOR_VERSION 19 -#define ODK_MINOR_VERSION 5 +#define ODK_MINOR_VERSION 6 /* ODK Version string. Date changed automatically on each release. */ -#define ODK_RELEASE_DATE "ODK v19.5 2025-03-11" +#define ODK_RELEASE_DATE "ODK v19.6 2025-06-03" /* The lowest version number for an ODK message. */ #define ODK_FIRST_VERSION 16 diff --git a/oemcrypto/odk/src/core_message_deserialize.cpp b/oemcrypto/odk/src/core_message_deserialize.cpp index e1cdbd0..f3320b6 100644 --- a/oemcrypto/odk/src/core_message_deserialize.cpp +++ b/oemcrypto/odk/src/core_message_deserialize.cpp @@ -89,10 +89,8 @@ bool ParseRequest(uint32_t message_type, return true; } -} // namespace - -static bool GetNonceFromMessage(const std::string& oemcrypto_core_message, - ODK_NonceValues* nonce_values) { +bool GetNonceFromMessage(const std::string& oemcrypto_core_message, + ODK_NonceValues* nonce_values) { if (nonce_values == nullptr) return false; if (oemcrypto_core_message.size() < sizeof(ODK_CoreMessage)) return false; @@ -125,6 +123,8 @@ bool CopyCounterInfo(ODK_MessageCounter* dest, ODK_MessageCounterInfo* src) { return true; } +} // namespace + bool CoreLicenseRequestFromMessage(const std::string& oemcrypto_core_message, ODK_LicenseRequest* core_license_request) { ODK_NonceValues nonce; diff --git a/oemcrypto/odk/src/core_message_features.cpp b/oemcrypto/odk/src/core_message_features.cpp index 3e8abf4..760ce06 100644 --- a/oemcrypto/odk/src/core_message_features.cpp +++ b/oemcrypto/odk/src/core_message_features.cpp @@ -33,7 +33,7 @@ CoreMessageFeatures CoreMessageFeatures::DefaultFeatures( features.maximum_minor_version = 4; // 18.4 break; case 19: - features.maximum_minor_version = 5; // 19.5 + features.maximum_minor_version = 6; // 19.6 break; default: features.maximum_minor_version = 0; diff --git a/oemcrypto/odk/src/odk_timer.c b/oemcrypto/odk/src/odk_timer.c index a1a9eb8..3de8eeb 100644 --- a/oemcrypto/odk/src/odk_timer.c +++ b/oemcrypto/odk/src/odk_timer.c @@ -3,12 +3,16 @@ // License Agreement. #include -#include #include "odk.h" #include "odk_attributes.h" #include "odk_overflow.h" #include "odk_structs_priv.h" +#include "odk_versions.h" + +/* This is a special value used to signal that the latest API + * minor version should be used for a particular API major version. */ +#define ODK_LATEST_API_MINOR_VERSION UINT32_MAX /* Private function. Checks to see if the license is active. Returns * ODK_TIMER_EXPIRED if the license is valid but inactive. Returns @@ -241,6 +245,62 @@ OEMCryptoResult ODK_ComputeRenewalDuration(const ODK_TimerLimits* timer_limits, return ODK_SET_TIMER; } +/* Private function. Initialize the timer limits to default values. */ +static void InitializeTimerLimits(ODK_TimerLimits* timer_limits) { + if (timer_limits == NULL) { + return; + } + timer_limits->soft_enforce_rental_duration = false; + timer_limits->soft_enforce_playback_duration = false; + timer_limits->earliest_playback_start_seconds = 0; + timer_limits->rental_duration_seconds = 0; + timer_limits->total_playback_duration_seconds = 0; + timer_limits->initial_renewal_duration_seconds = 0; +} + +/* Private function. Obtains the maximum minor version for a given major + * version. */ +static uint32_t GetApiMinorVersion(uint32_t api_major_version) { + /* This needs to be updated with new major version releases. */ + switch (api_major_version) { + case 16: + return ODK_V16_MINOR_VERSION; + case 17: + return ODK_V17_MINOR_VERSION; + case 18: + return ODK_V18_MINOR_VERSION; + case 19: + return ODK_V19_MINOR_VERSION; + default: + return 0; + } +} + +/* Private function. Initialize the nonce values. + * Note: |api_minor_version| may be set to ODK_LATEST_API_MINOR_VERSION.*/ +static void InitializeNonceValues(ODK_NonceValues* nonce_values, + uint32_t api_major_version, + uint32_t api_minor_version, + uint32_t session_id) { + if (nonce_values == NULL) { + return; + } + if (api_major_version > ODK_MAJOR_VERSION) { + api_major_version = ODK_MAJOR_VERSION; + } + /* Floor the API minor version to the maximum minor version for the API major + * version. */ + const uint32_t max_api_minor_version = GetApiMinorVersion(api_major_version); + if (api_minor_version > max_api_minor_version) { + api_minor_version = max_api_minor_version; + } + + nonce_values->api_major_version = api_major_version; + nonce_values->api_minor_version = api_minor_version; + nonce_values->nonce = 0; + nonce_values->session_id = session_id; +} + /************************************************************************/ /************************************************************************/ /* Public functions, declared in odk.h. */ @@ -254,38 +314,27 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits, if (timer_limits == NULL || clock_values == NULL || nonce_values == NULL) { 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; - timer_limits->rental_duration_seconds = 0; - timer_limits->total_playback_duration_seconds = 0; - timer_limits->initial_renewal_duration_seconds = 0; - + InitializeTimerLimits(timer_limits); ODK_InitializeClockValues(clock_values, 0); + InitializeNonceValues(nonce_values, api_major_version, + ODK_LATEST_API_MINOR_VERSION, session_id); + return OEMCrypto_SUCCESS; +} - 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 = 4; - break; - case 19: - nonce_values->api_minor_version = 5; - break; - default: - nonce_values->api_minor_version = 0; - break; +/* This is called when certain OEMCrypto implementations opens a new session. */ +OEMCryptoResult ODK_InitializeSessionValuesEx(ODK_TimerLimits* timer_limits, + ODK_ClockValues* clock_values, + ODK_NonceValues* nonce_values, + uint32_t api_major_version, + uint32_t api_minor_version, + uint32_t session_id) { + if (timer_limits == NULL || clock_values == NULL || nonce_values == NULL) { + return OEMCrypto_ERROR_INVALID_CONTEXT; } - nonce_values->nonce = 0; - nonce_values->session_id = session_id; - + InitializeTimerLimits(timer_limits); + ODK_InitializeClockValues(clock_values, 0); + InitializeNonceValues(nonce_values, api_major_version, api_minor_version, + session_id); return OEMCrypto_SUCCESS; } diff --git a/oemcrypto/odk/src/odk_versions.h b/oemcrypto/odk/src/odk_versions.h new file mode 100644 index 0000000..17fa449 --- /dev/null +++ b/oemcrypto/odk/src/odk_versions.h @@ -0,0 +1,24 @@ +// Copyright 2025 Google LLC. This file and proprietary +// source code may only be used and distributed under the Widevine +// License Agreement. + +#ifndef WIDEVINE_ODK_SRC_ODK_VERSIONS_H_ +#define WIDEVINE_ODK_SRC_ODK_VERSIONS_H_ + +#include + +#include "odk_structs.h" + +/* Highest ODK minor version number by major version. */ +#define ODK_V16_MINOR_VERSION 5 +#define ODK_V17_MINOR_VERSION 8 +#define ODK_V18_MINOR_VERSION 10 + +/* Whenever the next major version is released, this should be updated to the + * new major version. */ +#if ODK_MAJOR_VERSION != 19 +# error "ODK_MAJOR_VERSION has changed. Please update this file." +#endif +#define ODK_V19_MINOR_VERSION ODK_MINOR_VERSION + +#endif // WIDEVINE_ODK_SRC_ODK_VERSIONS_H_ diff --git a/oemcrypto/odk/test/odk_test.cpp b/oemcrypto/odk/test/odk_test.cpp index bd14883..80b0f52 100644 --- a/oemcrypto/odk/test/odk_test.cpp +++ b/oemcrypto/odk/test/odk_test.cpp @@ -1275,7 +1275,7 @@ std::vector TestCases() { {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, 4}, - {19, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 19, 5}, + {19, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 19, 6}, // 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}, @@ -1291,6 +1291,7 @@ std::vector TestCases() { {ODK_MAJOR_VERSION, 19, 3, 19, 3}, {ODK_MAJOR_VERSION, 19, 4, 19, 4}, {ODK_MAJOR_VERSION, 19, 5, 19, 5}, + {ODK_MAJOR_VERSION, 19, 6, 19, 6}, {0, 16, 3, 16, 3}, {0, 16, 4, 16, 4}, {0, 16, 5, 16, 5}, @@ -1304,6 +1305,7 @@ std::vector TestCases() { {0, 19, 3, 19, 3}, {0, 19, 4, 19, 4}, {0, 19, 5, 19, 5}, + {0, 19, 6, 19, 6}, }; return test_cases; } diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h b/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h index fec38f8..41013f7 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto_api_macros.h @@ -34,8 +34,8 @@ // version bumps to v17.1, the first released OPK implementation would be // v17.1.0 #define API_MAJOR_VERSION 19 -#define API_MINOR_VERSION 5 +#define API_MINOR_VERSION 6 #define OPK_PATCH_VERSION 0 -#define OPK_BUILD_ID "19.5.0" +#define OPK_BUILD_ID "2025-06-10" #endif /* OEMCRYPTO_TA_OEMCRYPTO_API_MACROS_H_ */ diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto_object_table.c b/oemcrypto/opk/oemcrypto_ta/oemcrypto_object_table.c index cea8108..5450e1c 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto_object_table.c +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto_object_table.c @@ -7,11 +7,12 @@ #include "oemcrypto_check_macros.h" #include "wtpi_logging_interface.h" -static void* UnsafeGetElem(OPKI_ObjectTable* table, uint32_t index) { +static void* UnsafeGetElem(const OPKI_ObjectTable* table, uint32_t index) { return (char*)table->elems + index * table->elem_size; } -void* OPKI_AllocFromObjectTable(OPKI_ObjectTable* table, uint32_t* index) { +void* OPKI_AllocFromObjectTable(const OPKI_ObjectTable* table, + uint32_t* index) { if (!table) return NULL; if (table->next_free[0] == 0) { // This should be impossible, so this means we aren't initialized yet (since @@ -21,16 +22,17 @@ void* OPKI_AllocFromObjectTable(OPKI_ObjectTable* table, uint32_t* index) { } } - const uint32_t new_index = table->first_free; + const uint32_t new_index = table->mutable_members->first_free; if (new_index == table->capacity) return NULL; if (index) *index = new_index; - table->first_free = table->next_free[new_index]; + table->mutable_members->first_free = table->next_free[new_index]; ABORT_IF(table->is_used[new_index], "Inconsistent free list"); table->is_used[new_index] = true; return UnsafeGetElem(table, new_index); } -OEMCryptoResult OPKI_FreeFromObjectTable(OPKI_ObjectTable* table, void* elem) { +OEMCryptoResult OPKI_FreeFromObjectTable(const OPKI_ObjectTable* table, + void* elem) { if (!table) return OEMCrypto_ERROR_INVALID_CONTEXT; if (!elem) return OEMCrypto_SUCCESS; @@ -43,7 +45,7 @@ OEMCryptoResult OPKI_FreeFromObjectTable(OPKI_ObjectTable* table, void* elem) { return OPKI_FreeFromObjectTableByIndex(table, index); } -OEMCryptoResult OPKI_FreeFromObjectTableByIndex(OPKI_ObjectTable* table, +OEMCryptoResult OPKI_FreeFromObjectTableByIndex(const OPKI_ObjectTable* table, uint32_t index) { if (!table) return OEMCrypto_ERROR_INVALID_CONTEXT; if (index >= table->capacity) { @@ -60,30 +62,30 @@ OEMCryptoResult OPKI_FreeFromObjectTableByIndex(OPKI_ObjectTable* table, if (result != OEMCrypto_SUCCESS) return result; } - table->next_free[index] = table->first_free; - table->first_free = index; + table->next_free[index] = table->mutable_members->first_free; + table->mutable_members->first_free = index; table->is_used[index] = false; return OEMCrypto_SUCCESS; } -void* OPKI_GetFromObjectTable(OPKI_ObjectTable* table, uint32_t index) { +void* OPKI_GetFromObjectTable(const OPKI_ObjectTable* table, uint32_t index) { if (!table || index >= table->capacity || !table->is_used[index]) { return NULL; } return UnsafeGetElem(table, index); } -void OPKI_UnsafeClearObjectTable(OPKI_ObjectTable* table) { +void OPKI_UnsafeClearObjectTable(const OPKI_ObjectTable* table) { if (!table) return; for (uint32_t i = 0; i < table->capacity; i++) { table->next_free[i] = i + 1; table->is_used[i] = false; } - table->first_free = 0; + table->mutable_members->first_free = 0; } -uint32_t OPKI_GetObjectTableUseCount(OPKI_ObjectTable* table) { +uint32_t OPKI_GetObjectTableUseCount(const OPKI_ObjectTable* table) { if (!table) return 0; uint32_t ret = 0; for (uint32_t index = 0; index < table->capacity; index++) { diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto_object_table.h b/oemcrypto/opk/oemcrypto_ta/oemcrypto_object_table.h index bab0434..821ddce 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto_object_table.h +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto_object_table.h @@ -15,15 +15,19 @@ extern "C" { #endif +typedef struct OPKI_ObjectTableMutableMembers { + uint32_t first_free; +} OPKI_ObjectTableMutableMembers; + typedef struct OPKI_ObjectTable { uint32_t capacity; size_t elem_size; - uint32_t first_free; // Note, the argument pointer can be a pointer to any type. OEMCryptoResult (*dtor)(void*); void* elems; uint32_t* next_free; bool* is_used; + OPKI_ObjectTableMutableMembers* mutable_members; } OPKI_ObjectTable; /** @@ -36,14 +40,15 @@ typedef struct OPKI_ObjectTable { /* Note these arrays are initialized to 0. */ \ static uint32_t var_name##_next_free[(max_count)]; \ static bool var_name##_is_used[(max_count)]; \ - static OPKI_ObjectTable var_name = { \ + static OPKI_ObjectTableMutableMembers var_name##_mutable_members; \ + static const OPKI_ObjectTable var_name = { \ .capacity = (max_count), \ .elem_size = sizeof(type_name), \ .dtor = dtor_arg, \ - .first_free = 0, \ .elems = var_name##_elems, \ .next_free = var_name##_next_free, \ .is_used = var_name##_is_used, \ + .mutable_members = &var_name##_mutable_members, \ } /** @@ -51,30 +56,31 @@ typedef struct OPKI_ObjectTable { * no more free elements. If |index| is not null, it will be filled with the * index of the new object. */ -void* OPKI_AllocFromObjectTable(OPKI_ObjectTable* table, uint32_t* index); +void* OPKI_AllocFromObjectTable(const OPKI_ObjectTable* table, uint32_t* index); /** * Frees an object and makes it available for allocation. If the table was * given a destructor, this calls it. If the destructor fails, the object is * still allocated in the table. */ -OEMCryptoResult OPKI_FreeFromObjectTable(OPKI_ObjectTable* table, void* elem); +OEMCryptoResult OPKI_FreeFromObjectTable(const OPKI_ObjectTable* table, + void* elem); /** The same as FreeFromObjectTable, but gives an index instead. */ -OEMCryptoResult OPKI_FreeFromObjectTableByIndex(OPKI_ObjectTable* table, +OEMCryptoResult OPKI_FreeFromObjectTableByIndex(const OPKI_ObjectTable* table, uint32_t index); /** Gets the object at the given index, or NULL if not valid. */ -void* OPKI_GetFromObjectTable(OPKI_ObjectTable* table, uint32_t index); +void* OPKI_GetFromObjectTable(const OPKI_ObjectTable* table, uint32_t index); /** * Deletes all objects from the table, allowing any to be used again. This * does NOT invoke destructors */ -void OPKI_UnsafeClearObjectTable(OPKI_ObjectTable* table); +void OPKI_UnsafeClearObjectTable(const OPKI_ObjectTable* table); /** Gets the number of objects used from the given table. */ -uint32_t OPKI_GetObjectTableUseCount(OPKI_ObjectTable* table); +uint32_t OPKI_GetObjectTableUseCount(const OPKI_ObjectTable* table); #ifdef __cplusplus } // extern "C" diff --git a/oemcrypto/opk/oemcrypto_ta/oemcrypto_usage_table.c b/oemcrypto/opk/oemcrypto_ta/oemcrypto_usage_table.c index 997a5dd..98ecd86 100644 --- a/oemcrypto/opk/oemcrypto_ta/oemcrypto_usage_table.c +++ b/oemcrypto/opk/oemcrypto_ta/oemcrypto_usage_table.c @@ -1426,7 +1426,7 @@ OEMCryptoResult OPKI_ShrinkUsageTableHeader(uint32_t new_entry_count, LOGE("Usage table not initialized"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (new_entry_count >= g_usage_table.table_size) { + if (new_entry_count > g_usage_table.table_size) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } for (size_t i = new_entry_count; i < g_usage_table.table_size; i++) { diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi/README.md b/oemcrypto/opk/oemcrypto_ta/wtpi/README.md index 066082d..8f07d7e 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi/README.md +++ b/oemcrypto/opk/oemcrypto_ta/wtpi/README.md @@ -3,36 +3,33 @@ Some of the headers in wtpi/ directory are tested by the code in wtpi_test/. wtpi_test uses serialization/generator/scrape_interface.py to parse the WTPI interface declarations and generate serialization APIs such as: -* OPK_Pack_SaveGenerationNumber_Request(), -* OPK_Unpack_K1_DeriveKeyFromKeyHandle_Response(), + +* `OPK_Pack_SaveGenerationNumber_Request()` +* `OPK_Unpack_K1_DeriveKeyFromKeyHandle_Response()` * ... In order for the types of the parameters of these WTPI interfaces to be correctly determined and inserted into the auto-generated -OPK_Pack_* / OPK_Unpack_* functions, certain naming conventions have to be -followed: - -* To pack a variable length buffer X with type uint8_t*, the size of the -array must be named as "X_length" or XLength". -* If an output variable length buffer doesn't have an output size specified in -the parameter list, and is supposed to have the same size as the input buffer, -then the output buffer must be named as "out_buffer". - -Below is an example following the naming convention above: -``` -OEMCryptoResult WTPI_C1_SHA256(const uint8_t* input, size_t input_length, - uint8_t* out_buffer); -``` -You can find more details in scrape_interface.py for what is looked for by the -parser. +OPK_Pack_* / OPK_Unpack_* functions, +[certain naming conventions][naming-conventions] have to be followed. WTPI interfaces that are currently covered by wtpi_test: -* wtpi_generation_number_interface.h, -* wtpi_crypto_and_key_management_interface_layer1.h, -* wtpi_crypto_asymmetric_interface.h, -* wtpi_crc32_interface.h, -* wtpi_provisioning_4_interface.h, + +* wtpi_generation_number_interface.h +* wtpi_crypto_and_key_management_interface_layer1.h +* wtpi_crypto_asymmetric_interface.h +* wtpi_provisioning_4_interface.h +* wtpi_crc32_interface.h +* wtpi_clock_interface_layer1.h +* wtpi_config_interface.h +* wtpi_device_key_interface.h + +However, all WTPI interface may potentially be covered someday, so it's best +practice to always follow [the naming conventions][naming-conventions]. Please be cautious when updating parameter names in these interfaces. It can potentially break the auto-generated serialization functions used by the WTPI -tests if the naming convention is not enforced. +tests if the naming conventions are not enforced. It can also cause the +generator to generate invalid or insecure code. + +[naming-conventions]: https://g3doc.corp.google.com/video/widevine/g3doc/devices/oec_function_conventions.md diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/cose_util.c b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/cose_util.c index 7de7870..58de948 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_reference/cose_util.c +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_reference/cose_util.c @@ -13,6 +13,7 @@ #include "dice/cbor_writer.h" #include "dice/config.h" #include "dice/dice.h" +#include "oemcrypto_api_macros.h" #include "oemcrypto_check_macros.h" #include "wtpi_crypto_and_key_management_interface_layer1.h" #include "wtpi_crypto_asymmetric_interface.h" @@ -217,20 +218,23 @@ static DiceResult EncodeConfigurationDescriptor(size_t buffer_size, CborOutInit(buffer, buffer_size, &out); CborWriteMap(/*num_pairs=*/2, &out); + char str_buf[32] = {0}; // Add component name. CborWriteInt(kComponentNameLabel, &out); if (is_leaf) { // The leaf certificate's component name must contain "Widevine". CborWriteTstr("Widevine", &out); } else { - char buf[32] = {0}; - snprintf(buf, sizeof(buf), "Component %u", entry_index); - CborWriteTstr(buf, &out); + snprintf(str_buf, sizeof(str_buf), "Component %u", entry_index); + CborWriteTstr(str_buf, &out); + memset(str_buf, 0, sizeof(str_buf)); } // Add component version. CborWriteInt(kComponentVersionLabel, &out); - CborWriteTstr("19", &out); + snprintf(str_buf, sizeof(str_buf), "%d", API_MAJOR_VERSION); + CborWriteTstr(str_buf, &out); + memset(str_buf, 0, sizeof(str_buf)); if (CborOutOverflowed(&out)) { return kDiceResultBufferTooSmall; @@ -423,7 +427,13 @@ static OEMCryptoResult GenerateEncodedBccPayload( // Add the profile name. CborWriteInt(kProfileNameLabel, &cbor_out); - CborWriteTstr("android.15", &cbor_out); + if (is_leaf) { + snprintf(str_buf, sizeof(str_buf), "widevine.%d", API_MAJOR_VERSION); + CborWriteTstr(str_buf, &cbor_out); + memset(str_buf, 0, sizeof(str_buf)); + } else { + CborWriteTstr("android.15", &cbor_out); + } // Add the subject public key. CborWriteInt(kSubjectPublicKeyLabel, &cbor_out); diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/cose_util.cpp b/oemcrypto/opk/oemcrypto_ta/wtpi_test/cose_util.cpp index aae843a..4f51e70 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/cose_util.cpp +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/cose_util.cpp @@ -87,6 +87,7 @@ void print_cbor(cn_cbor* cn, uint32_t type) { } namespace wtpi_test { +namespace { // Copied and modified from open-dice test_utils.cc ScopedCbor ExtractCwtFromCborCertificate(const uint8_t* certificate, size_t certificate_size) { @@ -157,6 +158,7 @@ ScopedCbor ExtractPublicKeyFromCwt(const cn_cbor* cwt) { } return key; } +} // namespace ScopedCbor ExtractPublicKeyFromBcc(const uint8_t* bytes, size_t bytes_len) { // Get bcc payload, which is a CBOR Web Token. diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/legacy_keywrap_test.cpp b/oemcrypto/opk/oemcrypto_ta/wtpi_test/legacy_keywrap_test.cpp index 96ae90c..6503daa 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/legacy_keywrap_test.cpp +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/legacy_keywrap_test.cpp @@ -16,6 +16,8 @@ #include "wtpi_device_key_interface.h" #define UUID_LENGTH 16 + +namespace { // This struct represents a wrapped blob that we do not yet know how to // interpret. It contains only the fields that we expect every versioned blob to // have. @@ -27,11 +29,11 @@ typedef struct WrappedData { } WrappedData; // The randomly-generated UUID that identifies a blob as a WrappedData struct, // in network byte order. -static const uint8_t kMagicUuid[UUID_LENGTH] = { - 0xb5, 0x76, 0x3b, 0xad, 0x84, 0x05, 0x40, 0xfd, - 0xa0, 0x88, 0x3b, 0x6c, 0x69, 0x97, 0xfc, 0x74}; +const uint8_t kMagicUuid[UUID_LENGTH] = {0xb5, 0x76, 0x3b, 0xad, 0x84, 0x05, + 0x40, 0xfd, 0xa0, 0x88, 0x3b, 0x6c, + 0x69, 0x97, 0xfc, 0x74}; // 1 in network byte order -static const uint8_t kVersionOne[sizeof(uint32_t)] = {0x00, 0x00, 0x00, 0x01}; +const uint8_t kVersionOne[sizeof(uint32_t)] = {0x00, 0x00, 0x00, 0x01}; // This is the layout of the |data| field of a WrappedData structure when its // |version| field is 1. typedef struct WrappedData_V1 { @@ -39,15 +41,15 @@ typedef struct WrappedData_V1 { uint8_t enc_data[]; } WrappedData_V1; -static OEMCryptoResult GetEncryptAndSignSize(uint32_t context, size_t in_size, - size_t* wrapped_size) { +OEMCryptoResult GetEncryptAndSignSize(uint32_t context, size_t in_size, + size_t* wrapped_size) { *wrapped_size = in_size + sizeof(WrappedData) + sizeof(WrappedData_V1); return OEMCrypto_SUCCESS; } OEMCryptoResult EncryptAndSign_V1(uint32_t context, const uint8_t* data, - size_t data_size, uint8_t* out, - size_t* out_size) { + size_t data_size, uint8_t* out, + size_t* out_size) { if (!out_size) { return OEMCrypto_ERROR_INVALID_CONTEXT; } @@ -91,6 +93,7 @@ OEMCryptoResult EncryptAndSign_V1(uint32_t context, const uint8_t* data, WTPI_K1_FreeKeyHandle(signing_key); return result; } +} // namespace class LegacyKeywrapTest : public ::testing::Test { protected: diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/ssl_util.cpp b/oemcrypto/opk/oemcrypto_ta/wtpi_test/ssl_util.cpp index 81028a1..3a8526a 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/ssl_util.cpp +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/ssl_util.cpp @@ -7,6 +7,7 @@ #include "log.h" +namespace { void dump_ssl_error(void) { int count = 0; unsigned long err; @@ -17,6 +18,7 @@ void dump_ssl_error(void) { LOGE("SSL Error %d -- %lu -- %s", count, err, buffer); } } +} // namespace bool DeserializePKCS8PrivateKey(const uint8_t* serialized_bytes, size_t size, RSA** rsa) { diff --git a/oemcrypto/opk/oemcrypto_ta/wtpi_test/test_rsa_key.cpp b/oemcrypto/opk/oemcrypto_ta/wtpi_test/test_rsa_key.cpp index c55f0b8..0cc52f4 100644 --- a/oemcrypto/opk/oemcrypto_ta/wtpi_test/test_rsa_key.cpp +++ b/oemcrypto/opk/oemcrypto_ta/wtpi_test/test_rsa_key.cpp @@ -12,7 +12,10 @@ * This is a PKCS8 RSA key encoded in DER format. */ -#include "stdint.h" +#include "test_common.h" + +#include + uint8_t test_rsa_key_der[] = { 0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, diff --git a/oemcrypto/opk/ports/linux/cas/tee/tee_simulator_cas/Makefile b/oemcrypto/opk/ports/linux/cas/tee/tee_simulator_cas/Makefile index 1931349..af2bb09 100644 --- a/oemcrypto/opk/ports/linux/cas/tee/tee_simulator_cas/Makefile +++ b/oemcrypto/opk/ports/linux/cas/tee/tee_simulator_cas/Makefile @@ -55,7 +55,16 @@ cflags += \ -DWTPI_BUILD_INFO=\"$(WTPI_BUILD_INFO)\" \ -DSUPPORT_CAS \ -DWV_POSIX_RESOURCE_ID=\"$(project)\" \ - -D_DEFAULT_SOURCE + -DOPK_CONFIG_SOC_VENDOR_NAME=$(SOC_VENDOR) \ + -DOPK_CONFIG_SOC_MODEL_NAME=$(SOC_MODEL) \ + -DOPK_CONFIG_TEE_OS_NAME=$(TEE_OS) \ + -DOPK_CONFIG_TEE_OS_VERSION=$(TEE_VERSION) \ + -DOPK_CONFIG_DEVICE_FORM_FACTOR=$(DEVICE_FORM_FACTOR) \ + -DOPK_CONFIG_IMPLEMENTER_NAME=$(IMPLEMENTER) \ + -DOPK_CONFIG_PROVISIONING_METHOD=$(PROVISIONING_METHOD) \ + -D_DEFAULT_SOURCE \ + -fstack-protector-strong \ + -D_DEBUG ldflags = \ -lrt -lpthread \ diff --git a/oemcrypto/opk/ports/linux/cas/tee/tee_simulator_cas/data_share.h b/oemcrypto/opk/ports/linux/cas/tee/tee_simulator_cas/data_share.h index 8b623e0..095930a 100644 --- a/oemcrypto/opk/ports/linux/cas/tee/tee_simulator_cas/data_share.h +++ b/oemcrypto/opk/ports/linux/cas/tee/tee_simulator_cas/data_share.h @@ -9,7 +9,7 @@ #include #include #include "OEMCryptoCENC.h" -#include "wtpi_config_macros.h" +#include "opk_config.h" #include "wtpi_crypto_and_key_management_interface_layer1.h" #ifdef __cplusplus diff --git a/oemcrypto/opk/ports/linux/common/tos_transport.cpp b/oemcrypto/opk/ports/linux/common/tos_transport.cpp index e8d431e..9074bf5 100644 --- a/oemcrypto/opk/ports/linux/common/tos_transport.cpp +++ b/oemcrypto/opk/ports/linux/common/tos_transport.cpp @@ -9,6 +9,8 @@ // posix_services.h implementation of semaphores and shared memory // which is based on the POSIX shared memory and semaphore libraries. +#include "tos_transport.h" + #include "odk_message.h" #include "posix_resources.h" #include "tos_transport_interface.h" @@ -20,19 +22,20 @@ using namespace posix; +namespace { // message request/response payload data -static RequestResponseBlock* shared_memory_ = nullptr; +RequestResponseBlock* shared_memory_ = nullptr; // mailbox containing the size of the payload -static MailboxBlock* mailbox_memory_ = nullptr; +MailboxBlock* mailbox_memory_ = nullptr; // post when a request message is ready -static RequestSemaphore* request_semaphore_ = nullptr; +RequestSemaphore* request_semaphore_ = nullptr; // post when a response message is ready -static ResponseSemaphore* response_semaphore_ = nullptr; +ResponseSemaphore* response_semaphore_ = nullptr; -static void ReleaseResources() { +void ReleaseResources() { if (shared_memory_) { delete shared_memory_; shared_memory_ = nullptr; @@ -51,6 +54,25 @@ static void ReleaseResources() { } } +// Get the size of the message from the mailbox and return it +uint32_t PeekSize(void) { + uint8_t* mailbox = mailbox_memory_->GetAddress(); + uint32_t message_size = (uint32_t)mailbox[0] | (uint32_t)mailbox[1] << 8 | + (uint32_t)mailbox[2] << 16 | + (uint32_t)mailbox[3] << 24; + return message_size; +} + +// Put the size of the message into the mailbox +void PokeSize(uint32_t size) { + uint8_t* mailbox = mailbox_memory_->GetAddress(); + mailbox[0] = (uint8_t)(size); + mailbox[1] = (uint8_t)(size >> 8); + mailbox[2] = (uint8_t)(size >> 16); + mailbox[3] = (uint8_t)(size >> 24); +} +} // namespace + bool TOS_Transport_Initialize(void) { if (!(shared_memory_ = new RequestResponseBlock()) || !(shared_memory_->Allocate(OPK_TRANSPORT_MESSAGE_SIZE))) { @@ -94,24 +116,6 @@ void TOS_Transport_ReleaseMessage(ODK_Message* message) { (void)message; } -// Get the size of the message from the mailbox and return it -static uint32_t PeekSize(void) { - uint8_t* mailbox = mailbox_memory_->GetAddress(); - uint32_t message_size = (uint32_t)mailbox[0] | (uint32_t)mailbox[1] << 8 | - (uint32_t)mailbox[2] << 16 | - (uint32_t)mailbox[3] << 24; - return message_size; -} - -// Put the size of the message into the mailbox -static void PokeSize(uint32_t size) { - uint8_t* mailbox = mailbox_memory_->GetAddress(); - mailbox[0] = (uint8_t)(size); - mailbox[1] = (uint8_t)(size >> 8); - mailbox[2] = (uint8_t)(size >> 16); - mailbox[3] = (uint8_t)(size >> 24); -} - // The request has been packed into the shared memory, all we need to // do is poke the message size in the mailbox and post on the request // semaphore, then wait for the response semaphore. The response will diff --git a/oemcrypto/opk/ports/linux/rules.mk b/oemcrypto/opk/ports/linux/rules.mk index e218fdc..4e263d4 100644 --- a/oemcrypto/opk/ports/linux/rules.mk +++ b/oemcrypto/opk/ports/linux/rules.mk @@ -52,6 +52,7 @@ cflags_c += \ cppflags += \ $(cflags) \ + -std=c++17 \ $(CPPFLAGS) # Filter out files and directories in third_party. @@ -105,7 +106,9 @@ define clang-tidy-rule .PHONY: clang-tidy-$(1) clang-tidy-$(1): @$(cmd-echo-silent) ' CLANG-TIDY $(1)' - ${q}clang-tidy $(clang-tidy-flags) $(1) -- $(cflags) + ${q}clang-tidy $(clang-tidy-flags) $(1) -- $(cflags) \ + $(if $(filter .c,$(suffix $(1))),-std=c11 -D_POSIX_C_SOURCE=200809L) \ + $(if $(filter .cpp,$(suffix $(1))),-std=c++17) endef define clang-tidy-rule-cpp diff --git a/oemcrypto/opk/ports/linux/ta/common/opk_config.h b/oemcrypto/opk/ports/linux/ta/common/opk_config.h index 7e78d44..91d1649 100644 --- a/oemcrypto/opk/ports/linux/ta/common/opk_config.h +++ b/oemcrypto/opk/ports/linux/ta/common/opk_config.h @@ -8,7 +8,7 @@ #define OPK_CONFIG_H_ #ifndef OPK_CONFIG_SECURITY_LEVEL -# define OPK_CONFIG_SECURITY_LEVEL OEMCrypto_Level3 +# define OPK_CONFIG_SECURITY_LEVEL OEMCrypto_Level1 #endif #ifndef OPK_CONFIG_RESOURCE_RATING_TIER diff --git a/oemcrypto/opk/ports/linux/ta/common/tee_simulator.cpp b/oemcrypto/opk/ports/linux/ta/common/tee_simulator.cpp index a0a1a9e..daf6aa3 100644 --- a/oemcrypto/opk/ports/linux/ta/common/tee_simulator.cpp +++ b/oemcrypto/opk/ports/linux/ta/common/tee_simulator.cpp @@ -19,6 +19,7 @@ static pthread_t main_thread_tid; static bool thread_running = false; +namespace { void signalHandler(int signum) { (void)signum; // TODO(fredgc): this doesn't actually kill anything because the main loop is @@ -27,6 +28,7 @@ void signalHandler(int signum) { // This exits, but then we skip the OPK_Terminate call. exit(0); } +} // namespace // The request message data must be copied into a local buffer // so the contents can't be modified while being parsed. diff --git a/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/oemcrypto_unittests_main.cpp b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/oemcrypto_unittests_main.cpp index 56b3817..960f09f 100644 --- a/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/oemcrypto_unittests_main.cpp +++ b/oemcrypto/opk/ports/optee/host/oemcrypto_unittests/oemcrypto_unittests_main.cpp @@ -9,7 +9,9 @@ #include "oemcrypto_corpus_generator_helper.h" #include "test_sleep.h" -static void acknowledge_cast() { +namespace { + +void acknowledge_cast() { std::cout << "==================================================================\n" << "= This device is expected to load x509 certs as a cast receiver. =\n" @@ -38,6 +40,8 @@ int CheckAndInstallProv30ROT() { return 0; } +} // namespace + // This special main procedure is used instead of the standard GTest main, // because we need to initialize the list of features supported by the device. // Also, the test filter is updated based on the feature list. diff --git a/oemcrypto/opk/ports/optee/host/rules.mk b/oemcrypto/opk/ports/optee/host/rules.mk index 80e0600..cff924a 100644 --- a/oemcrypto/opk/ports/optee/host/rules.mk +++ b/oemcrypto/opk/ports/optee/host/rules.mk @@ -106,7 +106,9 @@ define clang-tidy-rule .PHONY: clang-tidy-$(1) clang-tidy-$(1): @$(cmd-echo-silent) ' CLANG-TIDY $(1)' - ${q}clang-tidy $(clang-tidy-flags) $(1) -- $(cflags) + ${q}clang-tidy $(clang-tidy-flags) $(1) -- $(cflags) \ + $(if $(filter .c,$(suffix $(1))),-std=c11 -D_POSIX_C_SOURCE=200809L) \ + $(if $(filter .cpp,$(suffix $(1))),-std=c++17) endef define clang-tidy-rule-cpp diff --git a/oemcrypto/opk/ports/optee/ta/rules.mk b/oemcrypto/opk/ports/optee/ta/rules.mk index b5062c9..a3a0002 100644 --- a/oemcrypto/opk/ports/optee/ta/rules.mk +++ b/oemcrypto/opk/ports/optee/ta/rules.mk @@ -28,6 +28,8 @@ clang-tidy-flags = \ clang-tidy-cflags = \ -m$(ARCH) \ + $(if $(filter .c,$(suffix $(1))),-std=c11 -D_POSIX_C_SOURCE=200809L) \ + $(if $(filter .cpp,$(suffix $(1))),-std=c++17) \ $(comp-cppflags-$(call oname,$(1))) # Define a rule template to run clang-tidy with a single source file. diff --git a/oemcrypto/opk/ports/trusty/ta/reference/clang-tidy-inc.mk b/oemcrypto/opk/ports/trusty/ta/reference/clang-tidy-inc.mk index b4f22cb..f26cf9d 100644 --- a/oemcrypto/opk/ports/trusty/ta/reference/clang-tidy-inc.mk +++ b/oemcrypto/opk/ports/trusty/ta/reference/clang-tidy-inc.mk @@ -26,6 +26,8 @@ clang-tidy-flags := \ clang-tidy-cflags := \ $(MODULE_CFLAGS) \ + $(if $(filter .c,$(suffix $(1))),-std=c11 -D_POSIX_C_SOURCE=200809L) \ + $(if $(filter .cpp,$(suffix $(1))),-std=c++17) \ $(addprefix -D,$(MODULE_DEFINES) TRUSTY_USERSPACE) \ $(addprefix -I,\ $(MODULE_INCLUDES) \ @@ -37,7 +39,7 @@ clang-tidy-cflags := \ define clang-tidy-rule .PHONY: clang-tidy-$(1) clang-tidy-$(1): clang-tidy-flags := $(clang-tidy-flags) -clang-tidy-$(1): clang-tidy-cflags := $(clang-tidy-cflags) +clang-tidy-$(1): clang-tidy-cflags := $(call clang-tidy-cflags,$(1)) clang-tidy-$(1): @echo running clang-tidy: $(1) $(NOECHO)clang-tidy $(clang-tidy-flags) $(1) -- $(clang-tidy-cflags) diff --git a/oemcrypto/opk/ports/trusty/ta/reference/wtpi_lib/impl/crypto/ref/rules.mk b/oemcrypto/opk/ports/trusty/ta/reference/wtpi_lib/impl/crypto/ref/rules.mk new file mode 100644 index 0000000..f7d7734 --- /dev/null +++ b/oemcrypto/opk/ports/trusty/ta/reference/wtpi_lib/impl/crypto/ref/rules.mk @@ -0,0 +1,75 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULE := $(LOCAL_DIR) + +WV_TA_TOP_LEVEL := $(LOCAL_DIR)/../../../../ +SHARED_DIR := $(WV_TA_TOP_LEVEL)/shared +IMPL_DIR := $(WV_TA_TOP_LEVEL)/interface_impls + +CDM_DIR := trusty/vendor/widevine/cdm +APP_DIR := $(CDM_DIR)/oemcrypto/opk/oemcrypto_ta +SERIALIZATION_DIR := $(CDM_DIR)/oemcrypto/opk/serialization +ODK_DIR := $(CDM_DIR)/oemcrypto/odk + +ifndef WIDEVINE_PROVISION_METHOD +$(error WIDEVINE_PROVISION_METHOD is not set. \ + Please set it in the [target_name]-inc.mk file of your project) +endif + +MODULE_DEFINES += \ + WIDEVINE_PROVISION_METHOD=$(WIDEVINE_PROVISION_METHOD) \ + +# Default value if WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE is not set by *-inc.mk. +WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE ?= 0 +MODULE_DEFINES += \ + WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE=$(WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE) + +MODULE_DEFINES += \ + OPK_CONFIG_SOC_VENDOR_NAME=Google \ + OPK_CONFIG_SOC_MODEL_NAME=$(PLATFORM) \ + OPK_CONFIG_TEE_OS_NAME=Trusty \ + OPK_CONFIG_TEE_OS_VERSION=0.0 \ + OPK_CONFIG_DEVICE_FORM_FACTOR=phone+tablet \ + OPK_CONFIG_IMPLEMENTER_NAME=Widevine \ + WTPI_BUILD_INFO=TRUSTY \ + +# Widevine vendor code assumes trusty defines __linux__. We need to get this +# fixed upstream. TODO(b/232255239) +MODULE_CFLAGS += -D__linux__ + +MODULE_SRCS += \ + $(APP_DIR)/wtpi_reference/wtpi_decrypt_sample.c \ + +MODULE_INCLUDES += \ + $(LOCAL_DIR)/include \ + $(SHARED_DIR)/include \ + +MODULE_INCLUDES += \ + $(CDM_DIR)/oemcrypto/include \ + $(ODK_DIR)/include \ + $(CDM_DIR)/oemcrypto/odk/src \ + $(IMPL_DIR) \ + $(APP_DIR) \ + $(WV_TA_TOP_LEVEL)/include \ + $(APP_DIR)/wtpi \ + $(APP_DIR)/wtpi_reference \ + +MODULE_LIBRARY_DEPS += \ + trusty/user/base/lib/libc-trusty \ + +include make/library.mk diff --git a/oemcrypto/opk/ports/trusty/ta/reference/wtpi_lib/impl/device_key/ref/rules.mk b/oemcrypto/opk/ports/trusty/ta/reference/wtpi_lib/impl/device_key/ref/rules.mk new file mode 100644 index 0000000..cbe5024 --- /dev/null +++ b/oemcrypto/opk/ports/trusty/ta/reference/wtpi_lib/impl/device_key/ref/rules.mk @@ -0,0 +1,71 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULE := $(LOCAL_DIR) + +TOP_LEVEL := $(LOCAL_DIR)/../../../../ +SHARED_DIR := $(TOP_LEVEL)/shared +IMPL_DIR := $(TOP_LEVEL)/interface_impls + +CDM_DIR := trusty/vendor/widevine/cdm +APP_DIR := $(CDM_DIR)/oemcrypto/opk/oemcrypto_ta +SERIALIZATION_DIR := $(CDM_DIR)/oemcrypto/opk/serialization +ODK_DIR := $(CDM_DIR)/oemcrypto/odk + +ifndef WIDEVINE_PROVISION_METHOD +$(error WIDEVINE_PROVISION_METHOD is not set. \ + Please set it in the [target_name]-inc.mk file of your project) +endif + +MODULE_DEFINES += \ + WIDEVINE_PROVISION_METHOD=$(WIDEVINE_PROVISION_METHOD) \ + +# Default value if WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE is not set by *-inc.mk. +WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE ?= 0 +MODULE_DEFINES += \ + WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE=$(WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE) + +MODULE_DEFINES += \ + OPK_CONFIG_SOC_VENDOR_NAME=Google \ + OPK_CONFIG_SOC_MODEL_NAME=$(PLATFORM) \ + OPK_CONFIG_TEE_OS_NAME=Trusty \ + OPK_CONFIG_TEE_OS_VERSION=0.0 \ + OPK_CONFIG_DEVICE_FORM_FACTOR=phone+tablet \ + OPK_CONFIG_IMPLEMENTER_NAME=Widevine \ + WTPI_BUILD_INFO=TRUSTY \ + +MODULE_SRCS += \ + $(IMPL_DIR)/derive_key.c \ + +MODULE_INCLUDES += \ + $(LOCAL_DIR)/include \ + $(SHARED_DIR)/include \ + +MODULE_INCLUDES += \ + $(CDM_DIR)/oemcrypto/include \ + $(ODK_DIR)/include \ + $(CDM_DIR)/oemcrypto/odk/src \ + $(IMPL_DIR) \ + $(APP_DIR) \ + $(TOP_LEVEL)/include \ + $(APP_DIR)/wtpi \ + $(APP_DIR)/wtpi_reference \ + +MODULE_LIBRARY_DEPS += \ + trusty/user/base/lib/hwkey \ + +include make/library.mk diff --git a/oemcrypto/opk/ports/trusty/ta/reference/wtpi_lib/impl/storage/ref/rules.mk b/oemcrypto/opk/ports/trusty/ta/reference/wtpi_lib/impl/storage/ref/rules.mk new file mode 100644 index 0000000..df5fa14 --- /dev/null +++ b/oemcrypto/opk/ports/trusty/ta/reference/wtpi_lib/impl/storage/ref/rules.mk @@ -0,0 +1,95 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_DIR := $(GET_LOCAL_DIR) + +MODULE := $(LOCAL_DIR) + +WV_TA_TOP_LEVEL := $(LOCAL_DIR)/../../../../ +SHARED_DIR := $(WV_TA_TOP_LEVEL)/shared +IMPL_DIR := $(WV_TA_TOP_LEVEL)/interface_impls + +CDM_DIR := trusty/vendor/widevine/cdm +APP_DIR := $(CDM_DIR)/oemcrypto/opk/oemcrypto_ta +SERIALIZATION_DIR := $(CDM_DIR)/oemcrypto/opk/serialization +ODK_DIR := $(CDM_DIR)/oemcrypto/odk + +ifndef WIDEVINE_PROVISION_METHOD +$(error WIDEVINE_PROVISION_METHOD is not set. \ + Please set it in the [target_name]-inc.mk file of your project) +endif + +# oemcrypto.h will declare constants as C++-style statics. +# C sources do not like this, so change the behavior. +MODULE_CFLAGS += -DNO_OEMCRYPTO_VARIABLE_DEFINITIONS + +# Ensure API entry points are renamed in a predictable manner. +# TODO: can we remove this? +MODULE_CFLAGS += -DOEMCRYPTO_TA_TEST_ONLY + +# TODO: remove when the prototypes in oemcrypto.h are strict. +MODULE_CFLAGS += -Wno-strict-prototypes + +# TODO: remove when unused variable in dump_ssl_error() is fixed +MODULE_CFLAGS += -Wno-error=unused-but-set-variable + +MODULE_DEFINES += \ + WIDEVINE_PROVISION_METHOD=$(WIDEVINE_PROVISION_METHOD) \ + +# Default value if WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE is not set by *-inc.mk. +WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE ?= 0 +MODULE_DEFINES += \ + WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE=$(WIDEVINE_PROVISION_BCC_SIGNATURE_TYPE) + +MODULE_DEFINES += \ + OPK_CONFIG_SOC_VENDOR_NAME=Google \ + OPK_CONFIG_SOC_MODEL_NAME=$(PLATFORM) \ + OPK_CONFIG_TEE_OS_NAME=Trusty \ + OPK_CONFIG_TEE_OS_VERSION=0.0 \ + OPK_CONFIG_DEVICE_FORM_FACTOR=phone+tablet \ + OPK_CONFIG_IMPLEMENTER_NAME=Widevine \ + WTPI_BUILD_INFO=TRUSTY \ + +# Widevine vendor code assumes trusty defines __linux__. We need to get this +# fixed upstream. TODO(b/232255239) +MODULE_CFLAGS += -D__linux__ + +# The base Trusty app. +MODULE_SRCS += \ + $(IMPL_DIR)/wtpi_persistent_storage_layer1.c \ + $(IMPL_DIR)/wtpi_initialize_terminate.c \ + $(IMPL_DIR)/wtpi_root_of_trust_layer2.c \ + $(WV_TA_TOP_LEVEL)/tee_context.c \ + +MODULE_INCLUDES += \ + $(WV_TA_TOP_LEVEL)/include \ + $(CDM_DIR)/oemcrypto/include \ + $(ODK_DIR)/include \ + $(SERIALIZATION_DIR)/common \ + $(SERIALIZATION_DIR)/common/include \ + $(CDM_DIR)/oemcrypto/odk/src \ + $(SERIALIZATION_DIR)/os_interfaces \ + $(IMPL_DIR) \ + +MODULE_INCLUDES += \ + $(APP_DIR) \ + $(APP_DIR)/wtpi \ + $(APP_DIR)/wtpi_reference \ + +MODULE_LIBRARY_DEPS += \ + trusty/user/base/lib/libc-trusty \ + trusty/user/base/lib/storage \ + +include make/library.mk diff --git a/oemcrypto/opk/serialization/common/bump_allocator.c b/oemcrypto/opk/serialization/common/bump_allocator.c index e2ea685..5466219 100644 --- a/oemcrypto/opk/serialization/common/bump_allocator.c +++ b/oemcrypto/opk/serialization/common/bump_allocator.c @@ -52,6 +52,6 @@ UBSAN_IGNORE_UNSIGNED_OVERFLOW void* OPK_BumpAllocate(size_t nbytes) { void OPK_BumpAllocator_Reset(void) { LOGV("bump allocator capacity = %d", BUFFER_SIZE); - memset(buffer, 0, BUFFER_SIZE); + memset(buffer, 0, buffer_offset); buffer_offset = 0; } diff --git a/oemcrypto/opk/serialization/common/shared_buffer_allocator.c b/oemcrypto/opk/serialization/common/shared_buffer_allocator.c index 1c0efbd..ef457f5 100644 --- a/oemcrypto/opk/serialization/common/shared_buffer_allocator.c +++ b/oemcrypto/opk/serialization/common/shared_buffer_allocator.c @@ -122,7 +122,7 @@ void OPK_SharedBuffer_Terminate(void) { * allocated. */ void OPK_SharedBuffer_Reset(void) { - memset(&allocations_[0], 0, sizeof(allocations_)); + memset(&allocations_[0], 0, buffer_count_ * sizeof(allocations_[0])); next_buffer_offset_ = 0; next_buffer_index_ = 0; buffer_count_ = 0; diff --git a/oemcrypto/test/Android.mk b/oemcrypto/test/Android.mk deleted file mode 100644 index 98e9b4d..0000000 --- a/oemcrypto/test/Android.mk +++ /dev/null @@ -1,27 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_C_INCLUDES := \ - vendor/widevine/libwvdrmengine/cdm/util/include \ - -LOCAL_MODULE:=oemcrypto_test -LOCAL_LICENSE_KINDS:=legacy_by_exception_only legacy_proprietary -LOCAL_LICENSE_CONDITIONS:=by_exception_only proprietary by_exception_only -LOCAL_MODULE_TAGS := tests - -LOCAL_MODULE_OWNER := widevine -LOCAL_PROPRIETARY_MODULE := true - -LOCAL_C_INCLUDES += external/googletest/googlemock/include \ - -# When built, explicitly put it in the DATA/nativetest directory. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest - -ifneq ($(TARGET_ENABLE_MEDIADRM_64), true) -LOCAL_MODULE_TARGET_ARCH := arm x86 mips -endif - -include $(LOCAL_PATH)/common.mk - -include $(BUILD_EXECUTABLE) diff --git a/oemcrypto/test/GEN_api_lock_file.c b/oemcrypto/test/GEN_api_lock_file.c index 9a5af65..0481006 100644 --- a/oemcrypto/test/GEN_api_lock_file.c +++ b/oemcrypto/test/GEN_api_lock_file.c @@ -450,3 +450,11 @@ OEMCryptoResult _oecc157(OEMCrypto_SESSION session, uint8_t* wrapped_pvr_key, OEMCryptoResult _oecc158(OEMCrypto_SESSION session, const uint8_t* wrapped_pvr_key, size_t wrapped_pvr_key_length); + +// OEMCrypto_LoadLicenseData defined in v19.6 +OEMCryptoResult _oecc159(OEMCrypto_SESSION session, const uint8_t* data, + size_t data_length); + +// OEMCrypto_SaveLicenseData defined in v19.6 +OEMCryptoResult _oecc160(OEMCrypto_SESSION session, uint8_t* data, + size_t* data_length); diff --git a/oemcrypto/test/common.mk b/oemcrypto/test/common.mk deleted file mode 100644 index 2e9cb1b..0000000 --- a/oemcrypto/test/common.mk +++ /dev/null @@ -1,76 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -ifeq ($(filter mips mips64, $(TARGET_ARCH)),) -# Tests need to be compatible with devices that do not support gnu hash-style -LOCAL_LDFLAGS+=-Wl,--hash-style=both -endif - -# The unit tests can access v15 functions through the dynamic adapter: -LOCAL_CFLAGS += -DTEST_OEMCRYPTO_V15 - -LOCAL_SRC_FILES:= \ - GEN_api_lock_file.c \ - oec_device_features.cpp \ - oec_decrypt_fallback_chain.cpp \ - oec_key_deriver.cpp \ - oec_session_util.cpp \ - oemcrypto_corpus_generator_helper.cpp \ - oemcrypto_session_tests_helper.cpp \ - oemcrypto_basic_test.cpp \ - oemcrypto_cast_test.cpp \ - oemcrypto_decrypt_test.cpp \ - oemcrypto_generic_crypto_test.cpp \ - oemcrypto_license_test.cpp \ - oemcrypto_provisioning_test.cpp \ - oemcrypto_security_test.cpp \ - oemcrypto_usage_table_test.cpp \ - oemcrypto_test.cpp \ - oemcrypto_test_android.cpp \ - oemcrypto_test_main.cpp \ - ota_keybox_test.cpp \ - ../../cdm/util/test/test_sleep.cpp \ - ../util/src/bcc_validator.cpp \ - ../util/src/cbor_validator.cpp \ - ../util/src/device_info_validator.cpp \ - ../util/src/oemcrypto_ecc_key.cpp \ - ../util/src/oemcrypto_rsa_key.cpp \ - ../util/src/prov4_validation_helper.cpp \ - ../util/src/signed_csr_payload_validator.cpp \ - ../util/src/wvcrc.cpp \ - -LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/fuzz_tests \ - $(LOCAL_PATH)/../include \ - $(LOCAL_PATH)/../odk/include \ - $(LOCAL_PATH)/../odk/kdo/include \ - $(LOCAL_PATH)/../ref/src \ - $(LOCAL_PATH)/../util/include \ - vendor/widevine/libwvdrmengine/cdm/core/include \ - vendor/widevine/libwvdrmengine/cdm/util/include \ - vendor/widevine/libwvdrmengine/cdm/util/test \ - -LOCAL_STATIC_LIBRARIES := \ - libcdm \ - libcppbor \ - libjsmn \ - libgmock \ - libgtest \ - libgtest_main \ - libwvlevel3 \ - libcdm_protos \ - libcdm_utils \ - libwv_kdo \ - libwv_odk \ - libPlatformProperties \ - -LOCAL_SHARED_LIBRARIES := \ - libbase \ - libcrypto \ - libdl \ - libbinder_ndk \ - liblog \ - libmedia_omx \ - libprotobuf-cpp-lite \ - libstagefright_foundation \ - libutils \ - libz \ diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_opk_dispatcher_fuzz.cc b/oemcrypto/test/fuzz_tests/oemcrypto_opk_dispatcher_fuzz.cc index 231cf40..e270e4f 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_opk_dispatcher_fuzz.cc +++ b/oemcrypto/test/fuzz_tests/oemcrypto_opk_dispatcher_fuzz.cc @@ -7,13 +7,13 @@ namespace { void OpenOEMCryptoTASession() { uint8_t request_body[] = { - 0x06, // TAG_UINT32 + 0x07, // TAG_UINT32 0x09, 0x00, 0x00, 0x00, // API value (0x09) - 0x07, // TAG_UINT64 + 0x08, // TAG_UINT64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Timestamp 0x01, // TAG_BOOL 0x00, // value (false) - 0x0a // TAG_EOM + 0x0b // TAG_EOM }; ODK_Message request = ODK_Message_Create(request_body, sizeof(request_body)); ODK_Message_SetSize(&request, sizeof(request_body)); @@ -23,11 +23,11 @@ void OpenOEMCryptoTASession() { void InitializeOEMCryptoTA() { uint8_t request_body[] = { - 0x06, // TAG_UINT32 + 0x07, // TAG_UINT32 0x01, 0x00, 0x00, 0x00, // API value (0x01) - 0x07, // TAG_UINT64 + 0x08, // TAG_UINT64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Timestamp - 0x0a // TAG_EOM + 0x0b // TAG_EOM }; ODK_Message request = ODK_Message_Create(request_body, sizeof(request_body)); ODK_Message_SetSize(&request, sizeof(request_body)); diff --git a/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp b/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp index be0ab62..52d368d 100644 --- a/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp +++ b/oemcrypto/test/fuzz_tests/oemcrypto_opk_fuzztests.gyp @@ -42,12 +42,8 @@ { 'target_name': 'oemcrypto_opk_dispatcher_fuzz', 'include_dirs': [ - '<(oemcrypto_dir)/opk/serialization/common', '<(oemcrypto_dir)/opk/serialization/common/include', '<(oemcrypto_dir)/opk/serialization/os_interfaces', - '<(oemcrypto_dir)/opk/serialization/tee', - '<(oemcrypto_dir)/opk/serialization/tee/include', - '<(oemcrypto_dir)/opk/ports/trusty/include/', ], 'dependencies': [ '<(oemcrypto_dir)/opk/serialization/tee/tee.gyp:opk_tee', @@ -55,9 +51,9 @@ 'sources': [ 'oemcrypto_opk_dispatcher_fuzz.cc', '<(oemcrypto_dir)/opk/serialization/test/tos_secure_buffers.c', - '<(oemcrypto_dir)/opk/serialization/test/tos_transport_interface.c', '<(oemcrypto_dir)/opk/serialization/test/tos_logging.c', - '<(oemcrypto_dir)/opk/ports/trusty/serialization_adapter/shared_memory.c', + '<(oemcrypto_dir)/opk/serialization/test/tos_shared_memory.c', + '<(oemcrypto_dir)/opk/serialization/test/tos_transport_interface.c', ], }, { diff --git a/oemcrypto/test/oec_session_util.cpp b/oemcrypto/test/oec_session_util.cpp index 70297a8..1e169b4 100644 --- a/oemcrypto/test/oec_session_util.cpp +++ b/oemcrypto/test/oec_session_util.cpp @@ -1796,7 +1796,11 @@ void Session::close() { void Session::GenerateNonce(int* error_counter) { // We make one attempt. If it fails, we assume there was a nonce flood. - if (OEMCrypto_SUCCESS == OEMCrypto_GenerateNonce(session_id(), &nonce_)) { + // Using |temp_nonce| to avoid member |nonce_| being modified + // during failure. + uint32_t temp_nonce = 0; + if (OEMCrypto_SUCCESS == OEMCrypto_GenerateNonce(session_id(), &temp_nonce)) { + nonce_ = temp_nonce; return; } if (error_counter) { @@ -1806,7 +1810,8 @@ void Session::GenerateNonce(int* error_counter) { // The following is after a 1 second pause, so it cannot be from a nonce // flood. ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GenerateNonce(session_id(), &nonce_)); + OEMCrypto_GenerateNonce(session_id(), &temp_nonce)); + nonce_ = temp_nonce; } } diff --git a/oemcrypto/test/oemcrypto_basic_test.cpp b/oemcrypto/test/oemcrypto_basic_test.cpp index 71ad453..e37e2d5 100644 --- a/oemcrypto/test/oemcrypto_basic_test.cpp +++ b/oemcrypto/test/oemcrypto_basic_test.cpp @@ -317,14 +317,14 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) { */ TEST_F(OEMCryptoClientTest, VersionNumber) { const std::string log_message = - "OEMCrypto unit tests for API 19.5. Tests last updated 2025-03-11"; + "OEMCrypto unit tests for API 19.6. Tests last updated 2025-06-03"; cout << " " << log_message << "\n"; cout << " " << "These tests are part of Android V." << "\n"; LOGI("%s", log_message.c_str()); // If any of the following fail, then it is time to update the log message // above. EXPECT_EQ(ODK_MAJOR_VERSION, 19); - EXPECT_EQ(ODK_MINOR_VERSION, 5); + EXPECT_EQ(ODK_MINOR_VERSION, 6); EXPECT_EQ(kCurrentAPI, static_cast(ODK_MAJOR_VERSION)); RecordWvProperty("test_major_version", std::to_string(ODK_MAJOR_VERSION)); RecordWvProperty("test_minor_version", std::to_string(ODK_MINOR_VERSION)); @@ -498,45 +498,58 @@ TEST_F(OEMCryptoClientTest, CheckBuildInformation_OutputLengthAPI17) { ASSERT_GT(build_info_length, kZero) << "Signaling ERROR_SHORT_BUFFER should have assigned a length"; + // Try again using the size they provided, ensuring that it + // is successful. + const size_t initial_estimate_length = build_info_length; + build_info.assign(build_info_length, kNullChar); + result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length); + ASSERT_EQ(result, OEMCrypto_SUCCESS) + << "initial_estimate_length = " << initial_estimate_length + << ", build_info_length (output) = " << build_info_length; + ASSERT_GT(build_info_length, kZero) << "Build info cannot be empty"; + // Ensure the real length is within the size originally specified. + // OK if final length is smaller than estimated length. + ASSERT_LE(build_info_length, initial_estimate_length); + const size_t expected_length = build_info_length; + // Force a ERROR_SHORT_BUFFER using a non-zero value. // Note: It is assumed that vendors will provide more than a single // character of info. - const size_t second_attempt_length = - (build_info_length >= 2) ? build_info_length / 2 : 1; - build_info.assign(second_attempt_length, kNullChar); + const size_t short_length = (expected_length >= 2) ? expected_length / 2 : 1; + build_info.assign(short_length, kNullChar); build_info_length = build_info.size(); result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length); ASSERT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER) - << "second_attempt_length = " << second_attempt_length - << ", build_info_length" << build_info_length; + << "short_length = " << short_length + << ", expected_length = " << expected_length << ", build_info_length" + << build_info_length; // OEM specified build info length should be larger than the // original length if returning ERROR_SHORT_BUFFER. - ASSERT_GT(build_info_length, second_attempt_length); + ASSERT_GT(build_info_length, short_length); // Final attempt with a buffer large enough buffer, padding to // ensure the caller truncates. constexpr size_t kBufferPadSize = 42; - const size_t expected_length = build_info_length; - const size_t final_attempt_length = expected_length + kBufferPadSize; - build_info.assign(final_attempt_length, kNullChar); + const size_t oversize_length = expected_length + kBufferPadSize; + build_info.assign(oversize_length, kNullChar); build_info_length = build_info.size(); result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length); ASSERT_EQ(result, OEMCrypto_SUCCESS) - << "final_attempt_length = " << final_attempt_length + << "oversize_length = " << oversize_length << ", expected_length = " << expected_length - << ", build_info_length = " << build_info_length; + << ", build_info_length (output) = " << build_info_length; // Ensure not empty. ASSERT_GT(build_info_length, kZero) << "Build info cannot be empty"; // Ensure it was truncated down from the padded length. - ASSERT_LT(build_info_length, final_attempt_length) + ASSERT_LT(build_info_length, oversize_length) << "Should have truncated from oversized buffer: expected_length = " << expected_length; - // Ensure the real length is within the size originally specified. - // OK if final length is smaller than estimated length. - ASSERT_LE(build_info_length, expected_length); + // Ensure that length is equal to the length of the previous + // successful call. + ASSERT_EQ(build_info_length, expected_length); } // Verifies that OEMCrypto_BuildInformation() is behaving as expected @@ -680,7 +693,7 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) { // Whether this was built with FACTORY_MODE_ONLY defined {"is_factory_mode", JSMN_PRIMITIVE}, // ... provide information about liboemcrypto.so - // Special case, see kOptionalReeFields for details. + // Special case, see kReeOptionalFields for details. {kSpecialCaseReeKey, JSMN_OBJECT}, // Technically required, but several implementations // do not implement this fields. @@ -778,7 +791,7 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) { // The optional field "ree", if present, must follow the required // format. - const std::map kReeRequiredFields = { + const std::map kReeOptionalFields = { // liboemcrypto.so version in string format eg "2.15.0+tag" {"liboemcrypto_ver", JSMN_STRING}, // git hash of code that compiled liboemcrypto.so @@ -786,7 +799,6 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) { // ISO 8601 timestamp for when liboemcrypto.so was built {"build_timestamp", JSMN_STRING}}; - found_required_fields.clear(); for (int32_t i = 0; (i + 1) < static_cast(ree_tokens.size()); i += 2) { const jsmntok_t& key_token = ree_tokens[i]; @@ -796,11 +808,10 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) { const std::string key = build_info.substr(key_token.start, key_token.end - key_token.start); - if (kReeRequiredFields.find(key) != kReeRequiredFields.end()) { - ASSERT_EQ(value_token.type, kReeRequiredFields.at(key)) + if (kReeOptionalFields.find(key) != kReeOptionalFields.end()) { + ASSERT_EQ(value_token.type, kReeOptionalFields.at(key)) << "Unexpected optional REE field type: ree_field = " << key << ", build_info = " << build_info; - found_required_fields.insert(key); RecordWvProperty(kReeBuildInfoRecordPrefix + key, build_info.substr(value_token.start, value_token.end - value_token.start)); @@ -810,25 +821,6 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) { i += JsmnAncestorCount(ree_tokens, i + 1); } - // Step 4b: Ensure all required fields of the "ree" object were found. - if (found_required_fields.size() == kReeRequiredFields.size()) return; - // Generate a list of all the missing REE fields. - std::string missing_ree_fields; - for (const auto& required_field : kReeRequiredFields) { - if (found_required_fields.find(required_field.first) != - found_required_fields.end()) - continue; - if (!missing_ree_fields.empty()) { - missing_ree_fields.append(", "); - } - missing_ree_fields.push_back('"'); - missing_ree_fields.append(required_field.first); - missing_ree_fields.push_back('"'); - } - - FAIL() << "REE info JSON object does not contain all required keys; " - << "missing_ree_fields = [" << missing_ree_fields - << "], build_info = " << build_info; } TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) { diff --git a/oemcrypto/test/oemcrypto_corpus_generator_helper.cpp b/oemcrypto/test/oemcrypto_corpus_generator_helper.cpp index 6b603dc..52dc0a0 100644 --- a/oemcrypto/test/oemcrypto_corpus_generator_helper.cpp +++ b/oemcrypto/test/oemcrypto_corpus_generator_helper.cpp @@ -9,7 +9,9 @@ namespace wvoec { +namespace { bool g_generate_corpus; +} void AppendToFile(const std::string& file_name, const char* message, const size_t message_size) { diff --git a/oemcrypto/test/oemcrypto_decrypt_test.cpp b/oemcrypto/test/oemcrypto_decrypt_test.cpp index 34a2647..fa0ee5e 100644 --- a/oemcrypto/test/oemcrypto_decrypt_test.cpp +++ b/oemcrypto/test/oemcrypto_decrypt_test.cpp @@ -604,11 +604,13 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, ContinueDecryptionAfterIdleAndWake) { ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } +namespace { // Used to construct a specific pattern. constexpr OEMCrypto_CENCEncryptPatternDesc MakePattern(size_t encrypt, size_t skip) { return {encrypt, skip}; } +} // namespace INSTANTIATE_TEST_SUITE_P( CTRTests, OEMCryptoSessionTestsDecryptTests, diff --git a/oemcrypto/test/oemcrypto_session_tests_helper.cpp b/oemcrypto/test/oemcrypto_session_tests_helper.cpp index 175bb51..4caa7d0 100644 --- a/oemcrypto/test/oemcrypto_session_tests_helper.cpp +++ b/oemcrypto/test/oemcrypto_session_tests_helper.cpp @@ -8,18 +8,6 @@ using namespace wvoec; namespace wvoec { -// Make this function available when in Fuzz mode because we are not inheriting -// from OEMCryptoClientTest. -const uint8_t* find(const vector& message, - const vector& substring) { - vector::const_iterator pos = search( - message.begin(), message.end(), substring.begin(), substring.end()); - if (pos == message.end()) { - return nullptr; - } - return &(*pos); -} - void SessionUtil::CreateWrappedDRMKey() { if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) { // Have the device create a wrapped key. diff --git a/oemcrypto/util/src/wvcrc.cpp b/oemcrypto/util/src/wvcrc.cpp index 097ca70..5e1917d 100644 --- a/oemcrypto/util/src/wvcrc.cpp +++ b/oemcrypto/util/src/wvcrc.cpp @@ -11,6 +11,7 @@ namespace wvoec { namespace util { #define INIT_CRC32 0xffffffff +namespace { uint32_t wvrunningcrc32(const uint8_t* p_begin, size_t i_count, uint32_t i_crc) { constexpr uint32_t CRC32[256] = { @@ -67,6 +68,7 @@ uint32_t wvrunningcrc32(const uint8_t* p_begin, size_t i_count, return(i_crc); } +} // namespace uint32_t wvcrc32(const uint8_t* p_begin, size_t i_count) { return(wvrunningcrc32(p_begin, i_count, INIT_CRC32)); diff --git a/oemcrypto/util/test/hmac_unittest.cpp b/oemcrypto/util/test/hmac_unittest.cpp index bc4f355..0cbdb61 100644 --- a/oemcrypto/util/test/hmac_unittest.cpp +++ b/oemcrypto/util/test/hmac_unittest.cpp @@ -13,7 +13,8 @@ namespace wvoec { namespace util { -namespace { + +// Putting type in non-anonymous namespace to prevent linkage warnings. struct HmacTestVector { std::vector key; std::vector message; @@ -43,6 +44,7 @@ void PrintTo(const HmacTestVector& v, std::ostream* os) { *os << "signature_sha1 = " << wvutil::b2a_hex(v.signature_sha1) << "}"; } +namespace { std::vector FromString(const std::string& s) { return std::vector(s.begin(), s.end()); }