OEMCrypto and OPK 19.6.0
GitOrigin-RevId: 13a33e34413c19da1bfe76abcc66be519c9ac9d1
This commit is contained in:
23
CHANGELOG.md
23
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>"
|
||||
|
||||
## [Version 19.5][v19.5]
|
||||
|
||||
This release adds new OEMCrypto APIs to support CAS PVR. It also includes test
|
||||
|
||||
@@ -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<LogPriority>(sizeof(severities) /
|
||||
sizeof(severities[0]))) {
|
||||
if (level < 0 || static_cast<size_t>(level) >=
|
||||
sizeof(severities) / sizeof(severities[0])) {
|
||||
fprintf(kOutputFile, "[FATAL:%s(%d):%s] Invalid log priority level: %d\n",
|
||||
file, line, function, level);
|
||||
return;
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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_
|
||||
@@ -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 <stdlib.h>
|
||||
#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
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -3,12 +3,16 @@
|
||||
// License Agreement.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
24
oemcrypto/odk/src/odk_versions.h
Normal file
24
oemcrypto/odk/src/odk_versions.h
Normal file
@@ -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 <stdint.h>
|
||||
|
||||
#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_
|
||||
@@ -1275,7 +1275,7 @@ std::vector<VersionParameters> 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<VersionParameters> 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<VersionParameters> TestCases() {
|
||||
{0, 19, 3, 19, 3},
|
||||
{0, 19, 4, 19, 4},
|
||||
{0, 19, 5, 19, 5},
|
||||
{0, 19, 6, 19, 6},
|
||||
};
|
||||
return test_cases;
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
* This is a PKCS8 RSA key encoded in DER format.
|
||||
*/
|
||||
|
||||
#include "stdint.h"
|
||||
#include "test_common.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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,
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "wtpi_config_macros.h"
|
||||
#include "opk_config.h"
|
||||
#include "wtpi_crypto_and_key_management_interface_layer1.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
|
||||
@@ -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 \
|
||||
@@ -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));
|
||||
|
||||
@@ -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',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<unsigned>(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<std::string, jsmntype_t> kReeRequiredFields = {
|
||||
const std::map<std::string, jsmntype_t> 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<int32_t>(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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<uint8_t>& message,
|
||||
const vector<uint8_t>& substring) {
|
||||
vector<uint8_t>::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.
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
|
||||
namespace wvoec {
|
||||
namespace util {
|
||||
namespace {
|
||||
|
||||
// Putting type in non-anonymous namespace to prevent linkage warnings.
|
||||
struct HmacTestVector {
|
||||
std::vector<uint8_t> key;
|
||||
std::vector<uint8_t> 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<uint8_t> FromString(const std::string& s) {
|
||||
return std::vector<uint8_t>(s.begin(), s.end());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user