diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 82fadb5d..3a8061e8 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -58,10 +58,16 @@ class CryptoSession { virtual CdmClientTokenType GetPreProvisionTokenType() { return pre_provision_token_type_; } + + // The overloaded methods with |requested_level| may be called + // without a preceding call to Open. The other method must call Open first. virtual CdmSecurityLevel GetSecurityLevel(); + virtual CdmSecurityLevel GetSecurityLevel(SecurityLevel requested_level); + virtual bool GetApiVersion(uint32_t* version); + virtual bool GetApiVersion(SecurityLevel requested_level, uint32_t* version); + virtual bool GetInternalDeviceUniqueId(std::string* device_id); virtual bool GetExternalDeviceUniqueId(std::string* device_id); - virtual bool GetApiVersion(uint32_t* version); virtual bool GetSystemId(uint32_t* system_id); virtual bool GetProvisioningId(std::string* provisioning_id); virtual uint8_t GetSecurityPatchLevel(); @@ -108,7 +114,11 @@ class CryptoSession { 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); @@ -130,12 +140,20 @@ class CryptoSession { virtual CdmResponseType DeleteAllUsageReports(); virtual bool IsAntiRollbackHwPresent(); + // The overloaded methods with |security_level| may be called without a + // preceding call to Open. The other methods must call Open first. virtual bool GetHdcpCapabilities(HdcpCapability* current, HdcpCapability* max); + virtual bool GetHdcpCapabilities(SecurityLevel security_level, + HdcpCapability* current, + HdcpCapability* max); + virtual bool GetSupportedCertificateTypes(SupportedCertificateTypes* support); virtual bool GetRandom(size_t data_length, uint8_t* random_data); - virtual bool GetNumberOfOpenSessions(size_t* count); - virtual bool GetMaxNumberOfSessions(size_t* max); + virtual bool GetNumberOfOpenSessions(SecurityLevel security_level, + size_t* count); + virtual bool GetMaxNumberOfSessions(SecurityLevel security_level, + size_t* max); virtual bool GetSrmVersion(uint16_t* srm_version); virtual bool IsSrmUpdateSupported(); diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 51738a9f..3f4a05a3 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -481,24 +481,16 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, LOGI("CdmEngine::QueryStatus"); CryptoSession crypto_session(metrics_.GetCryptoMetrics()); CdmResponseType status; - M_TIME( - status = crypto_session.Open( - security_level), - metrics_.GetCryptoMetrics(), - crypto_session_open_, - status, - security_level); - if (status != NO_ERROR) - return status; if (!query_response) { LOGE("CdmEngine::QueryStatus: no query response destination"); return PARAMETER_NULL; } + // Add queries here, that can be answered before a session is opened if (query_token == QUERY_KEY_SECURITY_LEVEL) { CdmSecurityLevel found_security_level = - crypto_session.GetSecurityLevel(); + crypto_session.GetSecurityLevel(security_level); switch (found_security_level) { case kSecurityLevelL1: *query_response = QUERY_VALUE_SECURITY_LEVEL_L1; @@ -518,7 +510,104 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, found_security_level); return UNKNOWN_ERROR; } - } else if (query_token == QUERY_KEY_DEVICE_ID) { + return NO_ERROR; + } else if (query_token == QUERY_KEY_CURRENT_HDCP_LEVEL || + query_token == QUERY_KEY_MAX_HDCP_LEVEL) { + CryptoSession::HdcpCapability current_hdcp; + CryptoSession::HdcpCapability max_hdcp; + if (!crypto_session.GetHdcpCapabilities(security_level, ¤t_hdcp, + &max_hdcp)) { + LOGW("CdmEngine::QueryStatus: GetHdcpCapabilities failed"); + return UNKNOWN_ERROR; + } + *query_response = + MapHdcpVersion(query_token == QUERY_KEY_CURRENT_HDCP_LEVEL ? + current_hdcp : max_hdcp); + return NO_ERROR; + } else if (query_token == QUERY_KEY_USAGE_SUPPORT) { + bool supports_usage_reporting; + bool got_info = crypto_session.UsageInformationSupport( + security_level, + &supports_usage_reporting); + + if (!got_info) { + LOGW("CdmEngine::QueryStatus: UsageInformationSupport failed"); + metrics_.GetCryptoMetrics()->crypto_session_usage_information_support_ + .SetError(got_info); + return UNKNOWN_ERROR; + } + metrics_.GetCryptoMetrics()->crypto_session_usage_information_support_ + .Record(supports_usage_reporting); + + *query_response = + supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; + return NO_ERROR; + } else if (query_token == QUERY_KEY_NUMBER_OF_OPEN_SESSIONS) { + size_t number_of_open_sessions; + if (!crypto_session.GetNumberOfOpenSessions(security_level, + &number_of_open_sessions)) { + LOGW("CdmEngine::QueryStatus: GetNumberOfOpenSessions failed"); + return UNKNOWN_ERROR; + } + + *query_response = std::to_string(number_of_open_sessions); + return NO_ERROR; + } else if (query_token == QUERY_KEY_MAX_NUMBER_OF_SESSIONS) { + size_t maximum_number_of_sessions = 0; + if (!crypto_session.GetMaxNumberOfSessions(security_level, + &maximum_number_of_sessions)) { + LOGW("CdmEngine::QueryStatus: GetMaxNumberOfOpenSessions failed"); + return UNKNOWN_ERROR; + } + + *query_response = std::to_string(maximum_number_of_sessions); + return NO_ERROR; + } else if (query_token == QUERY_KEY_OEMCRYPTO_API_VERSION) { + uint32_t api_version; + if (!crypto_session.GetApiVersion(security_level, &api_version)) { + LOGW("CdmEngine::QueryStatus: GetApiVersion failed"); + return UNKNOWN_ERROR; + } + + *query_response = std::to_string(api_version); + return NO_ERROR; + } else if (query_token == QUERY_KEY_CURRENT_SRM_VERSION) { + uint16_t current_srm_version; + if (!crypto_session.GetSrmVersion(¤t_srm_version)) { + LOGW("CdmEngine::QueryStatus: GetCurrentSRMVersion failed"); + return UNKNOWN_ERROR; + } + + *query_response = std::to_string(current_srm_version); + return NO_ERROR; + } else if (query_token == QUERY_KEY_SRM_UPDATE_SUPPORT) { + bool is_srm_update_supported = crypto_session.IsSrmUpdateSupported(); + *query_response = + is_srm_update_supported ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; + return NO_ERROR; + } else if (query_token == QUERY_KEY_WVCDM_VERSION) { + std::string cdm_version; + if (!Properties::GetWVCdmVersion(&cdm_version)) { + LOGW("CdmEngine::QueryStatus: GetWVCdmVersion failed"); + return UNKNOWN_ERROR; + } + + *query_response = cdm_version; + return NO_ERROR; + } + + M_TIME( + status = crypto_session.Open( + security_level), + metrics_.GetCryptoMetrics(), + crypto_session_open_, + status, + security_level); + if (status != NO_ERROR) + return status; + + // Add queries here, that need an open session before they can be answered + if (query_token == QUERY_KEY_DEVICE_ID) { std::string deviceId; bool got_id = crypto_session.GetExternalDeviceUniqueId(&deviceId); metrics_.GetCryptoMetrics()->crypto_session_get_device_unique_id_ @@ -537,9 +626,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, return UNKNOWN_ERROR; } - std::ostringstream system_id_stream; - system_id_stream << system_id; - *query_response = system_id_stream.str(); + *query_response = std::to_string(system_id); } else if (query_token == QUERY_KEY_PROVISIONING_ID) { std::string provisioning_id; if (!crypto_session.GetProvisioningId(&provisioning_id)) { @@ -548,85 +635,6 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, } *query_response = provisioning_id; - } else if (query_token == QUERY_KEY_CURRENT_HDCP_LEVEL || - query_token == QUERY_KEY_MAX_HDCP_LEVEL) { - CryptoSession::HdcpCapability current_hdcp; - CryptoSession::HdcpCapability max_hdcp; - if (!crypto_session.GetHdcpCapabilities(¤t_hdcp, &max_hdcp)) { - LOGW("CdmEngine::QueryStatus: GetHdcpCapabilities failed"); - return UNKNOWN_ERROR; - } - *query_response = - MapHdcpVersion(query_token == QUERY_KEY_CURRENT_HDCP_LEVEL ? - current_hdcp : max_hdcp); - } else if (query_token == QUERY_KEY_USAGE_SUPPORT) { - bool supports_usage_reporting; - bool got_info = crypto_session.UsageInformationSupport( - &supports_usage_reporting); - - if (!got_info) { - LOGW("CdmEngine::QueryStatus: UsageInformationSupport failed"); - metrics_.GetCryptoMetrics()->crypto_session_usage_information_support_ - .SetError(got_info); - return UNKNOWN_ERROR; - } - metrics_.GetCryptoMetrics()->crypto_session_usage_information_support_ - .Record(supports_usage_reporting); - - *query_response = - supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; - } else if (query_token == QUERY_KEY_NUMBER_OF_OPEN_SESSIONS) { - size_t number_of_open_sessions; - if (!crypto_session.GetNumberOfOpenSessions(&number_of_open_sessions)) { - LOGW("CdmEngine::QueryStatus: GetNumberOfOpenSessions failed"); - return UNKNOWN_ERROR; - } - - std::ostringstream open_sessions_stream; - open_sessions_stream << number_of_open_sessions; - *query_response = open_sessions_stream.str(); - } else if (query_token == QUERY_KEY_MAX_NUMBER_OF_SESSIONS) { - size_t maximum_number_of_sessions = 0; - if (!crypto_session.GetMaxNumberOfSessions(&maximum_number_of_sessions)) { - LOGW("CdmEngine::QueryStatus: GetMaxNumberOfOpenSessions failed"); - return UNKNOWN_ERROR; - } - - std::ostringstream max_sessions_stream; - max_sessions_stream << maximum_number_of_sessions; - *query_response = max_sessions_stream.str(); - } else if (query_token == QUERY_KEY_OEMCRYPTO_API_VERSION) { - uint32_t api_version; - if (!crypto_session.GetApiVersion(&api_version)) { - LOGW("CdmEngine::QueryStatus: GetApiVersion failed"); - return UNKNOWN_ERROR; - } - - std::ostringstream api_version_stream; - api_version_stream << api_version; - *query_response = api_version_stream.str(); - } else if (query_token == QUERY_KEY_CURRENT_SRM_VERSION) { - uint16_t current_srm_version; - if (!crypto_session.GetSrmVersion(¤t_srm_version)) { - LOGW("CdmEngine::QueryStatus: GetCurrentSRMVersion failed"); - return UNKNOWN_ERROR; - } - - std::ostringstream current_srm_version_stream; - current_srm_version_stream << current_srm_version; - *query_response = current_srm_version_stream.str(); - } else if (query_token == QUERY_KEY_SRM_UPDATE_SUPPORT) { - bool is_srm_update_supported = crypto_session.IsSrmUpdateSupported(); - *query_response = - is_srm_update_supported ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; - } else if (query_token == QUERY_KEY_WVCDM_VERSION) { - std::string cdm_version; - if (!Properties::GetWVCdmVersion(&cdm_version)) { - LOGW("CdmEngine::QueryStatus: GetWVCdmVersion failed"); - return UNKNOWN_ERROR; - } - - *query_response = cdm_version; } else { LOGW("CdmEngine::QueryStatus: Unknown status requested, token = %s", query_token.c_str()); diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index 487ee7fc..dbcf6a4b 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -408,11 +408,11 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( return CERT_PROVISIONING_RESPONSE_ERROR_6; } - crypto_session_.Close(); if (cert_type_ == kCertificateX509) { *cert = provisioning_response.device_certificate(); *wrapped_key = wrapped_private_key; + crypto_session_.Close(); return NO_ERROR; } @@ -425,8 +425,10 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( DeviceFiles handle(file_system); if (!handle.Init(crypto_session_.GetSecurityLevel())) { LOGE("HandleProvisioningResponse: failed to init DeviceFiles"); + crypto_session_.Close(); return CERT_PROVISIONING_RESPONSE_ERROR_7; } + crypto_session_.Close(); if (!handle.StoreCertificate(device_certificate, wrapped_private_key)) { LOGE("HandleProvisioningResponse: failed to save provisioning certificate"); return CERT_PROVISIONING_RESPONSE_ERROR_8; diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 252bada6..dfb20fc5 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -314,12 +314,22 @@ bool CryptoSession::GetProvisioningToken(std::string* token) { CdmSecurityLevel CryptoSession::GetSecurityLevel() { LOGV("CryptoSession::GetSecurityLevel"); + if (!open_) { + LOGW("CryptoSession::GetSecurityLevel: session not open"); + return kSecurityLevelUninitialized; + } + return GetSecurityLevel(requested_security_level_); +} + +CdmSecurityLevel CryptoSession::GetSecurityLevel( + SecurityLevel requested_level) { + LOGV("CryptoSession::GetSecurityLevel"); if (!initialized_) { + LOGW("CryptoSession::GetSecurityLevel: not initialized"); return kSecurityLevelUninitialized; } - std::string security_level = - OEMCrypto_SecurityLevel(requested_security_level_); + std::string security_level = OEMCrypto_SecurityLevel(requested_level); if ((security_level.size() != 2) || (security_level.at(0) != 'L')) { return kSecurityLevelUnknown; @@ -406,16 +416,28 @@ bool CryptoSession::GetExternalDeviceUniqueId(std::string* device_id) { } bool CryptoSession::GetApiVersion(uint32_t* version) { + LOGV("CryptoSession::GetApiVersion"); + if (!open_) { + LOGW("CryptoSession::GetApiVersion: session not open"); + return false; + } + return GetApiVersion(requested_security_level_, version); +} + +bool CryptoSession::GetApiVersion(SecurityLevel security_level, + uint32_t* version) { + LOGV("CryptoSession::GetApiVersion"); if (!version) { LOGE("CryptoSession::GetApiVersion: No buffer passed to method."); return false; } if (!initialized_) { + LOGW("CryptoSession::GetApiVersion: not initialized"); return false; } - *version = OEMCrypto_APIVersion(requested_security_level_); + *version = OEMCrypto_APIVersion(security_level); // Record the version into the metrics. metrics_->oemcrypto_api_version_.Record(*version); @@ -1161,10 +1183,23 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) { } bool CryptoSession::UsageInformationSupport(bool* has_support) { - LOGV("UsageInformationSupport: id=%lu", oec_session_id_); - if (!initialized_) return false; + LOGV("CryptoSession::UsageInformationSupport"); + if (!open_) { + LOGW("CryptoSession::UsageInformationSupport: session not open"); + return false; + } + return UsageInformationSupport(requested_security_level_, has_support); +} - *has_support = OEMCrypto_SupportsUsageTable(requested_security_level_); +bool CryptoSession::UsageInformationSupport(SecurityLevel security_level, + bool* has_support) { + LOGV("CryptoSession::UsageInformationSupport"); + if (!initialized_) { + LOGW("CryptoSession::UsageInformationSupport: not initialized"); + return false; + } + + *has_support = OEMCrypto_SupportsUsageTable(security_level); return true; } @@ -1583,8 +1618,22 @@ bool CryptoSession::RewrapDeviceRSAKey30(const std::string& message, bool CryptoSession::GetHdcpCapabilities(HdcpCapability* current, HdcpCapability* max) { - LOGV("GetHdcpCapabilities: id=%lu", oec_session_id_); - if (!initialized_) return false; + LOGV("CryptoSession::GetHdcpCapabilities: id=%lu", oec_session_id_); + if (!open_) { + LOGW("CryptoSession::GetHdcpCapabilities: session not open"); + return false; + } + return GetHdcpCapabilities(requested_security_level_, current, max); +} + +bool CryptoSession::GetHdcpCapabilities(SecurityLevel security_level, + HdcpCapability* current, + HdcpCapability* max) { + LOGV("CryptoSession::GetHdcpCapabilities"); + if (!initialized_) { + LOGW("CryptoSession::GetHdcpCapabilities: not initialized"); + return false; + } if (current == NULL || max == NULL) { LOGE( "CryptoSession::GetHdcpCapabilities: |current|, |max| cannot be " @@ -1592,7 +1641,7 @@ bool CryptoSession::GetHdcpCapabilities(HdcpCapability* current, return false; } OEMCryptoResult status = - OEMCrypto_GetHDCPCapability(requested_security_level_, current, max); + OEMCrypto_GetHDCPCapability(security_level, current, max); if (OEMCrypto_SUCCESS != status) { metrics_->oemcrypto_current_hdcp_capability_.SetError(status); @@ -1640,9 +1689,13 @@ bool CryptoSession::GetRandom(size_t data_length, uint8_t* random_data) { return true; } -bool CryptoSession::GetNumberOfOpenSessions(size_t* count) { +bool CryptoSession::GetNumberOfOpenSessions(SecurityLevel security_level, + size_t* count) { LOGV("GetNumberOfOpenSessions"); - if (!initialized_) return false; + if (!initialized_) { + LOGW("CryptoSession::GetNumberOfOpenSessions: not initialized"); + return false; + } if (count == NULL) { LOGE("CryptoSession::GetNumberOfOpenSessions: |count| cannot be NULL"); return false; @@ -1650,7 +1703,7 @@ bool CryptoSession::GetNumberOfOpenSessions(size_t* count) { size_t sessions_count; OEMCryptoResult status = OEMCrypto_GetNumberOfOpenSessions( - requested_security_level_, &sessions_count); + security_level, &sessions_count); if (OEMCrypto_SUCCESS != status) { LOGW("OEMCrypto_GetNumberOfOpenSessions fails with %d", status); @@ -1663,9 +1716,14 @@ bool CryptoSession::GetNumberOfOpenSessions(size_t* count) { return true; } -bool CryptoSession::GetMaxNumberOfSessions(size_t* max) { +bool CryptoSession::GetMaxNumberOfSessions(SecurityLevel security_level, + size_t* max) { LOGV("GetMaxNumberOfSessions"); - if (!initialized_) return false; + if (!initialized_) { + LOGW("CryptoSession::GetMaxNumberOfSessions: not initialized"); + return false; + } + if (max == NULL) { LOGE("CryptoSession::GetMaxNumberOfSessions: |max| cannot be NULL"); return false; @@ -1673,7 +1731,7 @@ bool CryptoSession::GetMaxNumberOfSessions(size_t* max) { size_t max_sessions = 0; OEMCryptoResult status = OEMCrypto_GetMaxNumberOfSessions( - requested_security_level_, &max_sessions); + security_level, &max_sessions); if (OEMCrypto_SUCCESS != status) { LOGW("OEMCrypto_GetMaxNumberOfSessions fails with %d", status); metrics_->oemcrypto_max_number_of_sessions_.SetError(status);