Add Sandbox ID support
Merge from master branch of Widevine repo of http://go/wvgerrit/66078 Merge from oemcrypto-v15 branch of Widevine repo of http://go/wvgerrit/64022 This CL updates OEMCrypto ref code, unit tests, and core code for setting the sandbox id before initializing OEMCrypto. Test: unit tests only Test: tested as part of http://go/ag/5501993 Bug: 115834255 Change-Id: Id9831680fe4db1c69413815931cae4bc80df0c01
This commit is contained in:
@@ -64,6 +64,7 @@ class Properties {
|
|||||||
std::string* base_path);
|
std::string* base_path);
|
||||||
static bool GetFactoryKeyboxPath(std::string* keybox);
|
static bool GetFactoryKeyboxPath(std::string* keybox);
|
||||||
static bool GetOEMCryptoPath(std::string* library_name);
|
static bool GetOEMCryptoPath(std::string* library_name);
|
||||||
|
static bool GetSandboxId(std::string *sandbox_id);
|
||||||
static bool AlwaysUseKeySetIds();
|
static bool AlwaysUseKeySetIds();
|
||||||
static bool UseProviderIdInProvisioningRequest();
|
static bool UseProviderIdInProvisioningRequest();
|
||||||
|
|
||||||
|
|||||||
@@ -216,7 +216,14 @@ void CryptoSession::Init() {
|
|||||||
AutoLock auto_lock(crypto_lock_);
|
AutoLock auto_lock(crypto_lock_);
|
||||||
session_count_ += 1;
|
session_count_ += 1;
|
||||||
if (!initialized_) {
|
if (!initialized_) {
|
||||||
|
std::string sandbox_id;
|
||||||
OEMCryptoResult sts;
|
OEMCryptoResult sts;
|
||||||
|
if (Properties::GetSandboxId(&sandbox_id) && !sandbox_id.empty()) {
|
||||||
|
sts = OEMCrypto_SetSandbox(
|
||||||
|
reinterpret_cast<const uint8_t*>(sandbox_id.c_str()),
|
||||||
|
sandbox_id.length());
|
||||||
|
// TODO(blueeyes): it might be worth saving the sandbox id in a metric.
|
||||||
|
}
|
||||||
M_TIME(sts = OEMCrypto_Initialize(), metrics_, oemcrypto_initialize_, sts);
|
M_TIME(sts = OEMCrypto_Initialize(), metrics_, oemcrypto_initialize_, sts);
|
||||||
if (OEMCrypto_SUCCESS != sts) {
|
if (OEMCrypto_SUCCESS != sts) {
|
||||||
LOGE("OEMCrypto_Initialize failed: %d", sts);
|
LOGE("OEMCrypto_Initialize failed: %d", sts);
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ static const size_t kMaxGenericEncryptChunkSize = 100*1024;
|
|||||||
const OEMCryptoResult kOemCryptoResultVendorSpecificError1 =
|
const OEMCryptoResult kOemCryptoResultVendorSpecificError1 =
|
||||||
static_cast<OEMCryptoResult>(10008);
|
static_cast<OEMCryptoResult>(10008);
|
||||||
|
|
||||||
|
typedef OEMCryptoResult (*L1_SetSandbox_t)(const uint8_t* sandbox_id,
|
||||||
|
size_t sandbox_id_length);
|
||||||
typedef OEMCryptoResult (*L1_Initialize_t)(void);
|
typedef OEMCryptoResult (*L1_Initialize_t)(void);
|
||||||
typedef OEMCryptoResult (*L1_Terminate_t)(void);
|
typedef OEMCryptoResult (*L1_Terminate_t)(void);
|
||||||
typedef OEMCryptoResult (*L1_OpenSession_t)(OEMCrypto_SESSION* session);
|
typedef OEMCryptoResult (*L1_OpenSession_t)(OEMCrypto_SESSION* session);
|
||||||
@@ -279,6 +281,7 @@ typedef uint32_t (*L1_ResourceRatingTier_t)(void);
|
|||||||
struct FunctionPointers {
|
struct FunctionPointers {
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
L1_Initialize_t Initialize;
|
L1_Initialize_t Initialize;
|
||||||
|
L1_SetSandbox_t SetSandbox;
|
||||||
L1_Terminate_t Terminate;
|
L1_Terminate_t Terminate;
|
||||||
L1_OpenSession_t OpenSession;
|
L1_OpenSession_t OpenSession;
|
||||||
L1_CloseSession_t CloseSession;
|
L1_CloseSession_t CloseSession;
|
||||||
@@ -398,6 +401,8 @@ class WatchDog {
|
|||||||
|
|
||||||
// Called by worker thread.
|
// Called by worker thread.
|
||||||
void DoInit() {
|
void DoInit() {
|
||||||
|
// TODO(b/117558570): Level3 does not currently support sandbox.
|
||||||
|
// Level3_SetSandbox(&sandbox_id_[0], sandbox_id_.length());
|
||||||
status_ = Level3_Initialize();
|
status_ = Level3_Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,6 +574,11 @@ class Adapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSandbox(const uint8_t* sandbox_id,
|
||||||
|
size_t sandbox_id_length) {
|
||||||
|
sandbox_id_.assign(sandbox_id, sandbox_id + sandbox_id_length);
|
||||||
|
}
|
||||||
|
|
||||||
OEMCryptoResult Initialize() {
|
OEMCryptoResult Initialize() {
|
||||||
/*
|
/*
|
||||||
* To avoid changing the function signature and function contract, use a
|
* To avoid changing the function signature and function contract, use a
|
||||||
@@ -652,6 +662,13 @@ class Adapter {
|
|||||||
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_INVALID_L1);
|
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_INVALID_L1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!sandbox_id_.empty()) {
|
||||||
|
level1_.SetSandbox = (L1_SetSandbox_t)dlsym(level1_library_,
|
||||||
|
QUOTE(OEMCrypto_SetSandbox));
|
||||||
|
if (level1_.SetSandbox != NULL) {
|
||||||
|
level1_.SetSandbox(&sandbox_id_[0], sandbox_id_.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
OEMCryptoResult st = level1_.Initialize();
|
OEMCryptoResult st = level1_.Initialize();
|
||||||
if (st != OEMCrypto_SUCCESS) {
|
if (st != OEMCrypto_SUCCESS) {
|
||||||
LOGW("Could not initialize L1. Falling Back to L3.");
|
LOGW("Could not initialize L1. Falling Back to L3.");
|
||||||
@@ -961,6 +978,7 @@ class Adapter {
|
|||||||
struct FunctionPointers level3_;
|
struct FunctionPointers level3_;
|
||||||
std::map<OEMCrypto_SESSION, LevelSession> session_map_;
|
std::map<OEMCrypto_SESSION, LevelSession> session_map_;
|
||||||
wvcdm::Lock session_map_lock_;
|
wvcdm::Lock session_map_lock_;
|
||||||
|
std::vector<uint8_t> sandbox_id_;
|
||||||
// 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.
|
||||||
@@ -1212,6 +1230,16 @@ OEMCryptoResult OEMCrypto_CreateOldUsageEntry(
|
|||||||
}
|
}
|
||||||
} // namespace wvcdm
|
} // namespace wvcdm
|
||||||
|
|
||||||
|
extern "C" OEMCryptoResult OEMCrypto_SetSandbox(const uint8_t* sandbox_id,
|
||||||
|
size_t sandbox_id_length) {
|
||||||
|
if (!gAdapter.get()) {
|
||||||
|
gAdapter.reset(new Adapter());
|
||||||
|
}
|
||||||
|
gAdapter->SetSandbox(sandbox_id, sandbox_id_length);
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
|
extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
|
||||||
if (!gAdapter.get()) {
|
if (!gAdapter.get()) {
|
||||||
gAdapter.reset(new Adapter());
|
gAdapter.reset(new Adapter());
|
||||||
|
|||||||
@@ -151,6 +151,17 @@ bool Properties::GetOEMCryptoPath(std::string* library_name) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Properties::GetSandboxId(std::string* /* sandbox_id */) {
|
||||||
|
// TODO(fredgc): If needed, we could support android running on a VM by
|
||||||
|
// reading the sandbox ID from the file system. If the file system
|
||||||
|
// does not have a sandbox id, we would generate a random
|
||||||
|
// one. Another option is to have sandbox id be a system property.
|
||||||
|
// However, that is enough work not to do it pre-emptively. This
|
||||||
|
// TODO is just to let future coders know that the framework is in
|
||||||
|
// place, and should be pretty easy to plumb.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Properties::AlwaysUseKeySetIds() {
|
bool Properties::AlwaysUseKeySetIds() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
|
|||||||
return OEMCrypto_SUCCESS;
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" OEMCryptoResult OEMCrypto_SetSandbox(const uint8_t* /*sandbox_id*/,
|
||||||
|
size_t /*sandbox_id_length*/) {
|
||||||
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_Terminate(void) {
|
extern "C" OEMCryptoResult OEMCrypto_Terminate(void) {
|
||||||
if (!crypto_engine) {
|
if (!crypto_engine) {
|
||||||
LOGE("[OEMCrypto_Terminate(): not initialized]");
|
LOGE("[OEMCrypto_Terminate(): not initialized]");
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ void DeviceFeatures::Initialize(bool is_cast_receiver,
|
|||||||
supports_rsa_3072 = false;
|
supports_rsa_3072 = false;
|
||||||
api_version = 0;
|
api_version = 0;
|
||||||
derive_key_method = NO_METHOD;
|
derive_key_method = NO_METHOD;
|
||||||
|
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
|
||||||
if (OEMCrypto_SUCCESS != OEMCrypto_Initialize()) {
|
if (OEMCrypto_SUCCESS != OEMCrypto_Initialize()) {
|
||||||
printf("OEMCrypto_Initialize failed. All tests will fail.\n");
|
printf("OEMCrypto_Initialize failed. All tests will fail.\n");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -716,6 +716,8 @@ static const uint8_t kTestKeyRSAEuler_2048[] = {
|
|||||||
0x33, 0xe0, 0xdb, 0x03,
|
0x33, 0xe0, 0xdb, 0x03,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint8_t kTestSandbox[] = { 0x01, 0x02, 0x03 };
|
||||||
|
|
||||||
} // namespace wvoec
|
} // namespace wvoec
|
||||||
|
|
||||||
#endif // CDM_OEC_TEST_DATA_H_
|
#endif // CDM_OEC_TEST_DATA_H_
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil {
|
|||||||
const ::testing::TestInfo* const test_info =
|
const ::testing::TestInfo* const test_info =
|
||||||
::testing::UnitTest::GetInstance()->current_test_info();
|
::testing::UnitTest::GetInstance()->current_test_info();
|
||||||
LOGD("Running test %s.%s", test_info->test_case_name(), test_info->name());
|
LOGD("Running test %s.%s", test_info->test_case_name(), test_info->name());
|
||||||
|
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
|
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +226,7 @@ TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) {
|
|||||||
TEST_F(OEMCryptoClientTest, NormalInitTermination) {
|
TEST_F(OEMCryptoClientTest, NormalInitTermination) {
|
||||||
// Should be able to terminate OEMCrypto, and then restart it.
|
// Should be able to terminate OEMCrypto, and then restart it.
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate());
|
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate());
|
||||||
|
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
|
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4629,6 +4631,7 @@ class UsageTableTest : public GenericCryptoTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void Restart() {
|
virtual void Restart() {
|
||||||
|
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
|
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
|
||||||
EnsureTestKeys();
|
EnsureTestKeys();
|
||||||
ASSERT_NO_FATAL_FAILURE(session_.open());
|
ASSERT_NO_FATAL_FAILURE(session_.open());
|
||||||
|
|||||||
@@ -23,7 +23,10 @@ namespace wvoec {
|
|||||||
// These tests are required for LollyPop Android devices.
|
// These tests are required for LollyPop Android devices.
|
||||||
class OEMCryptoAndroidLMPTest : public ::testing::Test {
|
class OEMCryptoAndroidLMPTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); }
|
virtual void SetUp() {
|
||||||
|
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
|
||||||
|
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
|
||||||
|
}
|
||||||
|
|
||||||
virtual void TearDown() { OEMCrypto_Terminate(); }
|
virtual void TearDown() { OEMCrypto_Terminate(); }
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user