Snap for 6282504 from 778f75b210 to sc-release
Change-Id: I9b2004f89e4e68a96042ca8ef194c3fdb1c10ece
This commit is contained in:
@@ -168,7 +168,6 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libwvdrmcryptoplugin \
|
libwvdrmcryptoplugin \
|
||||||
libwvdrmdrmplugin \
|
libwvdrmdrmplugin \
|
||||||
libwvlevel3 \
|
libwvlevel3 \
|
||||||
libwv_odk \
|
|
||||||
|
|
||||||
LOCAL_SHARED_LIBRARIES := \
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
libbase \
|
libbase \
|
||||||
@@ -230,7 +229,6 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libwvdrmcryptoplugin_hidl \
|
libwvdrmcryptoplugin_hidl \
|
||||||
libwvdrmdrmplugin_hidl \
|
libwvdrmdrmplugin_hidl \
|
||||||
libwvlevel3 \
|
libwvlevel3 \
|
||||||
libwv_odk \
|
|
||||||
|
|
||||||
LOCAL_SHARED_LIBRARIES := \
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
android.hardware.drm@1.0 \
|
android.hardware.drm@1.0 \
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ cc_library_static {
|
|||||||
"vendor/widevine/libwvdrmengine/cdm/util/include",
|
"vendor/widevine/libwvdrmengine/cdm/util/include",
|
||||||
"vendor/widevine/libwvdrmengine/cdm/include",
|
"vendor/widevine/libwvdrmengine/cdm/include",
|
||||||
"vendor/widevine/libwvdrmengine/oemcrypto/include",
|
"vendor/widevine/libwvdrmengine/oemcrypto/include",
|
||||||
"vendor/widevine/libwvdrmengine/oemcrypto/odk/include",
|
|
||||||
"external/jsmn",
|
"external/jsmn",
|
||||||
"external/protobuf/src",
|
"external/protobuf/src",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ class CryptoSession {
|
|||||||
CdmResponseType GetSystemIdInternal(uint32_t* system_id);
|
CdmResponseType GetSystemIdInternal(uint32_t* system_id);
|
||||||
CdmResponseType GenerateRsaSignature(const std::string& message,
|
CdmResponseType GenerateRsaSignature(const std::string& message,
|
||||||
std::string* signature);
|
std::string* signature);
|
||||||
bool GetMaxSubsampleRegionSize(size_t* max);
|
size_t GetMaxSubsampleRegionSize();
|
||||||
|
|
||||||
bool SetDestinationBufferType();
|
bool SetDestinationBufferType();
|
||||||
|
|
||||||
@@ -429,6 +429,7 @@ class CryptoSession {
|
|||||||
static std::atomic<uint64_t> request_id_index_source_;
|
static std::atomic<uint64_t> request_id_index_source_;
|
||||||
|
|
||||||
uint32_t api_version_;
|
uint32_t api_version_;
|
||||||
|
size_t max_subsample_region_size_;
|
||||||
|
|
||||||
// Stores the most recent error code returned from a call to
|
// Stores the most recent error code returned from a call to
|
||||||
// OEMCrypto_DecryptCENC. This is used to reduce the total number of
|
// OEMCrypto_DecryptCENC. This is used to reduce the total number of
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ static_assert(ArraySize(kMaxSubsampleRegionSizes) ==
|
|||||||
"The kMaxSubsampleRegionSizes table needs to be updated to "
|
"The kMaxSubsampleRegionSizes table needs to be updated to "
|
||||||
"reflect the supported range of resource rating tiers.");
|
"reflect the supported range of resource rating tiers.");
|
||||||
|
|
||||||
constexpr size_t kDefaultMaximumChunkSize = 100 * KiB;
|
constexpr size_t kDefaultMaxSubsampleRegionSize = kMaxSubsampleRegionSizes[0];
|
||||||
|
|
||||||
// This maps a few common OEMCryptoResult to CdmResponseType. Many mappings
|
// This maps a few common OEMCryptoResult to CdmResponseType. Many mappings
|
||||||
// are not universal but are OEMCrypto method specific. Those will be
|
// are not universal but are OEMCrypto method specific. Those will be
|
||||||
@@ -217,7 +217,8 @@ CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
|
|||||||
requested_security_level_(kLevelDefault),
|
requested_security_level_(kLevelDefault),
|
||||||
usage_support_type_(kUnknownUsageSupport),
|
usage_support_type_(kUnknownUsageSupport),
|
||||||
usage_table_header_(nullptr),
|
usage_table_header_(nullptr),
|
||||||
api_version_(0) {
|
api_version_(0),
|
||||||
|
max_subsample_region_size_(0) {
|
||||||
assert(metrics);
|
assert(metrics);
|
||||||
Init();
|
Init();
|
||||||
life_span_.Start();
|
life_span_.Start();
|
||||||
@@ -1331,14 +1332,28 @@ CdmResponseType CryptoSession::GenerateRsaSignature(const std::string& message,
|
|||||||
"OEMCrypto_GenerateRSASignature");
|
"OEMCrypto_GenerateRSASignature");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CryptoSession::GetMaxSubsampleRegionSize(size_t* max) {
|
size_t CryptoSession::GetMaxSubsampleRegionSize() {
|
||||||
|
// If we haven't cached the answer yet, fetch it from OEMCrypto.
|
||||||
|
if (max_subsample_region_size_ == 0) {
|
||||||
uint32_t tier = 0;
|
uint32_t tier = 0;
|
||||||
if (!GetResourceRatingTier(&tier)) return false;
|
if (GetResourceRatingTier(&tier)) {
|
||||||
// Subtract RESOURCE_RATING_TIER_MIN to get a 0-based index into the table.
|
// Subtract RESOURCE_RATING_TIER_MIN to get a 0-based index into the
|
||||||
|
// table.
|
||||||
const uint32_t index = tier - RESOURCE_RATING_TIER_MIN;
|
const uint32_t index = tier - RESOURCE_RATING_TIER_MIN;
|
||||||
if (index >= ArraySize(kMaxSubsampleRegionSizes)) return false;
|
if (index < ArraySize(kMaxSubsampleRegionSizes)) {
|
||||||
*max = kMaxSubsampleRegionSizes[index];
|
max_subsample_region_size_ = kMaxSubsampleRegionSizes[index];
|
||||||
return true;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If something went wrong, use the default.
|
||||||
|
if (max_subsample_region_size_ == 0) {
|
||||||
|
LOGW("Unable to get maximum subsample region size. Defaulting to %zu.",
|
||||||
|
kDefaultMaxSubsampleRegionSize);
|
||||||
|
max_subsample_region_size_ = kDefaultMaxSubsampleRegionSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_subsample_region_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CryptoSession::Decrypt(
|
CdmResponseType CryptoSession::Decrypt(
|
||||||
@@ -1468,6 +1483,13 @@ CdmResponseType CryptoSession::Decrypt(
|
|||||||
// Convert the pattern descriptor
|
// Convert the pattern descriptor
|
||||||
OEMCrypto_CENCEncryptPatternDesc oec_pattern{params.pattern.encrypt_blocks,
|
OEMCrypto_CENCEncryptPatternDesc oec_pattern{params.pattern.encrypt_blocks,
|
||||||
params.pattern.skip_blocks};
|
params.pattern.skip_blocks};
|
||||||
|
// TODO(b/146581957): Remove this workaround once OEMCrypto treats (0,0) as
|
||||||
|
// 'cbcs' instead of 'cbc1'.
|
||||||
|
if (params.cipher_mode == kCipherModeCbc && oec_pattern.encrypt == 0 &&
|
||||||
|
oec_pattern.skip == 0) {
|
||||||
|
// (10, 0) is the preferred pattern for decrypting every block in 'cbcs'
|
||||||
|
oec_pattern.encrypt = 10;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if a key needs to be selected
|
// Check if a key needs to be selected
|
||||||
if (is_any_sample_protected) {
|
if (is_any_sample_protected) {
|
||||||
@@ -2723,12 +2745,7 @@ OEMCryptoResult CryptoSession::DecryptSample(
|
|||||||
OEMCryptoResult CryptoSession::LegacyDecrypt(
|
OEMCryptoResult CryptoSession::LegacyDecrypt(
|
||||||
const OEMCrypto_SampleDescription& sample, CdmCipherMode cipher_mode,
|
const OEMCrypto_SampleDescription& sample, CdmCipherMode cipher_mode,
|
||||||
const OEMCrypto_CENCEncryptPatternDesc& pattern) {
|
const OEMCrypto_CENCEncryptPatternDesc& pattern) {
|
||||||
size_t max_chunk_size;
|
const size_t max_chunk_size = GetMaxSubsampleRegionSize();
|
||||||
if (!GetMaxSubsampleRegionSize(&max_chunk_size)) {
|
|
||||||
LOGW("Unable to get maximum subsample region size. Defaulting to 100 KiB.");
|
|
||||||
max_chunk_size = kDefaultMaximumChunkSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
// We can be sure this is only called with one subsample containing one
|
// We can be sure this is only called with one subsample containing one
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
#include "license_protocol.pb.h"
|
#include "license_protocol.pb.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "metrics_collections.h"
|
#include "metrics_collections.h"
|
||||||
#include "odk.h"
|
|
||||||
#include "properties.h"
|
#include "properties.h"
|
||||||
#include "wv_cdm_constants.h"
|
#include "wv_cdm_constants.h"
|
||||||
|
|
||||||
|
|||||||
@@ -111,11 +111,6 @@ ssize_t WVCryptoPlugin::decrypt(bool secure, const uint8_t key[KEY_ID_SIZE],
|
|||||||
errorDetailMsg->setTo(
|
errorDetailMsg->setTo(
|
||||||
"The 'cens' schema is not supported by Widevine CDM.");
|
"The 'cens' schema is not supported by Widevine CDM.");
|
||||||
return kErrorUnsupportedCrypto;
|
return kErrorUnsupportedCrypto;
|
||||||
} else if (mode == kMode_AES_CBC &&
|
|
||||||
(pattern.mEncryptBlocks == 0 && pattern.mSkipBlocks == 0)) {
|
|
||||||
errorDetailMsg->setTo(
|
|
||||||
"The 'cbc1' schema is not supported by Widevine CDM.");
|
|
||||||
return kErrorUnsupportedCrypto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert parameters to the form the CDM wishes to consume them in.
|
// Convert parameters to the form the CDM wishes to consume them in.
|
||||||
|
|||||||
@@ -185,11 +185,6 @@ Return<void> WVCryptoPlugin::decrypt_1_2(
|
|||||||
_hidl_cb(Status_V1_2::BAD_VALUE, 0,
|
_hidl_cb(Status_V1_2::BAD_VALUE, 0,
|
||||||
"The 'cens' schema is not supported by Widevine CDM.");
|
"The 'cens' schema is not supported by Widevine CDM.");
|
||||||
return Void();
|
return Void();
|
||||||
} else if (mode == Mode::AES_CBC &&
|
|
||||||
(pattern.encryptBlocks == 0 && pattern.skipBlocks == 0)) {
|
|
||||||
_hidl_cb(Status_V1_2::BAD_VALUE, 0,
|
|
||||||
"The 'cbc1' schema is not supported by Widevine CDM.");
|
|
||||||
return Void();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert parameters to the form the CDM wishes to consume them in.
|
// Convert parameters to the form the CDM wishes to consume them in.
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ TEST_F(WVCryptoPluginTest, AttemptsToDecrypt) {
|
|||||||
"WVCryptoPlugin reported a detailed error message.";
|
"WVCryptoPlugin reported a detailed error message.";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WVCryptoPluginTest, RejectsCensAndCbc1) {
|
TEST_F(WVCryptoPluginTest, RejectsCens) {
|
||||||
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
||||||
|
|
||||||
constexpr size_t kSubSampleCount = 2;
|
constexpr size_t kSubSampleCount = 2;
|
||||||
@@ -380,7 +380,6 @@ TEST_F(WVCryptoPluginTest, RejectsCensAndCbc1) {
|
|||||||
static_cast<void*>(destination->unsecurePointer()));
|
static_cast<void*>(destination->unsecurePointer()));
|
||||||
ASSERT_NE(pDest, nullptr);
|
ASSERT_NE(pDest, nullptr);
|
||||||
|
|
||||||
Pattern noPattern = { 0, 0 };
|
|
||||||
Pattern recommendedPattern = { 1, 9 };
|
Pattern recommendedPattern = { 1, 9 };
|
||||||
|
|
||||||
// Provide the expected behavior for IsOpenSession
|
// Provide the expected behavior for IsOpenSession
|
||||||
@@ -409,15 +408,6 @@ TEST_F(WVCryptoPluginTest, RejectsCensAndCbc1) {
|
|||||||
EXPECT_EQ(status, Status::BAD_VALUE);
|
EXPECT_EQ(status, Status::BAD_VALUE);
|
||||||
EXPECT_EQ(bytesWritten, 0);
|
EXPECT_EQ(bytesWritten, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
plugin.decrypt(
|
|
||||||
false, hidl_array<uint8_t, 16>(keyId), hidl_array<uint8_t, 16>(iv),
|
|
||||||
Mode::AES_CBC, noPattern, hSubSamples, sourceBuffer, 0, hDestination,
|
|
||||||
[&](Status status, uint32_t bytesWritten,
|
|
||||||
hidl_string /* errorDetailMessage */) {
|
|
||||||
EXPECT_EQ(status, Status::BAD_VALUE);
|
|
||||||
EXPECT_EQ(bytesWritten, 0);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WVCryptoPluginTest, CommunicatesSecureBufferRequest) {
|
TEST_F(WVCryptoPluginTest, CommunicatesSecureBufferRequest) {
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ TEST_F(WVCryptoPluginTest, AttemptsToDecrypt) {
|
|||||||
"WVCryptoPlugin reported a detailed error message.";
|
"WVCryptoPlugin reported a detailed error message.";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WVCryptoPluginTest, RejectsCensAndCbc1) {
|
TEST_F(WVCryptoPluginTest, RejectsCens) {
|
||||||
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
android::sp<StrictMock<MockCDM>> cdm = new StrictMock<MockCDM>();
|
||||||
|
|
||||||
constexpr size_t kSubSampleCount = 2;
|
constexpr size_t kSubSampleCount = 2;
|
||||||
@@ -244,7 +244,6 @@ TEST_F(WVCryptoPluginTest, RejectsCensAndCbc1) {
|
|||||||
fread(inputData, sizeof(uint8_t), kDataSize, fp);
|
fread(inputData, sizeof(uint8_t), kDataSize, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
android::CryptoPlugin::Pattern noPattern = { 0, 0 };
|
|
||||||
android::CryptoPlugin::Pattern recommendedPattern = { 1, 9 };
|
android::CryptoPlugin::Pattern recommendedPattern = { 1, 9 };
|
||||||
|
|
||||||
// Provide the expected behavior for IsOpenSession
|
// Provide the expected behavior for IsOpenSession
|
||||||
@@ -267,15 +266,6 @@ TEST_F(WVCryptoPluginTest, RejectsCensAndCbc1) {
|
|||||||
"WVCryptoPlugin did not return an error for 'cens'.";
|
"WVCryptoPlugin did not return an error for 'cens'.";
|
||||||
EXPECT_NE(errorDetailMessage.size(), 0u) <<
|
EXPECT_NE(errorDetailMessage.size(), 0u) <<
|
||||||
"WVCryptoPlugin did not report a detailed error message for 'cens'.";
|
"WVCryptoPlugin did not report a detailed error message for 'cens'.";
|
||||||
|
|
||||||
res = plugin.decrypt(false, keyId, iv, CryptoPlugin::kMode_AES_CBC,
|
|
||||||
noPattern, inputData, subSamples, kSubSampleCount,
|
|
||||||
outputData, &errorDetailMessage);
|
|
||||||
|
|
||||||
EXPECT_EQ(res, kErrorUnsupportedCrypto) <<
|
|
||||||
"WVCryptoPlugin did not return an error for 'cbc1'.";
|
|
||||||
EXPECT_NE(errorDetailMessage.size(), 0u) <<
|
|
||||||
"WVCryptoPlugin did not report a detailed error message for 'cbc1'.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WVCryptoPluginTest, CommunicatesSecureBufferRequest) {
|
TEST_F(WVCryptoPluginTest, CommunicatesSecureBufferRequest) {
|
||||||
|
|||||||
@@ -844,7 +844,7 @@ void RenewalRoundTrip::FillAndVerifyCoreRequest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RenewalRoundTrip::CreateDefaultResponse() {
|
void RenewalRoundTrip::CreateDefaultResponse() {
|
||||||
if (license_messages_->api_version() < kCoreMessagesAPI) {
|
if (license_messages_->api_version() < kCoreMessagesAPI || is_release_) {
|
||||||
uint32_t control = 0;
|
uint32_t control = 0;
|
||||||
uint32_t nonce = 0;
|
uint32_t nonce = 0;
|
||||||
// If this is a v15 device, and a v15 license, and the license used a nonce,
|
// If this is a v15 device, and a v15 license, and the license used a nonce,
|
||||||
@@ -859,12 +859,9 @@ void RenewalRoundTrip::CreateDefaultResponse() {
|
|||||||
constexpr size_t index = 0;
|
constexpr size_t index = 0;
|
||||||
response_data_.keys[index].key_id_length = 0;
|
response_data_.keys[index].key_id_length = 0;
|
||||||
response_data_.keys[index].key_id[0] = '\0';
|
response_data_.keys[index].key_id[0] = '\0';
|
||||||
std::string kcVersion =
|
const uint32_t renewal_api =
|
||||||
"kc" + std::to_string(core_request_.api_major_version);
|
std::max<uint32_t>(core_request_.api_major_version, 15u);
|
||||||
if (global_features.api_version < kCoreMessagesAPI) {
|
std::string kcVersion = "kc" + std::to_string(renewal_api);
|
||||||
// For v15 or earlier devices, we use the api of the device.
|
|
||||||
kcVersion = "kc" + std::to_string(global_features.api_version);
|
|
||||||
}
|
|
||||||
memcpy(response_data_.keys[index].control.verification, kcVersion.c_str(),
|
memcpy(response_data_.keys[index].control.verification, kcVersion.c_str(),
|
||||||
4);
|
4);
|
||||||
const uint32_t duration = static_cast<uint32_t>(
|
const uint32_t duration = static_cast<uint32_t>(
|
||||||
|
|||||||
@@ -2804,7 +2804,8 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKey) {
|
|||||||
|
|
||||||
// Test that RewrapDeviceRSAKey verifies the RSA key is valid.
|
// Test that RewrapDeviceRSAKey verifies the RSA key is valid.
|
||||||
// TODO(b/144186970): This test should also run on Prov 3.0 devices.
|
// TODO(b/144186970): This test should also run on Prov 3.0 devices.
|
||||||
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKeyKeyboxTestAPI16) {
|
TEST_F(OEMCryptoLoadsCertificate,
|
||||||
|
CertificateProvisionBadRSAKeyKeyboxTestAPI16) {
|
||||||
Session s;
|
Session s;
|
||||||
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
|
ProvisioningRoundTrip provisioning_messages(&s, encoded_rsa_key_);
|
||||||
provisioning_messages.PrepareSession(keybox_);
|
provisioning_messages.PrepareSession(keybox_);
|
||||||
@@ -6065,17 +6066,10 @@ TEST_P(OEMCryptoUsageTableTest, TimingTest) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s2.close());
|
ASSERT_NO_FATAL_FAILURE(s2.close());
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||||
ASSERT_NO_FATAL_FAILURE(s2.open());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(s3.open());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(entry1.ReloadUsageEntry());
|
ASSERT_NO_FATAL_FAILURE(entry1.ReloadUsageEntry());
|
||||||
ASSERT_NO_FATAL_FAILURE(entry2.ReloadUsageEntry());
|
ASSERT_NO_FATAL_FAILURE(entry2.OpenAndReload(this));
|
||||||
ASSERT_NO_FATAL_FAILURE(entry3.ReloadUsageEntry());
|
ASSERT_NO_FATAL_FAILURE(entry3.OpenAndReload(this));
|
||||||
// Sending a release from an offline license that has been deactivate will
|
|
||||||
// only work if the license server can handle v16 licenses. This is a rare
|
|
||||||
// condition, so it is OK to break it during the transition months.
|
|
||||||
entry1.license_messages().set_api_version(global_features.api_version);
|
|
||||||
entry2.license_messages().set_api_version(global_features.api_version);
|
|
||||||
entry3.license_messages().set_api_version(global_features.api_version);
|
|
||||||
wvcdm::TestSleep::Sleep(kLongSleep);
|
wvcdm::TestSleep::Sleep(kLongSleep);
|
||||||
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
|
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
|
||||||
ASSERT_NO_FATAL_FAILURE(entry1.GenerateVerifyReport(kInactiveUsed));
|
ASSERT_NO_FATAL_FAILURE(entry1.GenerateVerifyReport(kInactiveUsed));
|
||||||
|
|||||||
Reference in New Issue
Block a user