Merge MaxNumberOfSessions changes from CDM
Bug: 18377675 Implement new OEMCrypto function to get max number of sessions https://widevine-internal-review.googlesource.com/#/c/12980/ Add oemcrypto static adapter for v9 https://widevine-internal-review.googlesource.com/#/c/13022/ Support new property to query MaxNumberOfSessions in CDM https://widevine-internal-review.googlesource.com/#/c/13020/ Fix GetHdcpCapabilities incorrect return if not initialized https://widevine-internal-review.googlesource.com/#/c/13210/ Change-Id: I02738c543cedd6e38d8826f845fec6cb2b1ede3c
This commit is contained in:
committed by
John "Juce" Bruce
parent
891bd057f4
commit
23c95a1251
@@ -101,6 +101,7 @@ class CryptoSession {
|
|||||||
virtual bool GetHdcpCapabilities(OemCryptoHdcpVersion* current,
|
virtual bool GetHdcpCapabilities(OemCryptoHdcpVersion* current,
|
||||||
OemCryptoHdcpVersion* max);
|
OemCryptoHdcpVersion* max);
|
||||||
virtual bool GetRandom(size_t data_length, uint8_t* random_data);
|
virtual bool GetRandom(size_t data_length, uint8_t* random_data);
|
||||||
|
virtual bool GetMaxNumberOfSessions(size_t* max);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Init();
|
void Init();
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ static const std::string QUERY_KEY_MAX_HDCP_LEVEL = "MaxHdcpLevel";
|
|||||||
// maximum supported HDCP level
|
// maximum supported HDCP level
|
||||||
static const std::string QUERY_KEY_USAGE_SUPPORT = "UsageSupport";
|
static const std::string QUERY_KEY_USAGE_SUPPORT = "UsageSupport";
|
||||||
// whether usage reporting is supported
|
// whether usage reporting is supported
|
||||||
|
static const std::string QUERY_KEY_MAX_NUMBER_OF_SESSIONS = "MaxNumberOfSessions";
|
||||||
|
|
||||||
static const std::string QUERY_VALUE_TRUE = "True";
|
static const std::string QUERY_VALUE_TRUE = "True";
|
||||||
static const std::string QUERY_VALUE_FALSE = "False";
|
static const std::string QUERY_VALUE_FALSE = "False";
|
||||||
|
|||||||
@@ -449,6 +449,12 @@ CdmResponseType CdmEngine::QueryStatus(CdmQueryMap* key_info) {
|
|||||||
supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
|
supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t maximum_number_of_sessions;
|
||||||
|
success = crypto_session.GetMaxNumberOfSessions(&maximum_number_of_sessions);
|
||||||
|
if (success) {
|
||||||
|
(*key_info)[QUERY_KEY_MAX_NUMBER_OF_SESSIONS] = maximum_number_of_sessions;
|
||||||
|
}
|
||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -951,7 +951,13 @@ bool CryptoSession::RewrapDeviceRSAKey(const std::string& message,
|
|||||||
bool CryptoSession::GetHdcpCapabilities(OemCryptoHdcpVersion* current_version,
|
bool CryptoSession::GetHdcpCapabilities(OemCryptoHdcpVersion* current_version,
|
||||||
OemCryptoHdcpVersion* max_version) {
|
OemCryptoHdcpVersion* max_version) {
|
||||||
LOGV("GetHdcpCapabilities: id=%ld", (uint32_t)oec_session_id_);
|
LOGV("GetHdcpCapabilities: id=%ld", (uint32_t)oec_session_id_);
|
||||||
if (!initialized_) return UNKNOWN_ERROR;
|
if (!initialized_) return false;
|
||||||
|
if (current_version == NULL || max_version == NULL) {
|
||||||
|
LOGE(
|
||||||
|
"CryptoSession::GetHdcpCapabilities: |current_version|, "
|
||||||
|
"|max_version| cannot be NULL");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
OEMCrypto_HDCP_Capability current, max;
|
OEMCrypto_HDCP_Capability current, max;
|
||||||
OEMCryptoResult status = OEMCrypto_GetHDCPCapability(¤t, &max);
|
OEMCryptoResult status = OEMCrypto_GetHDCPCapability(¤t, &max);
|
||||||
|
|
||||||
@@ -980,4 +986,22 @@ bool CryptoSession::GetRandom(size_t data_length, uint8_t* random_data) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CryptoSession::GetMaxNumberOfSessions(size_t* max) {
|
||||||
|
LOGV("GetMaxNumberOfSessions");
|
||||||
|
if (!initialized_) return false;
|
||||||
|
if (max == NULL) {
|
||||||
|
LOGE("CryptoSession::GetMaxNumberOfSessions: |max| cannot be NULL");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t max_sessions;
|
||||||
|
OEMCryptoResult status = OEMCrypto_GetMaxNumberOfSessions(&max_sessions);
|
||||||
|
if (OEMCrypto_SUCCESS != status) {
|
||||||
|
LOGW("OEMCrypto_GetMaxNumberOfSessions fails with %d", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*max = max_sessions;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}; // namespace wvcdm
|
}; // namespace wvcdm
|
||||||
|
|||||||
@@ -24,8 +24,10 @@
|
|||||||
#include "properties.h"
|
#include "properties.h"
|
||||||
|
|
||||||
using namespace wvoec3;
|
using namespace wvoec3;
|
||||||
|
using wvcdm::kLevelDefault;
|
||||||
|
using wvcdm::kLevel3;
|
||||||
|
|
||||||
namespace wvcdm {
|
namespace {
|
||||||
|
|
||||||
typedef OEMCryptoResult (*L1_Initialize_t)(void);
|
typedef OEMCryptoResult (*L1_Initialize_t)(void);
|
||||||
typedef OEMCryptoResult (*L1_Terminate_t)(void);
|
typedef OEMCryptoResult (*L1_Terminate_t)(void);
|
||||||
@@ -138,6 +140,7 @@ typedef OEMCryptoResult (*L1_DeleteUsageEntry_t)(
|
|||||||
const uint8_t* message, size_t message_length, const uint8_t* signature,
|
const uint8_t* message, size_t message_length, const uint8_t* signature,
|
||||||
size_t signature_length);
|
size_t signature_length);
|
||||||
typedef OEMCryptoResult (*L1_DeleteUsageTable_t)();
|
typedef OEMCryptoResult (*L1_DeleteUsageTable_t)();
|
||||||
|
typedef OEMCryptoResult (*L1_GetMaxNumberOfSessions_t)(size_t *maximum);
|
||||||
|
|
||||||
struct FunctionPointers {
|
struct FunctionPointers {
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
@@ -175,6 +178,7 @@ struct FunctionPointers {
|
|||||||
L1_ReportUsage_t ReportUsage;
|
L1_ReportUsage_t ReportUsage;
|
||||||
L1_DeleteUsageEntry_t DeleteUsageEntry;
|
L1_DeleteUsageEntry_t DeleteUsageEntry;
|
||||||
L1_DeleteUsageTable_t DeleteUsageTable;
|
L1_DeleteUsageTable_t DeleteUsageTable;
|
||||||
|
L1_GetMaxNumberOfSessions_t GetMaxNumberOfSessions;
|
||||||
|
|
||||||
L1_LoadKeys_V8_t LoadKeys_V8;
|
L1_LoadKeys_V8_t LoadKeys_V8;
|
||||||
L1_GenerateRSASignature_V8_t GenerateRSASignature_V8;
|
L1_GenerateRSASignature_V8_t GenerateRSASignature_V8;
|
||||||
@@ -290,6 +294,9 @@ class Adapter {
|
|||||||
LOOKUP(DeleteUsageEntry, OEMCrypto_DeleteUsageEntry);
|
LOOKUP(DeleteUsageEntry, OEMCrypto_DeleteUsageEntry);
|
||||||
LOOKUP(DeleteUsageTable, OEMCrypto_DeleteUsageTable);
|
LOOKUP(DeleteUsageTable, OEMCrypto_DeleteUsageTable);
|
||||||
}
|
}
|
||||||
|
if (level1_.version >= 10) {
|
||||||
|
LOOKUP(GetMaxNumberOfSessions, OEMCrypto_GetMaxNumberOfSessions);
|
||||||
|
}
|
||||||
if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) {
|
if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -353,6 +360,7 @@ class Adapter {
|
|||||||
level3_.ReportUsage = Level3_ReportUsage;
|
level3_.ReportUsage = Level3_ReportUsage;
|
||||||
level3_.DeleteUsageEntry = Level3_DeleteUsageEntry;
|
level3_.DeleteUsageEntry = Level3_DeleteUsageEntry;
|
||||||
level3_.DeleteUsageTable = Level3_DeleteUsageTable;
|
level3_.DeleteUsageTable = Level3_DeleteUsageTable;
|
||||||
|
level3_.GetMaxNumberOfSessions = Level3_GetMaxNumberOfSessions;
|
||||||
level3_.version = Level3_APIVersion();
|
level3_.version = Level3_APIVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,13 +374,13 @@ class Adapter {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FunctionPointers* get(SecurityLevel level) {
|
const FunctionPointers* get(wvcdm::SecurityLevel level) {
|
||||||
if (level1_valid_ && level == kLevelDefault) return &level1_;
|
if (level1_valid_ && level == kLevelDefault) return &level1_;
|
||||||
return &level3_;
|
return &level3_;
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelSession get(OEMCrypto_SESSION session) {
|
LevelSession get(OEMCrypto_SESSION session) {
|
||||||
AutoLock auto_lock(session_map_lock_);
|
wvcdm::AutoLock auto_lock(session_map_lock_);
|
||||||
map_iterator pair = session_map_.find(session);
|
map_iterator pair = session_map_.find(session);
|
||||||
if (pair == session_map_.end()) {
|
if (pair == session_map_.end()) {
|
||||||
return LevelSession();
|
return LevelSession();
|
||||||
@@ -380,7 +388,8 @@ class Adapter {
|
|||||||
return pair->second;
|
return pair->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult OpenSession(OEMCrypto_SESSION* session, SecurityLevel level) {
|
OEMCryptoResult OpenSession(OEMCrypto_SESSION* session,
|
||||||
|
wvcdm::SecurityLevel level) {
|
||||||
LevelSession new_session;
|
LevelSession new_session;
|
||||||
OEMCryptoResult result;
|
OEMCryptoResult result;
|
||||||
if (level == kLevelDefault && level1_valid_) {
|
if (level == kLevelDefault && level1_valid_) {
|
||||||
@@ -393,7 +402,7 @@ class Adapter {
|
|||||||
*session = new_session.session + kLevel3Offset;
|
*session = new_session.session + kLevel3Offset;
|
||||||
}
|
}
|
||||||
if (result == OEMCrypto_SUCCESS) {
|
if (result == OEMCrypto_SUCCESS) {
|
||||||
AutoLock auto_lock(session_map_lock_);
|
wvcdm::AutoLock auto_lock(session_map_lock_);
|
||||||
// Make sure session is not already in my list of sessions.
|
// Make sure session is not already in my list of sessions.
|
||||||
while (session_map_.find(*session) != session_map_.end()) {
|
while (session_map_.find(*session) != session_map_.end()) {
|
||||||
(*session)++;
|
(*session)++;
|
||||||
@@ -404,7 +413,7 @@ class Adapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult CloseSession(OEMCrypto_SESSION session) {
|
OEMCryptoResult CloseSession(OEMCrypto_SESSION session) {
|
||||||
AutoLock auto_lock(session_map_lock_);
|
wvcdm::AutoLock auto_lock(session_map_lock_);
|
||||||
map_iterator pair = session_map_.find(session);
|
map_iterator pair = session_map_.find(session);
|
||||||
if (pair == session_map_.end()) {
|
if (pair == session_map_.end()) {
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
@@ -421,7 +430,7 @@ class Adapter {
|
|||||||
struct FunctionPointers level1_;
|
struct FunctionPointers level1_;
|
||||||
struct FunctionPointers level3_;
|
struct FunctionPointers level3_;
|
||||||
std::map<OEMCrypto_SESSION, LevelSession> session_map_;
|
std::map<OEMCrypto_SESSION, LevelSession> session_map_;
|
||||||
Lock session_map_lock_;
|
wvcdm::Lock session_map_lock_;
|
||||||
// This is just for debugging the map between session ids.
|
// This is just for debugging the map between session ids.
|
||||||
// If we add this to the level 3 session id, then the external session
|
// If we add this to the level 3 session id, then the external session
|
||||||
// id will match the internal session id in the last two digits.
|
// id will match the internal session id in the last two digits.
|
||||||
@@ -430,6 +439,72 @@ class Adapter {
|
|||||||
|
|
||||||
static Adapter* kAdapter = 0;
|
static Adapter* kAdapter = 0;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace wvcdm {
|
||||||
|
|
||||||
|
OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session,
|
||||||
|
SecurityLevel level) {
|
||||||
|
if (!kAdapter) return OEMCrypto_ERROR_OPEN_SESSION_FAILED;
|
||||||
|
return kAdapter->OpenSession(session, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult OEMCrypto_IsKeyboxValid(SecurityLevel level) {
|
||||||
|
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
const FunctionPointers* fcn = kAdapter->get(level);
|
||||||
|
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
|
return fcn->IsKeyboxValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength,
|
||||||
|
SecurityLevel level) {
|
||||||
|
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
const FunctionPointers* fcn = kAdapter->get(level);
|
||||||
|
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
|
return fcn->GetDeviceID(deviceID, idLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength,
|
||||||
|
SecurityLevel level) {
|
||||||
|
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
const FunctionPointers* fcn = kAdapter->get(level);
|
||||||
|
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
|
return fcn->GetKeyData(keyData, keyDataLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
|
||||||
|
size_t keyBoxLength,
|
||||||
|
SecurityLevel level) {
|
||||||
|
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
const FunctionPointers* fcn = kAdapter->get(level);
|
||||||
|
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
|
return fcn->InstallKeybox(keybox, keyBoxLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t OEMCrypto_APIVersion(SecurityLevel level) {
|
||||||
|
if (!kAdapter) return 0;
|
||||||
|
const FunctionPointers* fcn = kAdapter->get(level);
|
||||||
|
if (!fcn) return 0;
|
||||||
|
return fcn->APIVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* OEMCrypto_SecurityLevel(SecurityLevel level) {
|
||||||
|
if (!kAdapter) return "";
|
||||||
|
const FunctionPointers* fcn = kAdapter->get(level);
|
||||||
|
if (!fcn) return "";
|
||||||
|
return fcn->SecurityLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OEMCrypto_SupportsUsageTable(SecurityLevel level) {
|
||||||
|
if (!kAdapter) return false;
|
||||||
|
const FunctionPointers* fcn = kAdapter->get(level);
|
||||||
|
if (!fcn) return false;
|
||||||
|
if (fcn->version == 8) return false;
|
||||||
|
return fcn->SupportsUsageTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace wvcdm
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
|
extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
|
||||||
if (kAdapter) {
|
if (kAdapter) {
|
||||||
delete kAdapter;
|
delete kAdapter;
|
||||||
@@ -452,12 +527,6 @@ extern "C" OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session) {
|
|||||||
return OEMCrypto_OpenSession(session, kLevelDefault);
|
return OEMCrypto_OpenSession(session, kLevelDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session,
|
|
||||||
SecurityLevel level) {
|
|
||||||
if (!kAdapter) return OEMCrypto_ERROR_OPEN_SESSION_FAILED;
|
|
||||||
return kAdapter->OpenSession(session, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) {
|
extern "C" OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) {
|
||||||
if (!kAdapter) return OEMCrypto_ERROR_CLOSE_SESSION_FAILED;
|
if (!kAdapter) return OEMCrypto_ERROR_CLOSE_SESSION_FAILED;
|
||||||
return kAdapter->CloseSession(session);
|
return kAdapter->CloseSession(session);
|
||||||
@@ -550,52 +619,20 @@ extern "C" OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
|
|||||||
return OEMCrypto_InstallKeybox(keybox, keyBoxLength, kLevelDefault);
|
return OEMCrypto_InstallKeybox(keybox, keyBoxLength, kLevelDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
|
|
||||||
size_t keyBoxLength,
|
|
||||||
SecurityLevel level) {
|
|
||||||
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
|
||||||
const FunctionPointers* fcn = kAdapter->get(level);
|
|
||||||
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
|
||||||
return fcn->InstallKeybox(keybox, keyBoxLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_IsKeyboxValid() {
|
extern "C" OEMCryptoResult OEMCrypto_IsKeyboxValid() {
|
||||||
return OEMCrypto_IsKeyboxValid(kLevelDefault);
|
return OEMCrypto_IsKeyboxValid(kLevelDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult OEMCrypto_IsKeyboxValid(SecurityLevel level) {
|
|
||||||
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
|
||||||
const FunctionPointers* fcn = kAdapter->get(level);
|
|
||||||
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
|
||||||
return fcn->IsKeyboxValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
|
extern "C" OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
|
||||||
size_t* idLength) {
|
size_t* idLength) {
|
||||||
return OEMCrypto_GetDeviceID(deviceID, idLength, kLevelDefault);
|
return OEMCrypto_GetDeviceID(deviceID, idLength, kLevelDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength,
|
|
||||||
SecurityLevel level) {
|
|
||||||
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
|
||||||
const FunctionPointers* fcn = kAdapter->get(level);
|
|
||||||
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
|
||||||
return fcn->GetDeviceID(deviceID, idLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
|
extern "C" OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
|
||||||
size_t* keyDataLength) {
|
size_t* keyDataLength) {
|
||||||
return OEMCrypto_GetKeyData(keyData, keyDataLength, kLevelDefault);
|
return OEMCrypto_GetKeyData(keyData, keyDataLength, kLevelDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength,
|
|
||||||
SecurityLevel level) {
|
|
||||||
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
|
||||||
const FunctionPointers* fcn = kAdapter->get(level);
|
|
||||||
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
|
||||||
return fcn->GetKeyData(keyData, keyDataLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
|
extern "C" OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
|
||||||
size_t dataLength) {
|
size_t dataLength) {
|
||||||
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
@@ -676,24 +713,10 @@ extern "C" uint32_t OEMCrypto_APIVersion() {
|
|||||||
return OEMCrypto_APIVersion(kLevelDefault);
|
return OEMCrypto_APIVersion(kLevelDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t OEMCrypto_APIVersion(SecurityLevel level) {
|
|
||||||
if (!kAdapter) return 0;
|
|
||||||
const FunctionPointers* fcn = kAdapter->get(level);
|
|
||||||
if (!fcn) return 0;
|
|
||||||
return fcn->APIVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" const char* OEMCrypto_SecurityLevel() {
|
extern "C" const char* OEMCrypto_SecurityLevel() {
|
||||||
return OEMCrypto_SecurityLevel(kLevelDefault);
|
return OEMCrypto_SecurityLevel(kLevelDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* OEMCrypto_SecurityLevel(SecurityLevel level) {
|
|
||||||
if (!kAdapter) return "";
|
|
||||||
const FunctionPointers* fcn = kAdapter->get(level);
|
|
||||||
if (!fcn) return "";
|
|
||||||
return fcn->SecurityLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt(
|
extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt(
|
||||||
OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length,
|
OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length,
|
||||||
const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) {
|
const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) {
|
||||||
@@ -751,14 +774,6 @@ extern "C" bool OEMCrypto_SupportsUsageTable() {
|
|||||||
return OEMCrypto_SupportsUsageTable(kLevelDefault);
|
return OEMCrypto_SupportsUsageTable(kLevelDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OEMCrypto_SupportsUsageTable(SecurityLevel level) {
|
|
||||||
if (!kAdapter) return false;
|
|
||||||
const FunctionPointers* fcn = kAdapter->get(level);
|
|
||||||
if (!fcn) return false;
|
|
||||||
if( fcn->version == 8 ) return false;
|
|
||||||
return fcn->SupportsUsageTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_UpdateUsageTable() {
|
extern "C" OEMCryptoResult OEMCrypto_UpdateUsageTable() {
|
||||||
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
|
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
|
||||||
@@ -828,4 +843,12 @@ extern "C" OEMCryptoResult OEMCrypto_DeleteUsageTable() {
|
|||||||
return sts;
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace wvcdm
|
extern "C" OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *maximum) {
|
||||||
|
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
const FunctionPointers* fcn = kAdapter->get(kLevelDefault);
|
||||||
|
if (!fcn) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
if (fcn->version < 10) {
|
||||||
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
return fcn->GetMaxNumberOfSessions(maximum);
|
||||||
|
}
|
||||||
|
|||||||
@@ -529,6 +529,17 @@ status_t WVDrmPlugin::getPropertyString(const String8& name,
|
|||||||
return kErrorCDMGeneric;
|
return kErrorCDMGeneric;
|
||||||
}
|
}
|
||||||
value = status[QUERY_KEY_USAGE_SUPPORT].c_str();
|
value = status[QUERY_KEY_USAGE_SUPPORT].c_str();
|
||||||
|
} else if (name == "maxNumberOfSessions") {
|
||||||
|
CdmQueryMap status;
|
||||||
|
CdmResponseType res = mCDM->QueryStatus(&status);
|
||||||
|
if (res != wvcdm::NO_ERROR) {
|
||||||
|
ALOGE("Error querying CDM status: %u", res);
|
||||||
|
return mapCdmResponseType(res);
|
||||||
|
} else if (!status.count(QUERY_KEY_MAX_NUMBER_OF_SESSIONS)) {
|
||||||
|
ALOGE("CDM did not report maximum number of media drm sessions");
|
||||||
|
return kErrorCDMGeneric;
|
||||||
|
}
|
||||||
|
value = status[QUERY_KEY_MAX_NUMBER_OF_SESSIONS].c_str();
|
||||||
} else {
|
} else {
|
||||||
ALOGE("App requested unknown string property %s", name.string());
|
ALOGE("App requested unknown string property %s", name.string());
|
||||||
return android::ERROR_DRM_CANNOT_HANDLE;
|
return android::ERROR_DRM_CANNOT_HANDLE;
|
||||||
|
|||||||
@@ -708,6 +708,10 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
|||||||
CdmQueryMap provisioningIDMap;
|
CdmQueryMap provisioningIDMap;
|
||||||
provisioningIDMap[QUERY_KEY_PROVISIONING_ID] = provisioningId;
|
provisioningIDMap[QUERY_KEY_PROVISIONING_ID] = provisioningId;
|
||||||
|
|
||||||
|
static const string maxSessions = "18";
|
||||||
|
CdmQueryMap maxSessionsMap;
|
||||||
|
maxSessionsMap[QUERY_KEY_MAX_NUMBER_OF_SESSIONS] = maxSessions;
|
||||||
|
|
||||||
EXPECT_CALL(cdm, QueryStatus(_))
|
EXPECT_CALL(cdm, QueryStatus(_))
|
||||||
.WillOnce(DoAll(SetArgPointee<0>(l1Map),
|
.WillOnce(DoAll(SetArgPointee<0>(l1Map),
|
||||||
Return(wvcdm::NO_ERROR)))
|
Return(wvcdm::NO_ERROR)))
|
||||||
@@ -718,6 +722,8 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
|||||||
.WillOnce(DoAll(SetArgPointee<0>(systemIDMap),
|
.WillOnce(DoAll(SetArgPointee<0>(systemIDMap),
|
||||||
Return(wvcdm::NO_ERROR)))
|
Return(wvcdm::NO_ERROR)))
|
||||||
.WillOnce(DoAll(SetArgPointee<0>(provisioningIDMap),
|
.WillOnce(DoAll(SetArgPointee<0>(provisioningIDMap),
|
||||||
|
Return(wvcdm::NO_ERROR)))
|
||||||
|
.WillOnce(DoAll(SetArgPointee<0>(maxSessionsMap),
|
||||||
Return(wvcdm::NO_ERROR)));
|
Return(wvcdm::NO_ERROR)));
|
||||||
|
|
||||||
String8 stringResult;
|
String8 stringResult;
|
||||||
@@ -759,6 +765,10 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
|||||||
ASSERT_EQ(OK, res);
|
ASSERT_EQ(OK, res);
|
||||||
EXPECT_THAT(vectorResult, ElementsAreArray(provisioningId.data(),
|
EXPECT_THAT(vectorResult, ElementsAreArray(provisioningId.data(),
|
||||||
provisioningId.size()));
|
provisioningId.size()));
|
||||||
|
|
||||||
|
res = plugin.getPropertyString(String8("maxNumberOfSessions"), stringResult);
|
||||||
|
ASSERT_EQ(OK, res);
|
||||||
|
EXPECT_EQ(maxSessions, stringResult.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WVDrmPluginTest, DoesNotGetUnknownProperties) {
|
TEST_F(WVDrmPluginTest, DoesNotGetUnknownProperties) {
|
||||||
|
|||||||
@@ -274,6 +274,7 @@ typedef enum RSA_Padding_Scheme {
|
|||||||
#define OEMCrypto_DeleteUsageTable _oecc34
|
#define OEMCrypto_DeleteUsageTable _oecc34
|
||||||
#define OEMCrypto_LoadKeys _oecc35
|
#define OEMCrypto_LoadKeys _oecc35
|
||||||
#define OEMCrypto_GenerateRSASignature _oecc36
|
#define OEMCrypto_GenerateRSASignature _oecc36
|
||||||
|
#define OEMCrypto_GetMaxNumberOfSessions _oecc37
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OEMCrypto_Initialize
|
* OEMCrypto_Initialize
|
||||||
@@ -1993,6 +1994,30 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session,
|
|||||||
*/
|
*/
|
||||||
OEMCryptoResult OEMCrypto_DeleteUsageTable();
|
OEMCryptoResult OEMCrypto_DeleteUsageTable();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OEMCRYPTO_GetMaxNumberOfSessions()
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Returns the maximum number of concurrent OEMCrypto sessions supported by
|
||||||
|
* the device. The CDM and OEMCrypto consumers can query this value so they
|
||||||
|
* can use resources more effectively.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* maximum (out) - the maximum number of OEMCrypto sessions supported by the
|
||||||
|
* device.
|
||||||
|
*
|
||||||
|
* Threading:
|
||||||
|
* This function may be called simultaneously with any other functions.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* OEMCrypto_SUCCESS
|
||||||
|
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||||||
|
*
|
||||||
|
* Version:
|
||||||
|
* This method is added in API version 10.
|
||||||
|
*/
|
||||||
|
OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *max);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ namespace wvoec3 {
|
|||||||
#define Level3_ReportUsage _lcc32
|
#define Level3_ReportUsage _lcc32
|
||||||
#define Level3_DeleteUsageEntry _lcc33
|
#define Level3_DeleteUsageEntry _lcc33
|
||||||
#define Level3_DeleteUsageTable _lcc34
|
#define Level3_DeleteUsageTable _lcc34
|
||||||
|
#define Level3_GetMaxNumberOfSessions _lcc37
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
@@ -185,6 +186,7 @@ OEMCryptoResult Level3_DeleteUsageEntry(OEMCrypto_SESSION session,
|
|||||||
const uint8_t *signature,
|
const uint8_t *signature,
|
||||||
size_t signature_length);
|
size_t signature_length);
|
||||||
OEMCryptoResult Level3_DeleteUsageTable();
|
OEMCryptoResult Level3_DeleteUsageTable();
|
||||||
|
OEMCryptoResult Level3_GetMaxNumberOfSessions(size_t *maximum);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif // LEVEL3_OEMCRYPTO_H_
|
#endif // LEVEL3_OEMCRYPTO_H_
|
||||||
|
|||||||
@@ -1291,4 +1291,15 @@ OEMCryptoResult OEMCrypto_DeleteUsageTable() {
|
|||||||
return OEMCrypto_SUCCESS;
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *maximum) {
|
||||||
|
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||||
|
LOGI("-- OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(%p)\n", maximum);
|
||||||
|
}
|
||||||
|
if (maximum == NULL) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
const size_t kMaxSupportedOEMCryptoSessions = 64;
|
||||||
|
*maximum = kMaxSupportedOEMCryptoSessions;
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace wvoec_mock
|
} // namespace wvoec_mock
|
||||||
|
|||||||
@@ -1597,7 +1597,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
|
|||||||
uint32_t version = OEMCrypto_APIVersion();
|
uint32_t version = OEMCrypto_APIVersion();
|
||||||
cout << " OEMCrypto API version is " << version << endl;
|
cout << " OEMCrypto API version is " << version << endl;
|
||||||
ASSERT_LE(8, version);
|
ASSERT_LE(8, version);
|
||||||
ASSERT_GE(9, version);
|
ASSERT_GE(10, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OEMCryptoClientTest, NormalGetKeyData) {
|
TEST_F(OEMCryptoClientTest, NormalGetKeyData) {
|
||||||
@@ -1650,6 +1650,13 @@ TEST_F(OEMCryptoClientTest, CheckHDCPCapability) {
|
|||||||
HDCPCapabilityAsString(maximum));
|
HDCPCapabilityAsString(maximum));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(OEMCryptoClientTest, CheckMaxNumberOfOEMCryptoSessions) {
|
||||||
|
size_t maximum;
|
||||||
|
OEMCryptoResult sts = OEMCrypto_GetMaxNumberOfSessions(&maximum);
|
||||||
|
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||||
|
printf(" Max Number of Sessions: %zu.\n", maximum);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(OEMCryptoClientTest, KeyboxValid) {
|
TEST_F(OEMCryptoClientTest, KeyboxValid) {
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid());
|
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid());
|
||||||
}
|
}
|
||||||
@@ -1732,19 +1739,23 @@ TEST_F(OEMCryptoClientTest, TwoSessionsOpenClose) {
|
|||||||
ASSERT_FALSE(s2.isOpen());
|
ASSERT_FALSE(s2.isOpen());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OEMCryptoClientTest, EightSessionsOpenClose) {
|
TEST_F(OEMCryptoClientTest, MaxSessionsOpenClose) {
|
||||||
Session s[8];
|
size_t max_sessions;
|
||||||
for (int i = 0; i < 8; i++) {
|
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetMaxNumberOfSessions(&max_sessions));
|
||||||
|
ASSERT_GT(max_sessions, 0);
|
||||||
|
vector<Session> s(max_sessions);
|
||||||
|
for (int i = 0; i < s.size(); i++) {
|
||||||
s[i].open();
|
s[i].open();
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, s[i].getStatus());
|
ASSERT_EQ(OEMCrypto_SUCCESS, s[i].getStatus());
|
||||||
ASSERT_TRUE(s[i].isOpen());
|
ASSERT_TRUE(s[i].isOpen());
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < s.size(); i++) {
|
||||||
s[i].close();
|
s[i].close();
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, s[i].getStatus());
|
ASSERT_EQ(OEMCrypto_SUCCESS, s[i].getStatus());
|
||||||
ASSERT_FALSE(s[i].isOpen());
|
ASSERT_FALSE(s[i].isOpen());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO(kqyang): Add more tests exercising multiple sessions.
|
||||||
|
|
||||||
TEST_F(OEMCryptoClientTest, GenerateNonce) {
|
TEST_F(OEMCryptoClientTest, GenerateNonce) {
|
||||||
Session s;
|
Session s;
|
||||||
|
|||||||
Reference in New Issue
Block a user