From 240652afcf5ce629658204ee3372adeae1d45357 Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Sat, 30 Jun 2018 22:30:57 -0700 Subject: [PATCH] Do Not Unprovision Baked-In DRM Certs Merge from Widevine repo of http://go/wvgerrit/49820 Devices with baked-in DRM certs cannot be reprovisioned. As such, we must protect them against being unprovisioned. Currently, our unit tests break such devices by attempting to unprovision them. This patch adds code to block the Unprovision() call on these devices. Bug: 69264798 Test: CE CDM Unit Tests Test: tested as part of http://go/ag/4674759 Change-Id: I49322dcb2d3d5c7953e870eb91a9e0b978d4dabe --- libwvdrmengine/cdm/core/include/crypto_session.h | 6 ++++-- libwvdrmengine/cdm/core/include/wv_cdm_types.h | 1 + libwvdrmengine/cdm/core/src/cdm_engine.cpp | 13 +++++++++++++ libwvdrmengine/cdm/core/test/test_printers.cpp | 2 ++ libwvdrmengine/include/WVErrors.h | 3 ++- libwvdrmengine/include/mapErrors-inl.h | 3 ++- libwvdrmengine/include_hidl/mapErrors-inl.h | 1 + 7 files changed, 25 insertions(+), 4 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 54aeec59..881187e6 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -199,11 +199,13 @@ class CryptoSession { virtual bool GenerateSubSessionNonce(const std::string& sub_session_key_id, bool* exists, uint32_t* nonce); + virtual CdmResponseType GetProvisioningMethod( + SecurityLevel requested_security_level, + CdmClientTokenType* token_type); + private: friend class CryptoSessionForTest; - CdmResponseType GetProvisioningMethod(SecurityLevel requested_security_level, - CdmClientTokenType* token_type); void Init(); void Terminate(); bool GetTokenFromKeybox(std::string* token); diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index a8cbc36b..15af94a2 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -333,6 +333,7 @@ enum CdmResponseType { GET_PROVISIONING_METHOD_ERROR = 289, SESSION_NOT_FOUND_17 = 290, SESSION_NOT_FOUND_18 = 291, + DEVICE_CANNOT_REPROVISION = 293, }; enum CdmKeyStatus { diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index da3a1b71..d3700c67 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -872,6 +872,19 @@ bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level) { } CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { + // Devices with baked-in DRM certs cannot be reprovisioned and therefore must + // not be unprovisioned. + CryptoSession crypto_session(metrics_.GetCryptoMetrics()); + CdmClientTokenType token_type = kClientTokenUninitialized; + CdmResponseType res = crypto_session.GetProvisioningMethod( + security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault, + &token_type); + if (res != NO_ERROR) { + return res; + } else if (token_type == kClientTokenDrmCert) { + return DEVICE_CANNOT_REPROVISION; + } + DeviceFiles handle(file_system_); if (!handle.Init(security_level)) { LOGE("CdmEngine::Unprovision: unable to initialize device files"); diff --git a/libwvdrmengine/cdm/core/test/test_printers.cpp b/libwvdrmengine/cdm/core/test/test_printers.cpp index 475c5f89..77ecc821 100644 --- a/libwvdrmengine/cdm/core/test/test_printers.cpp +++ b/libwvdrmengine/cdm/core/test/test_printers.cpp @@ -599,6 +599,8 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { break; case SESSION_NOT_FOUND_18: *os << "SESSION_NOT_FOUND_18"; break; + case DEVICE_CANNOT_REPROVISION: *os << "DEVICE_CANNOT_REPROVISION"; + break; default: *os << "Unknown CdmResponseType"; break; diff --git a/libwvdrmengine/include/WVErrors.h b/libwvdrmengine/include/WVErrors.h index 73a65e0d..bba7b798 100644 --- a/libwvdrmengine/include/WVErrors.h +++ b/libwvdrmengine/include/WVErrors.h @@ -269,10 +269,11 @@ enum { kNotAnEntitlementSession = ERROR_DRM_VENDOR_MIN + 278, kLoadEntitledContentKeysError = ERROR_DRM_VENDOR_MIN + 279, kGetProvisioningError = ERROR_DRM_VENDOR_MIN + 280, + kDeviceCannotReprovision = ERROR_DRM_VENDOR_MIN + 281, // This should always follow the last error code. // The offset value should be updated each time a new error code is added. - kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 280, + kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 281, // Used by crypto test mode kErrorTestMode = ERROR_DRM_VENDOR_MAX, diff --git a/libwvdrmengine/include/mapErrors-inl.h b/libwvdrmengine/include/mapErrors-inl.h index 029c11d9..0c8ecd25 100644 --- a/libwvdrmengine/include/mapErrors-inl.h +++ b/libwvdrmengine/include/mapErrors-inl.h @@ -520,7 +520,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kLoadEntitledContentKeysError; case wvcdm::GET_PROVISIONING_METHOD_ERROR: return kGetProvisioningError; - + case wvcdm::DEVICE_CANNOT_REPROVISION: + return kDeviceCannotReprovision; } // Return here instead of as a default case so that the compiler will warn diff --git a/libwvdrmengine/include_hidl/mapErrors-inl.h b/libwvdrmengine/include_hidl/mapErrors-inl.h index 1637e626..f6528073 100644 --- a/libwvdrmengine/include_hidl/mapErrors-inl.h +++ b/libwvdrmengine/include_hidl/mapErrors-inl.h @@ -299,6 +299,7 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) { case wvcdm::NOT_AN_ENTITLEMENT_SESSION: case wvcdm::LOAD_ENTITLED_CONTENT_KEYS_ERROR: case wvcdm::GET_PROVISIONING_METHOD_ERROR: + case wvcdm::DEVICE_CANNOT_REPROVISION: ALOGW("Returns UNKNOWN error for legacy status: %d", res); return Status::ERROR_DRM_UNKNOWN;