Finer-Grained OEMCrypto Locking

(This is a merge of http://go/wvgerrit/72867)

This patch replaces the previous static std::mutexes in CryptoSession
with shared_mutexes, allowing multiple readers to access the resources
they protect. For the shared fields, this means only Initialize(),
Terminate(), and the code that sets up the usage table headers needs
exclusive access. All other CryptoSession code is able to read these
fields in parallel.

For OEMCrypto, the static OEMCrypto lock is joined by a per-session
std::mutex, which are used in concert to enforce the OEMCrypto v15
threading guarantees.

On my machine this results in a noticeable increase in performance for
the parallel unit tests.

Bug: 70889998
Bug: 118584039
Test: CE CDM Unit Tests
Test: Android Unit Tests
Test: Jenkins Tests
Change-Id: Ie6332ae4926ed4f14af897685d37bfe63831b14f
This commit is contained in:
John W. Bruce
2019-02-19 13:58:07 -08:00
parent d925048c35
commit e10ac3b465
2 changed files with 181 additions and 118 deletions

View File

@@ -17,6 +17,7 @@
#include "key_session.h" #include "key_session.h"
#include "metrics_collections.h" #include "metrics_collections.h"
#include "oemcrypto_adapter.h" #include "oemcrypto_adapter.h"
#include "rw_lock.h"
#include "timer_metric.h" #include "timer_metric.h"
#include "wv_cdm_types.h" #include "wv_cdm_types.h"
@@ -256,7 +257,7 @@ class CryptoSession {
// OEMCrypto to use a test keybox. // OEMCrypto to use a test keybox.
// Ownership of the object is transfered to CryptoSession. // Ownership of the object is transfered to CryptoSession.
static void SetCryptoSessionFactory(CryptoSessionFactory* factory) { static void SetCryptoSessionFactory(CryptoSessionFactory* factory) {
std::unique_lock<std::mutex> auto_lock(factory_lock_); std::unique_lock<std::mutex> auto_lock(factory_mutex_);
factory_.reset(factory); factory_.reset(factory);
} }
@@ -311,25 +312,59 @@ class CryptoSession {
size_t max_chunk_size); size_t max_chunk_size);
static void IncrementIV(uint64_t increase_by, std::vector<uint8_t>* iv_out); static void IncrementIV(uint64_t increase_by, std::vector<uint8_t>* iv_out);
// These methods should be used to take the various CryptoSession locks in // These methods should be used to take the various CryptoSession mutexes in
// preference to taking the locks directly. // preference to taking the mutexes directly.
// //
// The Static Field Lock should be taken before accessing any of // A lock should be taken on the Static Field Mutex before accessing any of
// CryptoSession's non-atomic static fields. The OEMCrypto Lock should be // CryptoSession's non-atomic static fields. It can be taken as a reader or as
// taken before calling into OEMCrypto. Note that accessing |key_session_| // a writer, depending on how you will be accessing the static fields.
// often accesses OEMCrypto, so this lock should be held before calling into //
// |key_session_| as well. If a function needs to take both locks // Before calling into OEMCrypto, code must take locks on the OEMCrypto Mutex
// simultaneously, it must *always* take the Static Field Lock first. In // and/or the OEMCrypto Session Mutex. Which of them should be taken and how
// general, locks should only be held for the minimum time necessary. // depends on the OEMCrypto function being called; consult the OEMCrypto
// (e.g. |oem_crypto_lock_| should only be held for the duration of a single // specification's threading guarantees before making any calls. The OEMCrypto
// call into OEMCrypto, unless there is a compelling argument otherwise such // specification defines several classes of functions for the purposes of
// as making two calls into OEMCrypto immediately after each other.) // parallelism. The methods below lock the OEMCrypto Mutex and OEMCrypto
// Session Mutex in the correct order and manner to fulfill the guarantees in
// the specification.
//
// For this function class... | ...use this locking method
// ------------------------------+---------------------------
// Initialization & Termination | WithOecWriteLock()
// Property | WithOecReadLock()
// Session Initialization | WithOecWriteLock()
// Usage Table | WithOecWriteLock()
// Session | WithOecSessionLock()
//
// Note that accessing |key_session_| often accesses the OEMCrypto session, so
// WithOecSessionLock() should be used before accessing |key_session_| as
// well.
//
// If a function needs to take a lock on both the Static Field Mutex and some
// of the OEMCrypto mutexes simultaneously, it must *always* lock the Static
// Field Mutex before the OEMCrypto mutexes.
//
// In general, all locks should only be held for the minimum time necessary
// (e.g. a lock on the OEMCrypto mutexes should only be held for the duration
// of a single call into OEMCrypto) unless there is a compelling argument
// otherwise, such as making two calls into OEMCrypto immediately after each
// other.
template <class Func> template <class Func>
static auto WithStaticFieldLock(const char* tag, Func body) static auto WithStaticFieldWriteLock(const char* tag, Func body)
-> decltype(body()); -> decltype(body());
template <class Func> template <class Func>
static auto WithOecLock(const char* tag, Func body) -> decltype(body()); static auto WithStaticFieldReadLock(const char* tag, Func body)
-> decltype(body());
template <class Func>
static auto WithOecWriteLock(const char* tag, Func body) -> decltype(body());
template <class Func>
static auto WithOecReadLock(const char* tag, Func body) -> decltype(body());
template <class Func>
auto WithOecSessionLock(const char* tag, Func body) -> decltype(body());
static bool IsInitialized(); static bool IsInitialized();
@@ -337,11 +372,12 @@ class CryptoSession {
static const size_t kAes128BlockSize = 16; // Block size for AES_CBC_128 static const size_t kAes128BlockSize = 16; // Block size for AES_CBC_128
static const size_t kSignatureSize = 32; // size for HMAC-SHA256 signature static const size_t kSignatureSize = 32; // size for HMAC-SHA256 signature
// The |WithStaticFieldLock| and |WithOecLock| methods should be used in // The locking methods above should be used in preference to taking these
// preference to taking these locks directly. When taken, the rules of // mutexes directly. If code takes these manually and needs to take more
// ordering documented with those functions must still be upheld. // than one, it must *always* take them in the order they are defined here.
static std::mutex static_field_lock_; static shared_mutex static_field_mutex_;
static std::mutex oem_crypto_lock_; static shared_mutex oem_crypto_mutex_;
std::mutex oem_crypto_session_mutex_;
static bool initialized_; static bool initialized_;
static int session_count_; static int session_count_;
@@ -374,9 +410,9 @@ class CryptoSession {
uint32_t api_version_; uint32_t api_version_;
// In order to avoid creating a deadlock if instantiation needs to take any // In order to avoid creating a deadlock if instantiation needs to take any
// of the CryptoSession static locks, |factory_| is protected by its own lock // of the CryptoSession static mutexes, |factory_| is protected by its own
// that is only used in the two funtions that interact with it. // mutex that is only used in the two funtions that interact with it.
static std::mutex factory_lock_; static std::mutex factory_mutex_;
static std::unique_ptr<CryptoSessionFactory> factory_; static std::unique_ptr<CryptoSessionFactory> factory_;
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession); CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession);

View File

@@ -75,8 +75,8 @@ void DeleteX509Stack(STACK_OF(X509)* stack) {
} // namespace } // namespace
namespace wvcdm { namespace wvcdm {
std::mutex CryptoSession::static_field_lock_; shared_mutex CryptoSession::static_field_mutex_;
std::mutex CryptoSession::oem_crypto_lock_; shared_mutex CryptoSession::oem_crypto_mutex_;
bool CryptoSession::initialized_ = false; bool CryptoSession::initialized_ = false;
int CryptoSession::session_count_ = 0; int CryptoSession::session_count_ = 0;
UsageTableHeader* CryptoSession::usage_table_header_l1_ = NULL; UsageTableHeader* CryptoSession::usage_table_header_l1_ = NULL;
@@ -214,7 +214,7 @@ CdmResponseType CryptoSession::GetProvisioningMethod(
SecurityLevel requested_security_level, SecurityLevel requested_security_level,
CdmClientTokenType* token_type) { CdmClientTokenType* token_type) {
OEMCrypto_ProvisioningMethod method; OEMCrypto_ProvisioningMethod method;
WithOecLock("GetProvisioningMethod", [&] { WithOecReadLock("GetProvisioningMethod", [&] {
method = OEMCrypto_GetProvisioningMethod(requested_security_level); method = OEMCrypto_GetProvisioningMethod(requested_security_level);
}); });
metrics_->oemcrypto_provisioning_method_.Record(method); metrics_->oemcrypto_provisioning_method_.Record(method);
@@ -241,12 +241,12 @@ CdmResponseType CryptoSession::GetProvisioningMethod(
void CryptoSession::Init() { void CryptoSession::Init() {
LOGV("CryptoSession::Init"); LOGV("CryptoSession::Init");
WithStaticFieldLock("Init", [&] { WithStaticFieldWriteLock("Init", [&] {
session_count_ += 1; session_count_ += 1;
if (!initialized_) { if (!initialized_) {
std::string sandbox_id; std::string sandbox_id;
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("Init", [&] { WithOecWriteLock("Init", [&] {
if (Properties::GetSandboxId(&sandbox_id) && !sandbox_id.empty()) { if (Properties::GetSandboxId(&sandbox_id) && !sandbox_id.empty()) {
sts = OEMCrypto_SetSandbox( sts = OEMCrypto_SetSandbox(
reinterpret_cast<const uint8_t*>(sandbox_id.c_str()), reinterpret_cast<const uint8_t*>(sandbox_id.c_str()),
@@ -268,7 +268,7 @@ void CryptoSession::Init() {
void CryptoSession::Terminate() { void CryptoSession::Terminate() {
LOGV("CryptoSession::Terminate"); LOGV("CryptoSession::Terminate");
WithStaticFieldLock("Terminate", [&] { WithStaticFieldWriteLock("Terminate", [&] {
LOGV("initialized_=%d, session_count_=%d", initialized_, session_count_); LOGV("initialized_=%d, session_count_=%d", initialized_, session_count_);
if (session_count_ > 0) { if (session_count_ > 0) {
session_count_ -= 1; session_count_ -= 1;
@@ -277,7 +277,7 @@ void CryptoSession::Terminate() {
} }
if (session_count_ > 0 || !initialized_) return; if (session_count_ > 0 || !initialized_) return;
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("Terminate", [&] { WithOecWriteLock("Terminate", [&] {
sts = OEMCrypto_Terminate(); sts = OEMCrypto_Terminate();
}); });
if (OEMCrypto_SUCCESS != sts) { if (OEMCrypto_SUCCESS != sts) {
@@ -307,7 +307,7 @@ CdmResponseType CryptoSession::GetTokenFromKeybox(std::string* token) {
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]); uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("GetTokenFromKeybox", [&] { WithOecReadLock("GetTokenFromKeybox", [&] {
M_TIME( M_TIME(
status = status =
OEMCrypto_GetKeyData(buf, &buf_size, requested_security_level_), OEMCrypto_GetKeyData(buf, &buf_size, requested_security_level_),
@@ -338,7 +338,7 @@ CdmResponseType CryptoSession::GetTokenFromOemCert(std::string* token) {
while (true) { while (true) {
size_t buf_size = temp_buffer.size(); size_t buf_size = temp_buffer.size();
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]); uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
WithOecLock("GetTokenFromOemCert", [&] { WithOecSessionLock("GetTokenFromOemCert", [&] {
status = OEMCrypto_GetOEMPublicCertificate(oec_session_id_, buf, status = OEMCrypto_GetOEMPublicCertificate(oec_session_id_, buf,
&buf_size); &buf_size);
}); });
@@ -402,7 +402,7 @@ CdmSecurityLevel CryptoSession::GetSecurityLevel(
} }
std::string security_level; std::string security_level;
WithOecLock("GetSecurityLevel", [&] { WithOecReadLock("GetSecurityLevel", [&] {
security_level = OEMCrypto_SecurityLevel(requested_level); security_level = OEMCrypto_SecurityLevel(requested_level);
}); });
@@ -448,14 +448,14 @@ CdmResponseType CryptoSession::GetInternalDeviceUniqueId(
id.resize(id_length); id.resize(id_length);
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("GetInternalDeviceUniqueId Attempt 1", [&] { WithOecReadLock("GetInternalDeviceUniqueId Attempt 1", [&] {
sts = OEMCrypto_GetDeviceID(&id[0], &id_length, requested_security_level_); sts = OEMCrypto_GetDeviceID(&id[0], &id_length, requested_security_level_);
}); });
// Increment the count of times this method was called. // Increment the count of times this method was called.
metrics_->oemcrypto_get_device_id_.Increment(sts); metrics_->oemcrypto_get_device_id_.Increment(sts);
if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { if (sts == OEMCrypto_ERROR_SHORT_BUFFER) {
id.resize(id_length); id.resize(id_length);
WithOecLock("GetInternalDeviceUniqueId Attempt 2", [&] { WithOecReadLock("GetInternalDeviceUniqueId Attempt 2", [&] {
sts = OEMCrypto_GetDeviceID(&id[0], &id_length, sts = OEMCrypto_GetDeviceID(&id[0], &id_length,
requested_security_level_); requested_security_level_);
}); });
@@ -494,7 +494,7 @@ CdmResponseType CryptoSession::GetExternalDeviceUniqueId(
size_t id_length = 0; size_t id_length = 0;
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("GetExternalDeviceUniqueId", [&] { WithOecReadLock("GetExternalDeviceUniqueId", [&] {
sts = OEMCrypto_GetDeviceID(NULL, &id_length, requested_security_level_); sts = OEMCrypto_GetDeviceID(NULL, &id_length, requested_security_level_);
}); });
metrics_->oemcrypto_get_device_id_.Increment(sts); metrics_->oemcrypto_get_device_id_.Increment(sts);
@@ -538,7 +538,7 @@ bool CryptoSession::GetApiVersion(SecurityLevel security_level,
return false; return false;
} }
WithOecLock("GetApiVersion", [&] { WithOecReadLock("GetApiVersion", [&] {
*version = OEMCrypto_APIVersion(security_level); *version = OEMCrypto_APIVersion(security_level);
}); });
// Record the version into the metrics. // Record the version into the metrics.
@@ -758,7 +758,7 @@ CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) {
uint8_t CryptoSession::GetSecurityPatchLevel() { uint8_t CryptoSession::GetSecurityPatchLevel() {
uint8_t patch; uint8_t patch;
WithOecLock("GetSecurityPatchLevel", [&] { WithOecReadLock("GetSecurityPatchLevel", [&] {
patch = OEMCrypto_Security_Patch_Level(requested_security_level_); patch = OEMCrypto_Security_Patch_Level(requested_security_level_);
}); });
metrics_->oemcrypto_security_patch_level_.Record(patch); metrics_->oemcrypto_security_patch_level_.Record(patch);
@@ -781,15 +781,17 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
OEMCrypto_SESSION sid; OEMCrypto_SESSION sid;
requested_security_level_ = requested_security_level; requested_security_level_ = requested_security_level;
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("Open() calling OEMCrypto_OpenSession", [&] { WithOecWriteLock("Open() calling OEMCrypto_OpenSession", [&] {
sts = OEMCrypto_OpenSession(&sid, requested_security_level); sts = OEMCrypto_OpenSession(&sid, requested_security_level);
}); });
if (sts != OEMCrypto_SUCCESS) { if (sts != OEMCrypto_SUCCESS) {
WithStaticFieldLock("Open() reporting OEMCrypto_OpenSession Failure", [&] { WithStaticFieldReadLock(
LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", "Open() reporting OEMCrypto_OpenSession Failure",
sts, session_count_, (int)initialized_); [&] {
}); LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d",
sts, session_count_, (int)initialized_);
});
return MapOEMCryptoResult(sts, OPEN_CRYPTO_SESSION_ERROR, "Open"); return MapOEMCryptoResult(sts, OPEN_CRYPTO_SESSION_ERROR, "Open");
} }
@@ -808,7 +810,7 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
uint64_t request_id_base; uint64_t request_id_base;
OEMCryptoResult random_sts; OEMCryptoResult random_sts;
WithOecLock("Open() calling OEMCrypto_GetRandom", [&] { WithOecReadLock("Open() calling OEMCrypto_GetRandom", [&] {
random_sts = OEMCrypto_GetRandom( random_sts = OEMCrypto_GetRandom(
reinterpret_cast<uint8_t*>(&request_id_base), sizeof(request_id_base)); reinterpret_cast<uint8_t*>(&request_id_base), sizeof(request_id_base));
}); });
@@ -834,10 +836,10 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
if (security_level == kSecurityLevelL1 || if (security_level == kSecurityLevelL1 ||
security_level == kSecurityLevelL3) { security_level == kSecurityLevelL3) {
{ {
// This block cannot use |WithStaticFieldLock| because it needs to // This block cannot use |WithStaticFieldWriteLock| because it needs
// unlock the lock partway through. // to unlock the lock partway through.
LOGV("Static Field Lock - Open() Initializing Usage Table"); LOGV("Static Field Write Lock - Open() Initializing Usage Table");
std::unique_lock<std::mutex> auto_lock(static_field_lock_); std::unique_lock<shared_mutex> auto_lock(static_field_mutex_);
UsageTableHeader** header = security_level == kSecurityLevelL1 UsageTableHeader** header = security_level == kSecurityLevelL1
? &usage_table_header_l1_ ? &usage_table_header_l1_
@@ -866,7 +868,7 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
metrics_->oemcrypto_usage_table_support_.SetError(result); metrics_->oemcrypto_usage_table_support_.SetError(result);
} }
WithOecLock("Open() calling key_session_.reset()", [&] { WithOecSessionLock("Open() calling key_session_.reset()", [&] {
key_session_.reset(new ContentKeySession(oec_session_id_, metrics_)); key_session_.reset(new ContentKeySession(oec_session_id_, metrics_));
}); });
@@ -880,7 +882,7 @@ void CryptoSession::Close() {
OEMCryptoResult close_sts; OEMCryptoResult close_sts;
bool update_usage_table = false; bool update_usage_table = false;
WithOecLock("Close", [&] { WithOecWriteLock("Close", [&] {
close_sts = OEMCrypto_CloseSession(oec_session_id_); close_sts = OEMCrypto_CloseSession(oec_session_id_);
}); });
metrics_->oemcrypto_close_session_.Increment(close_sts); metrics_->oemcrypto_close_session_.Increment(close_sts);
@@ -932,7 +934,7 @@ CdmResponseType CryptoSession::LoadKeys(
CdmResponseType result = KEY_ADDED; CdmResponseType result = KEY_ADDED;
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("LoadKeys", [&] { WithOecSessionLock("LoadKeys", [&] {
if (key_type == kLicenseKeyTypeEntitlement && if (key_type == kLicenseKeyTypeEntitlement &&
key_session_->Type() != KeySession::kEntitlement) { key_session_->Type() != KeySession::kEntitlement) {
key_session_.reset(new EntitlementKeySession(oec_session_id_, metrics_)); key_session_.reset(new EntitlementKeySession(oec_session_id_, metrics_));
@@ -979,7 +981,7 @@ CdmResponseType CryptoSession::LoadKeys(
CdmResponseType CryptoSession::LoadEntitledContentKeys( CdmResponseType CryptoSession::LoadEntitledContentKeys(
const std::vector<CryptoKey>& key_array) { const std::vector<CryptoKey>& key_array) {
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("LoadEntitledContentKeys", [&] { WithOecSessionLock("LoadEntitledContentKeys", [&] {
sts = key_session_->LoadEntitledContentKeys(key_array); sts = key_session_->LoadEntitledContentKeys(key_array);
}); });
@@ -1009,7 +1011,7 @@ CdmResponseType CryptoSession::LoadCertificatePrivateKey(
size_t buf_size = temp_buffer.size(); size_t buf_size = temp_buffer.size();
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]); uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock( WithOecSessionLock(
"LoadCertificatePrivateKey() calling OEMCrypto_GetOEMPublicCertificate", "LoadCertificatePrivateKey() calling OEMCrypto_GetOEMPublicCertificate",
[&] { [&] {
sts = sts =
@@ -1018,7 +1020,7 @@ CdmResponseType CryptoSession::LoadCertificatePrivateKey(
metrics_->oemcrypto_get_oem_public_certificate_.Increment(sts); metrics_->oemcrypto_get_oem_public_certificate_.Increment(sts);
LOGV("LoadDeviceRSAKey: id=%lu", oec_session_id_); LOGV("LoadDeviceRSAKey: id=%lu", oec_session_id_);
WithOecLock( WithOecSessionLock(
"LoadCertificatePrivateKey() calling OEMCrypto_LoadDeviceRSAKey()", "LoadCertificatePrivateKey() calling OEMCrypto_LoadDeviceRSAKey()",
[&] { [&] {
M_TIME(sts = OEMCrypto_LoadDeviceRSAKey( M_TIME(sts = OEMCrypto_LoadDeviceRSAKey(
@@ -1050,7 +1052,7 @@ CdmResponseType CryptoSession::RefreshKeys(const std::string& message,
} }
LOGV("RefreshKeys: id=%lu", oec_session_id_); LOGV("RefreshKeys: id=%lu", oec_session_id_);
OEMCryptoResult refresh_sts; OEMCryptoResult refresh_sts;
WithOecLock("RefreshKeys", [&] { WithOecSessionLock("RefreshKeys", [&] {
M_TIME(refresh_sts = OEMCrypto_RefreshKeys( M_TIME(refresh_sts = OEMCrypto_RefreshKeys(
oec_session_id_, msg, message.size(), oec_session_id_, msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()), reinterpret_cast<const uint8_t*>(signature.data()),
@@ -1067,7 +1069,7 @@ CdmResponseType CryptoSession::RefreshKeys(const std::string& message,
CdmResponseType CryptoSession::SelectKey(const std::string& key_id, CdmResponseType CryptoSession::SelectKey(const std::string& key_id,
CdmCipherMode cipher_mode) { CdmCipherMode cipher_mode) {
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("SelectKey", [&] { WithOecSessionLock("SelectKey", [&] {
sts = key_session_->SelectKey(key_id, cipher_mode); sts = key_session_->SelectKey(key_id, cipher_mode);
}); });
@@ -1105,7 +1107,7 @@ CdmResponseType CryptoSession::SelectKey(const std::string& key_id,
CdmResponseType CryptoSession::GenerateDerivedKeys(const std::string& message) { CdmResponseType CryptoSession::GenerateDerivedKeys(const std::string& message) {
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("GenerateDerivedKeys without session_key", [&] { WithOecSessionLock("GenerateDerivedKeys without session_key", [&] {
sts = key_session_->GenerateDerivedKeys(message); sts = key_session_->GenerateDerivedKeys(message);
}); });
@@ -1116,7 +1118,7 @@ CdmResponseType CryptoSession::GenerateDerivedKeys(const std::string& message) {
CdmResponseType CryptoSession::GenerateDerivedKeys( CdmResponseType CryptoSession::GenerateDerivedKeys(
const std::string& message, const std::string& session_key) { const std::string& message, const std::string& session_key) {
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("GenerateDerivedKeys with session_key", [&] { WithOecSessionLock("GenerateDerivedKeys with session_key", [&] {
sts = key_session_->GenerateDerivedKeys(message, session_key); sts = key_session_->GenerateDerivedKeys(message, session_key);
}); });
@@ -1138,7 +1140,7 @@ CdmResponseType CryptoSession::GenerateSignature(const std::string& message,
// At most two attempts. // At most two attempts.
// The first attempt may fail due to buffer too short // The first attempt may fail due to buffer too short
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
WithOecLock("GenerateSignature", [&] { WithOecSessionLock("GenerateSignature", [&] {
M_TIME(sts = OEMCrypto_GenerateSignature( M_TIME(sts = OEMCrypto_GenerateSignature(
oec_session_id_, oec_session_id_,
reinterpret_cast<const uint8_t*>(message.data()), reinterpret_cast<const uint8_t*>(message.data()),
@@ -1181,7 +1183,7 @@ CdmResponseType CryptoSession::GenerateRsaSignature(const std::string& message,
// At most two attempts. // At most two attempts.
// The first attempt may fail due to buffer too short // The first attempt may fail due to buffer too short
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
WithOecLock("GenerateRsaSignature", [&] { WithOecSessionLock("GenerateRsaSignature", [&] {
M_TIME(sts = OEMCrypto_GenerateRSASignature( M_TIME(sts = OEMCrypto_GenerateRSASignature(
oec_session_id_, oec_session_id_,
reinterpret_cast<const uint8_t*>(message.data()), reinterpret_cast<const uint8_t*>(message.data()),
@@ -1247,7 +1249,7 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
if (!params.is_encrypted && if (!params.is_encrypted &&
params.subsample_flags == params.subsample_flags ==
(OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)) { (OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)) {
WithOecLock("Decrypt() calling CopyBuffer", [&] { WithOecSessionLock("Decrypt() calling CopyBuffer", [&] {
M_TIME(sts = OEMCrypto_CopyBuffer(oec_session_id_, params.encrypt_buffer, M_TIME(sts = OEMCrypto_CopyBuffer(oec_session_id_, params.encrypt_buffer,
params.encrypt_length, params.encrypt_length,
&buffer_descriptor, &buffer_descriptor,
@@ -1279,7 +1281,7 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
if (result != NO_ERROR) return result; if (result != NO_ERROR) return result;
} }
WithOecLock("Decrypt() calling key_session_->Decrypt()", [&] { WithOecSessionLock("Decrypt() calling key_session_->Decrypt()", [&] {
sts = key_session_->Decrypt(params, buffer_descriptor, sts = key_session_->Decrypt(params, buffer_descriptor,
pattern_descriptor); pattern_descriptor);
}); });
@@ -1348,7 +1350,7 @@ bool CryptoSession::UsageInformationSupport(SecurityLevel security_level,
return false; return false;
} }
WithOecLock("UsageInformationSupport", [&] { WithOecReadLock("UsageInformationSupport", [&] {
*has_support = OEMCrypto_SupportsUsageTable(security_level); *has_support = OEMCrypto_SupportsUsageTable(security_level);
}); });
return true; return true;
@@ -1365,7 +1367,7 @@ CdmResponseType CryptoSession::UpdateUsageInformation() {
} }
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("UpdateUsageInformation", [&] { WithOecWriteLock("UpdateUsageInformation", [&] {
status = OEMCrypto_UpdateUsageTable(); status = OEMCrypto_UpdateUsageTable();
}); });
metrics_->oemcrypto_update_usage_table_.Increment(status); metrics_->oemcrypto_update_usage_table_.Increment(status);
@@ -1385,7 +1387,7 @@ CdmResponseType CryptoSession::DeactivateUsageInformation(
// TODO(fredgc or rfrias): make sure oec_session_id_ is valid. // TODO(fredgc or rfrias): make sure oec_session_id_ is valid.
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("DeactivateUsageInformation", [&] { WithOecWriteLock("DeactivateUsageInformation", [&] {
status = OEMCrypto_DeactivateUsageEntry( status = OEMCrypto_DeactivateUsageEntry(
oec_session_id_, pst, provider_session_token.length()); oec_session_id_, pst, provider_session_token.length());
}); });
@@ -1425,7 +1427,7 @@ CdmResponseType CryptoSession::GenerateUsageReport(
size_t usage_length = 0; size_t usage_length = 0;
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("GenerateUsageReport Attempt 1", [&] { WithOecWriteLock("GenerateUsageReport Attempt 1", [&] {
status = OEMCrypto_ReportUsage( status = OEMCrypto_ReportUsage(
oec_session_id_, pst, provider_session_token.length(), NULL, oec_session_id_, pst, provider_session_token.length(), NULL,
&usage_length); &usage_length);
@@ -1439,7 +1441,7 @@ CdmResponseType CryptoSession::GenerateUsageReport(
std::vector<uint8_t> buffer(usage_length); std::vector<uint8_t> buffer(usage_length);
WithOecLock("GenerateUsageReport Attempt 2", [&] { WithOecWriteLock("GenerateUsageReport Attempt 2", [&] {
status = OEMCrypto_ReportUsage(oec_session_id_, pst, status = OEMCrypto_ReportUsage(oec_session_id_, pst,
provider_session_token.length(), &buffer[0], provider_session_token.length(), &buffer[0],
&usage_length); &usage_length);
@@ -1516,7 +1518,7 @@ CdmResponseType CryptoSession::ReleaseUsageInformation(
const uint8_t* pst = msg + GetOffset(message, provider_session_token); const uint8_t* pst = msg + GetOffset(message, provider_session_token);
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("ReleaseUsageInformation", [&] { WithOecWriteLock("ReleaseUsageInformation", [&] {
status = OEMCrypto_DeleteUsageEntry( status = OEMCrypto_DeleteUsageEntry(
oec_session_id_, pst, provider_session_token.length(), msg, oec_session_id_, pst, provider_session_token.length(), msg,
message.length(), sig, signature.length()); message.length(), sig, signature.length());
@@ -1538,7 +1540,7 @@ CdmResponseType CryptoSession::DeleteUsageInformation(
CdmResponseType response = NO_ERROR; CdmResponseType response = NO_ERROR;
LOGV("CryptoSession::DeleteUsageInformation"); LOGV("CryptoSession::DeleteUsageInformation");
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("DeleteUsageInformation", [&] { WithOecWriteLock("DeleteUsageInformation", [&] {
status = OEMCrypto_ForceDeleteUsageEntry( status = OEMCrypto_ForceDeleteUsageEntry(
reinterpret_cast<const uint8_t*>(provider_session_token.c_str()), reinterpret_cast<const uint8_t*>(provider_session_token.c_str()),
provider_session_token.length()); provider_session_token.length());
@@ -1559,7 +1561,7 @@ CdmResponseType CryptoSession::DeleteMultipleUsageInformation(
const std::vector<std::string>& provider_session_tokens) { const std::vector<std::string>& provider_session_tokens) {
LOGV("CryptoSession::DeleteMultipleUsageInformation"); LOGV("CryptoSession::DeleteMultipleUsageInformation");
CdmResponseType response = NO_ERROR; CdmResponseType response = NO_ERROR;
WithOecLock("DeleteMultipleUsageInformation", [&] { WithOecWriteLock("DeleteMultipleUsageInformation", [&] {
for (size_t i = 0; i < provider_session_tokens.size(); ++i) { for (size_t i = 0; i < provider_session_tokens.size(); ++i) {
OEMCryptoResult status = OEMCrypto_ForceDeleteUsageEntry( OEMCryptoResult status = OEMCrypto_ForceDeleteUsageEntry(
reinterpret_cast<const uint8_t*>(provider_session_tokens[i].c_str()), reinterpret_cast<const uint8_t*>(provider_session_tokens[i].c_str()),
@@ -1581,7 +1583,7 @@ CdmResponseType CryptoSession::DeleteMultipleUsageInformation(
CdmResponseType CryptoSession::DeleteAllUsageReports() { CdmResponseType CryptoSession::DeleteAllUsageReports() {
LOGV("DeleteAllUsageReports"); LOGV("DeleteAllUsageReports");
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("DeleteAllUsageReports", [&] { WithOecWriteLock("DeleteAllUsageReports", [&] {
status = OEMCrypto_DeleteOldUsageTable(); status = OEMCrypto_DeleteOldUsageTable();
}); });
metrics_->oemcrypto_delete_usage_table_.Increment(status); metrics_->oemcrypto_delete_usage_table_.Increment(status);
@@ -1598,7 +1600,7 @@ CdmResponseType CryptoSession::DeleteAllUsageReports() {
bool CryptoSession::IsAntiRollbackHwPresent() { bool CryptoSession::IsAntiRollbackHwPresent() {
bool is_present; bool is_present;
WithOecLock("IsAntiRollbackHwPresent", [&] { WithOecReadLock("IsAntiRollbackHwPresent", [&] {
is_present = OEMCrypto_IsAntiRollbackHwPresent(requested_security_level_); is_present = OEMCrypto_IsAntiRollbackHwPresent(requested_security_level_);
}); });
metrics_->oemcrypto_is_anti_rollback_hw_present_.Record(is_present); metrics_->oemcrypto_is_anti_rollback_hw_present_.Record(is_present);
@@ -1612,7 +1614,7 @@ CdmResponseType CryptoSession::GenerateNonce(uint32_t* nonce) {
} }
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("GenerateNonce", [&] { WithOecSessionLock("GenerateNonce", [&] {
result = OEMCrypto_GenerateNonce(oec_session_id_, nonce); result = OEMCrypto_GenerateNonce(oec_session_id_, nonce);
}); });
metrics_->oemcrypto_generate_nonce_.Increment(result); metrics_->oemcrypto_generate_nonce_.Increment(result);
@@ -1690,7 +1692,7 @@ CdmResponseType CryptoSession::RewrapDeviceRSAKey(
// and 0 as wrapped_rsa_key_length. // and 0 as wrapped_rsa_key_length.
size_t wrapped_rsa_key_length = 0; size_t wrapped_rsa_key_length = 0;
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("RewrapDeviceRSAKey Attempt 1", [&] { WithOecSessionLock("RewrapDeviceRSAKey Attempt 1", [&] {
M_TIME(status = OEMCrypto_RewrapDeviceRSAKey( M_TIME(status = OEMCrypto_RewrapDeviceRSAKey(
oec_session_id_, signed_msg, message.size(), oec_session_id_, signed_msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()), reinterpret_cast<const uint8_t*>(signature.data()),
@@ -1705,7 +1707,7 @@ CdmResponseType CryptoSession::RewrapDeviceRSAKey(
} }
wrapped_rsa_key->resize(wrapped_rsa_key_length); wrapped_rsa_key->resize(wrapped_rsa_key_length);
WithOecLock("RewrapDeviceRSAKey Attempt 2", [&] { WithOecSessionLock("RewrapDeviceRSAKey Attempt 2", [&] {
M_TIME(status = OEMCrypto_RewrapDeviceRSAKey( M_TIME(status = OEMCrypto_RewrapDeviceRSAKey(
oec_session_id_, signed_msg, message.size(), oec_session_id_, signed_msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()), reinterpret_cast<const uint8_t*>(signature.data()),
@@ -1749,7 +1751,7 @@ CdmResponseType CryptoSession::RewrapDeviceRSAKey30(
// and 0 as wrapped_rsa_key_length. // and 0 as wrapped_rsa_key_length.
size_t wrapped_private_key_length = 0; size_t wrapped_private_key_length = 0;
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("RewrapDeviceRSAKey30 Attempt 1", [&] { WithOecSessionLock("RewrapDeviceRSAKey30 Attempt 1", [&] {
M_TIME( M_TIME(
status = OEMCrypto_RewrapDeviceRSAKey30( status = OEMCrypto_RewrapDeviceRSAKey30(
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(), oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
@@ -1766,7 +1768,7 @@ CdmResponseType CryptoSession::RewrapDeviceRSAKey30(
} }
wrapped_private_key->resize(wrapped_private_key_length); wrapped_private_key->resize(wrapped_private_key_length);
WithOecLock("RewrapDeviceRSAKey30 Attempt 2", [&] { WithOecSessionLock("RewrapDeviceRSAKey30 Attempt 2", [&] {
M_TIME( M_TIME(
status = OEMCrypto_RewrapDeviceRSAKey30( status = OEMCrypto_RewrapDeviceRSAKey30(
oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(), oec_session_id_, msg_nonce, msg_wrapping_key, wrapping_key.size(),
@@ -1809,7 +1811,7 @@ CdmResponseType CryptoSession::GetHdcpCapabilities(SecurityLevel security_level,
return PARAMETER_NULL; return PARAMETER_NULL;
} }
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("GetHdcpCapabilities", [&] { WithOecReadLock("GetHdcpCapabilities", [&] {
status = OEMCrypto_GetHDCPCapability(security_level, current, max); status = OEMCrypto_GetHDCPCapability(security_level, current, max);
}); });
@@ -1837,7 +1839,7 @@ bool CryptoSession::GetSupportedCertificateTypes(
} }
uint32_t oec_support; uint32_t oec_support;
WithOecLock("GetSupportedCertificateTypes", [&] { WithOecReadLock("GetSupportedCertificateTypes", [&] {
oec_support = OEMCrypto_SupportedCertificates(requested_security_level_); oec_support = OEMCrypto_SupportedCertificates(requested_security_level_);
}); });
support->rsa_2048_bit = oec_support & OEMCrypto_Supports_RSA_2048bit; support->rsa_2048_bit = oec_support & OEMCrypto_Supports_RSA_2048bit;
@@ -1853,7 +1855,7 @@ CdmResponseType CryptoSession::GetRandom(size_t data_length,
return PARAMETER_NULL; return PARAMETER_NULL;
} }
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("GetRandom", [&] { WithOecReadLock("GetRandom", [&] {
sts = OEMCrypto_GetRandom(random_data, data_length); sts = OEMCrypto_GetRandom(random_data, data_length);
}); });
metrics_->oemcrypto_get_random_.Increment(sts); metrics_->oemcrypto_get_random_.Increment(sts);
@@ -1876,7 +1878,7 @@ CdmResponseType CryptoSession::GetNumberOfOpenSessions(
size_t sessions_count; size_t sessions_count;
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("GetNumberOfOpenSessions", [&] { WithOecReadLock("GetNumberOfOpenSessions", [&] {
status = OEMCrypto_GetNumberOfOpenSessions(security_level, &sessions_count); status = OEMCrypto_GetNumberOfOpenSessions(security_level, &sessions_count);
}); });
@@ -1907,7 +1909,7 @@ CdmResponseType CryptoSession::GetMaxNumberOfSessions(
size_t max_sessions = 0; size_t max_sessions = 0;
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("GetMaxNumberOfSessions", [&] { WithOecReadLock("GetMaxNumberOfSessions", [&] {
status = OEMCrypto_GetMaxNumberOfSessions(security_level, &max_sessions); status = OEMCrypto_GetMaxNumberOfSessions(security_level, &max_sessions);
}); });
@@ -1931,7 +1933,7 @@ CdmResponseType CryptoSession::GetSrmVersion(uint16_t* srm_version) {
} }
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("GetSrmVersion", [&] { WithOecReadLock("GetSrmVersion", [&] {
status = OEMCrypto_GetCurrentSRMVersion(srm_version); status = OEMCrypto_GetCurrentSRMVersion(srm_version);
}); });
@@ -1942,7 +1944,7 @@ CdmResponseType CryptoSession::GetSrmVersion(uint16_t* srm_version) {
bool CryptoSession::IsSrmUpdateSupported() { bool CryptoSession::IsSrmUpdateSupported() {
LOGV("IsSrmUpdateSupported"); LOGV("IsSrmUpdateSupported");
if (!IsInitialized()) return false; if (!IsInitialized()) return false;
return WithOecLock("IsSrmUpdateSupported", [&] { return WithOecReadLock("IsSrmUpdateSupported", [&] {
return OEMCrypto_IsSRMUpdateSupported(); return OEMCrypto_IsSRMUpdateSupported();
}); });
} }
@@ -1956,7 +1958,7 @@ CdmResponseType CryptoSession::LoadSrm(const std::string& srm) {
} }
OEMCryptoResult status; OEMCryptoResult status;
WithOecLock("LoadSrm", [&] { WithOecWriteLock("LoadSrm", [&] {
status = OEMCrypto_LoadSRM( status = OEMCrypto_LoadSRM(
reinterpret_cast<const uint8_t*>(srm.data()), srm.size()); reinterpret_cast<const uint8_t*>(srm.data()), srm.size());
}); });
@@ -1984,7 +1986,7 @@ bool CryptoSession::GetResourceRatingTier(SecurityLevel security_level,
LOGE("tier destination not provided"); LOGE("tier destination not provided");
return false; return false;
} }
WithOecLock("GetResourceRatingTier", [&] { WithOecReadLock("GetResourceRatingTier", [&] {
*tier = OEMCrypto_ResourceRatingTier(security_level); *tier = OEMCrypto_ResourceRatingTier(security_level);
}); });
if (*tier < RESOURCE_RATING_TIER_LOW || *tier > RESOURCE_RATING_TIER_HIGH) { if (*tier < RESOURCE_RATING_TIER_LOW || *tier > RESOURCE_RATING_TIER_HIGH) {
@@ -2010,7 +2012,7 @@ bool CryptoSession::GetBuildInformation(SecurityLevel security_level,
return false; return false;
} }
const char* build_information; const char* build_information;
WithOecLock("GetBuildInformation", [&] { WithOecReadLock("GetBuildInformation", [&] {
build_information = OEMCrypto_BuildInformation(security_level); build_information = OEMCrypto_BuildInformation(security_level);
}); });
if (build_information == nullptr) { if (build_information == nullptr) {
@@ -2030,7 +2032,7 @@ uint32_t CryptoSession::IsDecryptHashSupported(SecurityLevel security_level) {
} }
uint32_t secure_decrypt_support; uint32_t secure_decrypt_support;
WithOecLock("IsDecryptHashSupported", [&] { WithOecReadLock("IsDecryptHashSupported", [&] {
secure_decrypt_support = OEMCrypto_SupportsDecryptHash(security_level); secure_decrypt_support = OEMCrypto_SupportsDecryptHash(security_level);
}); });
switch (secure_decrypt_support) { switch (secure_decrypt_support) {
@@ -2052,7 +2054,7 @@ CdmResponseType CryptoSession::SetDecryptHash(
const std::string& hash) { const std::string& hash) {
LOGV("SetDecryptHash"); LOGV("SetDecryptHash");
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("SetDecryptHash", [&] { WithOecSessionLock("SetDecryptHash", [&] {
sts = OEMCrypto_SetDecryptHash( sts = OEMCrypto_SetDecryptHash(
oec_session_id_, frame_number, oec_session_id_, frame_number,
reinterpret_cast<const uint8_t*>(hash.data()), hash.size()); reinterpret_cast<const uint8_t*>(hash.data()), hash.size());
@@ -2071,7 +2073,7 @@ CdmResponseType CryptoSession::GetDecryptHashError(std::string* error_string) {
uint32_t failed_frame_number; uint32_t failed_frame_number;
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("GetDecryptHashError", [&] { WithOecSessionLock("GetDecryptHashError", [&] {
sts = OEMCrypto_GetHashErrorCode(oec_session_id_, &failed_frame_number); sts = OEMCrypto_GetHashErrorCode(oec_session_id_, &failed_frame_number);
}); });
error_string->assign(std::to_string(sts)); error_string->assign(std::to_string(sts));
@@ -2127,7 +2129,7 @@ CdmResponseType CryptoSession::GenericEncrypt(const std::string& in_buffer,
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("GenericEncrypt", [&] { WithOecSessionLock("GenericEncrypt", [&] {
M_TIME( M_TIME(
sts = OEMCrypto_Generic_Encrypt( sts = OEMCrypto_Generic_Encrypt(
oec_session_id_, reinterpret_cast<const uint8_t*>(in_buffer.data()), oec_session_id_, reinterpret_cast<const uint8_t*>(in_buffer.data()),
@@ -2190,7 +2192,7 @@ CdmResponseType CryptoSession::GenericDecrypt(const std::string& in_buffer,
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("GenericDecrypt", [&] { WithOecSessionLock("GenericDecrypt", [&] {
M_TIME( M_TIME(
sts = OEMCrypto_Generic_Decrypt( sts = OEMCrypto_Generic_Decrypt(
oec_session_id_, reinterpret_cast<const uint8_t*>(in_buffer.data()), oec_session_id_, reinterpret_cast<const uint8_t*>(in_buffer.data()),
@@ -2251,7 +2253,7 @@ CdmResponseType CryptoSession::GenericSign(const std::string& message,
// At most two attempts. // At most two attempts.
// The first attempt may fail due to buffer too short // The first attempt may fail due to buffer too short
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
WithOecLock("GenericSign", [&] { WithOecSessionLock("GenericSign", [&] {
M_TIME( M_TIME(
sts = OEMCrypto_Generic_Sign( sts = OEMCrypto_Generic_Sign(
oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()), oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()),
@@ -2312,7 +2314,7 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message,
if (result != NO_ERROR) return result; if (result != NO_ERROR) return result;
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("GenericVerify", [&] { WithOecSessionLock("GenericVerify", [&] {
M_TIME( M_TIME(
sts = OEMCrypto_Generic_Verify( sts = OEMCrypto_Generic_Verify(
oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()), oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()),
@@ -2391,7 +2393,7 @@ CdmResponseType CryptoSession::CreateUsageTableHeader(
size_t usage_table_header_size = usage_table_header->size(); size_t usage_table_header_size = usage_table_header->size();
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("CreateUsageTableHeader Attempt 1", [&] { WithOecWriteLock("CreateUsageTableHeader Attempt 1", [&] {
result = OEMCrypto_CreateUsageTableHeader( result = OEMCrypto_CreateUsageTableHeader(
requested_security_level_, requested_security_level_,
reinterpret_cast<uint8_t*>( reinterpret_cast<uint8_t*>(
@@ -2401,7 +2403,7 @@ CdmResponseType CryptoSession::CreateUsageTableHeader(
if (result == OEMCrypto_ERROR_SHORT_BUFFER) { if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
usage_table_header->resize(usage_table_header_size); usage_table_header->resize(usage_table_header_size);
WithOecLock("CreateUsageTableHeader Attempt 2", [&] { WithOecWriteLock("CreateUsageTableHeader Attempt 2", [&] {
result = OEMCrypto_CreateUsageTableHeader( result = OEMCrypto_CreateUsageTableHeader(
requested_security_level_, requested_security_level_,
reinterpret_cast<uint8_t*>( reinterpret_cast<uint8_t*>(
@@ -2423,7 +2425,7 @@ CdmResponseType CryptoSession::LoadUsageTableHeader(
LOGV("LoadUsageTableHeader: id=%lu", oec_session_id_); LOGV("LoadUsageTableHeader: id=%lu", oec_session_id_);
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("LoadUsageTableHeader", [&] { WithOecWriteLock("LoadUsageTableHeader", [&] {
result = OEMCrypto_LoadUsageTableHeader( result = OEMCrypto_LoadUsageTableHeader(
requested_security_level_, requested_security_level_,
reinterpret_cast<const uint8_t*>(usage_table_header.data()), reinterpret_cast<const uint8_t*>(usage_table_header.data()),
@@ -2468,7 +2470,7 @@ CdmResponseType CryptoSession::CreateUsageEntry(uint32_t* entry_number) {
} }
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("CreateUsageEntry", [&] { WithOecWriteLock("CreateUsageEntry", [&] {
result = OEMCrypto_CreateNewUsageEntry(oec_session_id_, entry_number); result = OEMCrypto_CreateNewUsageEntry(oec_session_id_, entry_number);
}); });
@@ -2495,7 +2497,7 @@ CdmResponseType CryptoSession::LoadUsageEntry(
LOGV("LoadUsageEntry: id=%lu", oec_session_id_); LOGV("LoadUsageEntry: id=%lu", oec_session_id_);
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("LoadUsageEntry", [&] { WithOecWriteLock("LoadUsageEntry", [&] {
result = OEMCrypto_LoadUsageEntry( result = OEMCrypto_LoadUsageEntry(
oec_session_id_, entry_number, oec_session_id_, entry_number,
reinterpret_cast<const uint8_t*>(usage_entry.data()), reinterpret_cast<const uint8_t*>(usage_entry.data()),
@@ -2546,7 +2548,7 @@ CdmResponseType CryptoSession::UpdateUsageEntry(
size_t usage_table_header_len = 0; size_t usage_table_header_len = 0;
size_t usage_entry_len = 0; size_t usage_entry_len = 0;
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("UpdateUsageEntry Attempt 1", [&] { WithOecWriteLock("UpdateUsageEntry Attempt 1", [&] {
result = OEMCrypto_UpdateUsageEntry( result = OEMCrypto_UpdateUsageEntry(
oec_session_id_, NULL, &usage_table_header_len, NULL, &usage_entry_len); oec_session_id_, NULL, &usage_table_header_len, NULL, &usage_entry_len);
}); });
@@ -2556,7 +2558,7 @@ CdmResponseType CryptoSession::UpdateUsageEntry(
usage_table_header->resize(usage_table_header_len); usage_table_header->resize(usage_table_header_len);
usage_entry->resize(usage_entry_len); usage_entry->resize(usage_entry_len);
WithOecLock("UpdateUsageEntry Attempt 2", [&] { WithOecWriteLock("UpdateUsageEntry Attempt 2", [&] {
result = OEMCrypto_UpdateUsageEntry( result = OEMCrypto_UpdateUsageEntry(
oec_session_id_, oec_session_id_,
reinterpret_cast<uint8_t*>( reinterpret_cast<uint8_t*>(
@@ -2588,7 +2590,7 @@ CdmResponseType CryptoSession::ShrinkUsageTableHeader(
size_t usage_table_header_len = 0; size_t usage_table_header_len = 0;
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("ShrinkUsageTableHeader Attempt 1", [&] { WithOecWriteLock("ShrinkUsageTableHeader Attempt 1", [&] {
result = OEMCrypto_ShrinkUsageTableHeader( result = OEMCrypto_ShrinkUsageTableHeader(
requested_security_level_, new_entry_count, NULL, requested_security_level_, new_entry_count, NULL,
&usage_table_header_len); &usage_table_header_len);
@@ -2597,7 +2599,7 @@ CdmResponseType CryptoSession::ShrinkUsageTableHeader(
if (result == OEMCrypto_ERROR_SHORT_BUFFER) { if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
usage_table_header->resize(usage_table_header_len); usage_table_header->resize(usage_table_header_len);
WithOecLock("ShrinkUsageTableHeader Attempt 2", [&] { WithOecWriteLock("ShrinkUsageTableHeader Attempt 2", [&] {
result = OEMCrypto_ShrinkUsageTableHeader( result = OEMCrypto_ShrinkUsageTableHeader(
requested_security_level_, new_entry_count, requested_security_level_, new_entry_count,
reinterpret_cast<uint8_t*>( reinterpret_cast<uint8_t*>(
@@ -2618,7 +2620,7 @@ CdmResponseType CryptoSession::MoveUsageEntry(uint32_t new_entry_number) {
LOGV("MoveUsageEntry: id=%lu", oec_session_id_); LOGV("MoveUsageEntry: id=%lu", oec_session_id_);
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("MoveUsageEntry", [&] { WithOecWriteLock("MoveUsageEntry", [&] {
result = OEMCrypto_MoveEntry(oec_session_id_, new_entry_number); result = OEMCrypto_MoveEntry(oec_session_id_, new_entry_number);
}); });
@@ -2660,7 +2662,7 @@ bool CryptoSession::CreateOldUsageEntry(
} }
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("CreateOldUsageEntry", [&] { WithOecWriteLock("CreateOldUsageEntry", [&] {
result = OEMCrypto_CreateOldUsageEntry( result = OEMCrypto_CreateOldUsageEntry(
requested_security_level_, time_since_license_received, requested_security_level_, time_since_license_received,
time_since_first_decrypt, time_since_last_decrypt, status, time_since_first_decrypt, time_since_last_decrypt, status,
@@ -2683,7 +2685,7 @@ CdmResponseType CryptoSession::CopyOldUsageEntry(
LOGV("CopyOldUsageEntry: id=%lu", oec_session_id_); LOGV("CopyOldUsageEntry: id=%lu", oec_session_id_);
OEMCryptoResult result; OEMCryptoResult result;
WithOecLock("CopyOldUsageEntry", [&] { WithOecWriteLock("CopyOldUsageEntry", [&] {
result = OEMCrypto_CopyOldUsageEntry( result = OEMCrypto_CopyOldUsageEntry(
oec_session_id_, oec_session_id_,
reinterpret_cast<const uint8_t*>(provider_session_token.data()), reinterpret_cast<const uint8_t*>(provider_session_token.data()),
@@ -2699,7 +2701,7 @@ bool CryptoSession::GetAnalogOutputCapabilities(bool* can_support_output,
bool* can_support_cgms_a) { bool* can_support_cgms_a) {
LOGV("GetAnalogOutputCapabilities: id=%lu", oec_session_id_); LOGV("GetAnalogOutputCapabilities: id=%lu", oec_session_id_);
uint32_t flags; uint32_t flags;
WithOecLock("GetAnalogOutputCapabilities", [&] { WithOecReadLock("GetAnalogOutputCapabilities", [&] {
flags = OEMCrypto_GetAnalogOutputFlags(requested_security_level_); flags = OEMCrypto_GetAnalogOutputFlags(requested_security_level_);
}); });
@@ -2779,7 +2781,7 @@ OEMCryptoResult CryptoSession::CopyBufferInChunks(
} }
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("CopyBufferInChunks", [&] { WithOecSessionLock("CopyBufferInChunks", [&] {
M_TIME(sts = OEMCrypto_CopyBuffer( M_TIME(sts = OEMCrypto_CopyBuffer(
oec_session_id_, params.encrypt_buffer + additional_offset, oec_session_id_, params.encrypt_buffer + additional_offset,
chunk_size, &buffer_descriptor, subsample_flags), chunk_size, &buffer_descriptor, subsample_flags),
@@ -2853,7 +2855,7 @@ OEMCryptoResult CryptoSession::DecryptInChunks(
// pattern length long, which is also guaranteed to be an exact number // pattern length long, which is also guaranteed to be an exact number
// of AES blocks long. // of AES blocks long.
OEMCryptoResult sts; OEMCryptoResult sts;
WithOecLock("DecryptInChunks", [&] { WithOecSessionLock("DecryptInChunks", [&] {
M_TIME( M_TIME(
sts = OEMCrypto_DecryptCENC( sts = OEMCrypto_DecryptCENC(
oec_session_id_, params.encrypt_buffer + additional_offset, oec_session_id_, params.encrypt_buffer + additional_offset,
@@ -2927,27 +2929,52 @@ void CryptoSession::IncrementIV(uint64_t increase_by,
} }
template <class Func> template <class Func>
auto CryptoSession::WithStaticFieldLock(const char* tag, Func body) auto CryptoSession::WithStaticFieldWriteLock(const char* tag, Func body)
-> decltype(body()) { -> decltype(body()) {
LOGV("Static Field Lock - %s", tag); LOGV("Static Field Write Lock - %s", tag);
std::unique_lock<std::mutex> auto_lock(static_field_lock_); std::unique_lock<shared_mutex> auto_lock(static_field_mutex_);
return body(); return body();
} }
template <class Func> template <class Func>
auto CryptoSession::WithOecLock(const char* tag, Func body) auto CryptoSession::WithStaticFieldReadLock(const char* tag, Func body)
-> decltype(body()) { -> decltype(body()) {
LOGV("OEMCrypto Lock - %s", tag); LOGV("Static Field Read Lock - %s", tag);
std::unique_lock<std::mutex> auto_lock(oem_crypto_lock_); shared_lock<shared_mutex> auto_lock(static_field_mutex_);
return body();
}
template <class Func>
auto CryptoSession::WithOecWriteLock(const char* tag, Func body)
-> decltype(body()) {
LOGV("OEMCrypto Write Lock - %s", tag);
std::unique_lock<shared_mutex> auto_lock(oem_crypto_mutex_);
return body();
}
template <class Func>
auto CryptoSession::WithOecReadLock(const char* tag, Func body)
-> decltype(body()) {
LOGV("OEMCrypto Read Lock - %s", tag);
shared_lock<shared_mutex> auto_lock(oem_crypto_mutex_);
return body();
}
template <class Func>
auto CryptoSession::WithOecSessionLock(const char* tag, Func body)
-> decltype(body()) {
LOGV("OEMCrypto Session Lock - %s", tag);
shared_lock<shared_mutex> oec_auto_lock(oem_crypto_mutex_);
std::unique_lock<std::mutex> session_auto_lock(oem_crypto_session_mutex_);
return body(); return body();
} }
bool CryptoSession::IsInitialized() { bool CryptoSession::IsInitialized() {
return WithStaticFieldLock("IsInitialized", [] { return initialized_; }); return WithStaticFieldReadLock("IsInitialized", [] { return initialized_; });
} }
// CryptoSesssionFactory support // CryptoSesssionFactory support
std::mutex CryptoSession::factory_lock_; std::mutex CryptoSession::factory_mutex_;
// The factory will either be set by WvCdmTestBase, or a default factory is // The factory will either be set by WvCdmTestBase, or a default factory is
// created on the first call to MakeCryptoSession. // created on the first call to MakeCryptoSession.
std::unique_ptr<CryptoSessionFactory> CryptoSession::factory_ = std::unique_ptr<CryptoSessionFactory> CryptoSession::factory_ =
@@ -2955,7 +2982,7 @@ std::unique_ptr<CryptoSessionFactory> CryptoSession::factory_ =
CryptoSession* CryptoSession::MakeCryptoSession( CryptoSession* CryptoSession::MakeCryptoSession(
metrics::CryptoMetrics* crypto_metrics) { metrics::CryptoMetrics* crypto_metrics) {
std::unique_lock<std::mutex> auto_lock(factory_lock_); std::unique_lock<std::mutex> auto_lock(factory_mutex_);
// If the factory_ has not been set, then use a default factory. // If the factory_ has not been set, then use a default factory.
if (factory_.get() == NULL) factory_.reset(new CryptoSessionFactory()); if (factory_.get() == NULL) factory_.reset(new CryptoSessionFactory());
return factory_->MakeCryptoSession(crypto_metrics); return factory_->MakeCryptoSession(crypto_metrics);