OEMCrypto v16.1

Merge of http://go/wvgerrit/93404

This CL updates the Widevine CDM to support OEMCrypto v16.1

Test: Tested in 16.2 CL
Bug: 141247171
Change-Id: I69bd993500f6fb63bf6010c8b0250dc7acc3d71b
This commit is contained in:
Fred Gylys-Colwell
2020-01-18 10:11:24 -08:00
parent 7e2619e379
commit 7665614b2e
132 changed files with 12331 additions and 9341 deletions

View File

@@ -195,9 +195,6 @@ class CdmEngine {
// system. This will force the device to reprovision itself.
virtual CdmResponseType Unprovision(CdmSecurityLevel security_level);
// Delete OEMCrypto usage tables. Used by Unprovision().
virtual CdmResponseType DeleteUsageTable(CdmSecurityLevel security_level);
// Return the list of key_set_ids stored on the current (origin-specific)
// file system.
virtual CdmResponseType ListStoredLicenses(
@@ -364,7 +361,6 @@ class CdmEngine {
const CdmSessionId* forced_session_id,
CdmSessionId* session_id);
void DeleteAllUsageReportsUponFactoryReset();
bool ValidateKeySystem(const CdmKeySystem& key_system);
CdmResponseType GetUsageInfo(const std::string& app_id,
SecurityLevel requested_security_level,
@@ -396,7 +392,10 @@ class CdmEngine {
Clock clock_;
std::string spoid_;
// usage related variables
// Usage related variables
// Used to isolate a single active usage information license. Loading,
// creating or releasing a different usage licenses through the engine
// API will release the handle to previously active secure stop license.
std::unique_ptr<CdmSession> usage_session_;
std::unique_ptr<UsagePropertySet> usage_property_set_;
int64_t last_usage_information_update_time_;

View File

@@ -142,10 +142,6 @@ class CdmSession {
}
virtual CdmSecurityLevel GetSecurityLevel() { return security_level_; }
// Delete usage information for the list of tokens, |provider_session_tokens|.
virtual CdmResponseType DeleteMultipleUsageInformation(
const std::vector<std::string>& provider_session_tokens);
virtual CdmResponseType UpdateUsageTableInformation();
virtual CdmResponseType UpdateUsageEntryInformation();
virtual bool is_initial_usage_update() { return is_initial_usage_update_; }

View File

@@ -48,6 +48,8 @@ class CertificateProvisioning {
FileSystem* file_system, const CdmProvisioningResponse& response,
std::string* cert, std::string* wrapped_key);
bool supports_core_messages() const { return supports_core_messages_; }
// Helper methods
// Extract serial number and system ID from a DRM Device certificate.
@@ -73,6 +75,13 @@ class CertificateProvisioning {
CdmCertificateType cert_type_;
std::unique_ptr<ServiceCertificate> service_certificate_;
// Indicates whether OEMCrypto supports core messages, and whether the
// CDM should expect a core message in the response. This is primarly
// used to distinguish between v16+ OEMCrypto or and earlier version.
// Assume core messages are supported, and check if OEMCrypto populates
// the core message field when calling PrepAndSignProvisioningRequest().
bool supports_core_messages_ = true;
CORE_DISALLOW_COPY_AND_ASSIGN(CertificateProvisioning);
};

View File

@@ -75,6 +75,8 @@ class CryptoSession {
virtual CdmSecurityLevel GetSecurityLevel(SecurityLevel requested_level);
virtual bool GetApiVersion(uint32_t* version);
virtual bool GetApiVersion(SecurityLevel requested_level, uint32_t* version);
virtual bool GetApiMinorVersion(SecurityLevel requested_level,
uint32_t* minor_version);
virtual CdmResponseType GetInternalDeviceUniqueId(std::string* device_id);
virtual CdmResponseType GetExternalDeviceUniqueId(std::string* device_id);
@@ -89,13 +91,15 @@ class CryptoSession {
virtual bool IsOpen() { return open_; }
virtual CryptoSessionId oec_session_id() { return oec_session_id_; }
// Key request/response
// All request/responses
virtual const std::string& request_id() { return request_id_; }
virtual CdmResponseType PrepareRequest(const std::string& key_deriv_message,
bool is_provisioning,
std::string* signature);
virtual CdmResponseType PrepareRenewalRequest(const std::string& message,
std::string* signature);
virtual CdmResponseType GenerateNonce(uint32_t* nonce);
// License request/responses
virtual CdmResponseType PrepareAndSignLicenseRequest(
const std::string& message, std::string* core_message,
std::string* signature);
// V15 licenses.
virtual CdmResponseType LoadKeys(const std::string& message,
const std::string& signature,
const std::string& mac_key_iv,
@@ -104,52 +108,45 @@ class CryptoSession {
const std::string& provider_session_token,
const std::string& srm_requirement,
CdmLicenseKeyType key_type);
virtual CdmResponseType LoadEntitledContentKeys(
const std::vector<CryptoKey>& key_array);
virtual CdmResponseType LoadCertificatePrivateKey(std::string& wrapped_key);
// V16 licenses.
virtual CdmResponseType LoadLicense(const std::string& signed_message,
const std::string& core_message,
const std::string& signature);
// Renewal request/responses
virtual CdmResponseType PrepareAndSignRenewalRequest(
const std::string& message, std::string* core_message,
std::string* signature);
// V15 licenses.
virtual CdmResponseType RefreshKeys(const std::string& message,
const std::string& signature,
int num_keys, const CryptoKey* key_array);
virtual CdmResponseType GenerateNonce(uint32_t* nonce);
const std::vector<CryptoKey>& key_array);
// V16 licenses.
virtual CdmResponseType LoadRenewal(const std::string& signed_message,
const std::string& core_message,
const std::string& signature);
// Entitled content Keys.
virtual CdmResponseType LoadEntitledContentKeys(
const std::vector<CryptoKey>& key_array);
// Provisioning request/responses
virtual CdmResponseType GenerateDerivedKeys(const std::string& message);
virtual CdmResponseType GenerateDerivedKeys(const std::string& message,
const std::string& session_key);
virtual CdmResponseType RewrapCertificate(const std::string& signed_message,
const std::string& signature,
const std::string& nonce,
const std::string& private_key,
const std::string& iv,
const std::string& wrapping_key,
std::string* wrapped_private_key);
virtual CdmResponseType PrepareAndSignProvisioningRequest(
const std::string& message, std::string* core_message,
std::string* signature);
virtual CdmResponseType LoadProvisioning(const std::string& signed_message,
const std::string& core_message,
const std::string& signature,
std::string* wrapped_private_key);
virtual CdmResponseType LoadCertificatePrivateKey(
const std::string& wrapped_key);
// Media data path
virtual CdmResponseType Decrypt(const CdmDecryptionParameters& params);
// Usage related methods
// The overloaded method with |security_level| may be called without a
// preceding call to Open. The other method must call Open first.
virtual bool UsageInformationSupport(bool* has_support);
virtual bool UsageInformationSupport(SecurityLevel security_level,
bool* has_support);
virtual CdmResponseType UpdateUsageInformation(); // only for OEMCrypto v9-12
virtual CdmResponseType DeactivateUsageInformation(
const std::string& provider_session_token);
virtual CdmResponseType GenerateUsageReport(
const std::string& provider_session_token, std::string* usage_report,
UsageDurationStatus* usage_duration_status,
int64_t* seconds_since_started, int64_t* seconds_since_last_played);
virtual CdmResponseType ReleaseUsageInformation(
const std::string& message, const std::string& signature,
const std::string& provider_session_token);
// Delete a usage information for a single token. This does not require
// a signed message from the server.
virtual CdmResponseType DeleteUsageInformation(
const std::string& provider_session_token);
// Delete usage information for a list of tokens. This does not require
// a signed message from the server.
virtual CdmResponseType DeleteMultipleUsageInformation(
const std::vector<std::string>& provider_session_tokens);
virtual CdmResponseType DeleteAllUsageReports();
virtual bool IsAntiRollbackHwPresent();
// The overloaded methods with |security_level| may be called without a
@@ -178,6 +175,9 @@ class CryptoSession {
std::string* info);
virtual bool GetBuildInformation(std::string* info);
virtual bool GetMaximumUsageTableEntries(SecurityLevel security_level,
size_t* number_of_entries);
virtual bool GetDecryptHashSupport(SecurityLevel security_level,
uint32_t* hash_support);
@@ -205,32 +205,49 @@ class CryptoSession {
CdmSigningAlgorithm algorithm,
const std::string& signature);
// Usage table header and usage entry related methods
// Usage table API related methods.
// Used to manipulate the CDM managed usage table header & entries,
// delegating calls to OEMCrypto.
// Usage support.
virtual CdmResponseType GetUsageSupportType(CdmUsageSupportType* type);
// The overloaded method with |security_level| may be called without a
// preceding call to Open. The other method must call Open first.
virtual bool UsageInformationSupport(bool* has_support);
virtual bool UsageInformationSupport(SecurityLevel security_level,
bool* has_support);
// Usage report.
virtual CdmResponseType DeactivateUsageInformation(
const std::string& provider_session_token);
virtual CdmResponseType GenerateUsageReport(
const std::string& provider_session_token, std::string* usage_report,
UsageDurationStatus* usage_duration_status,
int64_t* seconds_since_started, int64_t* seconds_since_last_played);
// Usage table header.
virtual UsageTableHeader* GetUsageTableHeader() {
return usage_table_header_;
}
virtual CdmResponseType GetUsageSupportType(CdmUsageSupportType* type);
virtual CdmResponseType CreateUsageTableHeader(
CdmUsageTableHeader* usage_table_header);
virtual CdmResponseType LoadUsageTableHeader(
const CdmUsageTableHeader& usage_table_header);
// Usage entry.
virtual CdmResponseType CreateUsageEntry(uint32_t* entry_number);
virtual CdmResponseType LoadUsageEntry(uint32_t entry_number,
const CdmUsageEntry& usage_entry);
virtual CdmResponseType UpdateUsageEntry(
CdmUsageTableHeader* usage_table_header, CdmUsageEntry* usage_entry);
// Adjust usage entries in usage table header.
virtual CdmResponseType ShrinkUsageTableHeader(
uint32_t new_entry_count, CdmUsageTableHeader* usage_table_header);
virtual CdmResponseType MoveUsageEntry(uint32_t new_entry_number);
virtual bool CreateOldUsageEntry(uint64_t time_since_license_received,
uint64_t time_since_first_decrypt,
uint64_t time_since_last_decrypt,
UsageDurationStatus status,
const std::string& server_mac_key,
const std::string& client_mac_key,
const std::string& provider_session_token);
virtual CdmResponseType CopyOldUsageEntry(
const std::string& provider_session_token);
virtual bool GetAnalogOutputCapabilities(bool* can_support_output,
bool* can_disable_output,
bool* can_support_cgms_a);
@@ -271,27 +288,11 @@ class CryptoSession {
static bool ExtractSystemIdFromOemCert(const std::string& oem_cert,
uint32_t* system_id);
CdmResponseType GetSystemIdInternal(uint32_t* system_id);
CdmResponseType GenerateSignature(const std::string& message,
std::string* signature);
CdmResponseType GenerateRsaSignature(const std::string& message,
std::string* signature);
bool SetDestinationBufferType();
CdmResponseType RewrapDeviceRSAKey(const std::string& message,
const std::string& signature,
const std::string& nonce,
const std::string& enc_rsa_key,
const std::string& rsa_key_iv,
std::string* wrapped_rsa_key);
CdmResponseType RewrapDeviceRSAKey30(const std::string& message,
const std::string& nonce,
const std::string& private_key,
const std::string& iv,
const std::string& wrapping_key,
std::string* wrapped_private_key);
CdmResponseType SelectKey(const std::string& key_id,
CdmCipherMode cipher_mode);
@@ -336,7 +337,7 @@ class CryptoSession {
// Initialization & Termination | WithOecWriteLock()
// Property | WithOecReadLock()
// Session Initialization | WithOecWriteLock()
// Usage Table | WithOecWriteLock()
// Usage Table Header & Entries | WithOecWriteLock()
// Session | WithOecSessionLock()
//
// Note that accessing |key_session_| often accesses the OEMCrypto session, so
@@ -400,7 +401,6 @@ class CryptoSession {
bool is_destination_buffer_type_valid_;
SecurityLevel requested_security_level_;
bool is_usage_support_type_valid_;
CdmUsageSupportType usage_support_type_;
UsageTableHeader* usage_table_header_;
static UsageTableHeader* usage_table_header_l1_;

View File

@@ -35,6 +35,11 @@ class InitializationData {
std::vector<video_widevine::WidevinePsshData_EntitledKey> ExtractWrappedKeys()
const;
bool contains_entitled_keys() const { return contains_entitled_keys_; }
// Dump information to the logs for debugging.
void DumpToLogs() const;
// The static system ID for PSSH boxes indicating Widevine content.
static const std::string WidevineSystemID();
private:
bool SelectWidevinePssh(const CdmInitData& init_data,

View File

@@ -80,7 +80,11 @@ class CdmLicense {
return provider_session_token_;
}
virtual bool is_offline() { return is_offline_; }
virtual bool is_offline() const { return is_offline_; }
virtual bool supports_core_messages() const {
return supports_core_messages_;
}
virtual const VersionInfo& GetServiceVersion() {
return latest_service_version_;
@@ -105,18 +109,18 @@ class CdmLicense {
video_widevine::LicenseRequest* license_request);
CdmResponseType HandleContentKeyResponse(
const std::string& msg, const std::string& signature,
const std::string& mac_key_iv, const std::string& mac_key,
const std::vector<CryptoKey>& key_array,
const std::string& msg, const std::string& core_message,
const std::string& signature, const std::string& mac_key_iv,
const std::string& mac_key, const std::vector<CryptoKey>& key_array,
const video_widevine::License& license);
// HandleEntitlementKeyResponse loads the entitlement keys in |key_array| into
// the crypto session. In addition, it also extracts content keys from
// |wrapped_keys_| and loads them for use.
CdmResponseType HandleEntitlementKeyResponse(
const std::string& msg, const std::string& signature,
const std::string& mac_key_iv, const std::string& mac_key,
const std::vector<CryptoKey>& key_array,
const std::string& msg, const std::string& core_message,
const std::string& signature, const std::string& mac_key_iv,
const std::string& mac_key, const std::vector<CryptoKey>& key_array,
const video_widevine::License& license);
CdmResponseType HandleNewEntitledKeys(
@@ -139,6 +143,11 @@ class CdmLicense {
std::string provider_session_token_;
bool renew_with_client_id_;
bool is_offline_;
// Indicates whether the license contains / supports OEMCrypto-level
// support for core messages. If the original license was created before
// upgrading from V15, or if the licensing server is still running V15,
// then the license does not support core messages.
bool supports_core_messages_;
// Associated with ClientIdentification encryption
bool use_privacy_mode_;

View File

@@ -23,6 +23,7 @@ OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength,
OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength,
SecurityLevel level);
uint32_t OEMCrypto_APIVersion(SecurityLevel level);
uint32_t OEMCrypto_MinorAPIVersion(SecurityLevel level);
const char* OEMCrypto_SecurityLevel(SecurityLevel level);
OEMCryptoResult OEMCrypto_GetHDCPCapability(SecurityLevel level,
OEMCrypto_HDCP_Capability* current,
@@ -47,15 +48,14 @@ OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(SecurityLevel level,
uint32_t new_table_size,
uint8_t* header_buffer,
size_t* header_buffer_length);
OEMCryptoResult OEMCrypto_CreateOldUsageEntry(
SecurityLevel level, uint64_t time_since_license_received,
uint64_t time_since_first_decrypt, uint64_t time_since_last_decrypt,
OEMCrypto_Usage_Entry_Status status, uint8_t* server_mac_key,
uint8_t* client_mac_key, const uint8_t* pst, size_t pst_length);
uint32_t OEMCrypto_GetAnalogOutputFlags(SecurityLevel level);
const char* OEMCrypto_BuildInformation(SecurityLevel level);
uint32_t OEMCrypto_ResourceRatingTier(SecurityLevel level);
uint32_t OEMCrypto_SupportsDecryptHash(SecurityLevel level);
size_t OEMCrypto_MaximumUsageTableHeaderSize(SecurityLevel level);
OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(uint8_t* public_cert,
size_t* public_cert_length,
SecurityLevel level);
} // namespace wvcdm
/* The following functions are deprecated in OEMCrypto v13. They are defined
@@ -104,18 +104,8 @@ OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat(
OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data,
OEMCrypto_LicenseType license_type, OEMCryptoCipherMode* cipher_modes);
OEMCryptoResult OEMCrypto_UpdateUsageTable();
OEMCryptoResult OEMCrypto_DeactivateUsageEntry_V12(const uint8_t* pst,
size_t pst_length);
OEMCryptoResult OEMCrypto_DeleteUsageEntry(
OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length,
const uint8_t* message, size_t message_length, const uint8_t* signature,
size_t signature_length);
OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst,
size_t pst_length);
typedef struct {
const uint8_t* entitlement_key_id;
size_t entitlement_key_id_length;
@@ -150,10 +140,9 @@ OEMCryptoResult OEMCrypto_RefreshKeys_V14(
const uint8_t* signature, size_t signature_length, size_t num_keys,
const OEMCrypto_KeyRefreshObject_V14* key_array);
OEMCryptoResult OEMCrypto_CopyBuffer_V14(const uint8_t* data_addr,
size_t data_length,
OEMCrypto_DestBufferDesc* out_buffer,
uint8_t subsample_flags);
OEMCryptoResult OEMCrypto_CopyBuffer_V14(
const uint8_t* data_addr, size_t data_length,
OEMCrypto_DestBufferDesc* out_buffer_descriptor, uint8_t subsample_flags);
} // extern "C"

View File

@@ -124,17 +124,8 @@ class UsageTableHeader {
CdmResponseType Shrink(metrics::CryptoMetrics* metrics,
uint32_t number_of_usage_entries_to_delete);
CdmResponseType UpgradeFromUsageTable(DeviceFiles* handle,
metrics::CryptoMetrics* metrics);
bool UpgradeLicensesFromUsageTable(DeviceFiles* handle,
metrics::CryptoMetrics* metrics);
bool UpgradeUsageInfoFromUsageTable(DeviceFiles* handle,
metrics::CryptoMetrics* metrics);
virtual bool is_inited() { return is_inited_; }
virtual bool CreateDummyOldUsageEntry(CryptoSession* crypto_session);
// Performs and LRU upgrade on all loaded CdmUsageEntryInfo from a
// device file that had not yet been upgraded to use the LRU data.
virtual bool LruUpgradeAllUsageEntries();

View File

@@ -26,10 +26,17 @@ static const size_t CERTIFICATE_DATA_SIZE = 4 * 1024;
// (NaN in JS translates to 0 in unix timestamp).
static const int64_t NEVER_EXPIRES = 0;
// This is the lower limit. For OEMCrypto v16+ one can query and find how many
// are supported
static constexpr size_t kMinimumUsageTableEntriesSupported = 200;
// Resource rating tiers
static const uint32_t RESOURCE_RATING_TIER_LOW = 1u;
static const uint32_t RESOURCE_RATING_TIER_MEDIUM = 2u;
static const uint32_t RESOURCE_RATING_TIER_HIGH = 3u;
static const uint32_t RESOURCE_RATING_TIER_VERY_HIGH = 4u;
static const uint32_t RESOURCE_RATING_TIER_MIN = RESOURCE_RATING_TIER_LOW;
static const uint32_t RESOURCE_RATING_TIER_MAX = RESOURCE_RATING_TIER_VERY_HIGH;
// OEMCrypto features by version
static const uint32_t OEM_CRYPTO_API_VERSION_SUPPORTS_RESOURCE_RATING_TIER = 15;
@@ -82,6 +89,10 @@ static const std::string QUERY_KEY_OEMCRYPTO_BUILD_INFORMATION =
"OemCryptoBuildInformation";
static const std::string QUERY_KEY_DECRYPT_HASH_SUPPORT = "DecryptHashSupport";
static const std::string QUERY_KEY_PROVISIONING_MODEL = "ProvisioningModel";
static const std::string QUERY_KEY_MAX_USAGE_TABLE_ENTRIES =
"MaxNumberOfUsageTableEntries";
static const std::string QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION =
"OemCryptoApiMinorVersion";
static const std::string QUERY_VALUE_TRUE = "True";
static const std::string QUERY_VALUE_FALSE = "False";

View File

@@ -72,8 +72,8 @@ enum CdmResponseType {
CERT_PROVISIONING_RESPONSE_ERROR_2 = 19,
CERT_PROVISIONING_RESPONSE_ERROR_3 = 20,
CERT_PROVISIONING_RESPONSE_ERROR_4 = 21,
CERT_PROVISIONING_RESPONSE_ERROR_5 = 22,
CERT_PROVISIONING_RESPONSE_ERROR_6 = 23,
/* previously CERT_PROVISIONING_RESPONSE_ERROR_5 = 22 */
/* previously CERT_PROVISIONING_RESPONSE_ERROR_6 = 23 */
CERT_PROVISIONING_RESPONSE_ERROR_7 = 24,
CERT_PROVISIONING_RESPONSE_ERROR_8 = 25,
/* previously CRYPTO_SESSION_OPEN_ERROR_1 = 26 */
@@ -341,7 +341,7 @@ enum CdmResponseType {
NO_MATCHING_ENTITLEMENT_KEY = 287,
LOAD_ENTITLED_CONTENT_KEYS_ERROR = 288,
GET_PROVISIONING_METHOD_ERROR = 289,
SESSION_NOT_FOUND_17 = 290,
INVALID_SESSION_2 = 290,
SESSION_NOT_FOUND_18 = 291,
NO_CONTENT_KEY_3 = 292,
DEVICE_CANNOT_REPROVISION = 293,
@@ -396,11 +396,14 @@ enum CdmResponseType {
NOT_IMPLEMENTED_ERROR = 342,
GET_SRM_VERSION_ERROR = 343,
REWRAP_DEVICE_RSA_KEY_ERROR = 344,
REWRAP_DEVICE_RSA_KEY_30_ERROR = 345,
LOAD_PROVISIONING_ERROR = 345,
INVALID_SRM_LIST = 346,
KEYSET_ID_NOT_FOUND_4 = 347,
SESSION_NOT_FOUND_22 = 348,
USAGE_INVALID_PARAMETERS_2 = 349,
CORE_MESSAGE_NOT_FOUND = 350,
LOAD_LICENSE_ERROR = 351,
LOAD_RENEWAL_ERROR = 352,
// Don't forget to add new values to
// * core/test/test_printers.cpp.
// * android/include/mapErrors-inl.h
@@ -482,15 +485,12 @@ enum CdmClientTokenType {
// kNonSecureUsageSupport - TEE does not provide any support for usage
// information.
// kUsageTableSupport - TEE persists usage information securely in a fixed
// size table, commonly 50 entries. (OEMCrypto v9+)
// kUsageEntrySupport - usage information (table headers and entries) are
// persisted in non-secure storage but are loaded and unloaded from
// the TEE during use (OEMCrypto v13+)
// kUnknownUsageSupport - usage support type is uninitialized or unavailable
enum CdmUsageSupportType {
kNonSecureUsageSupport,
kUsageTableSupport,
kUsageEntrySupport,
kUnknownUsageSupport,
};