From 7c3e06f46dde543521a5c2aabaf9cd4a684c7616 Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Thu, 18 Nov 2021 21:47:10 +0000 Subject: [PATCH] OEMCrypto Testing: Don't return key data if no keybox Merge from Widevine repo of http://go/wvgerrit/139336 When pretending we have no keybox, we should also have no system id or device id. This should reproduce our problem with the test app. Bug: 206570220 Test: reproduced problem using TestOPK app Change-Id: I893336ce8e1fd2272f5b511676e1da28654639a7 --- .../core/src/oemcrypto_adapter_dynamic.cpp | 48 +++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index 51bdfcb6..aedea7c9 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -666,7 +666,9 @@ uint32_t GetDebugIgnoreKeyboxCount() { LOGE("Could not parse an integer from '%s'", contents.c_str()); count = 0; } - LOGD("Using IgnoreDebugKeyboxCount = %u", count); + if (count > 0) { + LOGD("Using IgnoreDebugKeyboxCount = %u", count); + } return count; } @@ -1211,6 +1213,19 @@ class Adapter { : OEMCrypto_ERROR_NOT_IMPLEMENTED; } + bool IsOTAKeyboxSupported() { + // TODO(b/206570220): work around for failing Keybox reprovisioning is + // to fall back to Level 3 if the keybox is not found. + // Put this back when we can: *needs_keybox_provisioning = true; + return false; + if (!level1_valid_) return false; + if (!level1_.GenerateOTARequest) return false; + size_t buffer_size = 500; // a large buffer. + std::vector buffer(buffer_size); + return level1_.GenerateOTARequest(0, buffer.data(), &buffer_size, 0) != + OEMCrypto_ERROR_NOT_IMPLEMENTED; + } + private: bool level1_valid_; void* level1_library_; @@ -1287,6 +1302,8 @@ OEMCryptoResult OEMCrypto_InitializeAndCheckKeybox( gAdapter.reset(new Adapter()); } const OEMCryptoResult status = gAdapter->Initialize(); + // TODO(fredgc): if L1 is successful, but L3 is not, this does not try to + // continue on. if (status != OEMCrypto_SUCCESS) return status; const OEMCryptoResult keybox_status = gAdapter->ValidateOrInstallKeyboxOrCert(); @@ -1296,9 +1313,15 @@ OEMCryptoResult OEMCrypto_InitializeAndCheckKeybox( if (ignore_count > 0) { LOGD("Ignoring keybox status %d", static_cast(keybox_status)); } - LOGD("L1 has no keybox. Falling back to L3."); - gAdapter->FallBackToLevel3(); - return OEMCrypto_SUCCESS; + if (gAdapter->IsOTAKeyboxSupported()) { + LOGD("L1 needs keybox reprovisioning."); + *needs_keybox_provisioning = true; + return OEMCrypto_SUCCESS; + } else { + LOGD("L1 has no keybox. Falling back to L3."); + gAdapter->FallBackToLevel3(); + return OEMCrypto_SUCCESS; + } } return keybox_status; } @@ -1336,6 +1359,10 @@ OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength, const FunctionPointers* fcn = gAdapter->GetFunctionPointers(level); if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (fcn->GetDeviceID == nullptr) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + const uint32_t ignore_count = GetDebugIgnoreKeyboxCount(); + if (ignore_count > 0 && fcn->security_level == wvcdm::kSecurityLevelL1) { + return OEMCrypto_ERROR_KEYBOX_INVALID; + } return fcn->GetDeviceID(deviceID, idLength); } @@ -1345,6 +1372,10 @@ OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength, const FunctionPointers* fcn = gAdapter->GetFunctionPointers(level); if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (fcn->GetKeyData == nullptr) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + const uint32_t ignore_count = GetDebugIgnoreKeyboxCount(); + if (ignore_count > 0 && fcn->security_level == wvcdm::kSecurityLevelL1) { + return OEMCrypto_ERROR_KEYBOX_INVALID; + } return fcn->GetKeyData(keyData, keyDataLength); } @@ -2885,11 +2916,12 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateOTARequest( OEMCrypto_SESSION session, uint8_t* buffer, size_t* buffer_length, uint32_t use_test_key) { if (!gAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - const FunctionPointers* fcn = gAdapter->GetFunctionPointers(kLevelDefault); - if (!fcn) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - if (fcn->GenerateOTARequest == nullptr) + LevelSession pair = gAdapter->GetSession(session); + if (!pair.fcn) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + if (pair.fcn->GenerateOTARequest == nullptr) return OEMCrypto_ERROR_NOT_IMPLEMENTED; - return fcn->GenerateOTARequest(session, buffer, buffer_length, use_test_key); + return pair.fcn->GenerateOTARequest(pair.session, buffer, buffer_length, + use_test_key); } extern "C" OEMCryptoResult OEMCrypto_ProcessOTAKeybox(OEMCrypto_SESSION session,