From 58c1ea1fa2ab5c69075ecb8b9a71f87f1b708d26 Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Thu, 24 Jun 2021 03:28:19 +0000 Subject: [PATCH] Cache security level Merge from Widevine repo of http://go/wvgerrit/127743 There was some confusion about who owned the OEMCrypto security level string in a multithreaded environment. This is solved by caching the security level at initialization time. Bug: 188706160 Test: ran unit tests on bonito Change-Id: I93af3bb2e5a8bf190627ee568f752b5ea9543306 --- .../core/src/oemcrypto_adapter_dynamic.cpp | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index 194b2ee6..51e2c119 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -35,6 +35,7 @@ #include "metrics_collections.h" #include "properties.h" #include "wv_cdm_constants.h" +#include "wv_cdm_types.h" using namespace wvoec3; using video_widevine::ProvisioningResponse; @@ -319,6 +320,7 @@ typedef OEMCryptoResult (*L1_LoadProvisioning_t)( typedef uint32_t (*L1_MinorAPIVersion_t)(); struct FunctionPointers { + wvcdm::CdmSecurityLevel security_level; uint32_t version; L1_Initialize_t Initialize; L1_SetSandbox_t SetSandbox; @@ -690,6 +692,7 @@ class Adapter { level1_ = FunctionPointers(); // start with all null pointers. level3_ = FunctionPointers(); // start with all null pointers. + level3_.security_level = wvcdm::kSecurityLevelL3; LoadLevel3(); WatchDog* watcher = new WatchDog(sandbox_id_); watcher->CheckForPreviousFailure(&metrics); @@ -782,6 +785,7 @@ class Adapter { return false; } level1_.version = level1_.APIVersion(); + level1_.security_level = wvcdm::kSecurityLevelUninitialized; metrics->SetL1ApiVersion(level1_.version); metrics->SetL1MinApiVersion(kMinimumVersion); @@ -895,6 +899,22 @@ class Adapter { level1_library_, "OEMCrypto_FreeSecureBuffer"); } + if (level1_.SecurityLevel) { + const char* level = level1_.SecurityLevel(); + if (strncmp(level, "L1", 2) == 0) { + level1_.security_level = wvcdm::kSecurityLevelL1; + } else if (strncmp(level, "L3", 2) == 0) { + // It is possible that the dynamically loaded OEMCrypto is really L3. + // We might want to use it if it has better performance than the built + // in L3. + LOGW("L1 OEMCrypto is really L3"); + level1_.security_level = wvcdm::kSecurityLevelL3; + } else { + LOGE("Unknown security level %.2s", level); + level1_.security_level = wvcdm::kSecurityLevelUnknown; + } + } + // TODO(119830252): make the code below available to a static adapter. // Check if the keybox or oem certificate is valid, if so, we are finished // with initialization. @@ -1219,8 +1239,16 @@ const char* OEMCrypto_SecurityLevel(SecurityLevel level) { if (!gAdapter) return ""; const FunctionPointers* fcn = gAdapter->GetFunctionPointers(level); if (!fcn) return ""; - if (fcn->SecurityLevel == nullptr) return ""; - return fcn->SecurityLevel(); + switch (fcn->security_level) { + case kSecurityLevelL1: + return "L1"; + case kSecurityLevelL2: + return "L2"; + case kSecurityLevelL3: + return "L3"; + default: + return ""; + } } OEMCryptoResult OEMCrypto_GetHDCPCapability(